HXElement API - HelixDesignSystem/helix-ui GitHub Wiki

TODO: move to API docs

The HXElement class provides some syntactic sugar on top of native web component APIs to help reduce the boilerplate needed to build new custom elements.

static get is()

This static class member provides the name of the element being defined (e.g., hx-icon, hx-progress, etc.). If this is not defined, the class is not registered with the custom element registry.

export class HXNewElement extends HXElement {
    static get is () {
        return 'hx-new-element';
    }
    
    // ...
}

static get template()

This static class member is used to define the innerHTML of the element's Shadow DOM. If this is not defined, no Shadow DOM will be created.

export class HXNewElement extends HXElement {
    // ...

    static get template () {
        return `
            <style>#root { font-weight: 700; }</style>
            <div id="root">I'm in the Shadow DOM!</div>
        `;
    }

    // ...
}

static get $observedAttributes()

This static class member defines the list of attributes to watch for changes. If a defined attribute changes values, the $onAttributeChange() callback is called.

NOTE: By default, every class that extends HXElement will automatically handle changes of the following attributes:

  • disabled

You do not need to redefine any of the above in $observedAttributes.

export class HXNewElement extends HXElement {
    // ...

    static get $observedAttributes () {
        return [ 'value' ];
    }
    
    // ...
}

$onAttributeChange()

This callback method is called whenever an attribute listed in $observedAttributes changes values.

export class HXNewElement extends HXElement {
    $onAttributeChange (attr, oldVal, newVal) {
        if (attr === 'value') {
            this._doSomethingCool();
        }
    }
    
    // ...
}

$onCreate()

This lifecycle method is called at the end of construction and is useful to setup pre-connect setup logic.

  • Binding private listeners to the proper this value.
  • Initialization logic (before DOM attachment)
export class HXNewElement extends HXElement {
    // ...

    $onCreate () {
        this._onHover = this._onHover.bind(this);
    }

    // ...
}

$onConnect()

This lifecycle method is called at the end of the native connectedCallback() after HXElement has performed its connection logic. Use this method to initialize an element's behavior.

  • Default/initialize ARIA attributes
  • Default/initialize role attribute
  • Upgrading properties
  • Add event listeners
export class HXNewElement extends HXElement {
    // ...

    $onConnect () {
        this.$upgradeProperty('value');
        this._elRoot.addEventListener('mouseover', this._onHover);
    }

    // ...
}

$onDisconnect()

This lifecycle method is called at the end of the native disconnectedCallback() after HXElement has performed its disconnection logic. Add cleanup logic to this method:

  • Remove event listeners
  • Close connections
  • Clean up local storage
  • etc.
export class HXNewElement extends HXElement {
    // ...

    $onDisconnect () {
        this._elRoot.removeEventListener('mouseover', this._onHover);
    }

    // ...
}

All Together Now

import { HXElement } from 'path/to/HXElement';

export class HXNewElement extends HXElement {
    static get is () {
        return 'hx-new-element';
    }
    
    static get template () {
        return `
            <style>#root { font-weight: 700; }</style>
            <div id="root">I'm in the Shadow DOM!</div>
        `;
    }

    static get $observedAttributes () {
        return [ 'value' ];
    }
    
    $onAttributeChange (attr, oldVal, newVal) {
        if (attr === 'value') {
            this._doSomethingCool();
        }
    }
    
    $onCreate () {
        this._onHover = this._onHover.bind(this);
    }
    
    $onConnect () {
        this._elRoot.addEventListener('mouseover', this._onHover);
    }

    $onDisconnect () {
        this._elRoot.removeEventListener('mouseover', this._onHover);
    }

    // "private" event listener
    _onHover (evt) {
        this._doSomethingCool();
    }

    // "private" method
    _doSomethingCool () {
        // do cool stuff here
    }

    // readonly "private" property
    get _elRoot () {
        return this.shadowRoot.getElementById('root');
    }
}
⚠️ **GitHub.com Fallback** ⚠️