# dotUI > Full documentation for dotUI — a design system platform and component registry built on React Aria Components, Tailwind CSS 4, and TypeScript 5. Each section below is the complete markdown source of one documentation page. --- # Components ## Buttons [#buttons] ## Inputs, controls and form [#inputs-controls-and-form] ## Pickers [#pickers] ## Dates [#dates] ## Feedback [#feedback] ## Collections [#collections] ## Navigation [#navigation] ## Data display [#data-display] ## Colors [#colors] ## Overlays [#overlays] --- # Introduction **dotUI** is a design system platform and component registry that lets you generate a UI library that looks like your product, not a preset. You know how traditional UI libraries force a default aesthetic? Even the "Open Code" approach still requires hours (or weeks) of refactoring tokens, tweaking styles, and rewriting components. dotUI removes that friction. You build your design system with our editor in a few clicks, then install it via the shadcn CLI or export it to your favorite AI tool such as [v0](https://v0.dev). ## The foundational layer [#the-foundational-layer] I evaluated all major options for the foundational layer. Radix is effectively unmaintained, so the choice came down to [Base UI](https://base-ui.com) and [React Aria](https://react-spectrum.adobe.com/react-aria/index.html). While Base UI is very promising, it's still quite new and missing critical features that dotUI relies on. **React Aria** was the clear winner: battle-tested, comprehensive, and **incredibly flexible**. I've taken its powerful, unstyled primitives and given them a design system that looks like your product. ## API philosophy [#api-philosophy] ### Composition [#composition] The API is designed around composition, where each component generally has a 1:1 relationship with a single DOM element. This makes it easy to style every element, and control the layout and DOM order as needed to implement any pattern. ```tsx ``` ### With default children [#with-default-children] I've been using shadcn/ui and radix in several projects now, and yes, composition gives you much more flexibility, but it also adds too much boilerplate code. ### Reusable components [#reusable-components] Most UI libraries claim to be "composable" but end up creating duplicate components for every use case. You end up memorizing parallel APIs for the exact same pattern: You'll find MenuPopover, ComboboxPopover, DialogPopover, SelectPopover, when really they're just a **Popover** component. You'll also find "MenuTrigger", "ComboboxTrigger", "DialogTrigger", "ModalTrigger", "AlertDialogTrigger", "PopoverTrigger", when a "Button" should work everywhere. **dotUI gives you true reusable primitives across the entire library.** One `Popover` component that works with menus, dialogs, selects, and comboboxes. One `Button` component that works as any trigger. One `Input` component that works in text fields, search fields, and number fields. One `Label` component that works everywhere you need a label. This isn't just about a few components—it's a fundamental architectural principle. Every component is a true primitive that composes naturally with others, eliminating duplication and giving you real reusability. ## Documentation [#documentation] ### Showing rather than telling [#showing-rather-than-telling] Each component in dotUI comes with an interactive playground where you can play with the props and see the changes in code/preview in real time. ### Real-world examples [#real-world-examples] Each component page includes multiple real-world examples showing how to use the component in actual application scenarios. From simple use cases to complex compositions, you'll see exactly how components work together.
## Built for AI [#built-for-ai] dotUI is built for humans and AI. All components were written with a clear, consistent, and predictable API. ## Get involved [#get-involved] If you have any feedback, a bug report, or a feature request, you can open an issue on our [GitHub](https://github.com/mehdibha/dotUI/issues) or just DM me on X at [@mehdibha](https://x.com/mehdibha). Contributions are also welcome! I would be happy to see more people contributing to the project and making it better. --- # Installation ## App requirements [#app-requirements] Before you begin, make sure your project meets these requirements: * [React 19](https://react.dev) * [Tailwind CSS 4](https://tailwindcss.com/docs/v4-beta) * [TypeScript 5](https://www.typescriptlang.org/) ## Automatic installation [#automatic-installation] ### Initialize shadcn CLI [#initialize-shadcn-cli] Start by setting up the shadcn CLI in your project: npm pnpm yarn bun ```bash npx shadcn@latest init --no-base-style ``` ```bash pnpm dlx shadcn@latest init --no-base-style ``` ```bash yarn dlx shadcn@latest init --no-base-style ``` ```bash bun x shadcn@latest init --no-base-style ``` ### Configure your registry [#configure-your-registry] Choose or create a style, then update your `components.json` file to use the selected style. ```json title="components.json" { "style": "minimalist", // or "mehdibha/minimalist" "registries": { "@dotui": "https://dotui.org/r/{style}/{name}" } } ``` ### Init your style [#init-your-style] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/base ``` ```bash pnpm dlx shadcn@latest add @dotui/base ``` ```bash yarn dlx shadcn@latest add @dotui/base ``` ```bash bun x shadcn@latest add @dotui/base ``` ### Add components [#add-components] You can now add components to your project. npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/button ``` ```bash pnpm dlx shadcn@latest add @dotui/button ``` ```bash yarn dlx shadcn@latest add @dotui/button ``` ```bash bun x shadcn@latest add @dotui/button ``` To add all the components at once, you can use the `@dotui/all`. npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/all ``` ```bash pnpm dlx shadcn@latest add @dotui/all ``` ```bash yarn dlx shadcn@latest add @dotui/all ``` ```bash bun x shadcn@latest add @dotui/all ``` ### You're done! [#youre-done] --- # Accordion ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/accordion ``` ```bash pnpm dlx shadcn@latest add @dotui/accordion ``` ```bash yarn dlx shadcn@latest add @dotui/accordion ``` ```bash bun x shadcn@latest add @dotui/accordion ``` ## Anatomy [#anatomy] ```tsx import { Accordion } from '@/components/ui/accordion' import { Disclosure, DisclosurePanel, DisclosureTrigger, } from '@/components/ui/disclosure' ``` ```tsx Disclosure Heading Disclosure Panel Disclosure Heading Disclosure Panel ``` ## Open state [#open-state] Expanded items are tracked by each `Disclosure`'s `id`. Give the group `defaultExpandedKeys` for uncontrolled state, or `expandedKeys` with `onExpandedChange` to control it — both are a `Set` of ids. Pass `allowsMultipleExpanded` to let the set hold more than one id at a time. ```tsx How do I get started? ``` ## Examples [#examples] ## API Reference [#api-reference] ### Accordion [#accordion] --- # Alert ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/alert ``` ```bash pnpm dlx shadcn@latest add @dotui/alert ``` ```bash yarn dlx shadcn@latest add @dotui/alert ``` ```bash bun x shadcn@latest add @dotui/alert ``` ## Usage [#usage] Use alerts to display important messages that require user attention. ```tsx import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert' ``` ```tsx Alert Title Alert description ``` ## Anatomy [#anatomy] An alert composes a title, a description, and an optional action. To add an icon, place an icon element as the alert's first child — styles pick it up positionally, there is no icon prop. ```tsx import { Alert, AlertTitle, AlertDescription, AlertAction, } from '@/components/ui/alert' import { CircleAlert } from 'lucide-react' ; Title Description Action ``` `AlertAction` renders at the end and typically wraps a `Button` or `Badge`. ## Examples [#examples] ## API Reference [#api-reference] ### Alert [#alert] ### AlertTitle [#alerttitle] ### AlertDescription [#alertdescription] ### AlertAction [#alertaction] --- # Avatar ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/avatar ``` ```bash pnpm dlx shadcn@latest add @dotui/avatar ``` ```bash yarn dlx shadcn@latest add @dotui/avatar ``` ```bash bun x shadcn@latest add @dotui/avatar ``` ## Usage [#usage] Use avatars to represent users or entities with an image or initials. ```tsx import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar' ``` ```tsx MB ``` ## Anatomy [#anatomy] ```tsx import { Avatar, AvatarImage, AvatarFallback, AvatarBadge, AvatarGroup, AvatarGroupCount, } from '@/components/ui/avatar' ``` ```tsx {/* ... */} ``` `Avatar` is the container. `AvatarImage` renders the picture, `AvatarFallback` the initials or icon shown in its place, and `AvatarBadge` a status indicator overlaid on the corner. `AvatarGroup` stacks avatars with an overlapping layout, and `AvatarGroupCount` shows the remaining count. ## Fallback [#fallback] `AvatarImage` and `AvatarFallback` share loading state, so you always render both. `AvatarImage` appears only once its `src` finishes loading; until then — and if loading fails — `AvatarFallback` is shown instead. ## Examples [#examples] ## API Reference [#api-reference] ### Avatar [#avatar] ### AvatarImage [#avatarimage] ### AvatarFallback [#avatarfallback] ### AvatarBadge [#avatarbadge] ### AvatarGroup [#avatargroup] ### AvatarGroupCount [#avatargroupcount] --- # Badge ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/badge ``` ```bash pnpm dlx shadcn@latest add @dotui/badge ``` ```bash yarn dlx shadcn@latest add @dotui/badge ``` ```bash bun x shadcn@latest add @dotui/badge ``` ## Usage [#usage] Use badges to highlight status, categorize items, or show counts. ```tsx import { Badge } from '@/components/ui/badge' ``` ```tsx Badge ``` ## Examples [#examples] ## API Reference [#api-reference] --- # Breadcrumbs ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/breadcrumbs ``` ```bash pnpm dlx shadcn@latest add @dotui/breadcrumbs ``` ```bash yarn dlx shadcn@latest add @dotui/breadcrumbs ``` ```bash bun x shadcn@latest add @dotui/breadcrumbs ``` ## Usage [#usage] Use breadcrumbs to display a hierarchy of links showing the user's location in a site or application. ```tsx import { BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, Breadcrumbs, } from '@/components/ui/breadcrumbs' ``` ```tsx Home Components Breadcrumbs ``` ## Anatomy [#anatomy] Each `BreadcrumbItem` wraps a `BreadcrumbLink` and its own `BreadcrumbSeparator`. The separator lives inside the item, so omit it on the last one. It defaults to a chevron; pass `children` to override. ```tsx Home / Current ``` ## Framework Setup [#framework-setup] By default, `BreadcrumbLink` renders a plain `` tag. To integrate with your framework's router, override the component in your project's `breadcrumbs.tsx`. ### Next.js [#nextjs] ```tsx title="ui/breadcrumbs.tsx" import RouterLink from "next/link"; // [!code highlight] // .. const BreadcrumbLink = ({ className, ...props }: BreadcrumbLinkProps) => { return ( { "href" in domProps ? ( } href={href} {...domProps} /> ) : ( } {...domProps} /> ) } className={composeRenderProps(className, (className) => link({ className }), )} {...props} /> ); }; ``` ### TanStack Start [#tanstack-start] ```tsx title="ui/breadcrumbs.tsx" // [!code highlight:2] import { Link as RouterLink } from '@tanstack/react-router' import type { ToOptions } from '@tanstack/react-router' // .. interface BreadcrumbLinkProps extends Omit< React.ComponentProps, 'href' > { href?: string | ToOptions // [!code highlight] } const BreadcrumbLink = ({ className, ...props }: BreadcrumbLinkProps) => { return ( { if (typeof href === 'object') { return ( } {...href} {...domProps} /> ) } if (typeof href === 'string') { return ( } href={href} {...domProps} /> ) } return }} className={composeRenderProps(className, (className) => link({ className }), )} {...props} /> ) } ``` ## Examples [#examples] ## API Reference [#api-reference] ### Breadcrumbs [#breadcrumbs] ### BreadcrumbItem [#breadcrumbitem] ### BreadcrumbLink [#breadcrumblink] ### BreadcrumbSeparator [#breadcrumbseparator] --- # Button ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/button ``` ```bash pnpm dlx shadcn@latest add @dotui/button ``` ```bash yarn dlx shadcn@latest add @dotui/button ``` ```bash bun x shadcn@latest add @dotui/button ``` ## Usage [#usage] Button allow users to initiate an action or command with mouse, touch or keyboard interaction.
The button's label indicates the purpose of the action to the user. You may also include an icon for additional context. ```tsx import { Button } from '@dotui/registry/ui/button' ``` ```tsx ``` ## As a link [#as-a-link] Use `LinkButton` with `href` to render a navigation control styled as a button. Internal paths integrate with the client router; external URLs render a plain `
`. ```tsx import { LinkButton } from '@dotui/registry/ui/button' ;Dashboard ``` ## Examples [#examples] ## API Reference [#api-reference] ### Button [#button] ### LinkButton [#linkbutton] --- # Calendar ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/calendar ``` ```bash pnpm dlx shadcn@latest add @dotui/calendar ``` ```bash yarn dlx shadcn@latest add @dotui/calendar ``` ```bash bun x shadcn@latest add @dotui/calendar ``` ## Usage [#usage] Use `Calendar` to allow users to select a single date value. ```tsx import { Calendar } from '@/components/ui/calendar' ``` ```tsx ``` Use `RangeCalendar` to let users select a contiguous range of dates. ```tsx import { RangeCalendar } from '@/components/ui/calendar' ``` ```tsx ``` ## Composition [#composition] For full control, compose the calendar from its parts. ```tsx import { Calendar, CalendarHeader, CalendarHeading, CalendarGrid, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell, } from '@/components/ui/calendar' ``` ```tsx {(day) => {day}} {(date) => } ``` ## Value [#value] Calendar values use [`@internationalized/date`](https://react-spectrum.adobe.com/internationalized/date/) objects. Pass `defaultValue` for uncontrolled state, or `value` with `onChange` to control it. ```tsx import { parseDate } from '@internationalized/date' ; ``` ```tsx import { useState } from 'react' import { parseDate } from '@internationalized/date' import type { DateValue } from 'react-aria-components' const [value, setValue] = useState(parseDate('2020-02-03')) ; ``` ## Date availability [#date-availability] Constrain the selectable range with `minValue` and `maxValue`, or disable individual dates with `isDateUnavailable`. All take [`@internationalized/date`](https://react-spectrum.adobe.com/internationalized/date/) values, so derive them from `today(getLocalTimeZone())`. ```tsx import { getLocalTimeZone, today } from '@internationalized/date' const now = today(getLocalTimeZone()) ; [0, 6].includes(date.toDate(getLocalTimeZone()).getDay()) } /> ``` ## Examples [#examples] ## API Reference [#api-reference] ### Calendar [#calendar] ### RangeCalendar [#rangecalendar] ### CalendarHeader [#calendarheader] ### CalendarGrid [#calendargrid] ### CalendarGridHeader [#calendargridheader] ### CalendarHeaderCell [#calendarheadercell] ### CalendarGridBody [#calendargridbody] ### CalendarCell [#calendarcell] --- # Card ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/card ``` ```bash pnpm dlx shadcn@latest add @dotui/card ``` ```bash yarn dlx shadcn@latest add @dotui/card ``` ```bash bun x shadcn@latest add @dotui/card ``` ## Usage [#usage] ```tsx import { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '@/components/ui/card' ``` ```tsx Card Title Card Description Card Action

Card Content

Card Footer

``` ## Anatomy [#anatomy] ```tsx ``` `CardHeader` holds the `CardTitle`, `CardDescription`, and an optional `CardAction` pinned at the end of the header row. `CardContent` is the main body and `CardFooter` sits below it, usually for actions. ## Size [#size] Pass `size="sm"` to `Card` for a more compact card with tighter spacing. ```tsx {/* ... */} ``` ## Section borders [#section-borders] Add `border-b` to `CardHeader` or `border-t` to `CardFooter` to visually separate them from the content. ```tsx {/* ... */} ``` ## Examples [#examples] ## API Reference [#api-reference] ### Card [#card] ### CardHeader [#cardheader] ### CardTitle [#cardtitle] ### CardDescription [#carddescription] ### CardAction [#cardaction] ### CardContent [#cardcontent] ### CardFooter [#cardfooter] --- # Chart Charts are a thin, themeable layer over [Recharts](https://recharts.org). You write a chart with Recharts' own components — `BarChart`, `Bar`, `XAxis`, and the rest — and wrap them in `ChartContainer`, which maps your series to your design system's colors, handles light and dark theming, and makes the chart responsive. The tooltip, legend, and a visually-hidden data table are styled to match the rest of your components, so a chart looks at home next to a card or a button with no extra work. Use the primitives directly to build any chart Recharts supports, or install a ready-made family and copy the variant you need. Browse every variant on the [charts page](/charts). ## Installation [#installation] The primitives — `ChartContainer`, `ChartTooltip`, `ChartLegend`, their `*Content` variants, and `ChartDataTable` — ship as a single `chart` item: npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/chart ``` ```bash pnpm dlx shadcn@latest add @dotui/chart ``` ```bash yarn dlx shadcn@latest add @dotui/chart ``` ```bash bun x shadcn@latest add @dotui/chart ``` Each family — bar, line, area, pie, radar, and radial — ships as its own item with a curated set of variants, and pulls in `chart` and `card` automatically: npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/chart-bar ``` ```bash pnpm dlx shadcn@latest add @dotui/chart-bar ``` ```bash yarn dlx shadcn@latest add @dotui/chart-bar ``` ```bash bun x shadcn@latest add @dotui/chart-bar ``` You only need to add the `chart` item directly when you are composing a chart by hand. Installing any family brings the primitives along with it. ## Usage [#usage] Import the primitives you need alongside the Recharts components for your chart type: ```tsx import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts' import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, } from '@/components/ui/chart' ``` A chart is built from three pieces: your **data** (an array of rows), a **config** that describes each series, and the **Recharts chart** wrapped in `ChartContainer`. ```tsx const chartData = [ { month: 'January', desktop: 186 }, { month: 'February', desktop: 305 }, { month: 'March', desktop: 237 }, ] const chartConfig = { desktop: { label: 'Desktop', color: 'var(--chart-1)' }, } satisfies ChartConfig export function Example() { return ( } /> ) } ``` `ChartContainer` reads `chartConfig` and exposes each series key as a CSS variable — the `desktop` key becomes `var(--color-desktop)`, which the `Bar` references with its `fill`. This name-keyed indirection is the heart of the API: you assign a color once in config, and every Recharts element, the tooltip, and the legend pick it up by name. There is no color array to keep aligned with your data. ### Chart config [#chart-config] `config` maps each series key to a `label`, a `color` (or a per-theme `theme`), and an optional `icon`: ```tsx const chartConfig = { desktop: { label: 'Desktop', color: 'var(--chart-1)' }, mobile: { label: 'Mobile', color: 'var(--chart-2)' }, } satisfies ChartConfig ``` `ChartContainer` turns each entry into a `--color-` CSS variable you reference from Recharts (`fill="var(--color-desktop)"`), and the tooltip and legend read it for labels and icons. Use `satisfies ChartConfig` rather than a type annotation so TypeScript keeps the exact keys, which makes the matching `var(--color-)` names easy to keep in sync. Because config is separate from data, a key with no series of its own — an axis category, for example — can still carry a label and a color, which is how per-category coloring on pie and radial charts works. ## Theming [#theming] Series colors come from a categorical palette of five slots, `--chart-1` through `--chart-5`. Your design system derives them from its theme hues, so charts stay on-brand and adapt to light and dark automatically — no per-mode values to maintain. The palette is editable under **Chart colors** in the [editor](/create), and updates live as you tweak it on the [charts page](/charts). Point each series at a slot through its config color: ```tsx const chartConfig = { desktop: { label: 'Desktop', color: 'var(--chart-1)' }, mobile: { label: 'Mobile', color: 'var(--chart-2)' }, } satisfies ChartConfig ``` A color can be any CSS value, so you are not limited to the palette. To set a different color per mode, use `theme` instead of `color`: ```tsx const chartConfig = { desktop: { label: 'Desktop', theme: { light: '#2563eb', dark: '#60a5fa' } }, } satisfies ChartConfig ``` For per-category colors — common on pie and radial charts — give each row its own `fill` using the same `var(--color-)` names: ```tsx const chartData = [ { browser: 'chrome', visitors: 275, fill: 'var(--color-chrome)' }, { browser: 'safari', visitors: 200, fill: 'var(--color-safari)' }, ] ``` ## Tooltip and legend [#tooltip-and-legend] `ChartTooltip` and `ChartLegend` are the Recharts primitives; `ChartTooltipContent` and `ChartLegendContent` are the styled, config-aware contents you pass to them. Both resolve labels, colors, and icons from your config, so they stay consistent with the chart without extra wiring: ```tsx } /> } /> ``` `ChartTooltipContent` accepts an `indicator` of `dot`, `line`, or `dashed` to change the marker next to each value, plus `hideLabel` and `hideIndicator` to trim it down. `ChartLegendContent` accepts `hideIcon` and a `nameKey` for reading labels from a different config key. See the [API reference](#api-reference) for the full set of props. ## Accessibility [#accessibility] Charts encode data with color and position, which is invisible to assistive technology, so accessibility is handled in two layers. First, pass `accessibilityLayer` to the Recharts chart. It enables keyboard navigation and screen-reader announcements as the user moves across data points: ```tsx ``` Second — and unique to dotUI — every family demo renders `ChartDataTable` alongside the chart: a visually-hidden `` derived from the same `data` and `config`. It exposes the underlying figures to screen readers and other assistive tools without affecting the visual layout, giving you a real data-table fallback for free: ```tsx ``` `labelKey` names the field used for each row's header — the x-axis category on cartesian charts, or the slice name on pie and radial charts. `ChartDataTable` adapts to your data's shape on its own: one column per series for bar, line, area, and radar; a two-column category/value table for pie and radial. Pass it the same `data` and `config` you gave `ChartContainer` and it stays in sync. ## Families [#families] Each family is a curated set of variants — install one, then copy the variant you need. Browse them all on the [charts page](/charts). ## API Reference [#api-reference] ### ChartContainer [#chartcontainer] ### ChartTooltipContent [#charttooltipcontent] ### ChartLegendContent [#chartlegendcontent] ### ChartDataTable [#chartdatatable] --- # Checkbox Group ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/checkbox-group ``` ```bash pnpm dlx shadcn@latest add @dotui/checkbox-group ``` ```bash yarn dlx shadcn@latest add @dotui/checkbox-group ``` ```bash bun x shadcn@latest add @dotui/checkbox-group ``` ## Usage [#usage] Use `CheckboxGroup` to allow users to select multiple items from a list of options. ```tsx import { CheckboxGroup } from '@/components/ui/checkbox-group' import { Checkbox, CheckboxControl } from '@/components/ui/checkbox' import { FieldGroup, Label } from '@/components/ui/field' ``` ```tsx ``` ## Selection [#selection] Use `defaultValue` for uncontrolled checkbox groups, or `value` and `onChange` for controlled checkbox groups. ```tsx {/* ... */} ``` ```tsx const [frameworks, setFrameworks] = useState(['nextjs']) ; {/* ... */} ``` ## Validation [#validation] Set `isRequired` to require a selection, or drive `isInvalid` yourself. Render errors with `FieldError` — with the default `validationBehavior="native"` it surfaces the browser's message on form submit; use `validationBehavior="aria"` to validate live without native form semantics. ```tsx import { CheckboxGroup } from '@/components/ui/checkbox-group' import { FieldError, FieldGroup, Label } from '@/components/ui/field' ; {/* ... */} Please select a framework. ``` ## Examples [#examples] ## API Reference [#api-reference] ### CheckboxGroup [#checkboxgroup] ### Checkbox [#checkbox] --- # Checkbox ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/checkbox ``` ```bash pnpm dlx shadcn@latest add @dotui/checkbox ``` ```bash yarn dlx shadcn@latest add @dotui/checkbox ``` ```bash bun x shadcn@latest add @dotui/checkbox ``` ## Usage [#usage] Use `Checkbox` to allow users to select multiple items from a list of individual items, or to mark one individual item as selected. ```tsx import { Checkbox, CheckboxControl } from '@/components/ui/checkbox' import { Label } from '@/components/ui/field' ``` ```tsx ``` ## Anatomy [#anatomy] Pass a plain string and `Checkbox` wraps it in a `CheckboxControl` and `Label` for you. Pass elements instead and you compose the tree yourself — `CheckboxControl` renders the `CheckboxIndicator` (the box) and can hold `FieldContent` with a `Label` and `Description`. ```tsx import { Checkbox, CheckboxControl, CheckboxIndicator, } from '@/components/ui/checkbox' import { Description, FieldContent, Label } from '@/components/ui/field' ; Please read them before proceeding ``` ## Selection [#selection] The checkbox is selected or not. Use `defaultSelected` for uncontrolled state, or `isSelected` with `onChange` to control it. ```tsx const [isSelected, setIsSelected] = React.useState(false) Accept terms ``` ## Examples [#examples] ## API Reference [#api-reference] ### Checkbox [#checkbox] ### CheckboxControl [#checkboxcontrol] ### CheckboxIndicator [#checkboxindicator] --- # Color Area ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/color-area ``` ```bash pnpm dlx shadcn@latest add @dotui/color-area ``` ```bash yarn dlx shadcn@latest add @dotui/color-area ``` ```bash bun x shadcn@latest add @dotui/color-area ``` ## Usage [#usage] Use color areas to allow users to select a color from a two-dimensional gradient. ```tsx import { ColorArea } from '@/components/ui/color-area' import { ColorThumb } from '@/components/ui/color-thumb' ``` ```tsx ``` ## Anatomy [#anatomy] A `ColorArea` renders the gradient and positions a `ColorThumb`. If you omit children, a default `ColorThumb` is rendered for you. ```tsx import { ColorArea } from '@/components/ui/color-area' import { ColorThumb } from '@/components/ui/color-thumb' ; ``` ## Value [#value] Use `defaultValue` for uncontrolled state, or `value` with `onChange` to control it. Uncontrolled values accept a color string; controlled values are `Color` objects created with `parseColor`. ```tsx import { parseColor } from 'react-aria-components' const [value, setValue] = React.useState(parseColor('hsl(0, 100%, 50%)')) ``` ## Channels [#channels] `xChannel` and `yChannel` map two channels of the color to the horizontal and vertical axes of the gradient. ```tsx ``` ## Examples [#examples] ## API Reference [#api-reference] ### ColorArea [#colorarea] ### ColorThumb [#colorthumb] --- # Color Editor ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/color-editor ``` ```bash pnpm dlx shadcn@latest add @dotui/color-editor ``` ```bash yarn dlx shadcn@latest add @dotui/color-editor ``` ```bash bun x shadcn@latest add @dotui/color-editor ``` ## Usage [#usage] Use a color editor to let users adjust a color with a saturation/brightness area, channel sliders, and format-aware fields. Standalone, it manages its own color value; inside a [Color Picker](/docs/components/color-picker), it edits the picker's color instead. ```tsx import { ColorEditor } from '@/components/ui/color-editor' ``` ```tsx ``` ## Anatomy [#anatomy] `ColorEditor` renders a saturation/brightness area with channel sliders, then a row of format-aware fields. Omit children for the default layout, or compose the parts yourself. ```tsx import { ColorEditor, ColorEditorArea, ColorEditorFields, } from '@/components/ui/color-editor' ``` ```tsx ``` * `ColorEditorArea` — the color area, hue slider, and optional alpha slider. * `ColorEditorFields` — channel inputs for the current format, with an optional format selector. ## Composition [#composition] The default children render an area row and a fields row. Pass your own children to reorder, drop, or extend them — for example, dropping a swatch picker between the two parts. ```tsx {/* ... */} ``` ## Value [#value] The value is a React Aria `Color`. Use `defaultValue` for uncontrolled state, or `value` with `onChange` to control it. Pass a hex string (including alpha, e.g. `#5100FF80`) or a `Color` from `parseColor`. ```tsx ``` Inside a [Color Picker](/docs/components/color-picker), the editor adopts the picker's color — `value`, `defaultValue`, and `onChange` are ignored. ## Color format [#color-format] `ColorEditorFields` picks its channel inputs from the current format. Set the initial format with `defaultFormat` (`hex`, `rgb`, `hsl`, or `hsb`), or control it with `format` and `onFormatChange`. ```tsx ``` ## Examples [#examples] ## API Reference [#api-reference] ### ColorEditor [#coloreditor] ### ColorEditorArea [#coloreditorarea] ### ColorEditorFields [#coloreditorfields] --- # Color Field ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/color-field ``` ```bash pnpm dlx shadcn@latest add @dotui/color-field ``` ```bash yarn dlx shadcn@latest add @dotui/color-field ``` ```bash bun x shadcn@latest add @dotui/color-field ``` ## Usage [#usage] Use color fields to allow users to edit a color value using a text field. ```tsx import { ColorField } from '@/components/ui/color-field' import { Label } from '@/components/ui/field' import { Input } from '@/components/ui/input' ``` ```tsx ``` ## Anatomy [#anatomy] A `ColorField` wraps a `Label` and an `Input`. To attach an icon, replace the bare `Input` with an `InputGroup` and place an `InputGroupAddon` on either side. ```tsx import { ColorField } from '@/components/ui/color-field' import { Label } from '@/components/ui/field' import { Input, InputGroup, InputGroupAddon } from '@/components/ui/input' ; ``` ## Value [#value] The value is a `Color` object. Pass a hex string to `defaultValue` for uncontrolled state, or control it with `value` + `onChange` using `parseColor`, and read it back with `color.toString('hex')`. ```tsx import { type Color, parseColor } from 'react-aria-components' const [color, setColor] = React.useState(parseColor('#7f007f')) ``` ## Channels [#channels] Set `colorSpace` and `channel` to bind the field to a single channel of a color space instead of the full hex value. ```tsx ``` ## Examples [#examples] ## API Reference [#api-reference] --- # Color Picker ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/color-picker ``` ```bash pnpm dlx shadcn@latest add @dotui/color-picker ``` ```bash yarn dlx shadcn@latest add @dotui/color-picker ``` ```bash bun x shadcn@latest add @dotui/color-picker ``` ## Usage [#usage] Use color pickers to allow users to select a color from a palette or input a custom color value. The editing surface inside the popover is a [Color Editor](/docs/components/color-editor). ```tsx import { Button } from '@/components/ui/button' import { ColorEditor } from '@/components/ui/color-editor' import { ColorPicker } from '@/components/ui/color-picker' import { DialogContent } from '@/components/ui/dialog' import { Popover } from '@/components/ui/popover' ``` ```tsx Canada France ``` ## Anatomy [#anatomy] `Combobox` is assembled from the field, input, list-box, and popover primitives. `InputGroup` wraps the text `Input` and an `InputGroupAddon` trigger; the `Popover` holds a `ListBox` of `ListBoxItem` options. ```tsx ``` ## Value [#value] The value is the selected item's key. Use `defaultSelectedKey` for uncontrolled state, or `selectedKey` with `onSelectionChange` to control it. ```tsx const [country, setCountry] = React.useState('tn') {/* ... */} ``` ## Multiple selection [#multiple-selection] Set `selectionMode="multiple"` to select several items; the value becomes an array of keys via `defaultValue`/`value`. Render `ComboboxValue` with a function to display the selected items as a `TagGroup`. ```tsx selectionMode="multiple" defaultValue={['next']} > > {({ selectedItems, state }) => ( state.setValue(state.value.filter((k) => !keys.has(k))) } > {(item) => {item.name}} )} {/* ... */} ``` ## Content [#content] Pass static `ListBoxItem` children, or render options from data with `items` and a render function. Give each item a stable `id`, and a `textValue` when its content isn't a plain string. ```tsx {(item) => ( {item.label} )} ``` ## Sections [#sections] Group options with `ListBoxSection` and `ListBoxSectionHeader` — see the [Sections](#examples) demo. ## Async loading [#async-loading] Source items from `useAsyncList` and pass `isLoading` to the `ListBox` to show a loading state while fetching. ```tsx const list = useAsyncList({ async load({ signal }) { /* ... */ } }) {(item) => {item.name}} ``` ## Custom values [#custom-values] Set `allowsCustomValue` to let users submit text that doesn't match any option. ```tsx {/* ... */} ``` ## Examples [#examples] ## API Reference [#api-reference] ### Combobox [#combobox] ### ComboboxValue [#comboboxvalue] --- # Command ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/command ``` ```bash pnpm dlx shadcn@latest add @dotui/command ``` ```bash yarn dlx shadcn@latest add @dotui/command ``` ```bash bun x shadcn@latest add @dotui/command ``` ## Usage [#usage] `Command` is a thin wrapper around React Aria's [Autocomplete](https://react-spectrum.adobe.com/react-aria/Autocomplete.html). It ships no input or list of its own — you compose it from primitives you already have: a [`SearchField`](/docs/components/search-field) for the query and a [`ListBox`](/docs/components/list-box) for the commands. As the user types, the list is filtered down to the items whose text matches the query. ```tsx import { SearchIcon } from 'lucide-react' import { Command } from '@/components/ui/command' import { Input, InputGroup, InputGroupAddon } from '@/components/ui/input' import { ListBox, ListBoxItem } from '@/components/ui/list-box' import { SearchField } from '@/components/ui/search-field' ``` ```tsx console.log(key)}> Calendar Search Emoji Calculator ``` Filtering matches against each item's **`textValue`**. String children set it automatically, but items with rich content — an icon, a keyboard shortcut — need an explicit `textValue` to stay searchable. Group related commands with `ListBoxSection` and `ListBoxSectionHeader`, and respond to a selection with the list's `onAction` callback. Because the input and the list are ordinary primitives, anything they support works here too: put the `Command` inside a `Modal` for a `⌘K` palette, inside a `Popover` to filter a `Select`, or swap the `ListBox` for a `TagGroup`. See the [examples](#examples) below. ## Anatomy [#anatomy] `Command` re-exports the underlying primitives under `Command*` aliases so the whole palette imports from one place: `CommandInput` is a `SearchField`, `CommandContent` is a `ListBox`, and `CommandItem`, `CommandSection`, and `CommandSectionHeader` map to their `ListBox*` counterparts. ```tsx import { Command, CommandContent, CommandInput, CommandItem, CommandSection, CommandSectionHeader, } from '@/components/ui/command' ; ``` ## Filtering [#filtering] Matching is case- and punctuation-insensitive by default (`sensitivity: 'base'`, `ignorePunctuation: true`). Pass `filter` with any [`Intl.CollatorOptions`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator#options) to tune it — for example make matching accent-sensitive. ```tsx {/* … */} ``` ## Examples [#examples] ## API Reference [#api-reference] `Command` renders only the autocomplete wrapper. The input is a [`SearchField`](/docs/components/search-field) and the list is a [`ListBox`](/docs/components/list-box) — `CommandInput` and `CommandContent` are re-exported aliases for those primitives, so refer to their pages for the full set of props. ### Command [#command] ### CommandInput [#commandinput] ### CommandContent [#commandcontent] --- # Context Menu ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/context-menu ``` ```bash pnpm dlx shadcn@latest add @dotui/context-menu ``` ```bash yarn dlx shadcn@latest add @dotui/context-menu ``` ```bash bun x shadcn@latest add @dotui/context-menu ``` ## Usage [#usage] Wrap the trigger content and the menu's `Popover` inside `ContextMenu`. The menu opens at the pointer when the trigger is right-clicked, or after a long press on touch devices. ```tsx import { ContextMenu } from '@/components/ui/context-menu' import { MenuContent, MenuItem } from '@/components/ui/menu' import { Popover } from '@/components/ui/popover' ``` ```tsx Right click me Account settings Create team Command menu Log out ``` ## Anatomy [#anatomy] `ContextMenu` is a right-click / long-press trigger wrapping a `Popover` and a `MenuContent`. Items, submenus (`MenuSub`), and every menu concept come from the [Menu](/docs/components/menu) component. ```tsx import { ContextMenu } from '@/components/ui/context-menu' import { MenuContent, MenuItem, MenuSub } from '@/components/ui/menu' import { Popover } from '@/components/ui/popover' import { Separator } from '@/components/ui/separator' ; {/* trigger content */} ``` ## Open state [#open-state] The menu is uncontrolled by default. Pass `defaultOpen` for uncontrolled state, or `isOpen` with `onOpenChange` to control it. Use `isDisabled` to suppress the trigger entirely. ```tsx const [isOpen, setIsOpen] = React.useState(false) {/* ... */} ``` ## Examples [#examples] ## API Reference [#api-reference] ### ContextMenu [#contextmenu] --- # Date Field ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/date-field ``` ```bash pnpm dlx shadcn@latest add @dotui/date-field ``` ```bash yarn dlx shadcn@latest add @dotui/date-field ``` ```bash bun x shadcn@latest add @dotui/date-field ``` ## Usage [#usage] Use `DateField` to allow users to enter and edit date values using a keyboard. ```tsx import { DateField } from '@/components/ui/date-field' import { DateInput } from '@/components/ui/input' import { Label } from '@/components/ui/field' ``` ```tsx ``` ## Anatomy [#anatomy] `DateField` wraps a `Label`, a `DateInput` that renders the individually editable segments, and optionally a `Description` and `FieldError`. ```tsx import { DateField } from '@/components/ui/date-field' import { DateInput } from '@/components/ui/input' import { Description, FieldError, Label } from '@/components/ui/field' ; ``` ## Value [#value] Values are [`@internationalized/date`](https://react-spectrum.adobe.com/internationalized/date/index.html) objects. Use `defaultValue` for uncontrolled state, or `value` with `onChange` to control it. ```tsx import { parseDate } from '@internationalized/date' ; ``` Set `granularity` (`day`, `hour`, `minute`, or `second`) to control which segments render, and constrain the range with `minValue` and `maxValue`. ## Validation [#validation] Mark the field with `isRequired`, or drive it with `isInvalid` and a custom `validate`. Errors surface through `FieldError`. ```tsx Please select a date. ``` ## Examples [#examples] ## API Reference [#api-reference] ### DateField [#datefield] ### DateInput [#dateinput] ### DateSegment [#datesegment] --- # Date Picker ## Installation [#installation] npm pnpm yarn bun ```bash npx shadcn@latest add @dotui/date-picker ``` ```bash pnpm dlx shadcn@latest add @dotui/date-picker ``` ```bash yarn dlx shadcn@latest add @dotui/date-picker ``` ```bash bun x shadcn@latest add @dotui/date-picker ``` ## Usage [#usage] Use date pickers to allow users to select a date using a field and a calendar popover. ```tsx import { CalendarIcon } from 'lucide-react' import { Button } from '@/components/ui/button' import { Calendar } from '@/components/ui/calendar' import { DatePicker } from '@/components/ui/date-picker' import { DialogContent } from '@/components/ui/dialog' import { Label } from '@/components/ui/field' import { DateInput, InputGroup, InputGroupAddon } from '@/components/ui/input' import { Popover } from '@/components/ui/popover' ``` ```tsx ``` ## Anatomy [#anatomy] A date picker assembles a date field and a calendar overlay. The `InputGroup` holds the `DateInput` and a trigger `Button`; the `Popover` reveals a `Calendar`. `Label`, `Description`, and `FieldError` are optional field parts. ```tsx import { Button } from '@/components/ui/button' import { Calendar } from '@/components/ui/calendar' import { DatePicker } from '@/components/ui/date-picker' import { DialogContent } from '@/components/ui/dialog' import { Description, FieldError, Label } from '@/components/ui/field' import { DateInput, InputGroup, InputGroupAddon } from '@/components/ui/input' import { Popover } from '@/components/ui/popover' ;