A base class for building custom web components.
This class is built on CustomElement
, ElementAttributesProxy
, and NodeStructure
, inheriting their features.
If you want to quickly create a component, consider using the createComponent
function.
▶Create a component
Create a component
// Create a custom class that extends the Component class. class ColorPreviewComponent extends Component { static override get observedAttributes(): Array<string> { return ['color', 'size']; } // When a observed attributes changes, the template content is re-rendered. override template(): string { const color = this.attr.color ?? '#000000'; const size = this.attr.size ?? '100px'; return ` <style> :host { display: inline-block; width: ${size}; height: ${size}; } div { width: 100%; height: 100%; background-color: ${color}; } </style> <div onclick="this.clickHandler(event)"></div> `; } clickHandler(_event: Event): void { this.dispatch('color-preview-click'); } } // Define the custom element. ColorPreviewComponent.define('color-preview'); // Use the custom element in HTML. // <color-preview color="#ff0000" size="100px"></color-preview> // <color-preview color="#00ff00" size="100px"></color-preview> // <color-preview color="#0000ff" size="100px"></color-preview>
▶State management in component
State management in component
// The Store class is an observable store for complex state management. const colorPreviewStore = new Store({ color: '#000000', size: '100px', }); // The State class is an observable state for atomic state management. const debugState = new State(true); // Create a custom class that extends the Component class. class ColorPreviewComponent extends Component { override connectedCallback(): void { super.connectedCallback(); // must always be called first this.observe(colorPreviewStore, debugState); // observe the observables } override disconnectedCallback(): void { this.unobserve(colorPreviewStore, debugState); // unobserve the observables super.disconnectedCallback(); // should always be called last } // When a observed state changes, the template content is re-rendered. override template(): string { return ` <style> :host { display: inline-block; width: ${colorPreviewStore.state.size}; height: ${colorPreviewStore.state.size}; } div { width: 100%; height: 100%; background-color: ${colorPreviewStore.state.color}; } </style> <div onclick="this.clickHandler(event)"> ${debugState.get() ? colorPreviewStore.state.color : ''} </div> `; } clickHandler(event: Event): void { this.dispatch('color-preview-click'); if (debugState.get()) { console.log(event); } } } // Define the custom element. ColorPreviewComponent.define('color-preview'); // Use the custom element in HTML. // <color-preview></color-preview> // <color-preview></color-preview> // <color-preview></color-preview>
attr: ElementAttributesProxy
Returns a proxy object for element attributes.
content: ComponentContentContainer
Returns the same of this.structure.host
.
This is a convenient way to access the content container of the component.
structure: NodeStructure<ComponentContentContainer>
Returns the internal NodeStructure instance.
createContentContainer(): ComponentContentContainer
Creates the content container for the internal NodeStructure.
By default, this method creates an open shadow DOM.
Dispatches a custom event on the content container of the component.
The event bubbles out of the shadow DOM.
Observes one or more objects for changes.
If the object has a subscribe
function, it will be called with the update
method of this component as a callback for change notifications.
render(): void
Renders DOM with the template content.
template(): NodeStructureContent
Creates the template content.
This method should be implemented by subclasses to return the content.