Components
Every component ships three ways: a headless primitive, a styled registry surface you own outright, and a Figma component set. Pick a component to see all three — pages marked Docs soon are on their way.
Layout
Aspect Ratio
stableA box that constrains its content to a width-to-height ratio via CSS
aspect-ratio.ratiois a curated preset set of modifier classes (1/1, 4/3, 3/2, 16/9, 21/9 and their portrait inverses); a bespoke ratio comes from overriding --primitiv-aspect-ratio in a stylesheet.Box
stableThe escape hatch — a bare polymorphic element with no visual opinion. Exists so a consumer has something to attach a custom property or a one-off style to without reaching for a raw <div>.
Center
stableA single- or both-axis Flexbox centring box.
Container
stableA centred, max-width content column with token-bound inline gutters.
sizecaps the width against the breakpoint scale andguttersets the inline padding —responsive(the default) escalates it at the md and lg breakpoints, the fixed steps pin one value at every width. No inline styles: both props are curated presets.Divider
stableA separator between content sections — a
<span role="separator">whosearia-orientationdrives a horizontal or vertical rule.Grid
stableA CSS Grid container.
columnstakes a count or a mobile-first per-breakpoint map,gapthe spacing (a density-scaled Context token per step), andalign/justifyhow each item sits within its cell. No inline styles: the per-breakpoint column counts resolve to modifier classes, so the responsive behaviour is correct in server-rendered markup on the first paint.Spacer
stableA flex: 1 0 0 blank element for pushing flex siblings apart — toolbar left/right groups, card footers, nav bars.
Stack
stableA Flexbox stack —
directionpicks the axis,gapthe spacing (a density-scaled Context token per step),wrapwhether the row may break onto additional lines, andalign/justifythe alignment, all as modifier classes. No inline styles: the alignment props are curated presets, not raw CSS keywords.
Buttons
Button
stableA clickable action — a button, or a link styled as one via
asChild.Split Button
Docs soonOne primary action welded to a chevron trigger that opens a menu of related alternatives, bound into a single role="group" widget.
Forms
Checkbox
stableA tri-state checkbox with an optional inline label — an independent on/off (or mixed) form selection.
Checkbox Card
stableA card/tile-shaped checkbox — the whole bordered surface is the interactive element, not a small control plus a separate label. Composes the headless CheckboxCard primitive (role="checkbox", tri-state unchecked/checked/indeterminate). Sized xs–xl;
data-densityscales each size further.Field
stableA form-field wrapper — coordinates a label, control, description, and error message and cascades id / validity / disabled / required to the control it wraps.
Input
stableA single-line text input — the framed field consumers type into.
Input Group
stableA framed control with leading / trailing adornment slots — wraps an Input for icons, prefixes, clear buttons, and reveal toggles.
Radio
stableA single native radio input with an optional inline label, grouped with a shared
name.Radio Card
stableA card/tile-shaped radio item — the whole bordered surface is the interactive element, not a small control plus a separate label. Composes the headless RadioCard primitive (RadioCard.Root is role="radiogroup" with no visual anatomy of its own; RadioCard.Item is role="radio"). Sized xs–xl;
data-densityscales each size further.Segmented Control
stableA single-select segmented control — a linear strip of segments where exactly one is selected. The selected segment is brand-filled; the rest are secondary.
Slider
stableA draggable, keyboard-accessible control for selecting one value (or a range) along a track.
Switch
stableAn on/off toggle with an optional inline label — a native switch input for an immediate binary setting.
Textarea
stableA multi-line text input — the framed field consumers type longer content into.
Collections & Selection
Combobox
Docs soonAn editable text field with a filtered popup listbox, implementing the WAI-ARIA APG combobox pattern. The control is Input verbatim — same
framed-control/{size}/*geometry, same states — wrapped so a trailing chevron can sit beside the field, and the popup is a floating panel atelevation/overlaywhose rows resolve the shared dropdown tokens, so a combobox listbox and a menu are the same surface. Filtering is consumer-owned: there is nofilterprop. Keyboard, virtual-focus cursor, the query/value split and the open state all belong to the headless primitive.Listbox
Docs soonA persistently-visible list of selectable options implementing the WAI-ARIA APG listbox pattern. Unlike
select, this list is always on screen with no trigger and no popup, and its cursor is a virtual-focus position (aria-activedescendanton the root,data-highlightedon the option) rather than DOM focus — which is what lets a separate control, such as a search input or a command palette's text field, hold focus and drive the list at the same time. Framed like a form control on Input's geometry, with rows resolving the shared dropdown tokens so a listbox and a menu are the same surface. Keyboard, typeahead, cursor and selection are owned by the headless primitive.Miller Columns
Docs soonA horizontal strip of vertical lists where selecting a node reveals its children in the next column — the macOS Finder column view, with drag/keyboard-resizable columns and an optional preview pane.
Select
stableA single-select control with two render paths behind one API: a rich Popover-API listbox (the default) whose options carry icons, badges and a selected mark, or a native
<select>for flat, OS-native cases. The rich control is a framed field on the same geometry as Input; its panel and rows resolve the shared dropdown tokens, so a Select listbox and a Dropdown menu are the same surface. Positioned with CSS anchor positioning, wired by the component itself; keyboard, typeahead, focus and form submission are owned by the headless primitive.Tree
Docs soonA hierarchical list of expandable branches and selectable leaves — the WAI-ARIA tree view, with connector guide lines and an optional breadcrumb of the selected node's ancestry.
Typography
Blockquote
stableA <blockquote> with a left-stroke accent bar and an optional attribution line.
tonepicks the bar colour (default | accent);sizescales the quote and citation type together.Code Block
stableA block of source code — a bordered, tinted surface with mono type, an optional filename/copy header, an optional line-number gutter, and Prism syntax highlighting themed from tokens. Sized xs–xl;
data-densityscales the padding. Compound subcomponents (CodeBlock.Tabs/Header/List/Trigger/Content/Copy) add a tabbed variant that composes the headless Tabs primitive and reuses the tabs component's classes.Description List
stableA <dl> compound — one <dt> (fixed SemiBold) + one <dd> per pair.
layoutpicksstacked(dt above dd, dd indented) orinline(dt : dd side by side in a two-column grid), matching the two layouts in the Figma component set. Consumers compose multiple Term/Details pairs to form a full description list. row-gap/column-gap/details-indent are density-scaled Context tokens; inline's pair-to-pair gap reuses List's item-gap directly, matching the Figma binding.Figure
stableA <figure>/<figcaption> pairing that wraps self-contained content (an image, illustration, chart, code listing, table) with an optional caption in one of three positions — below (default), above, or overlaid on the media.
sizescales the caption's type off the body/{size} ramp (the media is size-independent, as in Figma); the caption's ownalignmatches Figma's Figcaption Align axis.Inline Code
stableInline code — a
<code>fragment set in the mono face on a tinted, hairline-bordered chip. Sized xs–xl so a snippet tracks the surrounding text;data-densityscales each size further.Kbd
stableA
<kbd>fragment set in the mono face on a raised, bordered key cap — the physical-keycap sibling of Inline Code. Sized xs–xl so a shortcut tracks the surrounding text;data-densityscales each size further.List
stableA <ul>/<ol> with custom, token-coloured markers and a controllable item gap, marker gap and indent — the styled counterpart to the bare list styles in primitiv.reset.
Prose
stableA flow-rhythm container — applies the
.primitiv-flowcontext so every direct child gets density-scoped vertical spacing via a one-directional owl. Zero behaviour; renders a semantic element, composing the consumer's own element viaasChild.Pull Quote
stableA large, centred editorial quote — no accent bar, no attribution, distinct from Blockquote. Rides the existing heading/* type scale; an optional decorative open-quote mark.
Overlays
Confirm Dialog
Docs soonA pre-arranged Modal for confirming or cancelling a single action — title, body slot, and a Cancel/Confirm footer, with the Confirm button's tone following the action (primary, or danger for a destructive one). Composes the registry
modalandbuttoncomponents directly rather than introducing new dialog anatomy.Context Menu
Docs soonA right-click / long-press context menu built on the native HTML Popover API — the same bordered, shadow-defined panel of selectable rows (plain items, checkbox/radio items, submenus) as Dropdown, positioned at the pointer instead of anchored to a trigger. Keyboard, typeahead, and focus are owned by the headless primitive.
Drawer
stableAn accessible drawer — a Modal dialog built on the native
<dialog>element that slides in from a screen edge (top, right, bottom, or left).Dropdown
stableA menu-button dropdown built on the native HTML Popover API — a bordered, shadow-defined panel of selectable rows (plain items, checkbox/radio items, submenus), grouped with labels and separators. Positioned with CSS anchor positioning; keyboard, typeahead, and focus are owned by the headless primitive.
Modal
stableAn accessible modal dialog built on the native
<dialog>element — a fixed-width surface with an optional dimmed backdrop (WAI-ARIA Modal Dialog pattern).Popover
stableA non-modal floating panel anchored to a trigger, built on the native HTML Popover API — a borderless, shadow-defined surface with a pointer arrow, positioned with CSS anchor positioning across all twelve placements.
Tooltip
stableA deferred, non-modal label anchored to a trigger (hover / focus). A flat bubble with a pointer arrow, in two tones — a high-contrast dark bubble (default) or a surface-coloured one (inverted).
Feedback & Status
Alert
stableAn assertive banner for high-priority, time-sensitive messages — a tone-matched icon, an optional title, a description, and an optional dismiss button. Composes the headless Alert primitive (role="alert") for the message and the registry Button (ghost variant) for the dismiss affordance. Sized xs–xl;
data-densityscales each size further.Empty State
stableThe placeholder shown when a collection, search, or view has no content — a decorative media slot, a headline, supporting copy, and recovery actions, centred in the space it fills. Composes the headless EmptyState primitive (role="status", a polite live region). Sized xs–xl;
data-densityscales each size further.Progress
stableA progress bar — a track with a fill that reports completion, or an animated indeterminate state when the ratio is unknown.
intentpicks the fill colour (primary/secondary/danger), matching the Figma set; the track stays neutral in every intent.
Disclosure
Accordion
stableA vertically stacked set of collapsible sections — hairline rows with a chevron that flips open→closed (WAI-ARIA Accordion pattern).
Breadcrumb
Docs soonA WAI-ARIA breadcrumb trail — a nav landmark wrapping an ordered list of ancestor-page links, ending with the current page.
Breadcrumb Overflow
Docs soonA Breadcrumb trail that collapses its middle entries behind an overflow menu once the trail exceeds keepStart + keepEnd items.
Carousel
Docs soonA responsive, accessible carousel — a scroll-snap viewport of slides with prev/next controls and indicator dots (WAI-ARIA Carousel pattern). Adapts to its container by default.
Collapsible
Docs soonA single disclosure widget pairing a trigger with a panel that expands and collapses — the single-item analogue of Accordion.
Pagination
Docs soonPage navigation for a paged collection — a row of square page cells with prev/next chevrons, or a compact "Page X of Y" readout. Truncated ranges collapse behind an ellipsis that opens a menu of the hidden pages.
Stepper
Docs soonA step rail for a multi-step form — numbered markers joined by connectors, over the headless Tabs. Each marker is a real tab: activation,
aria-selected, the roving tabindex, Home/End anddisabledall come from Tabs, restyled as a circle.orientationpicks the rail direction; sized xs–xl, anddata-densityscales each size further.Tabs
stableAn accessible tabbed interface — a tablist of triggers that switch between panels (WAI-ARIA Tabs pattern).
Navigation
Navigation Menu
Docs soonThe desktop dropdown site nav — a transparent bar of top-level entries, each either a plain link or a trigger that discloses a panel, with one panel open at a time. Panels project into a shared Viewport so the open one morphs into the next, and an Indicator (arrow or underline) tracks the open trigger. Implements the ARIA APG Disclosure Navigation Menu pattern, not a menubar: keyboard, hover-intent and focus are owned by the headless primitive.
Toggle Group
stableA set of independent on/off buttons in a shared track — any number can be pressed, including none. Framed like a Button: a pressed item is action/primary, an unpressed one action/secondary, inside a transparent bordered track whose radius is concentric with the items.
Data Display
Avatar
Docs soonA user image with a graceful fallback for while it loads, or when it is missing or broken.
Avatar Group
Docs soonAn overlapping row of Avatars with an optional "+N" overflow counter — the collaborators/attendees pattern. Composes the registry
avatarcomponent; the counter is itself an Avatar, not a Badge. Sized xs–xl;data-densityscales each size further.Badge
stableA small status/count indicator attached to another element or beside a heading. Read-only, never interactive. Four semantic tones × two treatments (a low-emphasis label chip, a high-emphasis counter chip), sized xs–xl;
data-densityscales each size further.Card
Docs soonA content container — an optional media region plus a padded content block holding a header, description and footer.
layoutpicks the arrangement:vertical(media above),horizontal(media beside), orcover(media behind the content, under a legibility scrim). Sized xs–xl;data-densityscales each size further.Chip
Docs soonAn interactive, removable label chip — filter bars, multi-select fields, inputs. The trailing remove button is core to the anatomy, not optional; an optional leading icon or avatar may precede the label. Sized xs–xl;
data-densityscales each size further.Data Table
Docs soonA framed data-table shell — a toolbar, a table and a footer that read as one object, plus the anatomy sorting, selection and expandable rows need. Owns no state: sorting, selection, expansion, filtering and pagination all arrive as props, so an external table engine (TanStack Table) can drive it.
Table
Docs soonAn accessible data table — a compound of standard HTML table elements (
<table>,<thead>,<tbody>,<tr>,<th>,<td>,<caption>) with a tokenised default theme.Tag
Docs soonA small label chip that tags content by category, topic, or status — typically shown in a group. Read-only, never interactive. Five tones (a plain neutral treatment plus four semantic tones), sized xs–xl;
data-densityscales each size further.