Page file
page.js
Web component is imported in this file
import { Component, html } from '@thewebformula/lithe'; /* 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 title = '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 '@thewebformula/lithe'; 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 '@thewebformula/lithe'; 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);