Components
71 components built on react-aria-components. Each one installs with the shadcn CLI into components/fma-ui/.
Buttons
- Button GroupVisually joins a row (or column) of buttons into one connected control, with shared borders and rounded end corners. Can include a separator or a plain text segment.
- ToggleA single two-state pressable button (on/off), in default/outline variants and three sizes — the single-button counterpart to ToggleGroup.
- Toggle GroupA connected row (or column) of Toggle buttons sharing one visual variant/size/spacing, for grouped single- or multi-select controls (e.g. text formatting).
Chat
- AttachmentA file/attachment chip for chat-style UIs — shows a name, optional upload progress or error state, and an independently clickable remove action.
- BubbleA single chat message bubble — start/end alignment for sent vs. received, several color variants, and an optional reactions pill overlaid on a corner.
- MarkerA small inline label used in chat/message timelines — a date separator, a status note, or similar metadata — rendered in muted text with an optional icon.
- MessageLayout for one message row in a chat UI — avatar, header, footer, and a content column that aligns to the start or end depending on who sent it. Pairs with Bubble for the actual message content.
- Message ScrollerAn auto-scrolling viewport for chat message lists: sticks to the latest message as new ones arrive, and shows a jump-to-end/start button once the user scrolls away. Experimental: it doesn't sit on react-aria-components like the rest of this registry, and @shadcn/react is still pre-1.0.
- QuestionnaireA multi-step form/survey block (progress, choices, text input, previous/skip/next/submit) for chat-kit style conversational flows. Built on @shadcn/react, not react-aria-components — upstream hasn't ported it to the aria base yet. Experimental while @shadcn/react is pre-1.0.
Data display
- AvatarA user/entity image with a text or icon fallback for when the image fails to load. Composes into overlapping groups for showing multiple participants.
- BadgeA small label for status, count, or category — inline with text or attached to another element. Semantic variants (info/success/warning/destructive/invert) in solid, light and outline styles, plus size and radius options. Can also render as a link.
- CarouselA carousel for cycling through slides (images, cards, or any content) with keyboard, swipe, and button navigation. Built on embla-carousel-react; CarouselPrevious/CarouselNext are Buttons wired to the carousel API.
- ChartComposable chart primitives (ChartContainer, ChartTooltip, ChartLegend) wrapping Recharts, themed via CSS custom properties from a ChartConfig. Supports area, bar, line, and pie charts.
- Data GridA data grid driven by a TanStack Table v9 instance and rendered with react-aria's Table, which brings cell keyboard navigation, aria-sort, selection, column resizing, row drag and drop and virtualization. Create the table with useTable({ features: dataGridFeatures, ... }): the exported features cover sorting, filtering with facets, pagination, selection, row expanding, row and column pinning, ordering, visibility and sizing, with client-side row models; for server-side data (or to show every row) set manualSorting/manualFiltering/manualPagination. Column meta takes headerTitle, skeleton, autoSize, headerClassName and cellClassName. Wrap parts in DataGrid table={table} recordCount={…}: DataGridTable, DataGridPagination, DataGridColumnHeader (sort indicator, plus a menu for pinning, moving and visibility when tableLayout enables them), DataGridColumnVisibility, DataGridColumnFilter (faceted, use filterFn: "arrHas"), DataGridRowSelect (with enableRowSelection), DataGridRowPin, DataGridRowDragHandle (with onRowsReorder) and DataGridRowExpand (with getRowCanExpand and DataGridTable's renderExpandedRow, a full-width details row). tableLayout.columnsDraggable lets users drag headers to reorder columns (keyboard users use the header menu's move actions). isLoading shows skeleton rows (meta.skeleton) or a spinner; meta.autoSize columns take the remaining width (not measured from content).
- Icon TileA square surface that gives icons a consistent footprint. variant: outline (bordered), elevated (raised chip), soft (tinted double container), solid (filled) or frame (double container matching Card); soft and solid follow currentColor, so a text color class retints them. size goes from xs to xl; radius is default (clamped to the tile) or full (circular). Renders a <span>; wrap it in a Button or Link to make it interactive.
- KbdDisplays a keyboard key or shortcut (e.g. ⌘K) inline, styled as a small pill. KbdGroup lays out several keys side by side for combos like ⌘+Shift+P.
- TableSemantic table primitives (header, body, rows, cells, footer, caption) built on react-aria-components' Table for accessible, sorting/selection-ready markup.
- TimelineA vertical or horizontal timeline rendered as an ordered list. value is the current step: items with step <= value get data-completed (filled indicator and separator) and the current one gets aria-current="step". Compose each TimelineItem from TimelineHeader (TimelineDate, TimelineTitle, TimelineIndicator), TimelineSeparator and TimelineContent.
Disclosure
- AccordionA vertically stacked set of headers that expand to reveal or hide associated content. Supports single or multiple items open at once.
- CollapsibleShows or hides a single section of content behind a trigger. A thin wrapper around react-aria-components' Disclosure — for several mutually-exclusive sections, use Accordion instead.
Feedback
- AlertA callout for important, static information — supports an icon, title, description, and an optional action, with semantic variants (destructive/info/success/warning/invert).
- EmptyA placeholder for empty states — no data, no search results, nothing configured yet. Composes an icon/media, title, description, and optional call-to-action content.
- Icon StackA layered icon illustration for empty states: three receding cards drawn from currentColor, with an optional glyph (children) laid flat on the front card. Pairs with EmptyMedia. Decorative: the SVG is hidden from assistive tech, so give the glyph aria-hidden too.
- ProgressA horizontal progress bar communicating the completion of a task, determinate or indeterminate, with optional label/value slots.
- SkeletonA pulsing placeholder block for content that's still loading — size and shape it with className to match whatever it stands in for.
- SonnerA themed wrapper around the sonner toast library. Renders the toast viewport (Toaster); call toast() from "sonner" anywhere to actually show one.
- SpinnerA spinning loading indicator icon (role="status"), sized via className — drop it inside a disabled button or empty state while something loads.
Forms
- ButtonDisplays a button, or a component that looks like one, with a set of visual variants and sizes. Also exports LinkButton (react-aria-components' Link, same variants) for link-as-button use cases.
- CalendarA date grid for selecting a single date, multiple dates or a range. The header opens month and year grids for fast navigation, and granularity switches the selection to whole months or years. unavailableRanges blocks booked spans, and an already-selected value that becomes blocked travels to the nearest available date.
- CheckboxA control for a single on/off/indeterminate value. Pair with an external Label (via id/htmlFor) laid out as a flex row rather than passing label text as children.
- Color PickerAn OKLCH color picker: lightness, chroma and hue sliders painted with the color's own gradients. Given a background (contrastWith), it shows the WCAG ratio, hatches the lightness that fails AA, marks the AA/AAA thresholds and offers "Fix to AA/AAA" buttons that jump to the nearest passing lightness keeping the hue. A grid of preset swatches (Tailwind's palette by default, or your own via swatches) sets the color in one click, hatching the presets that fail AA. ColorPicker is a swatch that opens it in a popover; ColorPickerPanel renders it inline.
- ComboboxA searchable, filterable select combining a text input with a listbox popover. Supports single selection (ComboboxValue) or a multi-select tag/chip input (ComboboxChips + ComboboxChip).
- Date FieldA segmented, keyboard-editable date input. granularity also accepts "month" and "year" for month- or year-only fields. Values blocked by minValue/maxValue or unavailableRanges move to the nearest available date once the field loses focus, so typing is never interrupted. Exports DateInput for composing date pickers.
- Date PickerA typed date input paired with a calendar popover over one value, for single dates (DatePicker) or ranges (DateRangePicker). Supports month- and year-only granularity, unavailableRanges, and a non-modal popover: the input stays editable while the calendar is open, and the calendar follows what is typed.
- FieldLayout primitives for building form fields: Field, FieldSet/FieldLegend for grouping, FieldLabel/FieldDescription/FieldError for the usual label+hint+error stack, and FieldSeparator for splitting a group. Pairs with Label, Input, and friends.
- InputA single-line text input, styled to match the rest of the registry. Plain native attributes (disabled, not isDisabled) since it wraps react-aria-components' bare Input rather than a higher-level field primitive.
- Input GroupWraps an Input or Textarea with leading/trailing addons (icons, text, or buttons) inside one bordered container, so the whole group shares a single focus ring and border.
- Input OtpA one-time-password / verification-code input rendered as individual boxed slots, backed by a single hidden text input for real typing, paste, and autofill behavior.
- LabelA form field label. Pair it with a control via id/htmlFor rather than passing label text as the control's own children — several toggle-style primitives (Checkbox, Switch, RadioGroupItem) render their children inside a small fixed-size box meant for a custom indicator, not prose.
- Masked InputAn Input with live Maskito formatting. mask takes a preset name ("cpf", "cnpj", "cpf-cnpj", "cep", "phone", "credit-card", "date", "time", "date-time", "date-range", "decimal"), a parameterized preset such as { type: "decimal", prefix: "R$ " } (safe to write inline), or custom Maskito options. Presets set inputMode, autoComplete and a placeholder. onValueChange receives the raw value (digits, ISO date, dot-decimal) and the masked text; value may be either, so a form can store only the raw value. Works inside a react-aria TextField. For other inputs, such as InputGroupInput, spread useMask(...).inputProps instead.
- Native SelectA styled wrapper around the real, native <select> — use it when you need actual native select behavior (mobile OS pickers, form autofill, no JS dependency) instead of react-aria-components' custom Select.
- Radio GroupA set of mutually-exclusive radio options. Pair each RadioGroupItem with an external Label via id/htmlFor — its own children slot is for a custom indicator, not label text.
- SelectA listbox-style picker (react-aria-components' Select) with a trigger, popover, groups, and an optional search input — richer than the native <select> (see native-select for that).
- Simple Time PickerA button showing a time that opens a popover with columns for hours, minutes, seconds and AM/PM. Values are @internationalized/date Time objects (value/defaultValue/onChange), like the registry's DateField. granularity ("hour", "minute", "second"; default "minute") picks the columns and hourCycle={12} adds AM/PM. minValue/maxValue disable out-of-range options and clamp picks to the nearest allowed time. Each column is a react-aria ListBox: arrow keys and typing move within it, Tab moves between columns, Escape closes. For typed entry use DateField with granularity="minute" or react-aria's TimeField.
- SliderA draggable single- or range-value slider, horizontal or vertical — pass an array default/value to get one thumb per value.
- SwitchA two-state on/off toggle switch, in default and compact sizes.
- TextareaA multi-line text input that auto-sizes to its content by default (field-sizing-content), rather than staying a fixed number of rows.
Layout
- CardA container for grouping related content, with header, title, description, action, content, and footer slots. Supports a compact size="sm" variant.
- DirectionSets LTR/RTL text-direction context for descendant react-aria-components — a compatibility shim so a Radix/Base UI-style direction prop keeps working via react-aria's locale system.
- ItemA generic row layout for lists of things — media/icon, title, description, and trailing actions — that renders as a <div> or, when given an href, a real link. Use ItemGroup to stack several with consistent spacing.
- ResizableResizable split panes (panel group, panel, drag handle) built on react-resizable-panels — for layouts like a sidebar/editor split the user can drag to resize.
- Scroll AreaA scrollable container with a themeable, always-consistent-looking scrollbar via native scrollbar-width/scrollbar-color — no JS scrollbar emulation.
- SeparatorA thin visual divider between content, horizontal or vertical.
Media
Navigation
- BreadcrumbShows the user's current location within a hierarchy, as a trail of links back to parent pages, with an ellipsis for collapsing long paths.
- MenubarAn app-style menu bar (File, Edit, View…). Menubar is a react-aria Toolbar, so arrow keys move between menus; each MenubarMenu pairs a MenubarTrigger with a MenubarContent built on DropdownMenu, including submenus (MenubarSub). Checkbox- and radio-like items come from react-aria selection: give a MenubarGroup selectionMode ("multiple" or "single") and selectedKeys/onSelectionChange, and its items show a check when selected. Menus open on press or Enter/Space/ArrowDown; while one is open, hovering another trigger or pressing ArrowLeft/ArrowRight opens the neighbouring menu.
- Navigation MenuSite-header navigation: a <nav> list of top-level links and disclosure dropdowns. A NavigationMenuItem holds either a NavigationMenuLink or a NavigationMenuTrigger (a button with aria-expanded) plus its NavigationMenuContent (a popover). Escape or a click outside closes the dropdown and returns focus to the trigger; following a link closes it too. Style plain links like triggers with navigationMenuTriggerStyle(), and mark the current page with aria-current="page". Dropdowns open on press; with openOnHover they also open when the pointer rests on a trigger (delay, closeDelay), as a non-modal "peek" that leaves focus alone, switches at once to another trigger and closes when the pointer leaves or on Escape. Pressing a peeked trigger keeps it open as a regular dropdown. Add NavigationMenuIndicator after the list for an arrow that slides under the open trigger. For app command menus use Menubar or DropdownMenu.
- PaginationPage-number navigation built from LinkButton — previous/next controls, numbered links, and an ellipsis for collapsed ranges.
- SidebarA collapsible application sidebar with a mobile drawer fallback, a Cmd/Ctrl+B keyboard shortcut, and composable header/content/footer/menu slots.
- StepperMulti-step navigation, horizontal or vertical, built on react-aria Tabs: arrow keys, Home and End move between steps and Enter or Space selects one (manual activation). value/defaultValue/onValueChange hold the current step. Each StepperItem is a tab whose data-state is completed (before the current step, or isCompleted), active or inactive; isDisabled skips it and isLoading shows the loading indicator. indicators swaps an indicator's content per state. StepperContent panels show the current step's content.
- TabsA tab list and its panels for switching between related views, with default and line visual variants, horizontal or vertical orientation.
Overlay
- Alert DialogA modal dialog that interrupts the user with important content and expects an explicit response (e.g. confirming a destructive action) — unlike Dialog, it can't be dismissed by clicking outside or pressing Escape.
- CommandA searchable list of commands or actions, filtered live as you type. Export CommandDialog wraps it in a Dialog for a full command-palette (⌘K) pattern. Pass CommandEmpty through CommandList's renderEmptyState, not as a child: the list only accepts items, groups and separators.
- Context MenuA menu that opens on right-click (or long-press on touch) instead of a regular trigger click. Supports nested submenus, separators, and keyboard shortcut display.
- DialogA modal window layered over the page, requiring explicit action (or Escape) to dismiss. Pair with react-aria-components' DialogTrigger to wire up the trigger and open state.
- DrawerA panel that slides in from an edge of the screen, with swipe-to-dismiss and snap-point support. Uses @base-ui/react (not react-aria-components), so its API and data attributes differ from this repo's other overlays.
- Dropdown MenuA menu of actions or options triggered by clicking a button. Supports nested submenus, separators, labels, and a shortcut-display slot for each item.
- Hover CardA popover that shows on hover or focus instead of click, for previewing content (a profile card, a link preview) without navigating away. Unlike a tooltip, it can contain interactive content.
- PopoverA non-modal floating panel anchored to a trigger — for supplementary controls or content (e.g. a settings form) that shouldn't block the rest of the page.
- SheetA modal panel that slides in from an edge of the screen (top/right/bottom/left) — for navigation drawers, filters, or forms that need more room than a popover.
- TooltipA short, non-interactive hint that appears on hover or keyboard focus of its trigger.