Can I create a custom element based on a native element?
posted on
Yes, but it’s implemented in all major browsers except Safari, which has no plan to support it.
Usually, when you write the constructor class for a Web Component you extend it from HTMLElement
:
class EnhancedButton extends HTMLElement { }
You can also extend from a native HTML element to gain all its features (DOM properties, methods, accessibility).
To do that, you have to do three things:
Pick the correct DOM interface and extend from it instead of HTMLElement.
class EnhancedButton extends HTMLButtonElement { }
In the define()
function, pass a third parameter that specifies which element you're extending.
customElements.define('enhanced-button', EnhancedButton, {extends: 'button'});
Use the new button variation.
<button is="enhanced-button">Click</button>
or
let button = document.createElement('button', {is: 'enhanced-button'});
button.textContent = 'Click';
or
let button = new EnhancedButton();
button.textContent = 'Click';
Here's an example:
class EnhancedButton extends HTMLButtonElement {
constructor() {
super();
this._expanded = false;
this.setAttribute('aria-expanded', this._expanded);
this.addEventListener('click', this._toggle);
}
_toggle() {
this._expanded = !this._expanded
this.setAttribute('aria-expanded', this._expanded);
}
}
customElements.define('enhanced-button', EnhancedButton, {extends: 'button'});
aria-expanded
on click.<button is="enhanced-button">Yo</button>
<div hidden>Yo!</div>
[is="enhanced-button"][aria-expanded="true"] + [hidden] {
display: block;
}
aria-expanded
is true.Yo!