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!