@ibyar/aurora
v2.5.0
Published
Create and define a usable 'custom elements', that compatible with other frameworks, using Typescript
Downloads
142
Maintainers
Readme
Aurora
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
CLI Install
npm i -g @ibyar/cli
yarn global add @ibyar/cli
Install
npm i --save @ibyar/aurora
yarn add @ibyar/aurora
Dependencies
| 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. | |
'HTML Template' Features
| 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 | ✓ |
Library Features
- [x] ES Module
- [x] Dependency Injection
- [x] Component
- [x] Directives (Attribute and Structural Directives)
- [x] Pipes
- [x] Lifecycle
- [x] Signals
- [x] @Input
- [x] @Output
- [x] @View
- [x] @HostListener [Supported by Component and Attribute directive].
- [x] @HostBinding [Supported by Component and Attribute directive].
- [x] @ViewChild
- [ ] @ViewChildren
- [ ] XSS (cross-site-scripting)
Built-in Directive
Structure Directives
- [x] *if
- [x] *for is same as ( *forOf )
- [x] *forIn
- [x] *forAwait
- [x] *switch and (*case, *default)
-- support control flow syntax
-- see directive syntax
structural-directive-syntax-reference
Attributes Directives
- [x] class [support
Single class binding
,Multi-class binding
]. - [x] style [support
Single style binding
,Multi-style binding
]. theSingle style binding with units
not yet supported.
Built-in Pipes ( Pipeline operator '|>' )
- [x] async
- [x] json
- [x] lowercase
- [x] uppercase
- [x] titlecase
- [x] keyvalue
- [x] slice
- [ ] date
- [ ] currency
- [ ] number
- [ ] percent
- [ ] i18nPlural
- [ ] i18nSelect
Web Component standards
- [x] Custom Elements
- [x] Shadow DOM
- [x] HTML Templates Element
- [x] HTML Templates Element with Shadow DOM
Custom Elements standards
- [x] Reflecting Properties to Attributes
- [x] Observing Changes to Attributes
- [x] Element Upgrades
- [x] Styling a Custom Element
- [x] Extending native HTML elements
- [ ] Extending a Custom Element
- [x] Two Component On Same Model Class
- [ ] Two Component Share Same Model Instance
Shadow DOM standards
- [x] Open Mode
- [x] Closed Mode
- [x] delegatesFocus
- [x] Shadow DOM event model
HTML Templates Element standards
- [x] Load template by ID from document
- [x] As Normal Custom Element
- [x] As Shadow DOM Element
how to bundle your package before publish
# always run ibyar cli to pre-build (AOT) your template and view types.
ibyar --build
#or
ibyar --build --watch
How to use:
HTML -- template parser example
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>
how to build
git clone https://github.com/ibyar/aurora.git
cd aurora
yarn install
yarn build
For NPM 7(workshop support):
git clone https://github.com/ibyar/aurora.git
cd aurora
npm install
npm run build
see test app for full example
Integration with Webpack
add @ibyar/cli as loader
module.exports = {
entry: './src/index.ts',
module: {
exprContextCritical: false,
rules: [
{
test: /\.tsx?$/,
use: ['@ibyar/cli',],
exclude: /node_modules/,
}
]
}
};
use ts-loader
// 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,
],
})
}
}
]
}
...
};
Integration with Rollup
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