Components
Package: @zuilib/components · React 18 · Headless UI v2 · Tailwind v4 (optional at runtime)
@zuilib/components is the component layer of ZUI: forty-odd primitives
that companies build their own design system on. Every visual decision in
them reads a token from @zuilib/tokens, so
customisation is CSS-variable overrides on :root or on any subtree, and
nothing else. Behaviour and accessibility come from Headless UI; the
components add the ZUI styling, sizes, form-state wiring and data-slot
hooks for your own CSS.
pnpm add @zuilib/components react react-dom @headlessui/react
import '@zuilib/components/zui.css' // or one of the Tailwind entries, see Getting started
import Button from '@zuilib/components/button'
What you get
| One import per component | @zuilib/components/button, /input, /dialog, …: tree-shakes to what you use. Compound parts are statics (Listbox.Option) and named exports |
| Tokens only | No raw colours, radii or sizes in the components. Override --primary, --radius, --control-height-md and every button, field and card follows |
| Headless UI state | data-open, data-checked, data-focus, data-disabled, data-invalid on the parts they belong to, plus data-state where Headless UI has nothing |
data-slot on every part | [data-slot="listbox-option"]: target a part from your own CSS without depending on class names |
| Forms | FormItem gives its control the id, label, description, error and disabled state; every field has invalid, size, fullWidth, name |
| RSC-safe | Every file starts with 'use client'; import from a server component and it just works |
| Dark mode | The dark class on <html> (or any wrapper) swaps the token values; the components do nothing special |
Start with Getting started for the stylesheet
choice, then Theming for how a brand is applied. The
Registry page covers installing single components as
source with the zui CLI.
Inventory
Actions
- Button: variants, sizes, loading, polymorphic
as - AIButton: Button with a sparkle and a generating state
Forms
- Fieldset: grouped fields with a legend and shared disabled state
- FormItem: label, control, description and message wired together
- Label, Description, Message: the field text parts
- Input, Textarea, RichTextarea
- NumberInput, PinInput, SearchInput
- Select: the native select, styled
- Listbox, Combobox: custom selects, single and multiple
- Checkbox, RadioGroup, Switch
- Slider: a native range input on the tokens
- FileUpload: drop zone and file list
Overlays
- Dialog: modal with backdrop, title and description
- Drawer: a side panel
- Popover: anchored panel
- Menu: actions list with keyboard navigation
- Tooltip: hover / focus hint
Navigation
Feedback
- Alert: inline status message
- Progress, Spinner, Skeleton
- EmptyState
Data display
Layout
Typography
Companions
@zuilib/form (react-hook-form binding), @zuilib/table (data tables on
TanStack Table) and @zuilib/toast build on these components and share the
same tokens. The text editor too.