VUI for HTML
71 of 97 component families as plain markup. Copy a file out of
dist/components/ and style it with
vui.css. No build step and no framework.
53 are rendered from the React source, so both editions emit the same
document. 18 are overlays, which React builds at runtime through a
portal: those ship as the native element for the job wearing the same shared classes, so
the styling is identical and the structure is the browser's. Add
vui.js for the three things HTML cannot do alone.
Theme
The same 6 presets the React edition ships, applied as custom properties on
:root. Every component below follows, because they all read
the same tokens.
accordion
alert
aspect-ratio
avatar
badge
breadcrumb
breadcrumbs
button
calendar
card
Northwind Traders
Trialing until 4 September
checkbox
command
command-palette
confirm-dialog
data-table
| Northwind Traders | paid | 2026-01-01T00:00:00.000Z | 250 |
| Contoso | pending | 2026-02-08T00:00:00.000Z | 387 |
| Fabrikam | overdue | 2026-03-15T00:00:00.000Z | 524 |
| Adventure Works | paid | 2026-04-22T00:00:00.000Z | 661 |
| Tailspin Toys | pending | 2026-05-02T00:00:00.000Z | 798 |
| Wide World Importers | overdue | 2026-06-09T00:00:00.000Z | 935 |
| Proseware | paid | 2026-07-16T00:00:00.000Z | 1072 |
| Northwind Traders | pending | 2026-08-23T00:00:00.000Z | 1209 |
data-table-panel
Invoices
Every invoice raised this quarter.
| Northwind Traders | paid | 2026-01-01T00:00:00.000Z | 250 |
| Contoso | pending | 2026-02-08T00:00:00.000Z | 387 |
| Fabrikam | overdue | 2026-03-15T00:00:00.000Z | 524 |
| Adventure Works | paid | 2026-04-22T00:00:00.000Z | 661 |
Showing 1 to 4 of 8
dialog
empty-state
No Invoices Yet
Invoices appear here once you send one. Nothing has been billed on this account.
error-state
We Could Not Load Your Invoices
The request did not complete. Try again, and if it keeps failing, contact support.
field-grid
Shown on the invoice.
filter-field
input
kbd
label
menu
org-switcher
organization-profile
page
password-input
profile-form
General
- Customer
- Northwind Traders
- Status
- paid
- Issued
- Thu Jan 01 2026 00:00:00 GMT+0000 (Coordinated Universal Time)
button-group
list
- Northwind Retail
- Sakura Foods
- Alpine Logistics
spinner
page-header
Orders
progress
radio-group
record-field
record-form
General
- Customer
- Status
- Issued
record-view
|
|
Name | Actions | |||
|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
required-mark
scroll-area
separator
skeleton
steps
- AccountWho you are
- OrganizationWhere you work
- 3Done
stepper
switch
table
| Organization | Country | Employees |
|---|---|---|
| Acme Industrial | Germany | 1,204 |
tabs
tanstack-chart
textarea
toggle
toggle-group
wizard
- Account
- Organization
- 3Done
Organization
Where you work.
Overlays, as native HTML
React renders these through a portal that only exists at runtime, so a static copy of its markup would be generated ids and measured transforms rather than a template. These use the element the browser already has for the job, with the same shared classes: the styling is identical and the structure is the browser's.
alert-dialog
cascading-combobox
chart
collapsible
Branch details
combobox
date-field
dropdown-menu
Actions
Organization
form-actions
hover-card
input-otp
multi-combobox
popover
Details
select
sheet
slider
time-field
toast
Organization saved
Northwind Traders was updated.
tooltip
Data driven, and shipping with the page templates
-
card-fields
The masking is the component. A static render is three empty boxes and shows none of it.
-
video-embed
The poster is static, the click that loads the player is not, and half of it is a picture.
-
status-field
Half of it needs a tooltip runtime, and the half that does not is the wrong default.
-
carousel
The slides render, the controls that change them do not, and it would sit on slide one.
-
pagination
The markup renders, the click that changes the page does not, and `vui.js` has no pager.
No markup of their own
-
voilet-shell
A whole application frame: sidebar, header, content and footer. A gallery specimen is a component in a box, and this is the box.
-
neon-shell
The third application frame: a full-width bar with the sidebar beneath it. Chrome for the same reason the other two are, it is the box rather than a component in one.
-
jira-shell
The fourth application frame: a bar carrying a primary action, over a resizable sidebar scoped to one project. The box rather than a component in one.
-
suite-shell
The fifth application frame, and the only one with no vertical navigation: an application rail, module tabs running across, and a filter sidebar inside the content.
-
mobile-nav
The mobile bottom bar and the drawer it opens: the frame under 768px, not a component a page composes. It left the Desk shell in `PD-979` because a bar on a small screen is not a theme's idea, and its drawer is a slot the theme fills (`PD-980`).
-
workspace-tabs
The Desk shell's open-tabs strip: browser chrome for the application, not a component a page composes. It is Pro for the same reason workspace-shell is, and a gallery the free editions render could not show it anyway.
-
zoho-shell
Zoho's frame: a 90px icon rail, a 250px second-level menu and the content. An application frame, not a component a page composes, and the only shell here with two persistent navigation columns.
-
rackwise-shell
Rack's frame, and the only one that opens its rail with an account block rather than a mark: it has no wordmark region at all. The box rather than a component in one.
-
tendora-shell
Reach's frame: a rail flush to the viewport with its own search under the mark, and a toolbar band under the page header rather than actions beside the title.
-
flow-shell
Flow's frame, and the only one whose chrome does not touch the viewport edge: a header card, a rail card and a content card floating on the page ground with a 12px gutter between them. Every sibling treats the edge as the chrome's boundary.
-
durara-shell
Counter's frame: the collapse control inside the rail's own head, a store switcher beneath it, an account panel as the rail's foot, a plan banner on every screen and a floating action button over all of it.
-
swift-shell
Panel's frame, and the only one with no header band: the page title is a text node in the content beside its own date pickers, so the shell draws no bar to put it in.
-
workspace-shell
The other application frame, and chrome for the same reason voilet-shell is: the box, not a component in one. It is Pro besides, so a gallery the free editions render could not show it anyway.
-
auth-context
A context provider. It renders its children and no markup of its own.
-
code
A pass-through: it renders `<code>` with whatever class it is given and has no styles of its own, so there is no markup to ship.
-
config
A provider carrying configuration. No markup of its own.
-
form
Inseparable from a `react-hook-form` context. `field-grid` is the markup an HTML buyer needs and it is emitted.
-
page-chrome
A provider carrying page chrome state. No markup of its own.
-
transaction-page
The page type, not a control: it draws its own header line and section cards, so it is chrome in the same sense the shells are.
-
sonner
A wrapper over the `sonner` React runtime, which renders its own DOM. The `toast` pattern is this edition's answer.
-
table-io-actions
Import and export actions for a table. No component of its own.
-
theme-provider
A provider carrying the theme configuration. No markup of its own.
-
use-form-fields
A hook. Nothing to render.