@webreflection/elements
v0.1.9
Published
HTML & SVG Custom Elements
Maintainers
Readme
@webreflection/elements
Social Media Photo by Marek Piwnicki on Unsplash
HTML & SVG Custom Elements, glueing qsa-observer and nonchalance together.
<script type="module">
import { elements, HTML, SVG } from 'https://esm.run/@webreflection/elements';
// same Custom Elements API
elements.whenDefined('my-h1').then(Class => {
console.log(Class.name, 'defined');
});
// native extends out of the box
// <h1 is="my-h1"></h1>
elements.define('my-h1', class MyH1 extends HTML.H1 {
// anything that works with classes works here
#private;
// only caveat:
// if defined, the constructor MUST forward arguments!
constructor(...args) {
super(...args);
this.#private = 'test';
}
// custom elements lifecycle (connected/disconnected/attributeChanged)
connectedCallback() {
console.log('connected', this.#private);
this.innerHTML = '@webreflection/elements 🥳';
}
});
// regular HTMLElement extends out of the box too
// <my-element></my-element>
elements.define('my-element', class MyElement extends HTML.Element {
connectedCallback() {
this.innerHTML = '<small>made with ❤️ by <a href="https://github.com/WebReflection/elements">@webreflection</a></small>';
}
});
// as it is for customElements, whenDefined works both
// before and after an element has been defined
elements.whenDefined('my-element').then(Class => {
console.log(Class.name, 'defined');
});
</script>
<h1 is="my-h1"></h1>
<my-element></my-element>Enjoy 👋
Native Support Included
If your browser supports natively HTML custom elements builtin extends (i.e. Chrome/ium or Firefox based), and HTML is all you want/need to extend 'cause SVG custom elements do not exist natively on the Web, you can use @webreflection/elements/native export instead, which offers the exact same API without any dependency, hence it's lightweight, easier to reason about, and natively wonderful.
If you don't know if that's supported and you would like to feature detect this ability, you can pick the @webreflection/elements/auto export insted, which uses a lazy load for Safari or any browser that wouldn't support builtins' extends.
Benefits around this module
- it is based on Web Standard APIs without requiring bloated polyfills
- it normalizes Custom Elements definition, without diverging between the builtin extend and the regular one:
define('my-link', class MyLink extend HTML.A {})to extendHTMLAnchorElement(output:<a is="my-link"></a>)define('my-el', class MyEl extend HTML.Element {})to extendHTMLElement(output:<my-el></my-el>)- elements are automatically upgraded once live on the DOM
- it simplifies creation of custom elements:
- elements can be created via
new MyLink()ornew MyEl(), reducing confusion arounddocument.createElement('a', { is: 'my-link' })VSdocument.createElement('my-el')
- elements can be created via
- it simplifies styling of elements via
[is="ce-name"]when attribute is present:- combined with @webreflection/element it helps creating custom elements builtins extend that will always reflect the
isattribute
- combined with @webreflection/element it helps creating custom elements builtins extend that will always reflect the
