v0.21

frontend components

introduction

dframework ships a complete library of zero dependency, high performance custom web components compiled into the frontend bundle. components are standard custom elements with no virtual dom, no compiler requirements, and no client build step. the framework compiles and bundles component files in public/js/components/ automatically on server boot.

built in components

d-checkbox

form associated checkbox switch with synchronized label and native form submission integration.

1<d-checkbox text="enable notifications" checked name="notifications" value="1"></d-checkbox>

attributes and properties

attribute property type default form description
checked checked boolean false yes checked state reflected in form submission
text text string "checkbox" no label text displayed beside the toggle
name name string "" no input field name used during form submission
value value string "on" no form submission payload sent when checked

programmatic api

1const checkbox = select('d-checkbox');
2
3// get or set checked state
4checkbox.checked = true;
5
6// update label text
7checkbox.text = 'allow telemetry';
8
9// update form payload name and value
10checkbox.name = 'telemetry';
11checkbox.value = 'accepted';

events

event detail bubbles description
change native event object no dispatched whenever the user toggles the checkbox

behavior


d-color-picker

high precision color picker featuring 2d saturation and brightness controls, hue slider, and alpha transparency controls.

1<d-color-picker value="#3b82f6" name="theme_color" label="accent color"></d-color-picker>

attributes and properties

attribute property type default form description
value value string "#d3ac5f" yes current hex color value (supports 3, 4, 6, 8 digit hex)
name name string "" no input name attribute for form submission
id id string "" no element identifier
label label string "color picker" no header label displayed above the picker
opened opened boolean false no whether the popup picker panel is initially open

programmatic api

1const picker = select('d-color-picker');
2
3// toggle popup panel visibility
4picker.toggle();
5
6// programmatically set hex color
7picker.setHex('#ef4444');
8
9// read color state
10console.log(picker.hex); // current hex string
11console.log(picker.h, picker.s, picker.b, picker.a); // hsb and alpha values

events

event detail bubbles description
change hex string yes dispatched when color changes via drag, input, or setHex
input hex string yes dispatched continuously during dragging

behavior


d-combobox

searchable, extensible select combobox with automatic floating placement, keyboard navigation, and dynamic option injection.

1<d-combobox
2 placeholder="select department"
3 allow-search
4 allow-input
5 name="department">
6 <option value="eng" selected>engineering</option>
7 <option value="des">product design</option>
8 <option value="ops">operations</option>
9</d-combobox>

attributes and properties

attribute property type default form description
placeholder placeholder string "" no placeholder text displayed when no option is selected
value value string null yes currently selected option value
allow-search allowSearch boolean false no enables real time search filtering input
allow-input allowInput boolean false no allows adding custom options via input and plus button
horizontal isHorizontal boolean false no switches option layout from vertical list to horizontal chips
name name string "" no form field name
id id string "" no component id
options options array [] no array of {value, text, content} objects

programmatic api

1const combo = select('d-combobox');
2
3// add option dynamically
4combo.addOption('mktg', 'marketing');
5
6// remove option by value
7combo.removeOption('ops');
8
9// clear all options
10combo.clearOptions();
11
12// set selected value programmatically
13combo.value = 'eng';
14
15// close all open comboboxes across document
16dCombobox.closeAll();

events

event detail bubbles description
change selected value string yes dispatched when an option is selected or added
input selected value string yes dispatched when selection changes
add {value, text, content} no dispatched when a custom option is added
open none yes dispatched when the dropdown panel opens
close none yes dispatched when the dropdown panel closes

behavior


d-context-menu

contextual right click menu with automatic boundary clamping and outside click suppression.

1<div class="card p-2">
2 right click inside this card
3 <d-context-menu>
4 <span>copy link</span>
5 <span>duplicate item</span>
6 <span>delete</span>
7 </d-context-menu>
8</div>

attributes and properties

attribute property type default form description
opened opened boolean false no whether the context menu is open
parent parent string "" no selector for target parent element (defaults to parent element)

programmatic api

1const menu = select('d-context-menu');
2
3// open context menu programmatically (optionally passing pointer event for cursor positioning)
4menu.open();
5menu.open(pointerEvent);
6
7// close context menu
8menu.close();
9
10// toggle context menu
11menu.toggle();
12
13// listen to item selection (e.detail is the clicked element)
14listen(menu, 'click', (e) => {
15 const target = e.target;
16 const action = target.closest('[data-action]')?.getAttribute('data-action');
17 if (action) handleAction(action);
18});

events

event detail bubbles description
click clicked element no emitted through component emitter when an item is selected

behavior


d-drawer

offcanvas navigation drawer with animated entrance transitions and wave styling.

1<d-drawer direction="left" id="main-drawer">
2 <nav class="flex-column g-1 p-2">
3 <a href="/dashboard">dashboard</a>
4 <a href="/settings">settings</a>
5 </nav>
6</d-drawer>

attributes and properties

attribute property type default form description
opened opened boolean false no whether the drawer is open
direction direction string "left" no entrance edge ("left", "right", "top", "bottom")

programmatic api

1const drawer = select('d-drawer');
2
3// open drawer (returns promise that resolves after animation completes)
4await drawer.open();
5
6// close drawer (returns promise)
7await drawer.close();
8
9// toggle drawer
10await drawer.toggle();
11
12// inspect animation and open state
13console.log(drawer.isOpened, drawer.isAnimating);

events

event detail bubbles description
open none yes dispatched when the opening animation completes
close none yes dispatched when the closing animation completes

behavior


d-dropdown

collapsible accordion dropdown container, perfect for faqs.

1<d-dropdown header="account security">
2 <div class="p-1 flex-column g-1">
3 <d-checkbox text="two factor authentication"></d-checkbox>
4 <a href="/sessions" class="btn btn-sm">manage active sessions</a>
5 </div>
6</d-dropdown>

attributes and properties

attribute property type default form description
header header string "dropdown" no title text displayed on the clickable header bar
opened opened boolean false no whether the dropdown is expanded

programmatic api

1const dropdown = select('d-dropdown');
2
3// open dropdown
4dropdown.open();
5
6// close dropdown
7dropdown.close();
8
9// toggle dropdown
10dropdown.toggle();
11
12// inspect open state
13console.log(dropdown.isOpened);

behavior


d-file-input

drag and drop file upload container with interactive item list, formatted byte size calculations, and compact bar modes.

1<d-file-input accept=".pdf,.zip,.csv" name="documents" multiple compact></d-file-input>

attributes and properties

attribute property type default form description
accept accept string "*/*" no allowed mime types or file extensions
icon icon string "dstrn-folder-line" no icon class displayed in dropzone
placeholder placeholder string "drag & drop file" no primary dropzone title
subtitle subtitle string "or click to browse" no secondary helper subtitle
compact compact boolean true no renders as a slim horizontal bar when true
multiple multiple boolean false no allows selecting and dropping multiple files
name name string "" no form payload field name
id id string "" no component id
value value object/array null yes File, File[], or url string payload

programmatic api

1const fileInput = select('d-file-input');
2
3// reset dropzone, clearing value, file list, and native input
4fileInput.reset();
5
6// inspect selected files
7console.log(fileInput.value); // File instance or File[] array

events

event detail bubbles description
change File, File[], or null yes dispatched when files are selected, dropped, or deleted

behavior


d-hamburger

responsive mobile navigation hamburger trigger and full screen navigation overlay with programmable breakpoints and multi level sliding subcategory panels.

1<nav class="nav">
2 <div class="container flex-row align-center justify-between py-1">
3 <a d-link href="/" class="flex-row align-center">
4 <img src="/img/logo.png" alt="logo">
5 </a>
6
7 <div id="nav-links" class="flex-row align-center g-2 md:d-flex d-none">
8 <a d-link href="/features" class="nav-link">features</a>
9 <div d-submenu="framework">
10 <a d-link href="/architecture">architecture</a>
11 <a d-link href="/benchmarks">benchmarks</a>
12 </div>
13 </div>
14
15 <d-hamburger target="#nav-links" breakpoint="md">
16 <div slot="header">
17 <img src="/img/logo.png" class="logo-mark">
18 </div>
19 <div slot="footer">
20 <d-text-input placeholder="search docs"></d-text-input>
21 </div>
22 </d-hamburger>
23 </div>
24</nav>

attributes and properties

attribute property type default form description
opened opened boolean false no whether the overlay is open
breakpoint breakpoint string "md" no breakpoint token (sm, md, lg, xl, xxl, ultra) or media query
target target string "" no selector of desktop container to clone links from
animation animation string "slide-down" no overlay transition (slide-down, fade, slide-right, slide-left)
direction direction string "top" no entrance direction
size size string "1.5em" no hamburger button size in em units
color color string "currentColor" no button stroke color
activecolor activeColor string "var(--accent)" no button color when open
autohidetarget autoHideTarget boolean true no automatically hides desktop target container below breakpoint
title title string "" no fallback header title when slot="header" is omitted

slots

programmatic api

1const hamburger = select('d-hamburger');
2
3// open overlay (returns promise)
4await hamburger.open();
5
6// close overlay (returns promise)
7await hamburger.close();
8
9// toggle overlay
10await hamburger.toggle();
11
12// navigate into a specific subcategory panel programmatically
13hamburger.navigateTo(subPanelElement, 'framework');
14
15// navigate back to previous parent panel
16hamburger.navigateBack();
17
18// close all open hamburger instances across the page
19dHamburger.closeAll();

events

event detail bubbles description
open none yes dispatched when overlay opens
close none yes dispatched when overlay closes

behavior


d-hold-button

press and hold button that prevents accidental triggers of destructive operations by requiring a continuous pointer press.

1<d-hold-button delay="1500" class="btn btn-red" type="submit">
2 hold to delete database
3</d-hold-button>

attributes and properties

attribute property type default form description
delay delay number 800 no hold duration in milliseconds required before triggering action
type type string "button" no button type ("button", "submit")
disabled disabled boolean false no whether the button is disabled

programmatic api

1const holdBtn = select('d-hold-button');
2
3// adjust required hold duration in ms
4holdBtn.delay = 2000;
5
6// toggle disabled state
7holdBtn.disabled = true;

events

event detail bubbles description
click native click event yes dispatched only after holding for the full delay duration

behavior


d-icon-button

icon button wrapper supporting custom icons, sizes, and dynamic theme active colors.

1<d-icon-button icon="dstrn-heart-line" size="2em" color="var(--content-l)" activecolor="var(--red)"></d-icon-button>

attributes and properties

attribute property type default form description
icon icon string "" no css icon class (e.g. dstrn-heart-line, dstrn-search)
size size string "4.2em" no font size of the icon container
color color string "var(--content-l)" no default icon color
activecolor activeColor string "var(--accent)" no active icon color
id id string "" no component id

d-image-input

drag and drop image dropzone with instant client preview and action overlay.

1<d-image-input accept="image/png,image/jpeg" name="avatar" fit="cover" placeholder="drop profile photo"></d-image-input>

attributes and properties

attribute property type default form description
accept accept string "image/png, image/jpeg, image/gif" no allowed image mime types
icon icon string "dstrn-pic-line" no placeholder icon class
placeholder placeholder string "drag & drop image" no dropzone title text
subtitle subtitle string "or click to browse" no dropzone subtitle text
replace-text replaceText string "replace" no text for overlay replace button
delete-text deleteText string "delete" no text for overlay delete button
no-replace noReplace boolean false no hides the replace button when true
no-delete noDelete boolean false no hides the delete button when true
fit fit string "contain" no object-fit CSS property (contain, cover, fill)
name name string "" no form payload field name
id id string "" no component id
value value object/string null yes File object or image URL string

programmatic api

1const imgInput = select('d-image-input');
2
3// reset dropzone and clear image preview
4imgInput.reset();
5
6// get or set preview src directly
7imgInput.preview = '/img/avatar.png';
8
9// read selected File instance
10console.log(imgInput.value);

events

event detail bubbles description
change File or null yes dispatched when an image is selected, dropped, or deleted

behavior


d-loader

high performance canvas arc spinner with automatic viewport intersection pause.

1<d-loader style="width: 2em; height: 2em;"></d-loader>

attributes and properties

attribute property type default form description
color color string "" no stroke color (defaults to --accent or computed text color)

programmatic api

1const loader = select('d-loader');
2
3// destroy loader and disconnect observers
4loader.destroy();

behavior


d-modal

modal dialog container with page scroll locking and backdrop dismiss protection.

1<d-modal id="confirm-modal" persistent>
2 <div class="flex-column g-1">
3 <h3>confirm deletion</h3>
4 <p class="text-content-l">this action cannot be undone.</p>
5 <div class="flex-row justify-end g-1 mt-1">
6 <button class="btn btn-sm" onclick="this.closest('d-modal').close()">cancel</button>
7 <button class="btn btn-sm btn-red">delete</button>
8 </div>
9 </div>
10</d-modal>

attributes and properties

attribute property type default form description
opened opened boolean false no whether the modal is currently visible
persistent persistent boolean false no whether the element remains in the dom when closed via backdrop click

programmatic api

1const modal = select('d-modal');
2
3// open modal (locks body scroll)
4modal.open();
5
6// close modal (runs exit animation and unlocks body scroll)
7modal.close();
8
9// close, await exit transition, and remove element from dom
10await modal.destroy();

events

event detail bubbles description
open none no dispatched when modal opens
close none no dispatched when modal closes

behavior and styling boundaries


d-morph

physics based morphing animation engine (dMotion) that transitions between named elements anywhere in the document with continuous geometry, border-radius, box-shadow, and form state interpolation.

1<d-morph name="summary-card" d-action="click" d-to="detail-card" d-duration="350" d-visible>
2 <div class="card p-2">
3 <h4>project summary</h4>
4 <p>click to expand details</p>
5 </div>
6</d-morph>
7
8<d-morph name="detail-card" d-action="click" d-to="summary-card" d-duration="350">
9 <div class="card p-4">
10 <h4>detailed project view</h4>
11 <p>full metadata and extended controls</p>
12 </div>
13</d-morph>

attributes and properties

attribute property type default description
name name string "" unique morph identifier registered in window.dMotion
d-visible none boolean false marks this morph element as initially active and visible
d-action none string "" trigger actions: "click", "long-press", "click-out"
d-to none string "" target morph name to transition to
d-duration none number computed transition duration in ms (computed from distance if omitted)

programmatic api (window.dMotion)

1// get a morph element instance by name
2const morph = dMotion.get('summary-card');
3
4// get the immediately previous morph element
5const prev = dMotion.getPrevious();
6
7// programmatically trigger a transition between two named elements
8await dMotion.transition('summary-card', 'detail-card', optionalTriggerNode);
9
10// register transition lifecycle hooks ('before' or 'after')
11dMotion.listen('summary-card', 'detail-card', () => {
12 console.log('transition starting');
13}, 'before');
14
15// unregister hook
16dMotion.unlisten('summary-card', 'detail-card', callback, 'before');
17
18// component methods on <d-morph>
19morph.show();
20morph.hide();

behavior


d-notification

toast notification component with linear progress bar countdown and automated exit lifecycle.

1<d-notification timer="4000" opened>
2 <p>project settings saved successfully</p>
3</d-notification>

attributes and properties

attribute property type default form description
opened opened boolean false no whether the toast notification is displayed
timer timer number 0 no auto dismissal duration in milliseconds (0 disables timer)

programmatic api

1const toast = select('d-notification');
2
3// show toast and start progress bar countdown
4toast.show();
5
6// hide toast
7toast.hide();
8
9// hide, wait for animation to finish, and remove from dom
10await toast.destroy();

behavior


d-skeleton

content loading placeholder shapes with customizable dimensions, line counts, and card presets.

1<d-skeleton type="text" lines="3" gap="0.5em"></d-skeleton>
2<d-skeleton type="circle" size="3em"></d-skeleton>
3<d-skeleton type="rect" width="100%" height="150px" radius="0.5em"></d-skeleton>
4<d-skeleton type="card"></d-skeleton>

attributes and properties

attribute property type default description
type type string "text" preset shape ("text", "circle", "rect", "card")
lines lines number 1 line count for "text" type (last line renders at 60% width)
width width string null CSS width
height height string null CSS height
size size string null shorthand for equal width and height on circle and rect
gap gap string "0.6em" vertical gap between lines in text mode
radius radius string null custom border-radius override

d-slider

range slider with pointer dragging, keyboard navigation, audio feedback, and automatic indicator text binding.

1<d-slider id="volume" name="volume" min="0" max="1" step="0.01" value="0.75"></d-slider>
2<span data-slider-volume class="text-content-l">75%</span>

attributes and properties

attribute property type default form description
value value number 0.5 yes current numeric slider value
min min number 0 no minimum allowable value
max max number 1 no maximum allowable value
step step number 0.01 no step increment for dragging and arrow keys
name name string "" no form payload field name
id id string "" no component id (used for data-slider-{id} text binding)
disabled disabled boolean false no disables slider interactions
thumbcolor thumbColor string "var(--accent)" no thumb color variable
fillcolor fillColor string "var(--accent-d)" no active track fill color variable
trackcolor trackColor string "var(--border-muted)" no inactive track background color variable
sfx none string embedded no audio sound effect URL or base64 audio payload

programmatic api

1const slider = select('d-slider');
2
3// read current value
4const current = slider.getValue();
5
6// set new value (updates visual fill, thumb position, and data-slider indicator)
7slider.setValue(0.85);

events

event detail bubbles description
input numeric value yes dispatched during continuous dragging and arrow key movement
change numeric value yes dispatched on pointer up or keyboard commit

behavior


d-text-input

enhanced input field with icon prefixes, keyboard shortcut binding, number stepper buttons, and form integration.

1<d-text-input
2 placeholder="search records"
3 icon="dstrn-search-line"
4 shortcut="cmd+k"
5 name="query">
6</d-text-input>

attributes and properties

attribute property type default form description
placeholder placeholder string "" no placeholder text
icon icon string "" no icon class name
type type string "text" no input type ("text", "password", "search", "number")
autocomplete autocomplete boolean false no browser autocomplete flag
value value string "" yes current input string value
name name string "" no form field name
id id string "" no component id
shortcut shortcut string "" no global keyboard shortcut (e.g. "cmd+k", "ctrl+f")
disabled disabled boolean false no disables input
readonly readonly boolean false no sets input to read only mode
min min string "" no minimum number value
max max string "" no maximum number value
step step string "1" no step value for number controls

programmatic api

1const input = select('d-text-input');
2
3// update value
4input.value = 'search term';
5
6// read or modify properties
7input.placeholder = 'type command';
8input.disabled = false;

events

event detail bubbles description
change string value yes dispatched on input modification

behavior


d-toggle

segmented toggle control with magnetic hover indicators and animated transitions.

1<d-toggle name="billing_period" value="0">
2 <div default>monthly billing</div>
3 <div>annual billing (save 20%)</div>
4</d-toggle>

attributes and properties

attribute property type default form description
value value number 0 yes zero indexed integer of currently selected option
name name string "" no form field name
id id string "" no component id
color color string "var(--container-l)" no container background color variable
activecolor activeColor string "var(--accent)" no active option highlight color
textcolor textColor string "var(--content-l)" no inactive option text color
textactivecolor textActiveColor string "" no active option text color
bgcolor bgColor string "var(--container-l)" no base background color
hovercolor hoverColor string "rgba(255, 255, 255, 0.05)" no hover background color

programmatic api

1const toggle = select('d-toggle');
2
3// get currently active button element
4console.log(toggle.selected);
5
6// activate option by index (number), string index, or button element
7toggle.selected = 1;
8
9// read or set numeric value
10toggle.value = 0;

events

event detail bubbles description
change selected index number yes dispatched when active selection changes

behavior


overriding built in components

every built in component behavior can be customized, extended, or completely overwritten by application code. to override a built in component, place a file with the exact same component filename under public/js/components/ (such as public/js/components/dCheckbox.js).

when compiling the frontend bundle, the compiler automatically detects the user file and replaces the built in component implementation in place.

1// public/js/components/dCheckbox.js
2class dCheckbox extends dComponent {
3 static form = true;
4 static get tag() { return 'd-checkbox'; }
5
6 // custom template or methods
7}
8
9dComponent.define(dCheckbox);

immutable base class

all custom elements and overrides extend dComponent. unlike UI components, dComponent is the immutable framework base class providing reactivity, reflection, and lifecycle management. the compiler always preserves the core dComponent implementation at the root of the bundle so all components inherit from it consistently.


dComponent (base class)

dComponent is the authoring base class for all custom web components in dframework. it provides property reflection, reactive proxy state, form integration, surgical dom rendering, and automatic memory cleanup.

1class dCounter extends dComponent {
2 static tag = 'd-counter';
3 static form = true; // opt into native form submission integration
4
5 static props = {
6 value: { type: 'number', default: 0, form: true },
7 step: { type: 'number', default: 1 },
8 disabled: { type: 'boolean', default: false },
9 label: { type: 'string', default: 'count' }
10 };
11
12 template() {
13 // called once on mount to establish initial innerHTML
14 return `
15 <span class="label">${this.label}</span>
16 <button class="dec" type="button">−</button>
17 <span class="value">${this.value}</span>
18 <button class="inc" type="button">+</button>
19 `;
20 }
21
22 mount() {
23 // called once after template initialization
24 this.effect(() => {
25 // reading this.state or props registers auto dependencies
26 document.title = `count: ${this.state.value ?? this.value}`;
27 return () => { document.title = 'app'; }; // optional cleanup
28 });
29 }
30
31 render() {
32 // called automatically on prop or state changes
33 // use for surgical dom updates only (never mutate this.state here)
34 this.refs('.value')[0].textContent = this.state.value ?? this.value;
35 this.refs('button.dec')[0].disabled = this.disabled;
36 this.refs('button.inc')[0].disabled = this.disabled;
37
38 // listeners attached inside render() are cleared and rebound automatically
39 this.listen(this.refs('button.dec')[0], 'click', () => this.decrement());
40 this.listen(this.refs('button.inc')[0], 'click', () => this.increment());
41 }
42
43 onPropChanged(name, oldVal, newVal) {
44 // called on attribute or property modifications
45 }
46
47 increment() {
48 this.setState(s => { s.value = (s.value ?? this.value) + this.step; });
49 }
50
51 decrement() {
52 this.setState(s => { s.value = (s.value ?? this.value) - this.step; });
53 }
54}
55
56dComponent.define(dCounter);

component definition and registration

register components using dComponent.define(Class):

1dComponent.define(dCounter);

lifecycle methods

method timing description
template() before mount returns initial HTML string to populate inner dom
mount() on first connection initializes component logic and registers effects
connected() on every connection called whenever element is attached to document
render() on state/prop change performs surgical dom node updates
onPropChanged(name, old, new) on prop mutation reacts to specific property changes
destroy() on disconnection teardown hook called when element is removed from dom
NOTE

`mount()` initialization is batched via `requestAnimationFrame` upon initial dom connection. this guarantees that all child nodes parsed in the light dom are present and available before `mount()` executes. for template components, template markup is preparsed on definition and stamped via cached `cloneNode(true)`. subsequent property and state updates are batched into a static 3 phase microtask flush.

fragment caching and batch mounting

for maximum throughput when generating dynamic content or lists of components, dComponent provides static utilities backed by an internal template lru cache:

1// parse html into a cached template fragment (avoids repeated innerHTML string parsing)
2const frag = dComponent.fragment('<div class="list-item"><span>title</span></div>');
3
4// append multiple nodes, fragments, or html strings in a single dom operation
5dComponent.appendMany(container, frag1, frag2, '<div class="extra">item</div>');

rendering strategy and surgical updates

dComponent avoids virtual dom overhead. dom nodes are created once in template() or mount(), while dynamic updates are applied surgically inside render().

IMPORTANT

`this.state` must never be modified inside `render()`. state mutations inside `render()` are blocked to prevent infinite update loops.

batched microtask update queue

property modifications and state mutations are automatically coalesced across all active components into a static 3 phase microtask flush:

  1. phase 1 (attribute sync): synchronizes observed html attributes for changed properties.
  2. phase 2 (rendering): clears transient render listeners and executes render() once per updated component.
  3. phase 3 (effects & form sync): reevaluates reactive effects, invalidates refs caches, synchronizes form internals, and dispatches an aggregated debugbar event.
1// multiple synchronous state mutations trigger exactly one render cycle in the next microtask
2this.state.title = 'new title';
3this.state.count = 42;

reactive state

1// update state and trigger microtask batched render()
2this.setState({ active: true });
3
4// functional updater
5this.setState(s => { s.count++; s.updatedAt = Date.now(); });
6
7// update state without triggering render() (still triggers effect loops)
8this.setState({ timer: Date.now() }, false);

effects and dependency tracking

1// auto tracking effect (tracks any accessed this.state or prop)
2this.effect(() => {
3 console.log('value updated:', this.state.value);
4 return () => console.log('cleaning up effect');
5});
6
7// explicit dependency array effect
8this.effect(() => {
9 fetchData(this.query);
10}, () => [this.query]);

automatic cleanup apis

these methods automatically clean up listeners, timers, and animation frame requests when the component is removed from the dom:

1// event listener with auto cleanup
2this.listen(element, 'click', (e) => this.handleClick(e));
3
4// listen to multiple elements
5this.listenAll(elements, 'click', (e) => this.handleClick(e));
6
7// unlisten manually if needed
8this.unlisten(element, 'click', handler);
9
10// auto cleared timers
11this.setTimeout(() => this.tick(), 1000);
12this.setInterval(() => this.refresh(), 5000);
13
14// auto cleared animation frame
15this.requestAnimationFrame((time) => this.draw(time));

dom caching and refs

this.refs(selector) caches queried element arrays between renders to eliminate repeated dom query overhead:

1const [inputEl] = this.refs('input.search');

inner content capture

access original light dom nodes passed into the custom element before template() execution:

1this.originalChildren // array of cloned child nodes
2this.originalHTML // original innerHTML string
3this.cloneChildren() // returns fresh clones of original child nodes

form integration

when static form = true, dComponent integrates with parent <form> elements and submits properties marked with form: true:

1static form = true;
2static props = {
3 value: { type: 'string', default: '', form: true }
4};
5
6// access parent form element
7console.log(this.form);

supports single values, file instances (File), file arrays (File[]), and multiple form properties automatically.

internal event emitter

1// listen to component events
2this.on('custom-event', (data) => console.log(data));
3
4// remove listener
5this.off('custom-event', handler);
6
7// emit event to internal listeners
8this.emit('custom-event', { id: 123 });

websocket integration

1// emit event through global websocket connection
2this.wire('chat:send', { message: 'hello' });