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);