Webformula core
Welcome Getting started Routing Serve / Build Signals and binding Web component Templates Fetcher Multiple languages github-circle-black-transparent GitHub github-circle-black-transparent Example app

Web component

Webformula core provides a convenient way to build native web components
Page file
page.js
Web component is imported in this file
        
  import { Component, html } from '@webformula/core';
  /* HTML imports will bundle with the build */
  import htmlTemplate from './page.html';

  // imported component
  import './component.js';
  
  export default class extends Component {
    // html page title
    static pageTitle = 'Page';

    // you can set the html from and import or use the template method (see below)
    static htmlTemplate = htmlTemplate;
    
    constructor() {
      super();
    }

    // this can be used in place of import the html file
    template() {
      return html`
        <div>Page Content</div>

        <!-- custom component -->
        <custom-button>Click</custom-button>
      `;
    }
  }
        
      
Component file
component.js
        
  <!-- component.html -->
  <button><slot></slot></button>
        
      
        
  import { Component } from '@webformula/core';
  import htmlTemplate from './component.html';
  
  class CustomButton extends Component {
    /**
      * Pass in HTML string. Use for imported .HTML
      * Supports template literals: <div>undefined</div>
      * @type {String}
      */
    static htmlTemplate = htmlTemplate;


    /**
      * Hook up shadow root
      * @type {Boolean}
      */
    static useShadowRoot = false;

    
    /**
      * @type {Boolean}
      */
    static shadowRootDelegateFocus = false;


    /**
      * Pass in styles for shadow root.
      * Can use imported stylesheets: import styles from '../styles.css' assert { type: 'css' };
      * @type {CSSStyleSheet}
      */
    static shadowRootStyleSheets;


    /**
      * @typedef {String} AttributeType
      * @value '' default handling
      * @value 'string' Convert to a string. null = ''
      * @value 'number' Convert to a number. isNaN = ''
      * @value 'int' Convert to a int. isNaN = ''
      * @value 'boolean' Convert to a boolean. null = false
      * @value 'event' Allows code to be executed. Similar to onchange="console.log('test')"
      */
      /**
      * Enhances observedAttributes, allowing you to specify types
      * You can still use `observedAttributes` in stead of this.
      * @type {Array.<[name:String, AttributeType]>}
      */
    static get observedAttributesExtended() { return []; }; // static observedAttributesExtended = [['required', 'boolean']];
    

    /**
      * Use with observedAttributesExtended
      * You can still use `attributeChangedCallback` in stead of this.
      * @function
      * @param {String} name - Attribute name
      * @param {String} oldValue - Old attribute value
      * @param {String} newValue - New attribute value
      */
    attributeChangedCallbackExtended(name, oldValue, newValue) { }


    // need to bind events to access `this`
    #onClick_bound = this.#onClick.bind(this);

    
    constructor() {
      super();
    }

    /**
     * Method that returns a html template string. This is an alternative to use static htmlTemplate
     * @name template
     * @function
     * @return {String}
     */
    template() { return '<div></div>' }

    connectedCallback() {}
    disconnectedCallback() {}
    beforeRender() {}

    afterRender() {
      this.#root.querySelector('button').addEventListener('click', this.#onClick_bound);
    }
    
    disconnectedCallback() {
      this.#root.querySelector('button').removeEventListener('click', this.#onClick_bound);
    }

    #onClick() {
      console.log('Custom button component clicked!');
    }
  }
  
  // define web component
  customElements.define('custom-button', CustomButton);
        
      
Interacting with component elements
        
  <!-- index.html -->
  <body>
    <custom-webcomponent></custom-webcomponent>
  </body>
        
      
        
  <!-- component.html -->
  <button onclick="this.closest('custom-webcomponent').clickIt()">Click it direct</button>
  <button id="eventlistener-button">Click it event listener</button>
        
      
        
  import { Component } from '@webformula/core';
  import html from './component.html'; // automatically bundles
  
  class CustomWebcomponent extends Component {
    static htmlTemplate = html;

    // need to bind events to access `this`
    #onClick_bound = this.clickIt.bind(this);

    varOne = 'var one';

    
    constructor() {
      super();
    }

    afterRender() {
      this.#root.querySelector('#eventlistener-button').addEventListener('click', this.#onClick_bound);
    }
    
    disconnectedCallback() {
      this.#root.querySelector('#eventlistener-button').removeEventListener('click', this.#onClick_bound);
    }

    clickIt() {
      console.log('click it!');
    }
  }
  
  // define web component
  customElements.define('custom-webcomponent', CustomWebcomponent);