# Siteplane UI Full Context > Canonical contracts from [the public registry](https://ui.siteplane.io/r/registry.json). > Siteplane UI release `0.1.1`. --- # Accordion > Siteplane UI release `0.1.1`. ## Public Purpose Accordion organizes several short, scannable disclosure panels. Use it for FAQs, compact settings, or supporting information that does not need to remain visible. Use Collapsible when there is only one panel. ## Import `import { Accordion, AccordionContent, AccordionItem, AccordionPanel, AccordionTrigger } from "@/components/ui/accordion";` ## Public API - `AccordionItem` owns a value and may be disabled independently. - `defaultValue`, `value`, and `onValueChange` use arrays, including single-open accordions. Add `multiple` only when several panels may remain open. - `AccordionContent` is a compatibility alias for `AccordionPanel`; new code uses `AccordionPanel`. - Keep `AccordionTrigger` and `AccordionPanel` inside the matching `AccordionItem`. ## Public Motion - `AccordionPanel` animates height through `--accordion-panel-height` and the shared expand duration and easing tokens. - Chevron rotation, trigger hover and press states, and reduced-motion behavior are built into the primitive. System and provider reduced-motion modes remove transition interpolation. Do not recreate them in feature code. ## Public Accessibility - `AccordionTrigger` renders a button and keeps Base UI keyboard, focus, and expanded-state semantics. - Set disabled state on `AccordionItem` so its trigger, panel, and state remain synchronized. - Allow multiple open panels only when comparing their content is useful. - Do not hide critical decisions, long forms, or primary workflows in an accordion. ## Public Agent Guidance - Use Accordion for a related group of disclosures and Collapsible for one disclosure. - Preserve the primitive indicator, panel, focus, disabled, and motion classes. - Use the canonical `AccordionPanel` name in new code. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/accordion) - [Registry source](https://ui.siteplane.io/r/accordion.json) --- # Alert > Siteplane UI release `0.1.1`. ## Public Purpose Alert presents important inline information in the content flow. Use semantic variants for information, success, warning, and error feedback that should remain visible while the user continues working. ## Import `import { Alert, AlertAction, AlertDescription, AlertTitle } from "@/components/ui/alert";` ## Public API - `variant` accepts `"default"`, `"info"`, `"success"`, `"warning"`, and `"error"`. - Use `AlertTitle` for the short summary, `AlertDescription` for supporting detail, and `AlertAction` for optional real Button or link controls. - Use Alert Dialog when a decision must block the workflow. ## Public Motion - Alert has no mount or exit animation. - Actions use their own Button or link interaction states; do not animate the Alert container locally. ## Public Accessibility - `Alert` renders with `role="alert"`. - Keep the title and description concise so announcements remain useful. - Do not communicate severity through color alone; the copy must identify the outcome or risk. - Actions require visible focus and an accessible name. ## Public Agent Guidance - Match the variant to the message semantics. - Use Alert Dialog for blocking confirmation and Toast for transient system feedback. - Keep native slots, variants, and accessibility behavior intact. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/alert) - [Registry source](https://ui.siteplane.io/r/alert.json) --- # Alert Dialog > Siteplane UI release `0.1.1`. ## Public Purpose Alert Dialog asks the user to confirm a blocking or destructive decision before the application continues. Use Dialog for ordinary modal forms and Alert for non-blocking inline feedback. ## Import `import { AlertDialog, AlertDialogClose, AlertDialogCreateHandle, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPopup, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog";` ## Public API - Every composition uses `AlertDialogTrigger`, `AlertDialogPopup`, `AlertDialogTitle`, `AlertDialogDescription`, and explicit cancel and confirm actions. - `AlertDialogCreateHandle` supports one shared confirmation dialog with detached triggers or imperative opening. - `AlertDialogPopup bottomStickOnMobile={false}` keeps the popup centered on small screens instead of attaching it to the bottom edge. - `AlertDialogFooter variant="bare"` removes the separated footer surface. ## Public Motion - Backdrop, viewport, popup, and mobile positioning use the native Alert Dialog motion and global reduced-motion contract. - Do not add local durations, transforms, or motion wrappers. ## Public Accessibility - The component renders `role="alertdialog"` with modal focus management, Escape handling, and focus restoration. - Every alert dialog requires a concise `AlertDialogTitle` and `AlertDialogDescription`. - Cancel and confirm actions must be real buttons. Use `AlertDialogClose` or controlled state to close the dialog. - In dirty-state flows, keep the original dialog open until the user confirms that it may be discarded. ## Public Agent Guidance - Reserve Alert Dialog for decisions that block progress or may cause data loss. - Use Dialog for non-destructive modal forms, Alert for persistent inline feedback, and Toast for transient feedback. - Preserve the native popup, footer, focus, and dismissal behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/alert-dialog) - [Registry source](https://ui.siteplane.io/r/alert-dialog.json) --- # Animated Buttons > Siteplane UI release `0.1.1`. ## Public Purpose Animated Buttons provide opt-in action controls whose motion carries the main visual feedback: a fill sweep, a directional surface expansion, or a centered icon-to-label expansion. ## Import `import { ExpandingArrowButton, ExpandingLogoutButton, FillSweepButton } from "@/components/ui/animated-buttons";` ## Public API - `FillSweepButton` accepts the standard Button props and the `default`, `secondary`, `outline`, and `destructive` variants. - `ExpandingArrowButton` accepts native button props, `label`, and `size`. - `ExpandingLogoutButton` accepts native button props, `label`, and the same four visual variants plus `size`. Its outer slot always reserves the expanded width. - The expanding controls support `sm`, `default`, `lg`, and `xl`. Without a local `size`, they inherit `SiteplaneUIProvider`; a local value wins. ## Public Motion - The installed package components are the source of truth; do not maintain local copies of their CSS. - Expanding Logout grows around a fixed center so its surrounding layout and visual anchor do not move. - Provider and system reduced-motion modes remove transition interpolation. ## Public Accessibility - All three controls render semantic buttons with focus-visible, disabled, and pointer behavior. - Hover motion is enhancement only; the label or accessible name identifies the action without relying on animation. ## Public Agent Guidance - Use these exports instead of copying the Showcase markup or CSS. - Keep the reserved Logout slot and scoped style hooks intact. - Do not wrap the controls in a second scale or layout animation. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/animated-controls/animated-buttons) - [Registry source](https://ui.siteplane.io/r/animated-buttons.json) --- # Autocomplete > Siteplane UI release `0.1.1`. ## Public Purpose Autocomplete combines free-text input with filtered suggestions. Use it for search, tagging, and command-like input where the typed value is meaningful. Use Select for a short closed list and Combobox when selection is constrained to listed options. ## Import `import { Autocomplete, AutocompleteEmpty, AutocompleteGroup, AutocompleteGroupLabel, AutocompleteInput, AutocompleteItem, AutocompleteList, AutocompletePopup, AutocompleteRow, AutocompleteStatus, useAutocompleteFilter } from "@/components/ui/autocomplete";` ## Public API - Render `AutocompleteInput`, `AutocompletePopup`, `AutocompleteList`, and `AutocompleteItem` together. - `mode` accepts `"list"`, `"both"`, `"inline"`, or `"none"` and controls how typed text is completed. - `AutocompletePopup` accepts `side`, `align`, `sideOffset`, and `alignOffset`; its defaults are `side="bottom"` and `align="start"`. - `AutocompleteItem disabled` represents an unavailable suggestion. - `AutocompleteList` provides the bounded ScrollArea, scrollbar gutter, and scroll fade used by long result sets. - `AutocompleteRow` supports grid-style result layouts. - `AutocompleteStatus` is the status line for loading and result messages; `AutocompleteEmpty` renders the no-results state. - Filter through root `items` or `useAutocompleteFilter` with `filteredItems`. ## Public Motion - Popup scale and fade, highlighted-item states, and reduced-motion behavior are native to the primitive. - Filtering, highlighting, status, and empty-state changes do not resize the input. - Interactive suggestions and icon actions use a pointer cursor; the text input keeps its text cursor. ## Public Accessibility - Give every `AutocompleteInput` an accessible name through a visible label, `aria-label`, or `aria-labelledby`. - Keep disabled suggestions unavailable to pointer and keyboard selection. - Connect invalid state to the input and render a visible `FieldError`. - The popup remains keyboard navigable and closes on Escape or outside click. ## Public Agent Guidance - Always compose the input, popup, list, and items; do not render a raw input without its suggestion list. - Use `Field` for a visible label, description, and validation. - Preserve native filtering, highlight, cursor, popup, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/autocomplete) - [Registry source](https://ui.siteplane.io/r/autocomplete.json) --- # Avatar > Siteplane UI release `0.1.1`. ## Public Purpose Avatar represents a person, team, or account with an image and a reliable text fallback. ## Import `import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";` ## Public API - `AvatarImage` renders the image and `AvatarFallback` renders initials or another short fallback. - The root defaults to a 32px circular avatar. Change size or radius with existing system classes on `Avatar`; do not create a parallel size API. - Keep `data-slot="avatar"`, `avatar-image`, and `avatar-fallback` intact. ## Public Motion - Avatar has no local animation. Image and fallback switching remains native to Base UI. - Avatar groups are static layout compositions and must not add ad-hoc scale or hover motion. ## Public Accessibility - Give `AvatarImage` meaningful alt text when the image conveys information. Use empty alt text when a nearby label already names the person. - Keep fallback text short and understandable. - Provide text outside a visual avatar group that names or summarizes its members. - Never communicate identity, role, or status through the image alone. ## Public Agent Guidance - Use Avatar only for people, teams, or account identity. - Do not create wrapper primitives or local size and radius APIs. - Preserve the image, fallback, and slot contract. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/avatar) - [Registry source](https://ui.siteplane.io/r/avatar.json) --- # Badge > Siteplane UI release `0.1.1`. ## Public Purpose Badge presents short status, label, or count information that helps people scan an interface. It does not replace explanatory copy. ## Import `import { Badge } from "@/components/ui/badge";` ## Public API - `variant` accepts `"default"`, `"secondary"`, `"outline"`, `"destructive"`, `"error"`, `"info"`, `"success"`, or `"warning"`. - `size` accepts `"sm"`, `"default"`, `"lg"`, or `"xl"`; without a local value, Badge inherits the nearest `SiteplaneUIProvider controlSize`. - Use `render` to make a Badge a semantic link or button without nesting interactive elements. ## Public Motion - A static Badge does not animate. - Interactive badges inherit their link or Button states; do not add local motion values. ## Public Accessibility - Keep Badge text short and explicit. - Do not communicate status through color or a status dot alone. - Interactive badges need correct link or button semantics, visible focus, and an accessible name. - Treat icons and dots as decorative when the text conveys the same meaning. ## Public Agent Guidance - Use existing variants and sizes instead of inventing local badge colors. - Do not use Badge for long explanatory text. - Use `render` when the badge itself is interactive. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/badge) - [Registry source](https://ui.siteplane.io/r/badge.json) --- # Breadcrumb > Siteplane UI release `0.1.1`. ## Public Purpose Breadcrumb shows the current resource within a hierarchy and provides short links back to its parent levels. ## Import `import { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";` ## Public API - `Breadcrumb` renders the named navigation landmark and `BreadcrumbList` contains its ordered items. - Use `BreadcrumbLink` for parent destinations and `BreadcrumbPage` for the current, non-interactive page. - `BreadcrumbSeparator` and `BreadcrumbEllipsis` are decorative. - Compose an ellipsis menu with the canonical `Menu` primitives when hidden levels need to remain reachable. ## Public Motion - Breadcrumb itself has no mount or exit animation. - An ellipsis menu uses Menu motion; Breadcrumb adds no local motion values. ## Public Accessibility - Keep the navigation landmark label and `aria-current="page"` semantics. - Every parent link needs a real destination. - Separators and ellipsis glyphs must not be announced as navigation targets. - An ellipsis menu must remain keyboard and focus accessible through Menu. ## Public Agent Guidance - Use Breadcrumb for hierarchy, not primary navigation, tabs, steps, filters, or process status. - Preserve native landmark, current-page, separator, ellipsis, and slot attributes. - Use existing Breadcrumb parts instead of wrapper primitives. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/breadcrumb) - [Registry source](https://ui.siteplane.io/r/breadcrumb.json) --- # Button > Siteplane UI release `0.1.1`. ## Public Purpose Button is the standard control for visible actions. Use a semantic link when navigation is the primary behavior. ## Import `import { Button } from "@/components/ui/button";` `import { ButtonWithIcon, IconButton, LoadingButton } from "@/components/ui/button-recipes";` ## Public API - `variant` accepts `"default"`, `"secondary"`, `"outline"`, `"ghost"`, `"destructive"`, `"destructive-outline"`, `"link"`, and `"success"`. - `size` accepts text sizes from `"xs"` through `"xl"` and the matching `"icon-*"` sizes. Without a local size, Button inherits `SiteplaneUIProvider controlSize`. - `size="xl"` is the opt-in customer-facing CTA format: 56px high with an 18px/24px label. Combine it with `width="full"` for a container-filling CTA and with a surrounding `SiteplaneUIProvider radius="sm"` for the global 8px main corner; size itself never overrides radius. - `render={}` changes the underlying element while retaining Button styling and omits the invalid button `type` attribute. - `loading` disables the control, sets busy semantics, and displays the native loading indicator. - `scale={false}` disables both hover and press scaling while preserving color, shadow, focus, loading, and disabled states. Use it when a trigger sits inside a larger custom element that must not move. - `align`, `width`, and `multiline` control content layout. - `bleed` makes the Button form a flush container edge. `surface` is for full-row or full-card actions and disables scale automatically. - `IconButton` requires an accessible `label`; `ButtonWithIcon` and `LoadingButton` are shared recipes, not new primitives. ## Public Motion - Default hover and press states use the central Button scale, duration, shadow, and reduced-motion tokens. - `scale={false}` removes hover and press transforms only. - `surface` avoids scale for full-area actions. - Loading recipes keep their idle width and crossfade between label and pending content without a second nested animation. ## Public Accessibility - Use Button for actions and a semantic anchor for navigation through the `render` prop. - Every icon-only Button needs an accessible label. - Loading and disabled Buttons must remain unavailable and expose their state; do not simulate disabled state with styling alone. - Keep visible focus and the coarse-pointer target supplied by the primitive. ## Public Agent Guidance - Never use a raw HTML button for a visible Siteplane control. - Use existing variants, sizes, and recipes instead of copying primitive class strings. - Prefer `scale={false}` for embedded triggers that must remain stationary; do not remove the remaining hover, pressed, or focus feedback. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/actions/button) - [Registry source](https://ui.siteplane.io/r/button.json) --- # Calendar > Siteplane UI release `0.1.1`. ## Public Purpose Calendar wraps React DayPicker for single-date, multiple-date, and date-range selection. Compose it with Popover and Button when a compact date field is needed. ## Import `import type { DateRange, DropdownProps } from "react-day-picker";` `import { Calendar } from "@/components/ui/calendar";` `import { Popover, PopoverPopup, PopoverTrigger } from "@/components/ui/popover";` ## Public API - Use DayPicker `mode="single"`, `"multiple"`, or `"range"` with the corresponding selected-value type. - Outside days are visible by default; set `showOutsideDays={false}` to hide adjacent-month days. - Use DayPicker `disabled` matchers for unavailable dates. - `captionLayout` supports `"label"`, `"dropdown"`, `"dropdown-months"`, and `"dropdown-years"`. Bound dropdown years with `startMonth` and `endMonth`. - `numberOfMonths` renders responsive multi-month calendars. - `month` with `onMonthChange` controls the visible month; use `defaultMonth` for uncontrolled initial state. - Custom `modifiers` and `modifiersClassNames` are merged with the native range-preview modifiers. - `classNames` is merged slot by slot with Siteplane defaults rather than replacing the full DayPicker class map. ## Public Motion - Month navigation and drilldown titles use central Calendar motion tokens. - Range hover preview changes modifiers without changing the committed selection. - Popover date pickers use Popover motion; do not add local durations or transforms. - Reduced motion is handled by the global motion contract. ## Public Accessibility - Preserve React DayPicker grid roles, keyboard navigation, focus management, and day labels. - Give the calendar a visible context or an accessible label. - Explain disabled date rules in nearby text when they are not self-evident. - A Popover date picker needs a clearly named trigger whose visible text reflects the current value or placeholder. ## Public Agent Guidance - Keep Calendar as the source of truth for date selection. - Use DayPicker props through the wrapper; do not rebuild its grid or navigation. - Preserve native classes, range-preview merging, focus behavior, and motion. - Use the canonical `PopoverPopup` name in new code. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/calendar) - [Registry source](https://ui.siteplane.io/r/calendar.json) --- # Card > Siteplane UI release `0.1.1`. ## Public Purpose Card groups related content, actions, forms, or framed data into a clear surface. It is not a general page-layout primitive. ## Import `import { Card, CardAction, CardContent, CardDescription, CardFooter, CardFrame, CardFrameAction, CardFrameDescription, CardFrameHeader, CardFrameTitle, CardHeader, CardPanel, CardTitle } from "@/components/ui/card";` ## Public API - Compose `CardHeader`, `CardTitle`, `CardDescription`, `CardAction`, `CardPanel`, and `CardFooter` as needed. - `CardContent` is a compatibility alias for `CardPanel`; use `CardPanel` in new code. - `CardFrame` and its slots support framed stacks and table-like content. - Adding `className="border-b"` to `CardHeader` or `className="border-t"` to `CardFooter` switches the adjacent CardPanel to full vertical padding for a visually separated section. - The root `render` prop may change the underlying semantic element. ## Public Motion - Card is a static container with no mount or exit animation. - Interactive children use their own primitive motion; do not animate Card locally. - Preserve native radius, clipping, surface, shadow, and slot classes. ## Public Accessibility - Card is visual grouping and does not replace semantic lists, tables, forms, headings, or landmarks. - Keep titles meaningful in their surrounding document structure. - Card actions remain real Button or link controls with visible focus. - If `render` changes the root element, retain semantics appropriate to the content. ## Public Agent Guidance - Use existing Card and CardFrame slots instead of wrapper primitives. - Use `CardPanel` in new code and treat `CardContent` only as a compatibility alias. - Do not use Card as a generic layout box. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/card) - [Registry source](https://ui.siteplane.io/r/card.json) --- # Checkbox > Siteplane UI release `0.1.1`. ## Public Purpose Checkbox represents one Boolean decision or one option in a multi-select group. ## Import `import { Checkbox } from "@/components/ui/checkbox";` `import { CheckboxGroup } from "@/components/ui/checkbox-group";` ## Public API - Use controlled `checked` and `onCheckedChange` or uncontrolled `defaultChecked`. - `indeterminate` represents a mixed parent state; it is not a selected value. - `size` accepts `"sm"`, `"default"`, `"lg"`, and `"xl"` and otherwise inherits `SiteplaneUIProvider controlSize`. - Use Checkbox Group for related multi-select options. ## Public Motion - Checked and indeterminate indicators use native checkbox motion and central exit tokens. - Reduced motion moves the indicator directly to its final state. - Pointer, hover, focus, invalid, and disabled states remain native. ## Public Accessibility - Every Checkbox needs visible label text or an accessible label. - Connect invalid state to the Checkbox and render a visible `FieldError`. - Make row or card compositions clickable without replacing Checkbox semantics. - Use indeterminate state only to summarize partial child selection. ## Public Agent Guidance - Do not use raw checkbox inputs for visible Siteplane controls. - Use Checkbox Group for related options. - Preserve native indicator, focus, cursor, invalid, disabled, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/checkbox) - [Registry source](https://ui.siteplane.io/r/checkbox.json) --- # Checkbox Group > Siteplane UI release `0.1.1`. ## Public Purpose Checkbox Group lets users select any number of options from a related set. Use Radio Group when exactly one option may be selected. ## Import `import { Checkbox } from "@/components/ui/checkbox";` `import { CheckboxGroup } from "@/components/ui/checkbox-group";` ## Public API - Give each child `Checkbox` a stable `value`; group `value`, `defaultValue`, and `onValueChange` use arrays. - `allValues` enables the first-class select-all contract. Combine it with `` to derive checked and indeterminate state and toggle all children without manual synchronization. - Use `size` on the group to size its children, with a local Checkbox size taking precedence. ## Public Motion - Check, indeterminate, border, focus, and reduced-motion behavior comes from Checkbox. - Selection must not change row or card dimensions. ## Public Accessibility - Name every group through visible context, `aria-label`, or `aria-labelledby`. - Pair every Checkbox with visible clickable label text or an accessible label. - Put invalid state on the group and render a visible `FieldError`. - The parent Checkbox must communicate mixed state when only some children are selected. ## Public Agent Guidance - Always group related multi-select options in Checkbox Group. - Use `allValues` and `Checkbox parent` for select-all behavior instead of rebuilding synchronization with local state. - Use `Field` for group labels, descriptions, and validation. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/checkbox-group) - [Registry source](https://ui.siteplane.io/r/checkbox-group.json) --- # Code / CodeBlock > Siteplane UI release `0.1.1`. ## Public Purpose Code formats short inline tokens. CodeBlock presents multiline or copyable snippets. ## Import ```tsx import { Code, CodeBlock } from "@/components/ui/code"; ``` ## Public API - Use `Code` inside prose and `CodeBlock` for complete snippets. - Use `mask` only with the built-in reveal and copy actions. - Keep copy and reveal actions in the reserved top-right action area. - Leave enough right-side padding for actions in long snippets. ## Public Motion - Code itself does not animate. - Copy and reveal feedback uses the native action behavior and global reduced-motion contract. ## Public Accessibility - Masked content requires a clearly named reveal control and a clearly named copy control. - Do not rely on syntax color alone to explain a snippet. - Never place real secrets in documentation, screenshots, or examples. ## Public Agent Guidance - Use Code for short inline tokens and CodeBlock for multiline snippets. - Do not build custom copy overlays around CodeBlock. - Keep all examples safe to publish. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/code) - [Registry source](https://ui.siteplane.io/r/code.json) --- # Collapsible > Siteplane UI release `0.1.1`. ## Public Purpose Collapsible controls one expandable section such as a disclosure, show-more block, or sidebar group. Use Accordion for a related collection of panels. ## Import `import { Collapsible, CollapsiblePanel, CollapsibleTrigger } from "@/components/ui/collapsible";` ## Public API - Use `defaultOpen` for uncontrolled initial state. - Use `open` with `onOpenChange` when another control or application state owns the disclosure state. - Set `disabled` on `Collapsible` to disable the trigger and state together. - `CollapsiblePanel hiddenUntilFound` keeps collapsed content available to browser find-in-page and lets the browser reveal a matching panel. - Keep trigger and panel inside the same root. ## Public Motion - Panel height uses `--collapsible-panel-height` with native starting and ending styles. - Keep the preview or product composition top-anchored so opening expands downward instead of recentering the entire control. - Chevron rotation and pointer states are additive composition behavior; do not nest a second height or opacity animation around the panel. - System and provider reduced-motion modes remove panel and chevron transition interpolation through the primitive and global contract. ## Public Accessibility - Give every trigger visible text or an accessible label. - Keep trigger and panel connected through the Base UI context. - Disabled state remains recognizable and cannot activate the panel. - Use `hiddenUntilFound` when collapsed documentation must remain searchable. ## Public Agent Guidance - Do not create toggle divs in place of `CollapsibleTrigger` and `CollapsiblePanel`. - Keep one state owner; do not mix controlled and uncontrolled props. - Avoid nested layout animations around the native panel transition. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/collapsible) - [Registry source](https://ui.siteplane.io/r/collapsible.json) --- # Color Picker > Siteplane UI release `0.1.1`. ## Public Purpose Color Picker lets users choose and submit short hexadecimal color values through a visual control. ## Import `import { ColorPicker } from "@/components/ui/color-picker";` ## Public API - The submitted form value is a normalized hexadecimal string. - `name`, `form`, `required`, and `disabled` are mirrored through the built-in hidden form field. - `size` accepts `"sm"`, `"default"`, `"lg"`, and `"xl"` and otherwise inherits `SiteplaneUIProvider controlSize`. - Use the swatch-only form only when visible label or surrounding context names the control. ## Public Motion - The picker popup follows the native Popover motion contract. - Hue and swatch controls keep native pointer and focus behavior. - Copy feedback uses the shared icon feedback sequence and respects reduced motion. ## Public Accessibility - Give the trigger and every text field an accessible name. - Keep visible focus throughout the trigger, popup, and text fields. - Preserve hidden-field semantics for `name`, `form`, `required`, and `disabled`. - Do not use a native browser color input as a parallel visible control. ## Public Agent Guidance - Keep hexadecimal value as the public form contract. - Use Color Picker rather than a raw visible color input. - Preserve normalization, form participation, popup, and focus behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/color-picker) - [Registry source](https://ui.siteplane.io/r/color-picker.json) --- # Combobox > Siteplane UI release `0.1.1`. ## Public Purpose Combobox provides searchable selection constrained to listed options. Use it for single select or chip-based multi-select. Use Select for a short unsearchable list and Autocomplete when free text is a valid value. ## Import `import { Combobox, ComboboxChip, ComboboxChipRemove, ComboboxChips, ComboboxChipsInput, ComboboxEmpty, ComboboxGroup, ComboboxGroupLabel, ComboboxInput, ComboboxItem, ComboboxList, ComboboxPopup, ComboboxRow, ComboboxStatus, ComboboxTrigger, ComboboxValue, useComboboxFilter } from "@/components/ui/combobox";` ## Public API - Filter through root `items` or `useComboboxFilter`; do not render a searchable list without filtering it. - `ComboboxTrigger` supports a button-triggered composition where the selected value stays in the trigger and search lives in the popup. - Set `ComboboxInput showTrigger={false}` for a plain search field without the trailing dropdown affordance. - `ComboboxPopup` accepts `side`, `align`, `sideOffset`, and `alignOffset`; defaults are bottom and start alignment. - `ComboboxItem disabled` marks an unavailable option. - `ComboboxList` provides the bounded ScrollArea and fades for long lists; `ComboboxRow` supports grid layouts. - `ComboboxStatus` renders loading or result status. - `ComboboxChips startAddon` adds leading context. Set `size` on `ComboboxChipsInput` to scale the complete chips field. ## Public Motion - Popup, filter, highlight, chips, and reduced-motion behavior remain native. - Active options and icon actions use a pointer cursor; input text keeps a text cursor. - Results and status changes must not change the input dimensions. ## Public Accessibility - Give the input or chips field a visible label, `aria-label`, or `aria-labelledby`. - Each chip needs an accessible name; its remove control already supplies the removal action semantics. - Keep disabled options unavailable to pointer and keyboard selection. - Connect invalid state to the input and render a visible `FieldError`. ## Public Agent Guidance - Use Combobox for searchable constrained selection, not free-text search. - Keep one filtering source and render input or trigger, popup, list, and items as one composition. - Preserve native cursor, focus, disabled, popup, scroll, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/combobox) - [Registry source](https://ui.siteplane.io/r/combobox.json) --- # Command > Siteplane UI release `0.1.1`. ## Public Purpose Command combines a dialog and autocomplete list for keyboard-driven navigation, search, and actions. It may also render as a standalone embedded command list. ## Import `import { Command, CommandCollection, CommandCreateHandle, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut } from "@/components/ui/command";` ## Public API - `CommandDialog` provides modal focus management; use the standalone `Command` composition only when the list belongs in the page. - `CommandCreateHandle` opens or closes the dialog from detached triggers or imperative application flows. - `autoHighlight` accepts `false`, `true`, or `"always"` and defaults to `"always"`, so the first result is ready for Enter. - Use `CommandGroup`, `CommandSeparator`, and `CommandShortcut` to make results scannable. - `CommandEmpty` reports no matches; `CommandFooter` may explain keyboard controls. ## Public Motion - Modal Command uses native Dialog backdrop and popup motion. - Filtering and highlighting come from Autocomplete; do not wrap either layer in a second transition. - Active items use a pointer cursor while CommandInput keeps a text cursor. ## Public Accessibility - CommandInput receives focus and must have a visible or accessible name. - Keep keyboard navigation, Enter selection, Escape dismissal, outside click, focus trapping, and focus restoration native. - Every CommandItem needs a clear label. Shortcuts are supporting context, not the only action name. - Dialog triggers need visible text or an accessible label. ## Public Agent Guidance - Use Command for search-driven navigation and actions, not as a generic menu or select. - Choose modal or standalone composition deliberately. - Preserve native Dialog and Autocomplete focus, filtering, cursor, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/command) - [Registry source](https://ui.siteplane.io/r/command.json) --- # Context Menu > Siteplane UI release `0.1.1`. ## Public Purpose Context Menu presents secondary actions at the pointer after a right click or long press. Keep primary actions visible outside the menu. ## Import `import { ContextMenu, ContextMenuCheckboxItem, ContextMenuGroup, ContextMenuGroupLabel, ContextMenuItem, ContextMenuLinkItem, ContextMenuPopup, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubPopup, ContextMenuSubTrigger, ContextMenuTrigger } from "@/components/ui/context-menu";` ## Public API - `ContextMenuPopup width` accepts `"auto"`, `"trigger"`, `"content"`, or `"at-least-trigger"`; use the prop instead of hardcoded width classes. - Popup placement is controlled by `side`, `align`, `sideOffset`, and `alignOffset`. Defaults are bottom, start, and zero side offset. - Use `inset` on items, group labels, and submenu triggers to align rows without leading icons. - `ContextMenuCheckboxItem size` accepts `"sm"`, `"default"`, `"lg"`, and `"xl"`. - All item, selection, label, separator, and submenu rows inherit the provider `controlSize`; repeated rows use the compact menu geometry from the global size contract rather than the 56px XL CTA height. - `ContextMenuLinkItem closeOnClick` defaults to `true`; set it to `false` only when navigation must leave the menu open. - Use `disabled` for unavailable actions. - Use `ContextMenuLinkItem` for navigation instead of adding link behavior to a command item. ## Public Motion - Popup and submenu scale, fade, placement, and reduced-motion behavior are native to Context Menu. - Active items and submenu triggers use a pointer cursor. - Do not add a second popup transition. ## Public Accessibility - The trigger target needs visible context that explains what will receive the actions. - Preserve right-click, long-press, keyboard, focus, Escape, and dismissal behavior. - Keep disabled items unavailable and visibly distinct. - Checkbox and radio items must retain their selection indicators. ## Public Agent Guidance - Use Context Menu only for pointer-related secondary actions. - Keep primary actions visible and discoverable elsewhere. - Use width, placement, inset, size, disabled, and link props instead of local menu styling. - Preserve native item, submenu, selection, cursor, and focus behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/context-menu) - [Registry source](https://ui.siteplane.io/r/context-menu.json) --- # Dashboard Shell > Siteplane UI release `0.1.1`. ## Public Purpose Dashboard Shell is a `registry:block` for product surfaces that combine the native Siteplane Sidebar with an app header and a dedicated content scroll region. Use it when sidebar and app-header geometry must stay aligned. The shell owns layout only; navigation, team switchers, account controls and footer content remain consumer compositions built from installed primitives. ## Import ```tsx import { DashboardShell, DashboardShellHeader, DashboardShellInset, DashboardShellMain, DashboardShellSidebar, DashboardShellSidebarHeader, DashboardShellSidebarTrigger, } from "@/components/patterns/dashboard-shell"; ``` ## Public API - `DashboardShell` renders the native `SidebarProvider` and defaults `--dashboard-shell-header-height` to `4rem`. - `DashboardShellSidebar` renders the native Sidebar and defaults to `collapsible="icon"`. - `DashboardShellSidebarHeader` and `DashboardShellHeader` share the same minimum-height variable so their top edge and height remain aligned. - The visible header divider belongs to `DashboardShellHeader`. Do not add a second divider directly below the sidebar header. - `DashboardShellHeader` accepts `divider={false}` when the app header should not separate from the main region. - `DashboardShellInset` uses the native `SidebarInset` and contains horizontal overflow. `DashboardShellMain` owns content scrolling. - Render `SidebarMenuButton` labels in child elements such as `` and provide a `tooltip` in icon-collapse mode. ## Public Motion - Sidebar collapse, mobile behavior and nested navigation motion remain native to the Sidebar primitive. - The shell adds no route or content entrance animation. Reduced-motion behavior comes from the primitives it composes. ## Public Accessibility - Use the native Sidebar trigger so its keyboard shortcut, focus behavior and screen-reader label remain intact. - Keep the header and main content as separate regions. The header stays fixed while the main region owns content scrolling. - Preserve a readable label and native tooltip contract for every icon-only item in collapsed navigation. ## Public Agent Guidance - Start with Dashboard Shell for product layouts that require both Sidebar and an aligned app header. - Do not rebuild Sidebar internals or create separate hardcoded header heights in the consumer. - Reusable shell changes belong in this pattern source; product-specific navigation and account content stay outside the pattern. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/dashboard-shell) - [Registry source](https://ui.siteplane.io/r/dashboard-shell.json) --- # Data Table > Siteplane UI release `0.1.1`. ## Public Purpose DataTable adds typed columns, sorting, active-row behavior, and empty states to the Siteplane UI Table primitive. Use Table directly for static markup. ## Import `import { DataTable } from "@/components/ui/data-table";` `import type { DataTableColumn } from "@/components/ui/data-table";` ## Public API - Accessor columns are sortable by default. Set `sortable: false` when sorting has no product meaning. - Use `sort` with `onSortChange` for controlled sorting or `initialSort` for uncontrolled initial state. - `column.align` accepts `"left"`, `"center"`, or `"right"`. - Without a custom `cell`, Date values use `toLocaleDateString()`, nullish values render empty, and other values use `String(value)`. - When `emptyState` is omitted, DataTable renders its built-in “No results” state. - `onRowClick`, `getRowId`, `activeRowId`, and `getRowAriaLabel` create an accessible active-row flow. - Row clicks ignore links, buttons, inputs, selects, textareas, `[role=button]`, `[role=link]`, and elements marked `data-row-click-ignore="true"`. - `sortClickArea="cell"` makes the complete sortable header cell interactive; the default is `"content"`. ## Public Motion - DataTable adds no mount, exit, or sorting animation. - Sort-header Buttons disable scale so header text remains stationary. - Row hover and active styling come from Table. ## Public Accessibility - Sortable headers expose `aria-sort`; their icons are decorative. - Clickable rows require a stable accessible label and support Enter and Space. - Interactive cell controls remain independent of the row action and must keep visible focus. - Active row state is contextual selection, not a substitute for checkbox-based bulk selection. - Empty states need a short explanation and, when possible, a useful next action. ## Public Agent Guidance - Keep Table as the native rendering layer and DataTable as the small typed behavior layer; do not add a TanStack dependency. - Define behavior in `DataTableColumn` rather than duplicating sorting in feature components. - Use row clicks only for opening or activating row context. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/data-table) - [Registry source](https://ui.siteplane.io/r/data-table.json) --- # Date Picker > Siteplane UI release `0.1.1`. ## Public Purpose Date Picker is a composition of Button, Popover, and Calendar for selecting a single date in an application flow. Use Calendar alone when the calendar should remain visible. ## Import `import { Calendar } from "@/components/ui/calendar";` `import { Popover, PopoverPopup, PopoverTrigger } from "@/components/ui/popover";` `import { Button } from "@/components/ui/button";` ## Public API - Date Picker is a documented composition, not a separate primitive. - Keep selected date and Popover open state in one clear controlled or uncontrolled owner. - Pass date rules such as disabled dates to Calendar. - Use `Field` for a visible label, description, invalid state, and error text. - Format the trigger label with the product locale while keeping the Date value as state. ## Public Motion - Opening and closing uses native Popover motion; month navigation uses native Calendar motion. - Do not wrap the composition in another height, opacity, or scale animation. - Selected, disabled, and invalid states must not change the trigger dimensions. ## Public Accessibility - Give the trigger visible label context, `aria-label`, or `aria-labelledby`. - Reflect invalid state on the trigger and render a visible `FieldError`. - Keep keyboard navigation, Escape dismissal, outside click, and focus restoration native. - The trigger text must communicate the selected date or a clear placeholder. ## Public Agent Guidance - Compose canonical `PopoverPopup`, Calendar, and Button; do not create a second Date Picker primitive. - Preserve native Calendar and Popover focus, dismissal, and motion. - Use Field for form integration. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/date-picker) - [Registry source](https://ui.siteplane.io/r/date-picker.json) --- # Destructive Confirmation > Siteplane UI release `0.1.1`. ## Public Purpose Destructive Confirmation is a `registry:component` for an irreversible account action with explicit cancellation, confirmation and a visible result status. ## Import ```tsx import { DestructiveConfirmation } from "@/components/patterns/destructive-confirmation"; ``` ## Public API - Render `DestructiveConfirmation` for the included delete-account example. - Replace the account copy and confirmation handler after installation while keeping separate Cancel and destructive confirmation actions. - Use AlertDialog for the decision boundary; use Dialog or an inline Alert when the user is not confirming an irreversible action. ## Public Motion - The recipe adds no motion and retains the native AlertDialog transition. - Reduced motion behavior is inherited from AlertDialog and the global motion provider. ## Public Accessibility - AlertDialog traps focus, names the decision and restores focus to the trigger when it closes. - Keep the consequence in the description and keep Cancel available before the destructive action. ## Public Agent Guidance - Install with `pnpm dlx shadcn@4.16.1 add @siteplane/destructive-confirmation`. - Adapt only the resource name, consequence text and confirmed action. - Use this ready-made recipe only when the request explicitly asks for the complete pattern and its built-in result state. Compose product-specific deletion actions such as deleting a workspace directly from Alert Dialog and Button. - Do not use a destructive confirmation for a reversible or informational event. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/destructive-confirmation) - [Registry source](https://ui.siteplane.io/r/destructive-confirmation.json) --- # Detail Drawer > Siteplane UI release `0.1.1`. ## Public Purpose Detail Drawer is a `registry:block` for inspecting contextual details about a row or entity in a right-side panel. It uses the native Drawer primitive; use Sheet for edit forms with a save-or-cancel contract. ## Import ```tsx import { DetailDrawer, DetailDrawerBody, DetailDrawerClose, DetailDrawerContent, DetailDrawerDescription, DetailDrawerFooter, DetailDrawerHeader, DetailDrawerTitle, DetailDrawerTrigger, } from "@/components/patterns/detail-drawer"; ``` ## Public API - Use Detail Drawer for inspection, history, related tasks and entity context, not irreversible decisions. - Keep title and description in the header, scannable details in the body, and secondary close or follow-up actions in the footer. - Triggers remain visible buttons or clearly focusable row actions. - Provide a close path through `showCloseButton`, `DetailDrawerClose` or both. - Use Sheet when the primary task is editing and saving a form. ## Public Motion - Drawer swipe, edge position and dismissal motion remain native to the Drawer primitive. - Do not copy Sheet motion onto Detail Drawer. Global reduced motion remains active through the underlying primitive. ## Public Accessibility - Keep the trigger visible in the row or entity context that opens the drawer. - Provide a descriptive title and, when useful, a description that identifies the inspected entity. - Provide an explicit close path through `showCloseButton`, `DetailDrawerClose` or both, and preserve the native Drawer focus and dismissal behavior. ## Public Agent Guidance - Compose Detail Drawer from its named slots and keep product details in consumer content. - Use Alert Dialog for irreversible confirmation and Sheet for create or edit workflows. - Do not replace the Drawer portal, focus, swipe or dismissal behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/detail-drawer) - [Registry source](https://ui.siteplane.io/r/detail-drawer.json) --- # Dialog > Siteplane UI release `0.1.1`. ## Public Purpose Dialog focuses attention on a decision, short form, or other modal task. Use Alert Dialog for destructive confirmation. ## Import `import { Dialog, DialogClose, DialogCreateHandle, DialogDescription, DialogFooter, DialogHeader, DialogPanel, DialogPopup, DialogTitle, DialogTrigger } from "@/components/ui/dialog";` ## Public API - Compose Trigger, Popup, Title, Description, optional Panel and Footer, and explicit actions. - `DialogCreateHandle` supports one dialog with detached triggers or imperative opening. - `DialogPopup closeProps` customizes the built-in close Button while preserving it. Use `showCloseButton={false}` only when another clear close action exists. - `DialogContent` is a compatibility alias for `DialogPopup`; use `DialogPopup` in new code. ## Public Motion - Backdrop uses the overlay duration and opacity transition. - Popup uses native dialog motion and the modal duration. - Do not add a second Dialog animation around the popup. - Global reduced-motion behavior removes unnecessary transforms. ## Public Accessibility - Every Dialog requires a concise `DialogTitle` and should include a `DialogDescription` when the task needs explanation. - Preserve modal focus trapping, initial focus, Escape, outside-click behavior, and focus restoration. - All close and submit controls must be real Button components with accessible names. - If the built-in close Button is hidden, provide an equally discoverable close action. ## Public Agent Guidance - Use Dialog for focused modal tasks and Alert Dialog for destructive confirmation. - Use canonical `DialogPopup` in new code. - Preserve native focus, dismissal, close Button, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/dialog) - [Registry source](https://ui.siteplane.io/r/dialog.json) --- # Drawer > Siteplane UI release `0.1.1`. ## Public Purpose Drawer provides swipeable edge panels for mobile menus, contextual details, and gesture-driven flows. Use Sheet for dialog-style form and save/cancel flows. ## Import `import { Drawer, DrawerCreateHandle, DrawerPanel, DrawerPopup, DrawerSwipeArea, DrawerTrigger } from "@/components/ui/drawer";` ## Public API - `position` places the Drawer at an edge. `swipeDirection` normally follows that position but may override the gesture direction. - `DrawerSwipeArea position` creates a fixed edge target that can open the Drawer with a swipe. - `DrawerCreateHandle` supports detached triggers and imperative opening. - `DrawerPanel scrollable={false}` removes the ScrollArea wrapper; `scrollFade={false}` keeps scroll edges hard instead of faded. - `allowSelection` on Header, Footer, and Panel chooses selectable content behavior instead of a drag surface. - Drawer menu items, checkbox items, and radio items accept `disabled`. - `variant="straight"` and inset variants define the native surface shape; do not recreate them with local classes. ## Public Motion - Popup, backdrop, stacking, snap points, and swipe progress are native Drawer behavior. - Do not copy Sheet motion onto Drawer or wrap the popup in another transform. - Interactive triggers and menu items use a pointer cursor. Drag and selectable content surfaces keep their appropriate default or text cursor. ## Public Accessibility - Give every Drawer a `DrawerTitle` and `DrawerDescription`, visually hidden when the visible design already supplies equivalent context. - Preserve Escape, focus restoration, and modal behavior where configured. - Disabled menu items must be unavailable and visibly distinct. - Keep text selection enabled for content users may need to copy. ## Public Agent Guidance - Use Drawer for edge and gesture flows; use Sheet for form-oriented flyouts. - Choose position, swipe area, scroll, selection, and disabled props through the public API instead of local overrides. - Preserve native gesture, stack, focus, cursor, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/drawer) - [Registry source](https://ui.siteplane.io/r/drawer.json) --- # Dropdown Menu > Siteplane UI release `0.1.1`. ## Public Purpose Dropdown Menu is the shadcn-compatible alias surface for Siteplane Menu. Use the canonical Menu names in new code; use Dropdown Menu names only while migrating existing shadcn-style code. ## Import `import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";` ## Public API - `DropdownMenuContent width` accepts `"auto"`, `"trigger"`, `"content"`, and `"at-least-trigger"`. Trigger width matches the anchor; content width is bounded by the viewport. - Placement props `side`, `align`, `sideOffset`, and `alignOffset` live on Content. Defaults are bottom, center, and a 4px side offset. - `anchor` positions the popup against a different element or virtual anchor. - Use `inset` on items, labels, and submenu triggers to align rows without leading icons. - Checkbox item `size` accepts `"sm"`, `"default"`, `"lg"`, and `"xl"`. - Items support icons with native size and opacity treatment and accept `disabled` for unavailable actions. - The alias maps to the same item, selection, and submenu contracts as Menu. ## Public Motion - Popup and submenu placement, scale, fade, and reduced-motion behavior come from Menu. - Do not add alias-specific motion. - Active items and submenu triggers use a pointer cursor. ## Public Accessibility - Give the trigger visible text or an accessible label. - Keep keyboard navigation, focus, Escape, outside click, and focus restoration native. - Disabled items remain unavailable and visibly distinct. - Checkbox and radio items retain their selection indicators. ## Public Agent Guidance - Prefer canonical `Menu*` names in new code. - Do not mix Menu and Dropdown Menu naming in one file. - Use public width, placement, anchor, inset, size, disabled, and icon behavior instead of local classes. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/dropdown-menu) - [Registry source](https://ui.siteplane.io/r/dropdown-menu.json) --- # Empty > Siteplane UI release `0.1.1`. ## Public Purpose Empty explains a genuine no-content state and can offer a clear next action. Use Skeleton for loading and Alert for an error that still has surrounding content. ## Import `import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";` ## Public API - Compose `EmptyHeader`, optional `EmptyMedia`, `EmptyTitle`, `EmptyDescription`, and optional `EmptyContent`. - A direct anchor inside `EmptyDescription` receives the native inline-link underline and hover treatment. - Put a primary recovery or creation action in `EmptyContent`; omit it when there is no meaningful next step. ## Public Motion - Empty has no mount or exit animation. - Actions use their own Button or link motion; do not animate the entire state. ## Public Accessibility - State plainly why no content is available. - Give the optional action an explicit label that describes its result. - Use meaningful media only as supporting context; never rely on the illustration or color alone. - Keep inline links semantic and keyboard focusable. ## Public Agent Guidance - Use Empty only for a real zero-data state, not loading, error, or permission denial by default. - Keep copy concise and action-oriented. - Compose existing slots instead of creating a parallel empty-state primitive. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/empty) - [Registry source](https://ui.siteplane.io/r/empty.json) --- # Field > Siteplane UI release `0.1.1`. ## Public Purpose Field connects one form control with its label, description, validation state, and error message. ## Import `import { Field, FieldControl, FieldDescription, FieldError, FieldItem, FieldLabel, FieldValidity } from "@/components/ui/field";` ## Public API - `Field invalid` controls the complete external error state for form libraries and keeps label, control, and error presentation synchronized. - `FieldLabel nativeLabel={false}` renders non-native label semantics for button-like controls such as Select triggers, where a native label is not appropriate. - `FieldItem disabled` disables and dims one item inside a larger active group. - `FieldControl` supports controlled `onValueChange(value, eventDetails)` in addition to uncontrolled `defaultValue`. - Use `FieldValidity` when rendering validation details from Base UI state. ## Public Motion - Field adds no local motion. - The contained control owns focus, pressed, popup, and validation transitions. - Error copy may appear without shifting the control itself. ## Public Accessibility - Every visible control needs a connected `FieldLabel` or an accessible label. - Connect descriptions and errors through the Field context rather than manual duplicate IDs. - Keep invalid state on the Field and control as required by the selected primitive. - Use `nativeLabel={false}` only for non-labelable button-like controls; do not remove a control’s accessible name. ## Public Agent Guidance - Use Field as the standard wrapper for one control, label, description, and error. - Do not render raw inputs without Field or another correctly connected label. - Prefer Field props and Base UI context to manual validation wiring. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/field) - [Registry source](https://ui.siteplane.io/r/field.json) --- # Fieldset > Siteplane UI release `0.1.1`. ## Public Purpose Fieldset groups related form fields under one shared semantic legend. A standalone field does not need a Fieldset. ## Import `import { Fieldset, FieldsetLegend } from "@/components/ui/fieldset";` ## Public API - `Fieldset` renders a native fieldset and `FieldsetLegend` provides its group name. - Put `FieldsetLegend` first, then compose each control with `Field`. - `disabled` disables all descendant form controls. - The default layout is a grid with system spacing; use existing spacing classes only when the composition needs a different density. ## Public Motion - Fieldset has no animation. - Descendant controls retain their own focus, disabled, and reduced-motion behavior. - Disabled and nested Fieldsets must not change control dimensions. ## Public Accessibility - Every Fieldset requires a `FieldsetLegend` that names the group. - Connect optional group descriptions with `aria-describedby`. - Keep each descendant control connected to its own FieldLabel and FieldError. - Do not use Fieldset only for visual layout when the fields are not semantically related. ## Public Agent Guidance - Group related controls with exactly one legend. - Do not place fields in a Fieldset without `FieldsetLegend`. - Preserve native fieldset and disabled semantics. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/fieldset) - [Registry source](https://ui.siteplane.io/r/fieldset.json) --- # Filter Bar > Siteplane UI release `0.1.1`. ## Public Purpose Filter Bar is a `registry:block` for list and table screens. It organizes search, filter controls, active-filter badges and clear actions without owning product state or query serialization. ## Import ```tsx import { FilterBar, FilterBarActions, FilterBarActiveFilters, FilterBarControls, FilterBarFilters, FilterBarSearch, } from "@/components/patterns/filter-bar"; ``` ## Public API - `FilterBar` provides layout slots only; the consuming screen owns search state, filters and URL synchronization. - Use Input for search, Menu or an appropriate selection primitive for filters, Badge for active filters and Button for actions. - Show clear actions only when search or filters are active, and keep active filter badges in their own row. - Search controls need visible or screen-reader labels. Active filters must describe their state in text rather than color alone. - Use `density="compact"` for a denser bar. Without a local value, density inherits from `SiteplaneUIProvider`. ## Public Motion - The bar itself does not animate. Menus, Selects and other floating controls retain their native floating-panel motion. - Reduced motion is inherited from those primitives and the global motion provider. ## Public Accessibility - Give every search and filter control a label; a placeholder is supporting copy, not an accessible name. - Describe active filters with readable text rather than color alone. - Keep clear actions keyboard reachable and name whether they clear one filter or the complete filter state. ## Public Agent Guidance - Keep product filtering logic outside the pattern. - Use native Siteplane controls in every slot instead of raw form or menu elements. - Prefer the density prop over local spacing overrides. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/filter-bar) - [Registry source](https://ui.siteplane.io/r/filter-bar.json) --- # Form > Siteplane UI release `0.1.1`. ## Public Purpose Form coordinates related fields, submission, validation, and server errors in one accessible workflow. ## Import `import { Form } from "@/components/ui/form";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` ## Public API - Give every Field a stable `name`. - `errors` accepts `Record`; each key matches a Field name and renders through its FieldError. - Use the native `onSubmit` flow and real submit and reset Button controls. - Group related sections with Fieldset and FieldsetLegend. ## Public Motion - Form has no animation of its own. - Controls and Buttons retain their native focus, loading, validation, and reduced-motion behavior. - Reserve stable space or use concise feedback so validation does not move the entire workflow unexpectedly. ## Public Accessibility - Every control requires a connected FieldLabel or accessible name. - Keep Field name, invalid state, Form errors, and FieldError synchronized. - Submit and reset Buttons need explicit visible action labels. - Move focus or provide an error summary when submission fails across several fields. ## Public Agent Guidance - Use Form for workflows with several related fields and shared submission or errors. - Do not use raw form controls without Field connections in visible app flows. - Keep server and client errors in the same Field error contract. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/form) - [Registry source](https://ui.siteplane.io/r/form.json) --- # Frame > Siteplane UI release `0.1.1`. ## Public Purpose Frame structures app surfaces such as settings panels, statistics, lists, and empty states. It provides a muted outer shell and one or more surfaced panels. ## Import ```tsx import { Frame, FrameDescription, FrameFooter, FrameHeader, FramePanel, FrameTitle, } from "@/components/ui/frame"; ``` ## Public API - `Frame` is the outer shell and `FramePanel` is the bordered surface. - Multiple direct FramePanel children stack with the native panel gap. - Use Header, Title, Description, and Footer as the intended content slots. - Compose semantic content inside the panel; Frame does not replace forms, lists, headings, or landmarks. ## Public Motion - Frame has no animation. - Child controls and overlays retain their native motion. - Preserve native radius, border, background, and inset-shadow treatment. ## Public Accessibility - Use headings and landmarks appropriate to the content inside Frame. - Keep actions as real Button or link controls with visible focus. - Do not rely on the surface boundary alone to explain relationships. - Empty-state content inside Frame follows the Empty component contract. ## Public Agent Guidance - Use FramePanel for the actual surfaced content. - Do not create parallel shell or panel primitives. - Keep native slots and surface styling intact. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/layout/frame) - [Registry source](https://ui.siteplane.io/r/frame.json) --- # Group > Siteplane UI release `0.1.1`. ## Public Purpose Group joins related controls into one visual cluster with shared borders and connected radii. Use ordinary flex or grid for unrelated actions or layout. ## Import `import { Group, GroupSeparator, GroupText } from "@/components/ui/group";` ## Public API - `orientation` accepts `"horizontal"` or `"vertical"`. - Match `GroupSeparator orientation` to the divider itself. A vertical Group needs `orientation="horizontal"` separators between rows. - `GroupText` is a non-interactive prefix, suffix, or status segment. - Nested direct-child Groups remain separate clusters with the native gap, allowing a toolbar to contain several connected control sets. ## Public Motion - Group does not animate. Children retain their native interaction and reduced-motion behavior. - Connected borders, radii, focus rings, and invalid state come from Group. - Do not add transforms to the entire cluster. ## Public Accessibility - Name every meaningful control group through `aria-label` or `aria-labelledby`. - Every icon-only Button needs its own accessible label. - Toggle-like controls retain `aria-pressed` or their native selection semantics. - `GroupText` is supporting text, never a control. ## Public Agent Guidance - Group only visually connects controls that belong to one task. - Use matching separator orientation and nested Groups for multiple clusters. - Do not use Group as a replacement for Toolbar semantics or general layout. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/layout/group) - [Registry source](https://ui.siteplane.io/r/group.json) --- # Icon Morphs > Siteplane UI release `0.1.1`. ## Public Purpose Icon Morphs provides the reusable hamburger-to-close control for navigation menus and similar disclosures. ## Import `import { MenuIconMorph } from "@/components/ui/icon-morphs";` ## Public API - Omit `open` for uncontrolled use and optionally set `defaultOpen`. - Pass `open` with `onOpenChange` when the menu or panel owns the state. - `size="sm" | "default" | "lg" | "xl"` overrides the inherited `SiteplaneUIProvider` size locally. - Native button props, `aria-controls`, disabled state, and click handlers are forwarded. ## Public Motion - Three bars use the staged Showcase transform to resolve into one close icon. - The control intentionally has no hover, pressed, or open background surface. - Provider and system reduced-motion modes remove the staged interpolation. ## Public Accessibility - `aria-expanded` follows the real component state. - The default accessible label changes between opening and closing the menu; provide a custom label when product copy requires it. - Preserve the visible focus outline even though the background stays clear. ## Public Agent Guidance - Connect the morph to the same state as the panel; do not animate a decorative duplicate that can drift out of sync. - Do not replace this control with a ghost Button, because its hover surface is intentionally absent here. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/animated-controls/icon-morphs) - [Registry source](https://ui.siteplane.io/r/icon-morphs.json) --- # Input > Siteplane UI release `0.1.1`. ## Public Purpose Input is the standard control for short free-text values, search fields, and compact form data. ## Import `import { Input } from "@/components/ui/input";` ## Public API - Use native input props for value, type, autocomplete, required, disabled, and form participation. - `variant="soft"` provides the borderless search and filter surface. - Visual `size` accepts Siteplane control sizes and otherwise inherits `SiteplaneUIProvider controlSize`; the numeric native HTML `size` attribute remains a width hint. - `size="xl"` uses the customer-facing single-line field format: 56px outer height, 16px/24px input text and 16px horizontal inset including the border. Pair it with a surrounding `SiteplaneUIProvider radius="sm"` for the global 8px main corner; size itself never overrides radius. - Use Input Group for tightly connected icons, units, shortcuts, or actions. ## Public Motion - Input does not translate or scale. - Focus remains visible through the native border, surface, ring, and shadow contract. - Disabled and invalid state do not change dimensions. ## Public Accessibility - Use a visible label in product forms; placeholder text is supporting context, not a label. - Connect invalid state to the Input and render a visible FieldError. - Keep browser autocomplete and input type appropriate to the value. - File inputs remain the Input primitive with the native file input behavior. ## Public Agent Guidance - Use Input for free text and Select for a closed option set. - Do not use placeholder-only labels. - Preserve native focus, disabled, invalid, and form semantics. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/input) - [Registry source](https://ui.siteplane.io/r/input.json) --- # Input Group > Siteplane UI release `0.1.1`. ## Public Purpose Input Group combines an input or textarea with tightly related icons, units, text, keyboard shortcuts, or inline actions. ## Import `import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea } from "@/components/ui/input-group";` ## Public API - `InputGroupAddon align` accepts `"inline-start"`, `"inline-end"`, `"block-start"`, or `"block-end"`. Block start places the addon row above the field. - Use `InputGroupText` for non-interactive prefixes, suffixes, and units. - Kbd may be placed in an addon and receives the native radius and spacing treatment. - Put real Button controls in an addon for copy, reveal, submit, or composer actions. Textarea groups include native Button layout for action rows. - Use Input Group only when the addon is tightly coupled to the field value. ## Public Motion - Focus and invalid rings wrap the complete group. - Empty addon space may focus the field; an interactive child keeps its own Button action. - The group itself does not animate, and invalid or disabled state must not change its dimensions. ## Public Accessibility - Give every input or textarea a visible FieldLabel, `aria-label`, or `aria-labelledby`. - Every interactive addon Button needs its own accessible name. - Supporting text, icons, units, and Kbd hints must not become the field's only label. - Connect invalid state to the field and render a visible FieldError. ## Public Agent Guidance - Use `align` instead of custom addon layout. - Use Input for a plain field without closely related addons. - Preserve focus routing, group rings, textarea action layout, and child control semantics. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/input-group) - [Registry source](https://ui.siteplane.io/r/input-group.json) --- # Kbd > Siteplane UI release `0.1.1`. ## Public Purpose Kbd displays individual keys or short keyboard shortcuts. It supplements, but never replaces, an accessible action label or help text. ## Import `import { Kbd, KbdGroup } from "@/components/ui/kbd";` ## Public API - Use `Kbd` for one key and `KbdGroup` for a short combination. - Kbd is non-interactive and keeps `pointer-events-none`. - Native no-wrap and shrink protection keeps combinations such as “⌘ K” together in compact layouts. - Kbd may appear as supporting content inside an Input Group addon. ## Public Motion - Kbd is static and has no reduced-motion exception. - Keep radius, size, and typography on the native primitive. ## Public Accessibility - A shortcut hint does not replace the accessible name of its action. - Keep combinations short and explain unfamiliar shortcuts in surrounding text. - An Input with a Kbd addon still needs a visible or accessible label. - Do not build dense shortcut reference walls inside compact product surfaces. ## Public Agent Guidance - Use KbdGroup instead of custom separators and spacing for combinations. - Preserve native slots, no-wrap, shrink, and pointer behavior. - Keep complete shortcut documentation in help content rather than the control. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/kbd) - [Registry source](https://ui.siteplane.io/r/kbd.json) --- # Label > Siteplane UI release `0.1.1`. ## Public Purpose Label gives one form control a visible, clickable name through `htmlFor` or wrapper semantics. ## Import `import { Label } from "@/components/ui/label";` ## Public API - Connect `htmlFor` to the control `id`, or wrap the control when the primitive supports that pattern. - `render` may change the underlying element while retaining Label behavior. - Use `FieldLabel` inside Field so disabled and validation context stays synchronized. ## Public Motion - Label has no animation. - Clickable labels use a pointer cursor and activate their connected control. - Disabled styling changes color without changing layout. ## Public Accessibility - Every visible Label must name exactly one connected control. - Controls without visible labels require an explicit accessible name. - Mark decorative required asterisks `aria-hidden`; expose required state on the control itself. - Connect invalid state to the control and render a visible FieldError. ## Public Agent Guidance - Do not render visible controls without a connected label or accessible name. - Use FieldLabel inside Field and Label for direct control pairings. - Preserve pointer, disabled, render, and native label behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/label) - [Registry source](https://ui.siteplane.io/r/label.json) --- # Menu > Siteplane UI release `0.1.1`. ## Public Purpose Menu presents grouped actions, choices, links, and submenus from a trigger. Use form controls such as Select, Checkbox, or Switch when the value belongs to a form field. ## Import `import { Menu, MenuCheckboxItem, MenuCreateHandle, MenuGroup, MenuGroupLabel, MenuItem, MenuLinkItem, MenuPopup, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, MenuSub, MenuSubPopup, MenuSubTrigger, MenuTrigger } from "@/components/ui/menu";` ## Public API - `MenuPopup side` accepts top, right, bottom, left, inline-start, and inline-end and defaults to bottom. - `align` accepts start, center, or end and defaults to center. `sideOffset` defaults to 4; `alignOffset` adjusts the cross-axis position. - `anchor` attaches the popup to another element or virtual anchor. - `width` accepts `"auto"`, `"trigger"`, `"content"`, or `"at-least-trigger"`. - Use `inset` on items, group labels, and submenu triggers to align rows without leading icons. - `MenuCheckboxItem size` accepts `"sm"`, `"default"`, `"lg"`, and `"xl"`. - All item, selection, label, separator, and submenu rows inherit the provider `controlSize`; repeated rows use the compact menu geometry from the global size contract rather than the 56px XL CTA height. - `MenuLinkItem closeOnClick` defaults to `true`; use `false` only when the menu should remain open after navigation. - `MenuCreateHandle` supports detached triggers and imperative opening. - Use `disabled` for unavailable items and the native icon slot treatment for leading icons. ## Public Motion - Popup and submenu placement, scale, fade, and reduced-motion behavior are native. - Active items, selection items, and submenu triggers use a pointer cursor. - Do not wrap the popup in a second animation. ## Public Accessibility - Give every trigger visible text or an accessible label. - Give a popup without visible context an accessible menu label. - Preserve Arrow key navigation, focus, Escape, outside click, and focus restoration. - Keep disabled items unavailable and visibly distinct. - Checkbox and radio items retain their selection indicators; shortcuts are supporting text only. ## Public Agent Guidance - Use Menu for actions and menu choices, not ordinary form fields. - Do not render raw items outside Menu and MenuPopup. - Use placement, anchor, width, inset, size, link, disabled, and handle APIs instead of local menu implementations. - Preserve native item, submenu, selection, cursor, focus, and motion behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/menu) - [Registry source](https://ui.siteplane.io/r/menu.json) --- # Meter > Siteplane UI release `0.1.1`. ## Public Purpose Meter communicates a known numeric value within a fixed range, such as storage usage, capacity, a rating, or a quota. Use Progress for an ongoing task whose completion is changing over time. ## Import `import { Meter, MeterIndicator, MeterLabel, MeterTrack, MeterValue } from "@/components/ui/meter";` ## Public API - Set `value`, optional `min` and `max`, and controlled or formatted value behavior on `Meter`. - `locale` controls the formatted numeric output and defaults to `"en-US"`. - Compose `MeterLabel`, `MeterValue`, `MeterTrack`, and `MeterIndicator` for a labelled measurement. Without children, Meter renders its Track and Indicator automatically. - Root `size` accepts `"sm"`, `"default"`, `"lg"`, or `"xl"` and provides the default size to every part. - `MeterLabel`, `MeterTrack`, and `MeterValue` each accept their own `size` override. A part-level size takes precedence over the root or provider size. - `MeterValue` accepts the Base UI render function when the displayed unit is not a percentage. ## Public Motion - MeterIndicator animates value changes with the central linger duration and Apple-out easing tokens. - The operating-system reduced-motion preference removes the transition. The forced `reducedMotionPreset` shortens the shared linger duration from 380ms to 120ms. - Value updates do not change the surrounding layout. ## Public Accessibility - Provide a visible `MeterLabel` or an explicit accessible name. - Preserve `aria-valuenow`, `aria-valuemin`, and `aria-valuemax` from the Base UI-backed root. - A custom MeterValue format must communicate the same numeric state as the indicator. - Meter is read-only. Use Slider or Number Field when a person must change the value. ## Public Agent Guidance - Use Meter only when the current value, minimum, and maximum are known. - Use Progress for task completion and Slider or Number Field for input. - Keep Track, Indicator, locale, size inheritance, and accessibility behavior inside the existing primitive. - Do not rebuild the visual from a raw progress element when Meter fits. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/meter) - [Registry source](https://ui.siteplane.io/r/meter.json) --- # Number Field > Siteplane UI release `0.1.1`. ## Public Purpose Use Number Field for numeric values that benefit from keyboard entry, step buttons, optional scrubbing and explicit range or formatting rules. ## Import `import { NumberField } from "@/components/ui/number-field";` `import { CursorGrowIcon, NumberFieldDecrement, NumberFieldGroup, NumberFieldIncrement, NumberFieldInput, NumberFieldScrubArea } from "@/components/ui/number-field";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` `import { Form } from "@/components/ui/form";` `import { Label } from "@/components/ui/label";` ## Public API - `NumberField` owns the value and accepts the Base UI number-field props plus `size="sm" | "default" | "lg" | "xl"`. - `size="xl"` gives the composed group the shared 56px customer-facing outer height and 16px value text. Use the surrounding provider's `radius="sm"` personality for the global 8px main corner. - Compose `NumberFieldGroup`, `NumberFieldInput`, `NumberFieldDecrement` and `NumberFieldIncrement` for the standard control. - `NumberFieldScrubArea` adds a labelled drag target for changing the value; `CursorGrowIcon` is the matching visual indicator. - Configure `min`, `max`, `step`, `format`, controlled `value` or uncontrolled `defaultValue` on `NumberField`, not on the input slot. ## Public Motion - Number Field adds no root-level enter or exit animation. Button feedback, focus, disabled and invalid states come from the native Siteplane primitives. - Scrubbing updates the value directly without moving the surrounding layout. The optional Rolling Digits documentation example is not part of the default primitive and reduces its digit transition to one frame in system and provider reduced-motion modes. ## Public Accessibility - Provide a visible label through `FieldLabel` or an explicit accessible name. - Give `NumberFieldScrubArea` a label that describes the value it changes. - Keep increment, decrement and keyboard behavior on the Base UI-backed slots, and pair invalid state with a visible `FieldError`. ## Public Agent Guidance - Use Input for free-form text and Slider for visual range selection. - Do not rebuild a numeric input from raw browser controls when Number Field fits. - Keep range, step and formatting rules on the root so every input method shares one contract. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/number-field) - [Registry source](https://ui.siteplane.io/r/number-field.json) --- # OTP Field > Siteplane UI release `0.1.1`. ## Public Purpose Use OTP Field for short one-time passwords, verification codes and recovery codes that should be entered as a fixed sequence of slots. ## Import `import { OTPField, OTPFieldInput, OTPFieldSeparator } from "@/components/ui/otp-field";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` ## Public API - `OTPField` is the root and requires `length`; it also accepts `size="sm" | "default" | "lg" | "xl"` and the Base UI OTP Field props. - `size="xl"` renders each slot as a 56px square; the segmented value remains a set of real inputs. Use the surrounding provider's `radius="sm"` personality for the global 8px main corner. - Render one `OTPFieldInput` for every character in DOM order. The number of slots must match `length`. - `OTPFieldSeparator` visually divides slot groups without changing the value length. - Use `validationType`, `normalizeValue`, `onValueInvalid`, `mask` and controlled or uncontrolled value props on the root. ## Public Motion - Slots do not translate or resize while the value changes. Focus, invalid and disabled feedback use the native state styles. - Reduced motion needs no extra handling because OTP Field does not animate with scale or movement. ## Public Accessibility - Pair the field with a visible `FieldLabel`; without one, give every slot a specific label such as `Character 2 of 6`. - Keep the slot count synchronized with `length` and explain rejected characters when custom validation is active. - Masking protects shoulder-surfing only; it is not a substitute for secure verification logic. ## Public Agent Guidance - Use OTP Field only for short fixed-length codes, not free text. - Keep every slot as a real `OTPFieldInput` and use `length`, not the legacy `maxLength` contract. - Do not replace the native slot, focus, disabled, invalid or masking behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/otp-field) - [Registry source](https://ui.siteplane.io/r/otp-field.json) --- # Pagination > Siteplane UI release `0.1.1`. ## Public Purpose Use Pagination for finite, page-based navigation when people need to move between known result pages. ## Import `import { Pagination } from "@/components/ui/pagination";` `import { PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious } from "@/components/ui/pagination";` `PaginationLink` unterstuetzt `isActive`, `size` und `render`. ## Public API - Compose `Pagination`, `PaginationContent` and `PaginationItem` as a navigation list. - Pagination is compositional and does not own page state: connect links to real routes or control the active page in the consuming app. - `PaginationLink` accepts `isActive` and every Button size: `xs`, `sm`, `default`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg` and `icon-xl`. - Use `PaginationPrevious`, `PaginationNext` and `PaginationEllipsis` for navigation and skipped ranges. - Use the Base UI `render` prop on links when integrating a router without introducing nested interactive elements. ## Public Motion - Pagination has no mount or exit animation. Hover, press and focus feedback come from the Button variant used by `PaginationLink`. - The component does not require a reduced-motion override. ## Public Accessibility - Keep the root as a labelled `nav` and `PaginationContent` as a real list. - Set `isActive` only on the current page so `aria-current="page"` remains accurate. - Preserve the built-in previous, next and ellipsis screen-reader labels. ## Public Agent Guidance - Use inert links only in examples; production pagination should navigate or update controlled page state. - Interactive demos should update `isActive` from controlled state so previous, next and page controls demonstrate the real behavior. - Do not hand-build rows of links or buttons when the Pagination slots fit. - Keep `aria-current`, `data-active`, labels and Button integration intact. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/pagination) - [Registry source](https://ui.siteplane.io/r/pagination.json) --- # Popover > Siteplane UI release `0.1.1`. ## Public Purpose Use Popover for short contextual interactions, supporting information or compact forms anchored to a trigger without leaving the current workflow. ## Import `import { Popover } from "@/components/ui/popover";` `import { PopoverClose, PopoverContent, PopoverCreateHandle, PopoverDescription, PopoverPopup, PopoverTitle, PopoverTrigger } from "@/components/ui/popover";` `import { Field } from "@/components/ui/field";` `import { Form } from "@/components/ui/form";` `import { Textarea } from "@/components/ui/textarea";` `import { InputGroup, InputGroupAddon, InputGroupInput } from "@/components/ui/input-group";` ## Public API - Compose `Popover`, `PopoverTrigger` and `PopoverPopup`; the popup already owns its portal and positioner. - `PopoverPopup` accepts `side`, `align`, `sideOffset`, `alignOffset`, `anchor`, `portalProps` and the popup content props. - Use `PopoverTitle`, `PopoverDescription` and `PopoverClose` for structured, dismissible content. - `PopoverCreateHandle` supports detached triggers or externally controlled popup access when the normal trigger relationship is not sufficient. ## Public Motion - `PopoverPopup` uses the shared floating-panel fade, scale and directional offset tokens. - Collision handling, transform origin and reduced-motion behavior remain part of the native Siteplane floating-panel contract. ## Public Accessibility - Escape, outside click and focus management are provided by Base UI and must remain intact. - Give icon-only triggers an accessible name and use `PopoverTitle` and `PopoverDescription` for structured content. - Use Tooltip for a non-interactive hint and Dialog or Alert Dialog for long or critical tasks. ## Public Agent Guidance - Keep portal, positioning, focus and dismissal logic inside the primitive. - Prefer the regular trigger relationship; use `anchor` or `PopoverCreateHandle` only for a genuine detached-anchor requirement. - Do not use Popover for irreversible decisions or long forms. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/popover) - [Registry source](https://ui.siteplane.io/r/popover.json) --- # Preview Card > Siteplane UI release `0.1.1`. ## Public Purpose Use Preview Card for optional supporting previews such as profiles, repositories, terms or products that appear from a hoverable and focusable trigger. ## Import ```tsx import { PreviewCard, PreviewCardTrigger, PreviewCardPopup, } from "@/components/ui/preview-card"; ``` `import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";` `import { Badge } from "@/components/ui/badge";` `import { Button } from "@/components/ui/button";` ## Public API - Compose `PreviewCard`, `PreviewCardTrigger` and `PreviewCardPopup`. - `PreviewCardTrigger` renders a link by default and accepts Base UI's `render` prop for another interactive element. - `PreviewCardPopup` accepts placement props including `side`, `align`, `sideOffset` and `anchor`; `anchor` can point at a different element or virtual position. - Keep popup content compact and non-essential because it is supplementary to the trigger's destination. ## Public Motion - The popup uses the native Siteplane floating-panel scale and opacity transition. - Open delay, close behavior and reduced motion remain controlled by the Preview Card primitive and global motion layer. ## Public Accessibility - The trigger must be an interactive element with its own accessible name and keyboard focus. - The preview opens from both hover and focus; preserve Escape behavior. - Images need useful alt text or a text fallback, and any popup action needs a clear accessible name. ## Public Agent Guidance - Never put required instructions, validation or critical status only inside a Preview Card. - Do not render a popup without an interactive trigger or a deliberate `anchor` relationship. - Use Popover instead when the floating content itself is the primary interactive task. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/preview-card) - [Registry source](https://ui.siteplane.io/r/preview-card.json) --- # Progress > Siteplane UI release `0.1.1`. ## Public Purpose Use Progress for measurable work with a known current value and maximum, such as uploads, imports or multi-step processing. ## Import `import { Progress } from "@/components/ui/progress";` `import { ProgressIndicator, ProgressLabel, ProgressTrack, ProgressValue } from "@/components/ui/progress";` ## Public API - `Progress` accepts a numeric `value` or `value={null}` for indeterminate status, plus `max`, `format`, `locale` and `size="sm" | "default" | "lg" | "xl"`; the wrapper defaults `locale` to `en-US`. - Compose `ProgressLabel`, `ProgressValue`, `ProgressTrack` and `ProgressIndicator` when custom children are needed. - `ProgressLabel`, `ProgressValue` and `ProgressTrack` each accept their own `size` override; otherwise they inherit the root or provider size. - Use `getAriaValueText` or `aria-valuetext` when the numeric value needs a human-readable explanation. ## Public Motion - Value changes animate through the shared Progress transition tokens; the surrounding layout remains stable. - The operating-system reduced-motion preference removes the indicator transition. The forced `reducedMotionPreset` shortens the shared linger duration from 380ms to 120ms, and the provider contract stops the continuous indeterminate fill. - Do not add local durations or transforms; state changes and progress semantics remain visible in every mode. ## Public Accessibility - Provide a visible label or explicit accessible name and keep `value` and `max` accurate. - Use human-readable value text for units or stages that a plain number cannot explain. - Use a numeric value for known progress. `value={null}` supports a short transitional indeterminate state when paired with useful `aria-valuetext`; Spinner or Skeleton can be clearer for unknown or long-running loading. ## Public Agent Guidance - Keep track and indicator together when supplying custom children. - Set locale deliberately for non-English products instead of relying on the `en-US` wrapper default. - Use part-level size overrides only when a real composition requires them; root size is the normal path. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/progress) - [Registry source](https://ui.siteplane.io/r/progress.json) --- # Radio Group > Siteplane UI release `0.1.1`. ## Public Purpose Use Radio Group when exactly one option must be selected from a short, visible set. ## Import `import { Radio, RadioGroup } from "@/components/ui/radio-group";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` `import { Form } from "@/components/ui/form";` `import { Button } from "@/components/ui/button";` `import { Label } from "@/components/ui/label";` ## Public API - `RadioGroup` accepts the Base UI group props, controlled or uncontrolled value, `disabled`, `readOnly` and `size="sm" | "default" | "lg" | "xl"`. - Each `Radio` requires a unique `value` and can override `disabled`, `readOnly` and inherited size. - `disabled` on the group disables every option; use item-level `disabled` only when individual choices are unavailable. - `readOnly` prevents changes without applying disabled styling, so accompany it with clear context when the state might otherwise look editable. ## Public Motion - Selection updates the native indicator, border and focus styles without changing layout dimensions. - Radio Group adds no group-level enter or exit animation. System and provider reduced-motion modes move the indicator directly to its final state instead of interpolating its fade and scale. ## Public Accessibility - Give every group an accessible name through `aria-label` or `aria-labelledby`. - Couple visible option labels to their Radio controls and give standalone controls an explicit label. - Pair invalid state with visible error text; disabled and read-only state must be understandable without relying on color alone. ## Public Agent Guidance - Use Checkbox Group for multiple selection and Select when the option set should remain collapsed. - Prefer group-level `disabled` when the complete choice is unavailable. - Do not build raw radio inputs outside the Radio Group contract. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/radio-group) - [Registry source](https://ui.siteplane.io/r/radio-group.json) --- # Resource List > Siteplane UI release `0.1.1`. ## Public Purpose Use Resource List for compact entity collections such as contacts, tasks, leads or files that do not need a tabular header and strict columns. ## Import ```tsx import { ResourceList, ResourceListContent, ResourceListDescription, ResourceListIndicator, ResourceListItem, ResourceListMeta, ResourceListTitle, } from "@/components/ui/resource-list"; ``` ## Public API - `ResourceList` accepts `density="default" | "compact"` and `variant="default" | "soft"`. - Compose `ResourceListItem`, `ResourceListIndicator`, `ResourceListContent`, `ResourceListTitle`, `ResourceListDescription` and `ResourceListMeta`. - `ResourceListItem` accepts `interactive`, `selected`, `active`, `disabled` and Base UI's `render` prop for a semantic button or link. - `ResourceListIndicator` supports `muted`, `success`, `warning`, `info`, `error` and `chart-1` through `chart-5`, plus `bar`, `diamond`, `dot` and `ring` shapes. ## Public Motion - Resource List uses quiet hover, active and selected state changes without row lift or entry animation. - Indicator and selection changes do not alter row measurements; reduced motion requires no extra behavior. ## Public Accessibility - Interactive rows must render as semantic buttons or links and retain visible keyboard focus. - Color indicators are supplementary. Provide status text, an icon label or another non-color explanation. - Keep title, description and metadata in their named slots so reading order stays predictable. ## Public Agent Guidance - Use Table for genuine column comparison and Resource List for lighter entity scanning. - Use all available indicator tones through the documented `tone` prop instead of adding local colors. - Do not simulate interactive rows with click handlers on non-focusable containers. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/resource-list) - [Registry source](https://ui.siteplane.io/r/resource-list.json) --- # Scroll Area > Siteplane UI release `0.1.1`. ## Public Purpose Use Scroll Area when content must overflow a deliberately bounded region while retaining Siteplane overlay scrollbars and keyboard scrolling. ## Import `import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";` `import { Separator } from "@/components/ui/separator";` `import { Badge } from "@/components/ui/badge";` `import { Button } from "@/components/ui/button";` ## Public API - `ScrollArea` accepts `scrollFade`, `scrollbarGutter`, `fill` and `clampContentMinWidth` in addition to the Base UI root props. - `fill` makes the content fill the viewport, which is useful for full-height children and centered empty states. - `clampContentMinWidth` defaults to `true`; set it to `false` when intrinsic-width content should create horizontal scrolling instead of shrinking. - `ScrollBar` is exported for custom composition and accepts `orientation="vertical" | "horizontal"`. ## Public Motion - Scrollbars fade through the native Siteplane Scroll Area transition. Content itself does not animate as it scrolls. - The operating-system reduced-motion preference removes the scrollbar fade and its delay. The forced `reducedMotionPreset` sets the active fade duration to 0ms while keeping scrolling and the scrollbar usable. ## Public Accessibility - Give the region an accessible name and a real bounded height or width. - Preserve the focusable viewport and visible focus ring for keyboard scrolling. - Do not hide required actions beyond an undiscoverable scroll boundary, and use pagination for very large datasets. ## Public Agent Guidance - Avoid nested scroll areas on the same axis. - Choose `clampContentMinWidth={false}` for wide tables or rows that must retain intrinsic width. - Do not replace large-data pagination with one indefinitely growing Scroll Area. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/layout/scroll-area) - [Registry source](https://ui.siteplane.io/r/scroll-area.json) --- # Select > Siteplane UI release `0.1.1`. ## Public Purpose Use Select for a bounded, known set of choices such as status, category, framework or filter values. ## Import ```tsx import { Select, SelectButton, SelectGroup, SelectGroupLabel, SelectItem, SelectLabel, SelectPopup, SelectSeparator, SelectTrigger, SelectValue, } from "@/components/ui/select"; ``` ## Public API - `Select` supports single or multiple controlled and uncontrolled values through the Base UI root contract. - `SelectTrigger size="xl"` uses the 56px customer-facing field height and 16px field text. Pair it with a surrounding `SiteplaneUIProvider radius="sm"` for the global 8px main corner. Popup item density and radius stay independent from the trigger size. - Compose `SelectTrigger`, `SelectValue`, `SelectPopup`, `SelectItem`, `SelectGroup`, `SelectGroupLabel`, `SelectLabel` and `SelectSeparator`; `SelectButton` is the standalone trigger-style button. - `SelectPopup` accepts `side`, `align`, `sideOffset`, `alignOffset`, `anchor`, `alignItemWithTrigger`, `portalProps` and popup props. - `SelectItem` accepts `disabled`. Long lists automatically expose the built-in scroll-up and scroll-down controls when the popup overflows. ## Public Motion - Select uses the shared floating-panel transition. Item-aligned popups keep the selected item stable while using the shared fade and scale behavior. - Placement, collision handling and reduced motion remain inside the native primitive. ## Public Accessibility - Give the trigger a visible label or accessible name and keep disabled or invalid state paired with clear text. - Preserve keyboard navigation, typeahead, focus return and the built-in long-list scroll controls. - A disabled option must remain understandable without being the only available choice. ## Public Agent Guidance - Use Combobox for large searchable sets and Autocomplete for suggestions while typing. - Configure placement on `SelectPopup`, not with local positioning wrappers. - Do not replace the built-in overflow behavior with a second nested scroll container. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/select) - [Registry source](https://ui.siteplane.io/r/select.json) --- # Selectable Card > Siteplane UI release `0.1.1`. ## Public Purpose Use Selectable Card for a single card-shaped choice when the whole surface should act as one button and expose its selected state. ## Import ```tsx import { SelectableCard } from "@/components/ui/selectable-card"; ``` ## Public API - `SelectableCard` renders a button by default, accepts Base UI's `render` prop and exposes a controlled `selected` boolean. - The component mirrors `selected` to `data-selected` and `aria-pressed`; update the value from the consumer's click handler. - Native button props such as `disabled`, `type`, accessible naming and keyboard activation remain available. ## Public Motion - Selection, hover and focus use color, border and ring transitions without moving the card. - Reduced motion requires no additional override because the component has no scale or translation animation. ## Public Accessibility - Keep the card as one semantic button with a clear accessible name. - Do not nest buttons, links or other interactive controls inside a clickable Selectable Card. - `aria-pressed` describes the selected state; do not replace it with color-only styling. ## Public Agent Guidance - Use Radio Group for a mutually exclusive list with native radio semantics and Checkbox for independent multiple selection. - Keep state controlled by the caller and preserve the button contract. - Do not hand-build a clickable card with a non-focusable container. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/selectable-card) - [Registry source](https://ui.siteplane.io/r/selectable-card.json) --- # Separator > Siteplane UI release `0.1.1`. ## Public Purpose Use Separator to communicate a real visual or structural boundary between related groups, toolbar actions or menu sections. ## Import `import { Separator } from "@/components/ui/separator";` `import { Button } from "@/components/ui/button";` ## Public API - `Separator` accepts the Base UI Separator props and defaults `orientation` to `horizontal`. - Set `orientation="vertical"` for side-by-side content; its parent must provide a usable block size. - Use the primitive's decorative or semantic contract instead of duplicating the divider with a raw border element. ## Public Motion - Separator is static and has no motion behavior. ## Public Accessibility - Use a decorative separator when the boundary is only visual; use semantic separator behavior when it represents a meaningful division. - Match `orientation` to the rendered direction so assistive technology receives the correct structure. ## Public Agent Guidance - Separator does not replace spacing. Keep layout gaps and padding for grouping. - Avoid stacking separators and borders when spacing or surface contrast already creates a clear boundary. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/layout/separator) - [Registry source](https://ui.siteplane.io/r/separator.json) --- # Settings Switch Rows > Siteplane UI release `0.1.1`. ## Public Purpose Settings Switch Rows is a `registry:component` for labelled settings with short descriptions, icons and a full-row switch target. ## Import ```tsx import { SettingsSwitchRows } from "@/components/patterns/settings-switch-rows"; ``` ## Public API - Render `SettingsSwitchRows` for the included workspace-update and automatic-dark-mode examples. - Adapt the labels, descriptions, icons and default values after installation. - Keep each row as a label around one Switch so the complete row remains the interaction target. ## Public Motion - The recipe adds no motion and retains the native Switch track and thumb transition. - Reduced motion behavior is inherited from Switch and the global motion provider. ## Public Accessibility - Each Switch receives its accessible name from the visible row label. - Keep descriptions concise and do not communicate the checked state through color alone. ## Public Agent Guidance - Install with `pnpm dlx shadcn@4.16.1 add @siteplane/settings-switch-rows`. - Use this recipe for compact boolean preferences with immediate effect. - Use Form and Field when a preference is submitted as part of a larger form. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/settings-switch-rows) - [Registry source](https://ui.siteplane.io/r/settings-switch-rows.json) --- # Sheet > Siteplane UI release `0.1.1`. ## Public Purpose Use Sheet for side or edge flyouts that contain edit, create and save/cancel workflows. Use Drawer for contextual inspection or gesture-driven panels. ## Import ```tsx import { Sheet, SheetClose, SheetDescription, SheetFooter, SheetHeader, SheetPanel, SheetPopup, SheetTitle, SheetTrigger, } from "@/components/ui/sheet"; ``` ## Public API - Compose `Sheet`, `SheetTrigger`, `SheetPopup`, `SheetHeader`, `SheetTitle`, `SheetDescription`, `SheetPanel`, `SheetFooter` and `SheetClose`. - `SheetPopup` accepts `side="right" | "left" | "top" | "bottom"`, `variant="default" | "inset"`, `showCloseButton`, `closeProps` and `portalProps`. - `closeProps` customizes the built-in close control without removing it; `showCloseButton={false}` removes that control when another explicit close path exists. - `SheetPanel` accepts `scrollFade`; set `scrollFade={false}` for a hard scroll edge. `SheetFooter` accepts `variant="default" | "bare"`. ## Public Motion - Backdrop and panel use the shared Sheet motion tokens, including side-aware translation and `--motion-sheet-x` or `--motion-sheet-y`. - Reduced motion removes transform-heavy movement while preserving open, close and focus behavior. ## Public Accessibility - Provide `SheetTitle` and, where helpful, `SheetDescription`; preserve focus trapping, Escape and focus return. - Keep at least one explicit close path through the built-in button or `SheetClose`. - Use semantic form controls and visible labels inside edit flows. ## Public Agent Guidance - Use Sheet for task-oriented forms and Drawer for contextual details or swipe interactions. - Customize the built-in close button through `closeProps` instead of adding a second overlapping control. - Keep scroll behavior in `SheetPanel` and do not add a competing nested vertical scroll container. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/sheet) - [Registry source](https://ui.siteplane.io/r/sheet.json) --- # Sidebar > Siteplane UI release `0.1.1`. ## Public Purpose Sidebar demonstrates persistent, collapsible application navigation composed from the native Sidebar primitives. It collapses to an icon rail on desktop and becomes an off-canvas drawer on mobile. Use Dashboard Shell instead when the page also needs a guaranteed app-header height, divider alignment and content-scroll contract. ## Import ```tsx import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupLabel, SidebarHeader, SidebarInset, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarProvider, SidebarTrigger, } from "@/components/ui/sidebar"; ``` ## Public API - Compose the persistent layout with `SidebarProvider`, `Sidebar` and `SidebarInset`. - Use the native content, group and menu slots for navigation. Keep KPI and report cards in the main content region. - Render menu labels inside child elements such as `` and provide `tooltip` when using `collapsible="icon"`. - `SidebarRail` can opt into native resize behavior through `resizable`; do not add a second drag implementation. - Local menu-button sizes override the provider; inherited control size is intentionally damped for navigation density. ## Public Motion - Desktop collapse animates the native Sidebar width and can be triggered through `SidebarTrigger`, the rail or Cmd/Ctrl+B. - Mobile off-canvas behavior, nested Collapsible navigation and Menu popups keep their native motion and reduced-motion support. - Do not add parallax or a content-wide backdrop layer. ## Public Accessibility - Persistent navigation needs clear labels and an active state that is not conveyed by color alone. - Collapsed icon navigation must preserve labels through the native Sidebar tooltip contract. - Keep the native trigger, rail, keyboard shortcut and mobile dismissal behavior instead of replacing them with custom click targets. ## Public Agent Guidance - Keep Sidebar as persistent navigation, not a general card or embedded overlay. - Reuse native collapse, mobile drawer, tooltip and optional resize behavior. - Use Dashboard Shell when sidebar and app-header alignment are part of the requirement. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/sidebar) - [Registry source](https://ui.siteplane.io/r/sidebar.json) --- # Skeleton > Siteplane UI release `0.1.1`. ## Public Purpose Use Skeleton to reserve the approximate shape of content while a layout is loading and the final value is not yet available. ## Import `import { Skeleton } from "@/components/ui/skeleton";` ## Public API - `Skeleton` accepts standard `div` props. Set its dimensions and shape with existing layout and radius utilities. - The primitive owns `data-slot="skeleton"` and the shared shimmer animation; it does not introduce content-specific variants. ## Public Motion - Skeleton uses the central `animate-skeleton` shimmer. Both the provider override and the operating-system reduced-motion preference stop it through the shared `siteplane-skeleton-motion` contract. - Do not add a second animation, fixed background attachment or component-local timing values. ## Public Accessibility - Keep placeholders hidden from the accessibility tree when they carry no meaningful status. - Announce loading on the surrounding region when users need that information; do not expose fake text or fake controls to screen readers. - Preserve layout without making the placeholder look interactive. ## Public Agent Guidance - Shape Skeleton with normal layout utilities instead of adding parallel variants or wrappers. - Use Spinner for an indeterminate operation indicator and Skeleton for content-shaped loading. - Remove the placeholder when real content arrives rather than layering both states. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/skeleton) - [Registry source](https://ui.siteplane.io/r/skeleton.json) --- # Slider > Siteplane UI release `0.1.1`. ## Public Purpose Use Slider for choosing one or more values from a continuous or stepped visual range. ## Import `import { Slider, SliderValue } from "@/components/ui/slider";` `import { Field, FieldLabel } from "@/components/ui/field";` ## Public API - `Slider` accepts controlled or uncontrolled values, `min`, `max`, `step`, `orientation`, `disabled` and `size="sm" | "default" | "lg" | "xl"` through the Base UI root contract. - `thumbCollisionBehavior="push" | "swap" | "none"` controls how thumbs behave when a range selection reaches another thumb. - `SliderValue` displays the current value and accepts its own size override; otherwise it inherits the root or provider size. - A value array renders one thumb per value; keep value order and labels meaningful for range sliders. ## Public Motion - Track fill and thumb feedback use shared Siteplane transition tokens. Dragging disables delayed interpolation so the control follows the pointer directly. - The operating-system reduced-motion preference removes thumb and track transitions. The forced `reducedMotionPreset` shortens their shared slow duration from 320ms to 100ms without changing drag or keyboard behavior. ## Public Accessibility - Provide an accessible label for every slider and distinct labels for multiple thumbs. - Keep keyboard increments, orientation and value limits aligned with the visible range. - Expose understandable value text when raw numbers do not describe the unit or meaning. ## Public Agent Guidance - Use Number Field when exact typed entry is primary, Meter for read-only measurement and Progress for task completion. - Choose `thumbCollisionBehavior` deliberately for multi-thumb sliders instead of assuming every range should push. - Do not rebuild track, indicator or thumbs from raw elements. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/slider) - [Registry source](https://ui.siteplane.io/r/slider.json) --- # Sortable Data Table > Siteplane UI release `0.1.1`. ## Public Purpose Sortable Data Table is a `registry:component` for sortable project data with full-cell sort targets and a keyboard-selectable active row. ## Import ```tsx import { SortableDataTable } from "@/components/patterns/sortable-data-table"; ``` ## Public API - Render `SortableDataTable` for the included project-table example. - Adapt the row type, data and typed columns after installation while keeping a stable row id. - Sortable columns need an accessor. Row selection is controlled by `activeRowId` and `onRowClick`. ## Public Motion - The recipe adds no sorting or row-selection motion. - The table updates immediately and respects the native focus behavior of DataTable. ## Public Accessibility - Sort buttons expose `aria-sort` through DataTable. - Interactive rows are keyboard reachable and need a row-specific accessible label. - Keep the active state textual or semantic; do not rely on background color alone. ## Public Agent Guidance - Install with `pnpm dlx shadcn@4.16.1 add @siteplane/sortable-data-table`. - Prefer DataTable columns and accessors over custom table sorting code. - Adapt the installed recipe source for project row types, column labels and a row-selection callback; keep the recipe when a project row opens Detail Drawer. - Use the lower-level DataTable for non-project data or materially different table mechanics. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/sortable-data-table) - [Registry source](https://ui.siteplane.io/r/sortable-data-table.json) --- # Spinner > Siteplane UI release `0.1.1`. ## Public Purpose Use Spinner for an indeterminate operation whose completion percentage is unknown, such as saving, refreshing or loading a bounded panel. ## Import `import { Spinner } from "@/components/ui/spinner";` `import { Button } from "@/components/ui/button";` ## Public API - `Spinner` accepts standard element props and `variant="default" | "ring" | "dots" | "bars" | "spokes" | "pulse" | "comet"`. - Size and color inherit from the surrounding context unless an existing utility explicitly changes them. - Button loading should use the Button `loading` contract rather than manually placing a separate Spinner next to the label. ## Public Motion - Each variant owns its loading animation; do not stack another spin, pulse or duration class on top. - Both the provider override and the operating-system reduced-motion preference stop root and child animations through the shared `siteplane-spinner-motion` contract. The static status indicator and its semantics remain visible. ## Public Accessibility - A standalone Spinner uses `role="status"` and needs a context-specific accessible label when `Loading` is not descriptive enough. - Keep nearby visible loading text available to assistive technology. - Use Progress when a real percentage or stage is known. ## Public Agent Guidance - Prefer the default variant unless another documented form better matches the available space. - Do not invent a new loader animation in product code. - Avoid showing several independent spinners for one operation. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/spinner) - [Registry source](https://ui.siteplane.io/r/spinner.json) --- # Stepper > Siteplane UI release `0.1.1`. ## Public Purpose Use Stepper to communicate ordered workflow progress or let users navigate between known steps. ## Import ```tsx import { Stepper, StepperButtonItem, StepperItem } from "@/components/ui/stepper"; ``` ## Public API - `Stepper` renders the ordered-list root. - `StepperItem` is read-only; `StepperButtonItem` renders an interactive step button. Both accept `status="open" | "current" | "done" | "blocked"`, `title`, `description`, `index` and `children`. - `children` render below the title and description inside the content slot, so a step can include supporting fields, actions or status details. - `StepperButtonItem` accepts normal button props including `disabled`; `current` sets `aria-current="step"`. - `current` controls only the selected indicator ring. It does not mutate `status`, so checkmarks, numbers and locks remain stable when users navigate. ## Public Motion - Indicator state uses the shared fast transition for its small focus/status accent. - Step content does not mount or collapse automatically. The operating-system reduced-motion preference removes the decorative indicator transition; the forced `reducedMotionPreset` shortens its shared fast duration from 140ms to 60ms. ## Public Accessibility - Keep visual and DOM order identical and preserve the ordered-list structure. - Mark exactly one current step when the workflow has a current position. - Use `StepperButtonItem` only when clicking a step performs a real navigation or state change; disabled steps must remain clearly unavailable. ## Public Agent Guidance - Use Timeline for read-only history and Stepper for ordered workflow progress. - Put supporting content in the documented `children` slot instead of creating a parallel item wrapper. - Do not make a read-only `StepperItem` appear clickable. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/stepper) - [Registry source](https://ui.siteplane.io/r/stepper.json) --- # Switch > Siteplane UI release `0.1.1`. ## Public Purpose Use Switch for a direct on/off preference whose change is understood as enabling or disabling a setting. ## Import `import { Switch } from "@/components/ui/switch";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` `import { Form } from "@/components/ui/form";` `import { Label } from "@/components/ui/label";` ## Public API - `Switch` accepts controlled `checked`, uncontrolled `defaultChecked`, `onCheckedChange`, `disabled`, `readOnly`, `required`, `name`, `value` and Base UI switch props. - `size="sm" | "default" | "lg" | "xl"` overrides the nearest `SiteplaneUIProvider` control size. - The native control mirrors checked, disabled and invalid state through Base UI attributes and form participation. - Every size keeps a consistent 2 px inset between track and thumb without changing the outer track dimensions. - Track radius scales with control size through the existing provider-derived radius tokens, and the thumb inherits the same radius, including `radius="none"`. ## Public Motion - The thumb translates and stretches through the native Siteplane Switch motion contract; hover and press feedback stay inside the primitive. - Reduced motion keeps the checked state immediate and removes non-essential transition. ## Public Accessibility - Pair every Switch with a visible clickable label or provide a precise accessible name. - Use Switch for settings, Checkbox for form agreement or multi-select, and never communicate state by color alone. - Disabled, read-only and invalid state need supporting context when the reason is not obvious. ## Public Agent Guidance - Use only the documented sizes or provider default. - Keep label and control as one clickable setting row without nesting unrelated actions. - Do not rebuild the switch track or thumb from raw elements. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/switch) - [Registry source](https://ui.siteplane.io/r/switch.json) --- # Table > Siteplane UI release `0.1.1`. ## Public Purpose Use Table for genuinely tabular, scannable data whose columns need semantic headers and consistent alignment. ## Import `import { Table } from "@/components/ui/table";` `import { TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "@/components/ui/table";` `variant?: "default" | "card"` ## Public API - Compose `Table`, `TableHeader`, `TableBody`, `TableFooter`, `TableRow`, `TableHead`, `TableCell` and `TableCaption`. - `Table` accepts `variant="default" | "card"`; the wrapper provides horizontal overflow through its native table container. - Set `data-state="selected"` on a selected row. Set `data-interactive="true"` on a clickable row to receive the native pointer and focus-visible treatment. - Use Data Table when sorting, accessor columns or controlled table behavior is required. ## Public Motion - Table has no mount or row-entry animation. Hover, selected and interactive states use quiet tokenized state changes. - Reduced motion needs no extra handling because rows do not translate or scale. ## Public Accessibility - Use real header cells, body cells and a caption when the surrounding context does not already name the table. - Interactive rows need keyboard activation and a clear focus target; nested buttons or links must remain independently operable. - Loading and empty rows should span the full column count. ## Public Agent Guidance - Do not use Table as a general layout grid. - Use `data-interactive="true"` instead of rebuilding clickable-row cursor and focus styles. - Keep sorting and accessor logic in Data Table, not in the primitive Table. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/table) - [Registry source](https://ui.siteplane.io/r/table.json) --- # Tabs > Siteplane UI release `0.1.1`. ## Public Purpose Use Tabs for equal-priority panels within one local page context, such as settings sections or compact detail views. ## Import `import { Tabs, TabsList, TabsPanel, TabsTab } from "@/components/ui/tabs";` `import { TabsContent, TabsTrigger } from "@/components/ui/tabs";` ## Public API - `Tabs` accepts controlled or uncontrolled `value`, `onValueChange`, `orientation` and `size="sm" | "default" | "lg" | "xl"` through the Base UI root contract. - `TabsList` accepts `variant="default" | "underline"` and can provide the size to its child tabs. - Each `TabsTab` requires a matching `value` and can be disabled or sized locally; render the corresponding content in `TabsPanel`. - `TabsContent` remains a compatibility alias for `TabsPanel`; new code should use the canonical `TabsPanel` name. ## Public Motion - The active indicator uses the native Siteplane position and size transition. Panels do not receive a heavy entrance animation. - The operating-system reduced-motion preference removes indicator interpolation. The forced `reducedMotionPreset` shortens the shared base duration from 180ms to 80ms while preserving selection and focus. ## Public Accessibility - Preserve the tab, tablist and tabpanel relationship generated by Base UI. - Keep orientation consistent with both layout and arrow-key navigation. - Do not make a disabled tab the only path to required content. ## Public Agent Guidance - Use Stepper for workflow steps and navigation links for global routing. - Use canonical `TabsPanel` in new code and keep value pairs unique. - Do not replace native indicator, focus or orientation behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/tabs) - [Registry source](https://ui.siteplane.io/r/tabs.json) --- # Task Calendar > Siteplane UI release `0.1.1`. ## Public Purpose Task Calendar is a `registry:block` for operational planning matrices: weeks are columns, weekdays are rows, day cells are clickable, and day details open in a large dialog. Only tasks with `calendarVisible` appear directly in a cell by default. Every task can still remain available through the day count and detail list. ## Import ```tsx import { TaskCalendar, type TaskCalendarTask, } from "@/components/patterns/task-calendar"; ``` ## Public API - `startDate` is normalized to Monday. `weeks` defaults to seven and controls the visible planning range. - `calendarVisible` controls direct cell visibility; `getVisibleTasks` can replace that rule. - `getDetailTasks` controls the day detail list. The default keeps every task for that day. - `maxVisibleTasks` limits task pills per cell; set it to `0` to keep all tasks in the detail list only. - `accent` accepts `chart-1` through `chart-5` or `muted`. Accent is supplementary; keep status or assignee available as text. - `dayDialogSize="wide"` expands the detail dialog. `dayDialogSidebarDensity="compact"` tightens only its task selector. - `renderDayDetail` replaces the right detail region; `renderDayHeaderEnd` extends its header. Consumer fetching and product logic remain outside the pattern. - `activeDate`, `activeTaskId`, `onDaySelect` and `onTaskSelect` connect the pattern to controlled product state or routing. ## Public Motion - Week navigation is immediate. Day navigation inside the open dialog uses the shared Calendar slide tokens. - Dialog, Popover and Resource List behavior remains native to the underlying primitives. Reduced motion removes non-essential movement. ## Public Accessibility - Keep day cells, task pills and task-count controls as separate focusable targets with clear accessible names. - Day-navigation buttons in the dialog need explicit previous/next labels and must not compete with task selection. - Keep task identity, status and assignee available as text; accent color is supplementary. - Preserve the native Dialog focus trap, Escape dismissal and labelled title relationship. ## Public Agent Guidance - Use Task Calendar for operational planning; do not turn the date-picker Calendar primitive into a planning matrix. - Put task-type filtering in data or resolver functions rather than hardcoding product categories in the pattern. - Use `renderDayDetail` for product-specific detail content and keep task identity in the provided header. - Keep a direct path from every visible task pill to the full day-detail dialog. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/task-calendar) - [Registry source](https://ui.siteplane.io/r/task-calendar.json) --- # Textarea > Siteplane UI release `0.1.1`. ## Public Purpose Use Textarea for longer free-form input such as notes, comments and multi-line descriptions. ## Import `import { Textarea } from "@/components/ui/textarea";` `import { Button } from "@/components/ui/button";` `import { Form } from "@/components/ui/form";` `import { Label } from "@/components/ui/label";` `import { InputGroup, InputGroupAddon, InputGroupText, InputGroupTextarea } from "@/components/ui/input-group";` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` ## Public API - `Textarea` accepts native textarea props plus `size="sm" | "default" | "lg" | "xl"`. - `size="xl"` keeps the multiline minimum-height contract while adopting the customer-facing 16px field text. Use the surrounding provider's `radius="sm"` personality for the global 8px main corner. - The control supports native vertical resize and content-based auto sizing through the Siteplane styles. - Use `InputGroupTextarea` when leading, trailing or block add-ons belong directly to the same field. ## Public Motion - Textarea itself does not translate or scale. Focus, invalid and disabled states update without changing layout measurements. - Manual resize remains native browser behavior and requires no reduced-motion override. ## Public Accessibility - Provide a visible label; placeholders are examples or hints, not accessible names. - Pair invalid state with `FieldError` and keep required, disabled and loading form state explicit. - Add-ons must not block focus or hide the native vertical resize affordance. ## Public Agent Guidance - Use Input for one-line values and Textarea for multi-line content. - Use `InputGroupTextarea` only for controls or hints directly coupled to the field. - Do not disable native resize or replace labels with placeholders without a product requirement. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/textarea) - [Registry source](https://ui.siteplane.io/r/textarea.json) --- # Theme Toggles > Siteplane UI release `0.1.1`. ## Public Purpose Theme Toggles provides two animated light/dark controls: one shape morph and one layered icon transition. ## Import `import { LayeredThemeToggle, SunMoonMorphToggle } from "@/components/ui/theme-toggles";` ## Public API - Both controls accept uncontrolled `defaultChecked` or controlled `checked` with `onCheckedChange`. - Native checkbox attributes such as `disabled`, `name`, and `aria-label` are forwarded. - `size="sm" | "default" | "lg" | "xl"` overrides the inherited `SiteplaneUIProvider` size locally. - `LayeredThemeToggle checkedIcon="sun" | "moon"` chooses which icon the checked state represents. ## Public Motion - `SunMoonMorphToggle` moves one masked shape and reveals its rays. - `LayeredThemeToggle` transitions actual CSS `transform` values so rotation and scale interpolate together; do not substitute individual transform utilities whose transition property does not match. - Provider and system reduced-motion modes make both state changes immediate. ## Public Accessibility - Keep the checkbox connected to the application theme state and provide a stable accessible name. - The icons are decorative; checked state remains available through the native input. ## Public Agent Guidance - Use controlled state for production theme switching so the icon cannot drift from the document theme. - Reuse these exports in headers and previews instead of copying their SVG or motion styles. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/animated-controls/theme-toggles) - [Registry source](https://ui.siteplane.io/r/theme-toggles.json) --- # Timeline > Siteplane UI release `0.1.1`. ## Public Purpose Use Timeline for read-only chronological history such as activity, status changes or audit events. ## Import ```tsx import { Timeline, TimelineDescription, TimelineItem, TimelineTitle } from "@/components/ui/timeline"; ``` ## Public API - Compose `Timeline`, `TimelineItem`, `TimelineTitle` and `TimelineDescription`. - `TimelineItem` accepts semantic status variants, an optional `marker`, and marker shapes `bar`, `diamond`, `dot` or `ring`. - Keep title, description and optional marker content in DOM order so chronology remains understandable without visual styling. ## Public Motion - Timeline is static by default and does not animate events on initial render. - State accents do not require a reduced-motion override. ## Public Accessibility - Keep DOM order identical to the visual chronological order. - Status must remain readable in text or another non-color cue; marker color alone is not enough. - Timeline is read-only. Use Stepper when people can control or navigate process steps. ## Public Agent Guidance - Use status variants only for real semantic meaning, not decoration. - Do not turn a Timeline item into a hidden workflow button. - Prefer Stepper for interactive progress and Resource List for non-chronological entity collections. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/data-display/timeline) - [Registry source](https://ui.siteplane.io/r/timeline.json) --- # Toast > Siteplane UI release `0.1.1`. ## Public Purpose Use Toast for brief feedback after a real user action when the message does not require a blocking decision. ## Import ```tsx import { ToastProvider, toastManager } from "@/components/ui/toast"; ``` ## Public API - Mount one `ToastProvider` at the app root. Its `position` supports `top-left`, `top-center`, `top-right`, `bottom-left`, `bottom-center` and `bottom-right`. - Use `toastManager.add`, `toastManager.update`, `toastManager.close` and `toastManager.promise(promise, { loading, success, error })` from anywhere below the provider. - Position controls viewport corner, stack direction, entry and exit direction, and the permitted swipe direction. ## Public Motion - Toast stacking, height, opacity, transform and swipe exit use the central Siteplane motion tokens. - The forced `reducedMotionPreset` shortens the tokenized stack transitions. Provider and operating-system reduced-motion modes stop both the continuous loading-icon spin and the cosmetic success/error update replay; messages and dismissal remain functional. ## Public Accessibility - Keep messages concise and announce the result of a real action; do not hide critical instructions only in a transient Toast. - Every Toast remains manually dismissible in addition to its timeout. - Choose wording and urgency that match the result, and avoid firing repeated messages for routine state changes. ## Public Agent Guidance - Mount exactly one app-wide provider and set its position deliberately. - Use `toastManager.promise` for a promise lifecycle instead of manually recreating loading, success and error updates. - Use Alert, inline validation or Dialog for information that must remain visible or requires a decision. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/feedback/toast) - [Registry source](https://ui.siteplane.io/r/toast.json) --- # Toggle > Siteplane UI release `0.1.1`. ## Public Purpose Use Toggle for one two-state button action such as bookmark, mute or text formatting. ## Import `import { Toggle } from "@/components/ui/toggle";` `import { Button } from "@/components/ui/button";` `import { BoldIcon, BookmarkIcon, StarIcon, Volume2Icon, VolumeXIcon } from "lucide-react";` ## Public API - `Toggle` accepts controlled `pressed`, uncontrolled `defaultPressed`, `onPressedChange`, native button props and Base UI's render contract. - `variant="default" | "outline"` and `size="sm" | "default" | "lg" | "xl"` are the complete visual variant set. - Base UI mirrors the pressed state to `aria-pressed` and `data-pressed`. ## Public Motion - Toggle uses the shared button-like hover and press feedback while keeping the persistent pressed state visually distinct. - Reduced motion removes non-essential scale feedback without changing selection state. ## Public Accessibility - Give icon-only Toggles an accessible label and keep controlled labels synchronized with state. - Use Toggle for one action, Toggle Group for related choices and Switch for a direct settings preference. - Preserve `aria-pressed` instead of expressing state with color alone. ## Public Agent Guidance - Use only the documented variants and sizes. - Keep hover, active and persistent pressed state separate. - Do not replace the Base UI pressed-state contract with a local click-state wrapper. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/actions/toggle) - [Registry source](https://ui.siteplane.io/r/toggle.json) --- # Toggle Group > Siteplane UI release `0.1.1`. ## Public Purpose Use Toggle Group for related toggle buttons that share single-select or multi-select state, such as formatting, alignment or view controls. ## Import ``` import { ToggleGroup, ToggleGroupItem, ToggleGroupSeparator, } from "@/components/ui/toggle-group"; ``` `import { Field, FieldDescription, FieldError, FieldLabel } from "@/components/ui/field";` `import { Form } from "@/components/ui/form";` `import { Button } from "@/components/ui/button";` `import { Label } from "@/components/ui/label";` `import { AlignLeftIcon, AlignCenterIcon, AlignRightIcon } from "lucide-react";` ## Public API - `ToggleGroup` accepts single or multiple selection, controlled or uncontrolled value arrays, orientation, disabled state, Button-style size and Toggle variant. - Each `ToggleGroupItem` requires a unique `value` and inherits group size and variant unless explicitly overridden. - `ToggleGroupSeparator` defaults to `orientation="vertical"`; set `orientation="horizontal"` inside a vertical group. - Use `multiple` for several active items; omit it for one active value. ## Public Motion - Pressed background, border and focus feedback use the native Toggle motion contract without changing group measurements. - Reduced motion keeps selection immediate and removes non-essential feedback transition. ## Public Accessibility - Give the group an accessible name and every icon-only item its own `aria-label`. - Keep single- and multi-select semantics aligned with the actual state model. - Pair invalid state with visible error text when the group participates in a form. ## Public Agent Guidance - Use Radio Group when explicit form-choice semantics are more important than compact toolbar presentation. - Match separator orientation to the group direction. - Do not build independent Toggle buttons when their values are meant to share one group state. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/actions/toggle-group) - [Registry source](https://ui.siteplane.io/r/toggle-group.json) --- # Toolbar > Siteplane UI release `0.1.1`. ## Public Purpose Use Toolbar to group equal-priority actions and controls in one compact roving-focus region. ## Import `import { Toolbar } from "@/components/ui/toolbar";` `import { ToolbarButton, ToolbarGroup, ToolbarInput, ToolbarLink, ToolbarSeparator } from "@/components/ui/toolbar";` `import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";` `import { Select, SelectItem, SelectPopup, SelectTrigger, SelectValue } from "@/components/ui/select";` `import { Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";` ## Public API - Compose `Toolbar`, `ToolbarGroup`, `ToolbarButton`, `ToolbarLink`, `ToolbarInput` and `ToolbarSeparator`. - `Toolbar` accepts Base UI toolbar props including `orientation`, `loopFocus` and `focusableWhenDisabled`. - Compose `ToolbarButton` through `render` with an existing Button, Toggle, Select or popup trigger instead of nesting interactive elements. - In a vertical Toolbar, the separator becomes horizontal through the native orientation contract; include it when groups need a real boundary. ## Public Motion - Toolbar itself is static. Nested Button, Toggle, Select and Tooltip primitives retain their own native motion. - No additional toolbar-level reduced-motion handling is required. ## Public Accessibility - Preserve Base UI roving focus and arrow-key navigation. - Give icon-only actions an accessible name; a Tooltip supplements but does not replace the trigger name. - Use inputs sparingly because arrow keys also have text-cursor meaning inside an input. ## Public Agent Guidance - Use `render` to compose existing controls into toolbar items. - Match separator direction to the toolbar orientation and keep related actions in `ToolbarGroup`. - Do not invent a parallel toolbar button visual contract. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/navigation/toolbar) - [Registry source](https://ui.siteplane.io/r/toolbar.json) --- # Tooltip > Siteplane UI release `0.1.1`. ## Public Purpose Use Tooltip for a short, non-essential hint that appears from hover or keyboard focus. It never replaces the trigger's own label or critical visible information. ## Import `import { Tooltip } from "@/components/ui/tooltip";` `import { TooltipCreateHandle, TooltipPopup, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";` `import { TooltipContent } from "@/components/ui/tooltip";` ## Public API - Mount `TooltipProvider` around a dense tooltip group, then compose `Tooltip`, `TooltipTrigger` and `TooltipPopup`. - `TooltipPopup` accepts `side`, `align="start" | "center" | "end"`, `sideOffset`, `alignOffset`, `anchor` and popup props. - `anchor` can position the popup from another element or virtual position instead of the normal trigger. - `TooltipCreateHandle` supports detached trigger relationships; `TooltipContent` remains a compatibility alias for `TooltipPopup`. ## Public Motion - Tooltip uses the shared floating-panel fade, scale and directional offset tokens. - Grouped tooltips can skip the repeated opening delay after the first tooltip; reduced motion remains global. ## Public Accessibility - The trigger needs its own visible name or `aria-label`; Tooltip content is supporting description only. - Do not place interactive controls inside `TooltipPopup`. - Use visible helper text, Alert or Toast for critical and screen-reader-relevant messages. ## Public Agent Guidance - Use `TooltipProvider` for dense groups such as toolbars, not as a replacement for visible labels. - Prefer the normal trigger relationship and use `anchor` or `TooltipCreateHandle` only for a genuine detached case. - Keep portal, positioning and motion internals inside the primitive. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/tooltip) - [Registry source](https://ui.siteplane.io/r/tooltip.json) --- # Validated Form > Siteplane UI release `0.1.1`. ## Public Purpose Validated Form is a `registry:component` for a complete submit flow with loading feedback, a server-style field error and a visible submitted result. ## Import ```tsx import { ValidatedForm } from "@/components/patterns/validated-form"; ``` ## Public API - Render `ValidatedForm` where the built-in public-handle example matches the product flow. - The form starts with `admin` to demonstrate the rejected response. Any other handle demonstrates the submitted state. - Replace the example copy and submit function after installation while preserving Form, Field, FieldError and the loading Button behavior. ## Public Motion - The recipe adds no motion. The loading Button retains its native Siteplane UI feedback. - Reduced motion behavior is inherited from the installed primitives. ## Public Accessibility - The Field label names the Input and FieldError announces validation through the Form contract. - Submission status uses a live status role without moving focus away from the form. ## Public Agent Guidance - Install with `pnpm dlx shadcn@4.16.1 add @siteplane/validated-form`. - Keep server errors in the Form `errors` prop and keep the loading state on the submit Button. - Use a custom form composition when the flow needs multiple fields or different validation behavior. ## Public Links - [Documentation and preview](https://ui.siteplane.io/docs/patterns/validated-form) - [Registry source](https://ui.siteplane.io/r/validated-form.json)