UIElement Docs Version 0.8.5

📘 Introduction

A lightweight solution to bring signals-based reactivity and state management to vanilla Web Components without the need for a complex framework.

What is UIElement?

UIElement is a lightweight JavaScript library that extends the native HTMLElement class to bring efficient state management and reactivity to your Web Components without client-side rendering or the overhead of a larger framework.

Why Use UIElement?

If you're looking for:

When Should You Use UIElement?

Best Use Cases:

Example Scenarios:

How UIElement Works

UIElement relies on signals—small pieces of reactive state that notify your components when changes occur. This allows for efficient updates to HTML content, handling reactivity only when necessary.

Signals & Auto-Effects: Signals automatically trigger updates to the DOM when they change.

this.set('count', 0); // Define a signal for 'count'
this.first('.count').map(setText('count')); // Automatically update content when 'count' changes

Benefits of UIElement over Traditional Frameworks

Quick Start Guide

A simple example to get started:

Count: Parity:

Source Code
HTML

my-counter.html html

<my-counter count="42">
	<p>
		Count: <span class="count"></span>
		Parity: <span class="parity"></span>
	</p>
	<button id="increment">+</button>
	<button id="decrement">-</button>
</my-counter>
CSS

my-counter.css css

my-counter {
	display: flex;
	gap: 0.5rem;
	margin-block: 1rem;

	p {
		display: inline-block;
		margin: 0;
	}

	span {
		margin-right: 0.5rem;
	}
}
JavaScript

my-counter.js js

import { UIElement, asInteger, on, setText } from '@efflore/ui-element'

class MyCounter extends UIElement {
	static observedAttributes = ['count']
	static attributeMap = {
		count: asInteger
	}

	connectedCallback() {
		this.set('parity', () => this.get('count') % 2 ? 'odd' : 'even')
		this.first('.increment').map(on('click', () => this.set('count', v => ++v)))
		this.first('.decrement').map(on('click', () => this.set('count', v => --v)))
		this.first('.count').map(setText('count'))
		this.first('.parity').map(setText('parity'))
	}
}
MyCounter.define('my-counter')

For a full setup, see the Installation & Setup page, or jump into the Detailed Walkthrough to learn how to build your first component.

Next Steps

Continue to the Installation & Setup to get started, or dive into Core Concepts to learn more about signals and reactivity.