Ibyar Aurora, is a web framework, that can create and define a Web Component standards ('custom elements', 'Shadow DOM' and 'HTML Templates'), that compatible with other frameworks, using Typescript.
This framework build with-in a embedded JavaScript Engine @ibyar/expressions to execute Template syntax and attributes binding.
- Demo: https://muhammad-salem.github.io/aurora-demo
- API Doc: https://muhammad-salem.github.io/aurora-docs
- Ibyar Expression & Elements parser: https://muhammad-salem.github.io/astexplorer
- select: JavaScript: @ibyar/expressions
- select: HTML: @ibyar/elements
- Custom Elements Everywhere for Aurora Test & Results: https://muhammad-salem.github.io/custom-elements-everywhere/libraries/aurora/results/results.html
npm i -g @ibyar/cli
yarn global add @ibyar/cli
npm i --save @ibyar/aurora
yarn add @ibyar/aurora
README | Description | NPM, PKG, SRC |
---|---|---|
@ibyar/cli | ibyar cli package | |
@ibyar/aurora | a central package to manage dependance only | |
@ibyar/core | create components, render elements bind attributes and handling events |
|
@ibyar/expressions | a JavaScript engine, parser and evaluator build by the guid of V8 JavaScript engine. Introduce a reactive scope concept to detect changes for scope variables, subscriptions based on a wave effect like concept,(simple what is subscribed will only be reevaluated again). Follow ESTree structural to generate an ast object. |
|
@ibyar/elements | parse HTML Template ,has tag names, properties for each tag |
|
@ibyar/pipes | implement all supported pipes | |
@ibyar/directives | implement all supported directives | |
@ibyar/platform | utility package for and plural stuff, json patch | |
@ibyar/decorators | ibyar decorators package | |
typescript | Runtime library for TypeScript helpers. | |
tslib | Runtime library for TypeScript helpers. |
Support | HTML Template |
---|---|
Parsing Attributes | âś“ |
One Way Data Binding | âś“ |
Two Way Data Binding | âś“ |
Event Binding | âś“ |
Template Parser | âś“ |
Template Syntax | âś“ |
Control Flow Syntax | âś“ |
Variables in templates | âś“ |
Template Reference Variables | âś“ |
Template HTML File | fetch or embedded |
Fragment | âś“ |
camelCase Property Naming | âś“ |
lowercase for root element Property Naming | âś“ |
- ES Module
- Dependency Injection
- Component
- Directives (Attribute and Structural Directives)
- Pipes
- Modules
- Lifecycle
- Signals
- input signal
- output signal
- view signal
- viewChild signal
- @HostListener [Supported by Component and Attribute directive].
- @HostBinding [Supported by Component and Attribute directive].
- XSS (cross-site-scripting)
- *if
- *for is same as ( *forOf )
- *forIn
- *forAwait
- *switch and (*case, *default)
-- support control flow syntax
-- see directive syntax
structural-directive-syntax-reference
- class [support
Single class binding
,Multi-class binding
]. - style [support
Single style binding
,Multi-style binding
]. theSingle style binding with units
not yet supported.
- async
- json
- lowercase
- uppercase
- titlecase
- keyvalue
- slice
- date
- currency
- number
- percent
- i18nPlural
- i18nSelect
- Reflecting Properties to Attributes
- Observing Changes to Attributes
- Element Upgrades
- Styling a Custom Element
- Extending native HTML elements
- Extending a Custom Element
- Two Component On Same Model Class
- Two Component Share Same Model Instance
- Load template by ID from document
- As Normal Custom Element
- As Shadow DOM Element
# always run ibyar cli to pre-build (AOT) your template and view types.
ibyar --build
#or
ibyar --build --watch
in a polyfills.ts file
- use
aurora
zone for detect changes
import 'zone.js';
import { bootstrapZone } from '@ibyar/aurora';
bootstrapZone('aurora');
- or use
manual
Zone, if you don't like to useZone.js
all the events likerxjs
observables, setTimeout and fetch, etc.. can't be detected, use signals to connect to variables changes, provide better debugging experience.
import { bootstrapZone } from '@ibyar/aurora';
bootstrapZone('manual');
- or use
proxy
Zone, if you don't like to useZone.js
but still like to have full change detection for your application. it my be hard in debugging your application.
import { bootstrapZone } from '@ibyar/aurora';
bootstrapZone('proxy');
-
you still can control the zone peer component while define your component by add
zone
t one of the zone types 'aurora', 'manual' and 'proxy'. ifaurora
is selected, you need to import theZone.js
package. -
the
zone
property in the@Component({zone: 'manual'})
is optional and will get the default value frombootstrapZone()
import { Component, HostListener, isModel, OnDestroy, OnInit } from '@ibyar/aurora';
import { interval, Subscription } from 'rxjs';
@Component({
selector: 'pipe-app',
zone: 'AURORA',
template: `
<style>.bs-color{color: var({{currentColor}});}</style>
@for(let color of colors; let i = index, isOdd = odd) {
isOdd :{{ isOdd? 'odd': 'even'}}
color: {{color}}
}
<!-- Local template variables -->
@let name = user.name;
@let name = user.name, age = user.age; <!-- comma separated variable declaration -->
@let greeting = 'Hello, ' + name;
@let data = data$ | async;
@let pi = 3.1459;
@let coordinates = {x: 50, y: 100};
@let longExpression = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit ' +
'sed do eiusmod tempor incididunt ut labore et dolore magna ' +
'Ut enim ad minim veniam...';
<div *for="const color of colors">
color: {{color}} <span *if="color === currentColor" class="bs-color"> Current Color ='{{currentColor}}'</span>
</div>
<table class="table">
<thead>
<tr>
<th class="bs-color" scope="col">pipe</th>
<th class="bs-color" scope="col">expression</th>
<th class="bs-color" scope="col">view</th>
</tr>
</thead>
<tbody>
<tr>
<td>async</td>
<td>observable |> async</td>
<td>{{observable |> async}}</td>
</tr>
<tr>
<td>*</td>
<td>text</td>
<td>{{text}}</td>
</tr>
<tr>
<td>lowercase</td>
<td>text |> lowercase</td>
<td>{{text |> lowercase}}</td>
</tr>
<tr>
<td>titlecase</td>
<td>text |> titlecase</td>
<td>{{text |> titlecase}}</td>
</tr>
<tr>
<td>uppercase</td>
<td>text |> uppercase</td>
<td>{{text |> uppercase}}</td>
</tr>
<tr>
<td>json</td>
<td>obj |> json</td>
<td>{{obj |> json}}</td>
</tr>
<tr>
<td>json <small>pre element</small></td>
<td>obj |> json:undefined:2</td>
<td>
<pre>{{obj |> json:undefined:2}}</pre>
</td>
</tr>
<tr>
<td>keyvalue</td>
<td>keyValueObject |> keyvalue</td>
<td>{{keyValueObject |> keyvalue |> json}}</td>
</tr>
<tr>
<td>keyvalue</td>
<td>keyValueObject |> keyvalue</td>
<td>{{keyValueObject |> keyvalue |> json}}</td>
</tr>
<tr>
<td>keyvalue</td>
<td>keyValueMap |> keyvalue</td>
<td>{{keyValueMap |> keyvalue |> json}}</td>
</tr>
<tr>
<td>slice</td>
<td>array |> slice:1:3</td>
<td>{{array |> slice:1:3}}</td>
</tr>
<tr>
<td>slice</td>
<td>slice(array, 1, 3)</td>
<td>{{slice(array, 1, 3)}}</td>
</tr>
<tr>
<td>call windows method directly</td>
<td>3345.54645 |> Math.trunc</td>
<td>{{3345.54645 |> Math.trunc}}</td>
</tr>
</tbody>
</table>
`
})
export class PipeAppComponent implements OnInit, OnDestroy {
text = 'Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups';
obj = {
a: [1, 2, 3],
b: 'property b',
c: {
d: [],
e: 4,
f: [{ 5: 'g' }]
}
};
keyValueObject = {
1: 100,
a: 'A00'
};
keyValueArray = [200, 300];
keyValueMap = new Map<number, number | string>([[1, 400], [2, 500], [3, 'B200']]);
observable = interval(1000);
array = ['a', 'b', 'c', 'd'];
readonly name = input('name');
readonly age = input.required();
readonly inputWithAlias = input('init-value', { alias: 'alias-name-1' });
readonly requiredInputWithAlias = input.required({ alias: 'alias-name-2' });
readonly event = output<string>();
colors = [
'--bs-blue',
'--bs-indigo',
'--bs-purple',
'--bs-pink',
'--bs-red',
'--bs-orange',
'--bs-yellow',
'--bs-green',
'--bs-teal',
'--bs-cyan',
'--bs-white',
'--bs-gray',
'--bs-gray-dark'
];
currentColor = this.colors[0];
subscription: Subscription;
onInit() {
let index = 0;
this.subscription = this.observable.subscribe(() => {
if (index === this.colors.length) {
index = 0;
}
this.currentColor = this.colors[index++];
if (isModel(this)) {
this.emitChangeModel('currentColor');
}
console.log(this.currentColor);
});
}
@HostListener('currentColor')
onCurrentColorChange() {
console.log(this.currentColor);
}
onDestroy() {
this.subscription.unsubscribe();
}
}
in index.html add:
<body>
<pipe-app></pipe-app>
<script type="module" src="path-to-main-file/index.js"></script>
</body>
git clone https://github.com/ibyar/aurora.git
cd aurora
yarn install
yarn build
git clone https://github.com/ibyar/aurora.git
cd aurora
npm install
npm run build
see test app for full example
module.exports = {
entry: './src/index.ts',
module: {
exprContextCritical: false,
rules: [
{
test: /\.tsx?$/,
use: ['@ibyar/cli',],
exclude: /node_modules/,
}
]
}
};
// 1. import default from the plugin module
import {
beforeCompileDirectiveOptions, beforeCompileComponentOptions,
afterDeclarationsCompileComponentOptions,
afterDeclarationsCompileDirectiveOptions,
scanDirectivesOnceAsTransformer,
} from '@ibyar/cli';
// 3. add getCustomTransformer method to the loader config
var config = {
...
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
options: {
... // other loader's options
getCustomTransformers: () => ({
before: [
scanDirectivesOnceAsTransformer(),
beforeCompileDirectiveOptions,
beforeCompileComponentOptions,
],
after: [],
afterDeclarations: [
afterDeclarationsCompileComponentOptions,
afterDeclarationsCompileDirectiveOptions,
],
})
}
}
]
}
...
};
import typescript from '@rollup/plugin-typescript';
import {
beforeCompileDirectiveOptions, beforeCompileComponentOptions,
afterDeclarationsCompileComponentOptions,
afterDeclarationsCompileDirectiveOptions,
scanDirectivesOnceAsTransformer,
} from '@ibyar/cli';
export default = {
...,
plugins: [
typescript({
transformers: {
before: [
{ type: 'program', factory: scanDirectivesOnceAsTransformer() },
{ type: 'program', factory: beforeCompileDirectiveOptions },
{ type: 'program', factory: beforeCompileComponentOptions },
],
after: [],
afterDeclarations: [
{ type: 'program', factory: afterDeclarationsCompileComponentOptions },
{ type: 'program', factory: afterDeclarationsCompileDirectiveOptions },
],
}
}),
],
...
};
see test app for full webpack
see test app for full rollup