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
- Lifecycle
- Signals
- @Input
- @Output
- @View
- @HostListener [Supported by Component and Attribute directive].
- @HostBinding [Supported by Component and Attribute directive].
- @ViewChild
- @ViewChildren
- 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.
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