Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
@hapiness/custom-elements-loader
Advanced tools
Readme
This module exposes a factory to use ElementsLoaderService inside JavaScript's applications like React.js
, Vue.js
or just standalone
.
THIS MODULE IS ONLY USED IN JiT (Just-in-Time) MODE AND THE BUILD WON'T BE THE MOST OPTIMIZED - TO HAVE THE BEST WAY AND THE BEST OPTIMIZED CUSTOM ELEMENTS INTEGRATION WITH AoT (Ahead-of-Time) MODE, CHECK HERE
DON'T USE THIS MODULE FOR ANGULAR APPLICATION
$ yarn add @hapiness/custom-elements-loader
or
$ npm install --save @hapiness/custom-elements-loader
All required dependencies will be automatically installed : @angular/animations
, @angular/common
, @angular/core
, @angular/compiler
, @angular/elements
, @angular/platform-browser
, @angular/platform-browser-dynamic
, @hapiness/ng-elements-loader
, @webcomponents/webcomponentsjs
, core-js
, document-register-element
, rxjs
and zone.js
.
If your custom element module must have more dependencies, you must install them by yourself
Before to use ElementsLoader
exposed by @hapiness/custom-elements-loader
, you must create your own custom-elements
modules.
To create a new library with Angular-CLI
, follow this guide.
This component will be the final custom-element
interpreted in your browser.
projects/made-with-love/src/lib/made-with-love.component.ts:
import { Component, Input, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'made-with-love',
templateUrl: './made-with-love.component.html',
encapsulation: ViewEncapsulation.ShadowDom
})
export class MadeWithLoveComponent implements OnInit {
private _name: string;
private _url: string;
private _color: string;
private _size: number;
constructor() {
this.size = 1;
this.color = 'red';
}
ngOnInit() {
if (!this._name || this._name.length === 0) {
console.error(`Name attribute must be provided!`);
}
}
get name(): string {
return this._name;
}
@Input()
set name(n: string) {
this._name = n;
}
get url(): string {
return this._url;
}
@Input()
set url(u: string) {
this._url = u;
}
get color(): string {
return this._color;
}
@Input()
set color(c: string) {
this._color = c;
}
get size(): number {
return this._size;
}
@Input()
set size(s: number) {
this._size = s;
}
}
Note: Your component must have encapsulation equals to ViewEncapsulation.ShadowDom
if you want to have shadowdomv1 support else you can delete this line to have original support.
projects/made-with-love/src/lib/made-with-love.component.html:
<ng-template #noUrl>
{{ name }}
</ng-template>
<span [style.font-size.em]="size">
Made with <span [style.color]="color">♥</span> by
<ng-container *ngIf="url && url.length > 0; else noUrl">
<a [attr.href]="url" target="_blank">{{ name }}</a>
</ng-container>
</span>
projects/made-with-love/src/lib/made-with-love.module.ts:
import { NgModule, Type } from '@angular/core';
import { CommonModule } from '@angular/common';
import { WithCustomElementComponent } from '@hapiness/ng-elements-loader';
import { MadeWithLoveComponent } from './made-with-love.component';
@NgModule({
imports: [
CommonModule
],
declarations: [
MadeWithLoveComponent
],
entryComponents: [
MadeWithLoveComponent
],
exports: [
MadeWithLoveComponent
]
})
export class MadeWithLoveModule implements WithCustomElementComponent {
customElementComponent: Type<MadeWithLoveComponent> = MadeWithLoveComponent;
}
Note: Your module must implement WithCustomElementComponent
interface exposed by @hapiness/ng-elements-loader
and, component must be declared inside entryComponents
and declaration
meta-data of NgModule
.
The minimum package.json
file for your module is described below:
projects/made-with-love/package.json:
{
"name": "made-with-love",
"version": "1.0.0",
"peerDependencies": {
"@hapiness/custom-elements-loader": "^7.2.0"
}
}
If your module has to have others dependencies not installed automatically by @hapiness/custom-elements-loader
like explained in installation, you must add them in dependencies section.
Your custom-element
module is now ready to be used so you have to publish it before use it in your application.
Create a JavaScript
application with your module and @hapiness/custom-elements-loader
in dependencies.
Install all dependencies
your module must have if not already installed.
We create a HTML
file with our custom element
inside.
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>Web Component</title>
</head>
<body>
<div>
<made-with-love name="Hapiness Framework" url="https://github.com/hapinessjs/" size="2"></made-with-love>
</div>
<script src="./main.js" type="text/javascript"></script>
</body>
</html>
main.js
file contains all JavaScript
elements to use ElementsLoader
and it's built with webpack.
main.ts
// POLYFILLS
import 'zone.js/dist/zone';
import 'core-js/es7/reflect';
/** In browsers that don't support Custom Elements natively **/
// import 'document-register-element';
/** You must add this if your application will be compiled in es5 because the specification requires developers use ES2015 classes to define Custom Elements **/
// import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';
import { ElementsLoader } from '@hapiness/custom-elements-loader';
import { MadeWithLoveModule } from 'made-with-love';
ElementsLoader.loadContainingCustomElements(
{
selector: 'made-with-love',
module: MadeWithLoveModule
}
).subscribe(undefined, e => console.error(e));
The creation of the custom element happens directly inside HTML
file with all attributes we want to display:
<made-with-love name="Hapiness Framework" url="https://github.com/hapinessjs/" size="2"></made-with-love>
Loading of the component happens inside main.ts
file.
import 'zone.js/dist/zone';
import 'core-js/es7/reflect';
/** In browsers that don't support Custom Elements natively **/
// import 'document-register-element';
/** You must add this if your application will be compiled in es5 because the specification requires developers use ES2015 classes to define Custom Elements **/
// import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';
/** IE9, IE10 and IE11 requires all of the following polyfills. **/
// import 'core-js/es6/symbol';
// import 'core-js/es6/object';
// import 'core-js/es6/function';
// import 'core-js/es6/parse-int';
// import 'core-js/es6/parse-float';
// import 'core-js/es6/number';
// import 'core-js/es6/math';
// import 'core-js/es6/string';
// import 'core-js/es6/date';
// import 'core-js/es6/array';
// import 'core-js/es6/regexp';
// import 'core-js/es6/map';
// import 'core-js/es6/weak-map';
// import 'core-js/es6/set';
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/** IE10 and IE11 requires the following for the Reflect API. */
// import 'core-js/es6/reflect';
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
**/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
loadContainingCustomElements
method of ElementsLoader
from @hapiness/custom-elements-loader
. This method takes in parameter CustomElementModuleSelector
or CustomElementModuleSelector[]
from @hapiness/ng-elements-loader
.export interface CustomElementModuleSelector {
selector: string;
module: Type<any>;
}
Selector is the custom tag
of your custom element
and module is the Angular
module contains the component.
Launch your application and you will see your custom element
displayed inside your JavaScript
application:
Made with ♥ by Hapiness Framework
In the previous component we have created only @Input
properties but sometimes, you'll want to emit event from your custom element
to the DOM
with @Ouput
properties.
Here an example of a component emits event to its parent:
projects/hello-world/src/lib/hello-world.component.ts:
import { Component, EventEmitter, OnInit, Output, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'hello-world',
templateUrl: './hello-world.component.html',
styleUrls: ['./hello-world.component.scss'],
encapsulation: ViewEncapsulation.ShadowDom
})
export class HelloWorldComponent implements OnInit {
private _sayHello$: EventEmitter<string>;
constructor() {
this._sayHello$ = new EventEmitter<string>();
}
ngOnInit() {
}
@Output('sayHello')
get sayHello$(): EventEmitter<string> {
return this._sayHello$;
}
sayHello() {
this._sayHello$.emit('Hello World');
}
}
projects/hello-world/src/lib/hello-world.component.html:
<div>
<button type="button" (click)="sayHello()">Say Hello with Event</button>
</div>
To use it and receive event, you must do this:
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>Web Component</title>
</head>
<body>
<div>
<hello-world></hello-world>
</div>
<script src="./main.js" type="text/javascript"></script>
</body>
</html>
We set a listener to catch sayHello
event and do what we want:
main.ts
// POLYFILLS
import 'zone.js/dist/zone';
import 'core-js/es7/reflect';
/** In browsers that don't support Custom Elements natively **/
// import 'document-register-element';
/** You must add this if your application will be compiled in es5 because the specification requires developers use ES2015 classes to define Custom Elements **/
// import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter';
import { ElementsLoader } from '@hapiness/custom-elements-loader';
import { HelloWorldModule } from 'hello-world';
ElementsLoader.loadContainingCustomElements(
{
selector: 'hello-world',
module: HelloWorldModule
}
).subscribe(undefined, e => console.error(e));
document.querySelector('hello-world').addEventListener('sayHello', (event: any) => alert(event.detail));
Angular v7.1.0+
ElementsLoaderService.registerContainingCustomElements()
method to be used for AoT compilerElementsLoaderService.loadContainingCustomElements()
method must be used only for JiT compilerwebcomponent
bundle with this tutorialAngular v7.0.3+
document-register-elements v1.13.1
latest version of the polyfill
only require if your browser doesn't support customElement
@webcomponents/webcomponentsjs v2.1.3
to fix issue with es5
compilation outside Angular
application like explain hereDOM
like this, it can be created or loaded asynchronously after registrationAngular v7.0.2+
Angular v6.1.7
to avoid the bug reported in this issueAngular v6.1.0+
Julien Fauville | Antoine Gomez | Sébastien Ritz | Nicolas Jessel |
Copyright (c) 2018 Hapiness Licensed under the MIT license.
FAQs
Factory to load Angular Custom Elements inside JavaScript's applications like React.js, Vue.js or just standalone
The npm package @hapiness/custom-elements-loader receives a total of 13 weekly downloads. As such, @hapiness/custom-elements-loader popularity was classified as not popular.
We found that @hapiness/custom-elements-loader demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.