# smartwebUI
> A dependency-free component library where semantic HTML is the public API and AI agents are first-class citizens. Components are hand-writable HTML enhanced by a small JS runtime; a machine-readable catalog (smartwebui.catalog.json) lets agents render validated, safe surfaces declaratively. Browser support: the fixed September 2024 baseline (Chrome/Edge 129+, Firefox 130+, Safari 18+) — no legacy bundles, no polyfills.
License: smartwebUI Source License v1.0 — © 2026 Elonovo. Free to use and customize for your own projects; redistributing modified or rebranded versions requires written permission. See LICENSE.md.
## Documentation
- [Getting started, theming, utilities, browser policy](https://www.smartwebui.dev/docs)
- [Design choices & tradeoffs, FAQ, comparison](https://www.smartwebui.dev/docs#design-choices)
- [Agent security & e-commerce scope](https://www.smartwebui.dev/docs#agent-security)
- [Component reference (50 HTML families; catalog has 51 declarative node types)](https://www.smartwebui.dev/docs#components)
- [Design tokens](https://www.smartwebui.dev/docs#tokens)
- [Agent contract and declarative surfaces](https://www.smartwebui.dev/docs#agent)
- [Changelog](https://www.smartwebui.dev/changelog)
- [Live showcase](https://www.smartwebui.dev/demo)
## Install
No build step. Copy `smartwebui.css` and `smartwebui.js` (optionally `smartwebui-agent.js` + `smartwebui.catalog.json` for agent surfaces, `smartwebui-stripe.js` for payments, `smartwebui-mapkit.js` for Apple maps, `smartwebui-datagrid.js` for advanced server-driven grids, `smartwebui-media.js` for video/audio/playlist players, `smartwebui-signature.js` for e-sign intent capture):
```html
```
## Core conventions for agents generating markup
- Every component is plain HTML with `smart-*` classes and `data-smart-*` behavior attributes. Hydration is automatic on DOMContentLoaded and after `SmartWebUI.update()`/`render()`/`patch()`.
- Interactive controls keep a native hidden input (`input[type=hidden]`) in sync, so ordinary form posts work unchanged.
- The `hidden` attribute is the primary visibility mechanism; `SmartWebUI.hide()` / `SmartWebUI.show()` manage it. Visibility utilities: `.smart-hidden`, `.smart-invisible`, `.smart-hidden-mobile`, `.smart-visible-mobile`.
- Spacing/typography/layout utilities: `.smart-p-*` / `.smart-m-*` / `.smart-gap-*` (0–8, token-referenced; logical `pt/pb/ps/pe` and `mt/mb/ms/me`; `mx/my` axes), `.smart-text-*`, `.smart-grid--2/3/4`, `.smart-span-2/full`, desktop spans, `.smart-container--sm/md/lg`, `.smart-ratio-*`, `.smart-elevated-*`, `.smart-rounded-*`, `.smart-divider`, `.smart-kbd`, `.smart-line-clamp-2/3/4`, `.smart-sticky(-top)`, `.smart-z-raised/sticky/tooltip/toast/banner`, tablet/desktop visibility, `.smart-reveal`, `.smart-skip-link` (focus-revealed bypass link to `#main`).
- Validation is native: `:user-invalid`/`:user-valid` are styled, `required` adds a marker, `.smart-error--live` reveals on failure; server errors use `.smart-field--invalid` + `.smart-error`. For JS-driven flows, `SmartWebUI.validate(form, rules, { summary })` wires `aria-invalid`, error messages, and a FormErrors summary.
- 1.0.2 components: vertical tabs (`.smart-tabs--vertical` + `aria-orientation="vertical"`, Up/Down keys), split button (`.smart-split-button` wrapping two `.smart-button`s + popover menu), quantity stepper (`.smart-quantity` with `[data-smart-step]` buttons + number input, `Field control: "quantity"`), password strength (`input[data-smart-strength]` auto-creates the meter), dropzone file upload (`.smart-file[data-smart-dropzone]`, `data-max-size` + `accept` validation, `SmartWebUI.upload(input, url, options)` with `smart:upload-*` progress events), OTP verification (`.smart-otp` digit row — auto-advance, paste distribution, `smart:otp` events, `Field control: "otp"` with `length`), countdown (`SmartWebUI.countdown(el, seconds, { warnBelow, onExpire })` or `data-smart-countdown` markup, `smart:countdown` events).
- 1.1 application kit: AppHeader + nested AppShell + Footer and the Alert consent placement; sticky/expandable/width-controlled/totals tables and page size; Field multi-select/numeric-range/rating/color/mask variations plus icon adornments and textarea counters; placed Toasts; collapsing Breadcrumbs; connectivity and scroll-to-top affordances; CommandPalette + shortcuts; Avatar groups/status, List timeline/key-value/notification/attachment variations, Progress ring/bar/spinner/skeleton variations, and the Carousel family (snap strip, gallery grid, zoomable lightbox viewer).
- 1.2 collaborative HTML: `data-smart-richtext` sanitizes toolbar HTML before hydrating the labelled `contenteditable` editor or writing its `input[type="hidden"]` form value (default tags: p, br, strong, b, em, i, u, ul, ol, li, a; subset with `data-smart-richtext-allow`); set `data-smart-richtext-required` for visible-editor validation and use `aria-labelledby`/`aria-label`; toolbar formatting controls expose `aria-pressed`; emits `smart:change` with `{ value, control }`. `data-smart-board` uses Enter/Space to lift, arrows to preview, Enter/Space to drop (Escape cancels), plus pointer/touch drag, emitting `smart:board` and `smart:move`; it creates a polite live region for move state and mirrors horizontal arrows in RTL. Default board minimum height is `--smart-board-min-block-size: 18rem`; use `smart-board--compact` for small boards. Opt-in `.smart-list--sortable[data-smart-sortable-list]` lists use left grip handles, Space/Enter lift/drop, Up/Down/Home/End movement, Escape cancellation, pointer/touch drag with edge autoscroll, form-order synchronization through `[data-smart-sort-order]`, and emit `smart:reorder` with `{ itemId, orderedIds, fromIndex, toIndex }`. `data-smart-composer` auto-resizes and emits `smart:send`.
- Badges and chips assume short labels. For long user-controlled or translated text, use `smart-badge--truncate` / `smart-chip--truncate` with a nested `__label` and full `title` or `aria-label`, or `--wrap` where vertical growth is acceptable; `--smart-label-max-inline-size` defaults to 18rem.
- Page-header toolbar: apply `smart-page-header--toolbar` to a `smart-page-header` and wrap its related filters, search, or view controls in `smart-page-header__toolbar`. The toolbar stays compact and inline from tablet widths upward, then wraps on smaller screens.
- Print: `.smart-no-print` hides chrome on paper; `.smart-print-document` is a flattened, print-optimized document surface for invoices and receipts.
- Scroll panes: `.smart-scroll-y` / `.smart-scroll-x` (thin scrollbars, contained overscroll), `.smart-pane-fill` / `-tall` / `-screen` (`--smart-pane-offset` subtracts chrome height) for messenger-style layouts.
- Chrome strings (placeholders, aria labels, validation messages) localize through `SmartWebUI.setLocale({ key: "…" })`; dates and currency always use `Intl`.
- All spacing/borders/radii are logical properties — set `dir="rtl"` and the interface mirrors.
- Use sprite SVGs, not Unicode glyphs, for interface actions and status marks. Icon-only controls require a textual accessible name; their SVG stays decorative. Keep prose punctuation, keyboard characters, and mathematical notation as text.
- Opt in to the unsupported-browser banner with ``.
## Agent runtime (smartwebui-agent.js)
- Protocol: `smartwebui.surface/1.0`. Surfaces are JSON: `{ surface: string, root: { type, id, children? } }`.
- 51 catalog node types: Stack, Cluster, Grid, Text, Icon, Button, Field, Choice, Switch, SegmentedControl, Card, Badge, Tabs, Accordion, Dialog, Drawer, PopoverMenu, Tooltip, Toast, Progress, Alert, Breadcrumbs, Pagination, Table, Empty, Avatar, List, Chip, PageHeader, AppShell, AppHeader, Footer, CommandPalette, FormErrors, Stepper, Payment, Chart, Carousel, RichText, Board, Conversation, Composer, Map, DataGrid, MediaPlayer, SignaturePad, Tree, ContextMenu, SplitPane, FilterBar, NotificationCenter. Universal property: `hidden` (boolean). These nodes cover every one of the 50 HTML families; Conversation and Composer are separate nodes while several related controls remain variants of Field or Dialog.
- Carousel nodes browse media: `items[]` carry `src` (surface src policy), `alt`, `caption`, and optional nested `content` nodes rendered over the media. `variant` is `carousel` (snap strip with dots and arrows) or `gallery` (grid of zoom-trigger cells); `ratio` is `1x1` | `4x3` | `16x9` | `21x9`. `autoplay` pauses on hover, focus, and offscreen and never starts under `prefers-reduced-motion`. `lightbox: true` opens a native-dialog viewer with swipe, drag-to-dismiss, and pinch/double-tap/⌘-scroll/keyboard zoom. `smart:slide` carries `{ index }`; snapshots expose `selected`. At most 24 items.
- MediaPlayer accepts safe relative/http(s) media, poster, and caption URLs and keeps native controls as its fallback. It cannot carry credentials, DRM settings, callbacks, autoplay, or inline media data; the application still owns authorization, rights, transcripts, codecs, analytics consent, streaming SDKs, and DRM.
- SignaturePad can declare only an empty signing surface. It never accepts a value, strokes, image, typed name, completed state, or submission action from an agent. Only explicit user interaction may populate its hidden value; the host owns consent, signer authentication, document integrity, audit evidence, encryption, retention, server validation, and legal review.
- Icons use names from `smartwebui-icons.json`; authored SVG points to `smartwebui-icons.svg#smart-icon-{name}`. Size is any CSS length through `--smart-icon-size`; stroke uses `--smart-icon-stroke`. Give standalone meaningful icons a label and leave decorative icons hidden from assistive technology. `loadIconCatalog()` pins the runtime sprite and catalog URLs to the loaded payload (`?v=version.count`) so a cached sprite can never lag a fresh catalog; call `setIconSource(spriteUrl, catalogUrl)` first when you host the sprite elsewhere.
- Chart nodes plot finite numeric series as `sparkline`, `bar`, `stacked-bar`, `line`, `area`, `combo`, `scatter`, `donut`, or `gauge`. Donut accepts an optional `hole` (0–0.85 of the radius); `hole: 0` renders a filled pie and omits center labels. Combo series may declare a `bar`, `line`, or `area` mark and a `left` or `right` axis. Scatter uses numeric x/y points. Gauge accepts min/max, thresholds, and an optional target for operational ranges; use Progress ring for completion. Provide axis names, units, and a concise `summary` for AI/computer-use readability. Tones are `accent` | `success` | `warning` | `danger` | `secondary` only. Do not emit SVG, hex colors, or path data. Sparkline belongs inside a metric `Card`.
- The renderer never accepts HTML, scripts, classes, or inline styles from agent JSON. Unknown properties fail closed. `href`/`src` are restricted to http(s), mailto, relative paths, and in-page hashes. Depth, node-count, and text-length limits apply.
- API: `SmartWebUI.render(target, surface)`, `SmartWebUI.patch(target, ops)` (`data.patch`, `node.upsert`, `node.remove`, `node.append`), `SmartWebUI.append(target, { parent, node | nodes })` for streaming growth, `SmartWebUI.adopt(target)` for server-rendered markup, `SmartWebUI.history(target)` → `{ undo(), redo(), clear(), entries, canUndo, canRedo }`, `SmartWebUI.validateSurface(surface)` → `{ valid, errors, issues: [{ path, message }] }`, `SmartWebUI.snapshot(target)` → `{ capturedAt, nodes: { [id]: { type, value?, checked?, selected?, expanded?, step?, open?, hidden? } } }`, `SmartWebUI.loadCatalog()`. Form validation is separate: `SmartWebUI.validate(form, rules, { summary })` on the core runtime (do not pass surface JSON to `validate()`).
- Application helpers: `copy(text)`, `confirm(options)`, formatters, `debounce`, `throttle`, `shortcuts.register()`, `observeBreakpoint()`, `observeLoadMore()`, `observeConnectivity()`, `focusFirst()`, `trapFocus()`, `trackDirty()`, `queryState.read/write/apply/bind`, `virtualize()`, and `scrollToTop()`.
- Server-side rendering: `smartwebui-surface.php` (PHP 8.0+, zero dependencies) emits the same semantic HTML with stable `data-smart-id` attributes and an embedded declaration. `SmartWebUISurface::container($surface)` returns a self-adopting block; `SmartWebUI.adopt("#id")` registers it in the browser without a rebuild, after which `patch()`, `snapshot()`, and `history()` work normally.
- Payment nodes are intent-only: the host mounts Stripe Elements via `SmartWebUIStripe.mount(slotId, { publishableKey, clientSecret })`. Keys, secrets, and card data never enter agent JSON. `elementType` accepts any Element — including `"address"` (with `addressMode: "billing" | "shipping"`) and `"expressCheckout"` for Apple Pay / Google Pay; `elementOptions` is forwarded to `elements.create()` verbatim.
- Events (bubbling CustomEvents): `smart:action`, `smart:change`, `smart:select`, `smart:combobox`, `smart:multiselect`, `smart:date`, `smart:time`, `smart:range`, `smart:rating`, `smart:tags`, `smart:tab`, `smart:accordion`, `smart:breadcrumbs`, `smart:step`, `smart:slide`, `smart:sort`, `smart:table-select`, `smart:table-action`, `smart:confirm`, `smart:toast-action`, `smart:chip-remove`, `smart:attachment-remove`, `smart:chart-select`, `smart:copy`, `smart:connectivity`, `smart:dirty`, `smart:query-state`, `smart:virtualize`, `smart:update`, `smart:patch`, `smart:surface`, `smart:adopt`, `smart:theme`, `smart:density`, `smart:material`, `smart:compat`, `smart:countdown`, `smart:countdown-expire`, `smart:locale`, `smart:validate`, `smart:quantity`, `smart:otp`, `smart:strength`, `smart:file`, `smart:upload-progress`, `smart:upload-done`, `smart:upload-error`, `smart:ready`, `smart:agent-ready`, `smart:stripe-ready`, `smart:payment-ready`, `smart:board`, `smart:move`, `smart:send`.
## Do not (agents)
- Do not pass surface JSON to `SmartWebUI.validate()` — use `SmartWebUI.validateSurface(surface)` for declarations; `validate(form, rules)` is for HTML forms only.
- Do not put publishable keys, client secrets, card data, or authoritative charge amounts in agent surfaces — host mounts payment UI and charges server-side.
- Do not put HTML strings inside surface JSON — use catalog node types; agents may write hand-authored smart-* HTML directly when that fits the host workflow.
- Do not assume legacy browsers — target the September 2024 baseline or newer (Chrome/Edge 129+, Firefox 130+, Safari 18+).
- Prefer server render + `SmartWebUI.adopt()` when the host is PHP or can emit first paint from `smartwebui-surface.php`.
- Treat agent `text` as untrusted copy — it can mislead users even when structurally valid.
## Theming
- Everything is token-driven (`--smart-*` CSS custom properties): accent, surfaces, text, spacing (0–12), radius, shadows, motion, z-index ladder (`--smart-z-raised/sticky/tooltip/toast/banner`), overlay scrim.
- `SmartWebUI.setTheme("light" | "dark" | "auto")`, `setDensity("comfortable" | "compact")`, `setMaterial("solid" | "liquid")`.
- Buttons support `SmartWebUI.setBusy(button, true)` for in-flight states.