Skip to content

DOM API

Everything exported by @idlekitjs/dom. Concepts and usage: Rendering with the DOM.

Renderer

Collects bindings and refreshes them once per frame. Connected to a ReactiveStore (which createEngine does for you when you pass renderer), it re-runs only the bindings whose actually read state keys changed; unconnected, it re-runs everything.

MethodBehavior
add(binding)Register a dependency-tracked binding; returns it
addAll(bindings)Register several at once
addFrame(binding)Register a binding re-run every frame, bypassing tracking (for values mutated in place: progress bars, timers)
render()Refresh due bindings, then frame bindings (the game calls this)
connect(store)Attach a store for dirty-key tracking (done by createEngine)
disconnect()Detach; falls back to re-run-everything

Bindings

ts
interface Binding {
  update(): void;
}

All built-ins cache their last value and skip identical DOM writes:

ts
bindText(element: HTMLElement, getter: () => unknown): Binding;
// element.textContent = String(getter())

bindClass(element: HTMLElement, className: string, getter: () => boolean): Binding;
// element.classList.toggle(className, getter())

bindVisible(element: HTMLElement, getter: () => boolean): Binding;
// element.hidden = !getter()

bindDisabled(element: HTMLButtonElement | HTMLInputElement, getter: () => boolean): Binding;
// element.disabled = getter()

Custom bindings are any { update() } object following the same cache-and-skip discipline — example.

bindEach

ts
import { bindEach } from "@idlekitjs/dom";
// or: import { bindEach } from "@idlekitjs/dom/bind-each";

function bindEach<VM>(
  container: HTMLElement,
  options: BindEachOptions<VM>,
): Binding;

interface BindEachOptions<VM> {
  items: () => Iterable<VM>;
  key: (item: VM) => string;
  create: (item: VM) => HTMLElement;
  update?: (element: HTMLElement, item: VM) => void;
  remove?: (element: HTMLElement, item: VM) => void | Promise<void>;
}

Keyed list binding. New keys call create, existing keys call update, and removed keys call remove before the element leaves the DOM. Register it with Renderer.add for state-key-driven lists or Renderer.addFrame for continuously mutated view models such as countdowns.

Browser runtime bridges

The requestAnimationFrame frame driver (createRafScheduler) and the screen/pixel helpers (screen) are browser runtime bridges, not DOM rendering — they live in @idlekitjs/browser.