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/cliyarn global add @ibyar/clinpm i --save @ibyar/aurorayarn 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/router | has the built-in directives for router and navigation | |
| @ibyar/forms | contain form group, form builder and native ui form group | |
| @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)
- OnChanges
- OnInit
- DoCheck
- AfterContentInit
- AfterContentChecked
- AfterViewInit
- AfterViewChecked
- OnViewMove
- OnViewAdopted
- OnDestroy
- *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 unitsnot 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 --watchin a polyfills.ts file
- use
aurorazone for detect changes
import 'zone.js';
import { bootstrapZone } from '@ibyar/aurora';
bootstrapZone('aurora');- or use
manualZone, if you don't like to useZone.jsall the events likerxjsobservables, 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
proxyZone, if you don't like to useZone.jsbut 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
zonet one of the zone types 'aurora', 'manual' and 'proxy'. ifaurorais selected, you need to import theZone.jspackage. -
the
zoneproperty 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 buildgit clone https://github.com/ibyar/aurora.git
cd aurora
npm install
npm run buildsee 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