# TUFFUI > Free, open-source React components for AI-agent interfaces: chats, tool calls, approvals, plans, traces, memory and usage. Components are React 19 + Tailwind CSS v4 + motion, distributed as a shadcn registry. Installing copies the source into components/ui and adds theme tokens (surface, surface-raised, border-strong, brand, positive, negative, warning) on top of the standard shadcn tokens. ## Surface Shell, Panel, Inset, IconTile and ShellHeader — the borderless layers every component is framed with. - Category: Foundations - Docs: https://tuffui.com/components/surface - Install: `npx shadcn@latest add https://tuffui.com/r/surface.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | Shell | `
` | — | Outer frame: rounded-[1.375rem] bg-surface p-1.5. | | Panel | `
` | — | Content area inside a shell: rounded-2xl bg-surface-inset. | | Inset | `
` | — | Deeper block inside a panel: rounded-xl bg-foreground/[0.04]. | | IconTile | `{ icon?: Icon } &
` | — | Tinted 36px square holding a filled Phosphor icon, or children. | | ShellHeader.icon | `Icon` | — | Phosphor icon shown in an IconTile, 12px from the shell edge. | | ShellHeader.title (required) | `ReactNode` | — | Header title. | | ShellHeader.subtitle | `ReactNode` | — | Secondary line under the title. | | ShellHeader.aside | `ReactNode` | — | Right side — a stat, pill or actions, vertically centered. | | ShellHeader.as | `"h2" \| "h3" \| "h4"` | `"h3"` | Heading level of the title. | ### Usage ```tsx import { Brain } from "@phosphor-icons/react"; import { Inset, Panel, Shell, ShellHeader } from "@/components/ui/surface"; export function MemoryCard() { return ( AGENTS.md ); } ``` ## Action Button Silver primary, secondary, quiet and danger buttons in two sizes, with icons, loading and icon-only buttons. - Category: Foundations - Docs: https://tuffui.com/components/action-button - Install: `npx shadcn@latest add https://tuffui.com/r/action-button.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | variant | `"primary" \| "secondary" \| "quiet" \| "danger"` | `"secondary"` | Primary is the silver gradient; use one per view. | | size | `"sm" \| "md"` | `"sm"` | Height 32px or 36px. | | icon | `Icon` | — | Leading Phosphor icon. | | iconWeight | `"fill" \| "bold"` | `"fill"` | Use bold for line glyphs like check, x and arrows. | | loading | `boolean` | `false` | Swaps the icon for a spinner and disables the button. | | IconButton.label (required) | `string` | — | Accessible name of an icon-only button; also its native title unless `tooltip` is set. | | IconButton.tooltip | `ReactNode \| true` | — | Shows our Tooltip instead of the native title. `true` reuses the label. Wrapping an IconButton in Tooltip also drops the title. | | IconButton.tooltipSide / tooltipAlign | `"top" \| "bottom" / "start" \| "center" \| "end"` | `"top" / "center"` | Where the tooltip sits relative to the button. | ### Usage ```tsx import { Check, Trash } from "@phosphor-icons/react"; import { Button, IconButton } from "@/components/ui/action-button"; ``` ## Choice Controls Switch, borderless Checkbox with a mixed state, and a RadioGroup with arrow-key navigation. - Category: Foundations - Docs: https://tuffui.com/components/choice-controls - Install: `npx shadcn@latest add https://tuffui.com/r/choice-controls.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | checked / defaultChecked | `boolean (Checkbox: \| "mixed")` | — | Controlled or uncontrolled state. | | onCheckedChange | `(checked: boolean) => void` | — | Called on toggle. | | label | `ReactNode` | — | Visible label; clicking it toggles. Without it, pass aria-label. | | description | `ReactNode` | — | Secondary line under the label. | | RadioGroup.value / defaultValue | `string` | — | Selected radio. | | RadioGroup.onValueChange | `(value: string) => void` | — | Called when a radio is picked by click or arrow keys. | | RadioGroup.label (required) | `string` | — | Accessible name of the group. | ### Usage ```tsx import { Checkbox, Radio, RadioGroup, Switch } from "@/components/ui/choice-controls"; ``` ## Status Pill Tinted status pills in five tones with icon or dot, plus a mono Tag for models, branches and transports. - Category: Foundations - Docs: https://tuffui.com/components/status-pill - Install: `npx shadcn@latest add https://tuffui.com/r/status-pill.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | tone | `"neutral" \| "brand" \| "positive" \| "negative" \| "warning"` | `"neutral"` | Tinted background and text color. Always pair with text. | | size | `"sm" \| "md"` | `"md"` | 20px or 24px tall. | | icon | `Icon` | — | Leading Phosphor icon. | | iconWeight | `"fill" \| "bold"` | `"fill"` | Bold for line glyphs. | ### Usage ```tsx import { CheckCircle } from "@phosphor-icons/react"; import { StatusPill, Tag } from "@/components/ui/status-pill"; Done Running opus-5.5 ``` ## Segmented Control Radio-style segmented switch with a sliding active pill that jumps instantly from the keyboard. - Category: Foundations - Docs: https://tuffui.com/components/segmented-control - Install: `npx shadcn@latest add https://tuffui.com/r/segmented-control.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | options (required) | `{ value: T; label: ReactNode; disabled?: boolean }[]` | — | Segments in order. | | value / defaultValue | `T` | — | Selected segment; defaults to the first. | | onValueChange | `(value: T) => void` | — | Called on click or arrow keys. | | label (required) | `string` | — | Accessible name of the radiogroup. | | size | `"sm" \| "md"` | `"sm"` | 32px or 36px tall. | ### Usage ```tsx import { Segmented } from "@/components/ui/segmented-control"; ``` ## Progress Bar Progress and meter bars in five tones with optional stripes, plus a stacked SegmentedBar. - Category: Foundations - Docs: https://tuffui.com/components/progress-bar - Install: `npx shadcn@latest add https://tuffui.com/r/progress-bar.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | value (required) | `number` | — | Current value. | | max | `number` | `100` | Upper bound. | | tone | `"brand" \| "positive" \| "negative" \| "warning" \| "neutral"` | `"brand"` | Fill color. | | color | `string` | — | Any CSS color for the fill. Overrides `tone`, e.g. a per-series color. | | size | `"sm" \| "md" \| "lg"` | `"md"` | 6, 8 or 12px tall. | | striped | `boolean` | `false` | Diagonal stripes on the fill; revealed with clip-path so they never stretch. | | kind | `"progress" \| "meter"` | `"progress"` | progressbar for work toward done, meter for a level. | | label (required) | `string` | — | Accessible name. | | valueText | `string` | — | Spoken value; defaults to a percentage. | | SegmentedBar.segments (required) | `{ id, label, value, color }[]` | — | Stacked segments in order. | ### Usage ```tsx import { ProgressBar, SegmentedBar } from "@/components/ui/progress-bar"; ``` ## Rolling Number Odometer-style number: each digit rolls to its new value, units and separators stay put. - Category: Foundations - Docs: https://tuffui.com/components/rolling-number - Install: `npx shadcn@latest add https://tuffui.com/r/rolling-number.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | value (required) | `number \| string` | — | A number, or a preformatted string like "87.2k". Only digits roll. | | format | `(value: number) => string` | — | Formats a numeric value; defaults to en-US grouping. | | stagger | `number` | `24` | Delay between neighbouring digits, right to left, in ms. | | className | `string` | — | Typography is inherited; tabular figures are applied. | ### Usage ```tsx import { RollingNumber } from "@/components/ui/rolling-number"; `$${n.toFixed(2)}`} /> ``` ## Text Field Borderless TextField, SearchField with clear and TextArea, with label, description and error wiring. - Category: Foundations - Docs: https://tuffui.com/components/text-field - Install: `npx shadcn@latest add https://tuffui.com/r/text-field.json` ### Props | Prop | Type | Default | Description | | --- | --- | --- | --- | | label | `ReactNode` | — | Visible label, linked to the control. | | description | `ReactNode` | — | Help text, linked with aria-describedby. | | error | `ReactNode` | — | Error text; marks the control aria-invalid and replaces the description. | | SearchField.onClear | `() => void` | — | Shows a clear button while there is text. | | ...rest | ` /