Vanilla web components and shared CSS. Built on Open Props tokens, native
<dialog> + Popover API, light DOM, no build step.
Why this library exists, how to load it, and the conventions it follows.
Tokens and style guidance for building consistent UI. Open Props primitives plus project-level semantic aliases.
Form fields, choice controls, help text, and validation messages.
.form-fields — form and field structure, labels, .input-group with prefix/suffix decoration, reading font for long-form text<x-select> — select with option groups, custom button content, [raw] inside an input group<ui-combobox> — autocomplete via mode="none|list|inline|both", async sources and their failures, chips and multiplerole="switch" — on/off toggle<fieldset> of radios — one of many, plain / segmented / card look, clearing the selection<small> swapping .field-help → .field-error → .field-success, with aria-invalid and aria-live; the same slot carries a server's rejection:user-valid / :user-invalid, disabled / readonly / locked, flux, busy while a save is in flight, error, which state wins, dirty tracking with .modifiedJS modules under public/ui/lib/ — orchestration helpers and stores that don't render UI themselves but back the components above.
job-queue.mjs — background queue: volatile closure jobs, plus fetch jobs persisted in IndexedDB and scheduled across tabs by a workerview.mjs — mount / swap / stop view componentsservice.mjs — register the parts of a page that hold timers, and stop them all with one callservice-worker.mjs — follow the page's service worker: which one served the page and what version it is, a new one installing or waiting, switching to it, and the precaching worker, which installs a checked snapshot, serves it and answers for its versionstable-table.mjs — re-render <tbody> while preserving hover/focusnotifications.mjs — store backing <ui-statusbar> + <ui-notifications>toast.mjs — transient announcementstooltip.mjs — hover/focus descriptionstree.mjs — decorate a nested <ul>/<li> into an APG tree viewlistbox.mjs — decorate elements already in the page into an APG listbox, including one nested inside another composite widgetaccordion.mjs — decorate <details>/<summary> into an APG accordion (region wiring, exclusivity, lazy load)l10n.mjs — translation + reactive localescroll-util.mjs — scroll a target into view only when it has left the reading zone, at the golden ratio, on both axes — vertically on the window or an inner scroll box, horizontally on whichever ancestor of the target scrolls sidewaysCustom elements and shared CSS patterns, grouped by role. Fields and their validation feedback have their own Forms card above.
.btn — Button — primary / outline / ghost / destructive, plus .btn-icon.badge — Badge — status pills<ui-toolbar> — horizontal group with roving tabindex (arrow-key nav)<ui-tab> / <ui-outlet> — tab list bound to a view switchertree() — nested <ul> into an APG tree view (expand/collapse, lazy children)listbox() — elements already in the page into an APG listbox (roving focus, typeahead)<ui-dialog> — modal, alert, response and slide (sheet) variants<ui-menu> — dropdown with submenus; trigger="contextmenu" for right-click menus<ui-popover> — anchored popover with light-dismisstoast() — transient status notificationtooltip() — description on hover, on focus, and on a held press.callout — Callout — a tinted remark about the element beside it, tinted by the caller<ui-notifications> — persistent list of warnings, opened from a trigger button<ui-statusbar> — projects the top active notification inline (role="status").status-success, .status-error), empty states, and which surface a form error belongs on.spin — Loading & spinners — inline spinner, busy overlay, and which to use when<bg-jobs> — operator table over the job queue: every job in the browser, counts by status, delete and retryaccordion() — Disclosure & Accordion (<details>)<article> — Card — list item with title, meta and actions<ui-icon> — Phosphor icon loader with a searchable grid<ui-code> — syntax-highlighted code display used throughout these docs