# Prototyper UI — Full Documentation > Composable React component library built on Base UI primitives. Tailwind CSS v4, OKLCH design tokens, shadcn-compatible. > Tech stack: React 19, Next.js 15, Tailwind CSS v4, Base UI, TypeScript. > Install components via: bunx @prototyperco/cli add {component} (or: pnpm dlx shadcn@latest add https://prototyper-ui.com/r/{component}.json) # Agent Setup > One-page setup guide for AI agents to install and configure Prototyper UI. URL: https://prototyper-ui.com/docs/agent-setup ## What is Prototyper UI? A component library designed end-to-end for generative UI. 59 accessible React components built on Base UI, Tailwind CSS v4, and OKLCH design tokens. Every component is a file — agents can read, compose, and render them in real time through structured MCP access. Humans can read the source, change anything, and ship it as their own. The **Live Canvas** is a live browser preview powered by Yjs. It lets agents and humans see the same UI in real time. ## Install the MCP server The `@prototyperco/mcp` package gives your agent structured access to components, docs, tokens, and the Live Canvas. Any MCP-compatible agent works — Claude Code, Cursor, OpenCode, Codex, VS Code, and more. ### Claude Code ```bash claude mcp add prototyper-ui -- npx -y @prototyperco/mcp@latest ``` ### Cursor Add to `.cursor/mcp.json`: ```json { "mcpServers": { "prototyper-ui": { "command": "npx", "args": ["-y", "@prototyperco/mcp@latest"] } } } ``` ### VS Code Add to `.vscode/settings.json`: ```json { "mcp.servers": { "prototyper-ui": { "command": "npx", "args": ["-y", "@prototyperco/mcp@latest"] } } } ``` ### Gemini CLI Add to `.gemini/settings.json` in your project, or `~/.gemini/settings.json` globally: ```json { "mcpServers": { "prototyper-ui": { "command": "npx", "args": ["-y", "@prototyperco/mcp@latest"] } } } ``` ### Codex CLI ```bash mkdir -p ~/.codex && cat >> ~/.codex/config.json << 'EOF' { "mcpServers": { "prototyper-ui": { "command": "npx", "args": ["-y", "@prototyperco/mcp@latest"] } } } EOF ``` ### Other agents Any agent that supports MCP can use the same config. The command is always `npx -y @prototyperco/mcp@latest`. ## Set up the project If the workspace doesn't already have Prototyper UI configured, run: ```bash bunx @prototyperco/cli setup ``` This installs dependencies, writes design tokens, configures Tailwind, adds MCP config for detected editors and Gemini CLI, and syncs skills for supported agents. ## Verify After installing the MCP server, call `list_components`. If it returns a list of components, the server is working. For Gemini CLI, run `/mcp refresh` or restart the session after editing `settings.json`. If Gemini asks you to trust the workspace before starting the server, accept the prompt first. ## Start designing Call `design_create` to open a live Live Canvas session. The bridge server starts automatically on the first call. ``` design_create({ title: "Login Page" }) ``` This returns a `previewUrl` — open it in a browser to see live updates as the agent builds UI. ## Key MCP tools | Tool | Purpose | | ----------------- | ----------------------------------------------- | | `list_components` | List all 56 components | | `get_component` | Full source, docs, and examples for a component | | `get_theme` | OKLCH design tokens CSS | | `design_create` | Start a new Live Canvas session | | `design_update` | Push component changes to the live preview | | `design_theme` | Update the theme in real time | | `design_get` | Read the current design state | ## Further reading - [MCP Server docs](/docs/for-agents/mcp-server) — full tool reference and environment variables - [Agent Skills docs](/docs/for-agents/skills) — Gemini CLI and Antigravity skill installs - [Live Canvas docs](/docs/design-bridge/getting-started) — architecture, sessions, and advanced usage - [Component list](/docs/components/button) — browse all components # Changelog > Version history and release notes for Prototyper UI. URL: https://prototyper-ui.com/docs/changelog ## v0.5.6 _CLI create install hardening_ ### CLI - Fixed pnpm 11 project creation by skipping create-next-app's early install and running dependency installation after Prototyper writes build approvals - New pnpm Next.js apps now install and start without requiring a manual `pnpm approve-builds` ## v0.5.5 _CLI project creation reliability_ ### CLI - Fixed pnpm 11 project creation by writing explicit build-script approvals for Next.js native dependencies - New apps created with pnpm now include `pnpm-workspace.yaml` approvals for `sharp` and `unrs-resolver` ## v0.5.4 _OSS readiness and release hardening_ ### Release - Added package-local MIT license files to all publishable packages - Added npm provenance to the publish workflow - Tightened CI so formatting is enforced instead of advisory - Updated publishable package versions for a coherent `0.5.4` release ### Dependencies - Cleared the production audit with patched transitive dependency overrides - Updated the terminal UI runtime to the latest OpenTUI API - Refreshed docs and MCP dependencies used by the public site and AI tooling ### Documentation - Updated CLI, Live Canvas, contributor, and environment guidance for the hosted bridge and Bun-powered terminal UI ## v0.5.0 _Initial public release_ ### Components - **46+ components** covering actions, forms, overlays, navigation, layout, data display, and feedback - Built on [Base UI](https://base-ui.com) primitives — accessible, unstyled foundations with Prototyper UI's design layer on top - Compound component pattern with flat named exports - `data-slot` attributes on every element for targeted CSS customization ### Design System - **OKLCH color tokens** — perceptually uniform colors with automatic derived states via `color-mix()` - **Role-based surfaces** — `surface`, `surface-secondary`, `surface-tertiary`, `field-background`, `overlay` - **Semantic shadows** — three tiers (`surface`, `field`, `overlay`) that adapt to dark mode - **Dark mode** — full token overrides via `.dark` class, with zeroed shadows and inset glow effects - **CSS utilities** — `focus-ring`, `focus-field-ring`, `invalid-field-ring`, `status-disabled`, `status-pending` - **Fluid easing** — signature `--ease-out-fluid` curve, CSS-first animations (no framer-motion) ### CLI (`@prototyperco/cli`) - `init` — Set up tokens, utilities, and project config - `add` — Install components with interactive picker and dependency resolution - `update` — Check and apply component updates from the registry - `doctor` — Verify project health and configuration - `machine-mode init` — Scaffold URL-driven machine mode endpoints - JSON mode (`--json`) for LLM-driven setup workflows - Compose scaffolding (`--compose`, `add compose`) ### MCP Server (`@prototyperco/mcp`) - 10 tools for AI assistants: `list_components`, `get_component_docs`, `get_component_source`, `get_theme`, `search_docs`, and more - Works with Claude Code, Cursor, and other MCP-compatible tools - Caching with TTL for fast repeated queries ### Compose (`@prototyperco/compose`) - JSON-patch streaming renderer for AI-generated interfaces - Anthropic and OpenAI provider support - Catalog system for component props, events, and slots - Real-time state management with optimistic updates ### LLM Endpoints - `/llms.txt` — Project overview for LLMs - `/llms-full.txt` — Complete documentation in plain text - `/llms-components.txt` — All component docs concatenated - `/llms/[component]` — Individual component documentation - `/prototyper-tokens.css` — Extractable design tokens ### Registry - shadcn-compatible registry at `prototyper-ui.com/r/{component}.json` - Works with both `bunx @prototyperco/cli add` and `npx shadcn@latest add` - Automatic dependency resolution for inter-component dependencies # CLI Reference > Complete reference for the Prototyper UI CLI — init, add, search, update, browse, diff, inspect, props, suggest, audit, scaffold, migrate, registry, theme, mcp, doctor, and machine-mode commands. URL: https://prototyper-ui.com/docs/cli The Prototyper UI CLI (`@prototyperco/cli`) is your gateway into the ecosystem — components, registries, AI skills, themes, and more. ```bash bunx @prototyperco/cli [options] ``` The CLI requires Bun 1.1 or newer. Inside an initialized project, running without a subcommand opens the full-screen terminal app with mouse support, component browser, and health dashboard. > **Note:** Bun is the supported runtime for the CLI. Use `bunx @prototyperco/cli ...` for both interactive and scripted flows. > `bunx prototyper` is not a shorthand for this package; it resolves to an unrelated npm package without a CLI executable. ## Terminal app Run the CLI without a subcommand inside a project that already has `package.json` and `prototyper.json`: ```bash bunx @prototyperco/cli ``` The CLI detects the current project state: | Project state | Behavior | | ------------------------------------ | -------------------------------------------- | | No `package.json` | Opens the create flow, or prints create help | | `package.json`, no `prototyper.json` | Runs `init` | | `package.json` and `prototyper.json` | Opens the full-screen terminal app | For a direct jump into the component catalog: ```bash bunx @prototyperco/cli browse ``` The full-screen app uses OpenTUI and needs Bun, a real TTY, color output, and a non-dumb terminal. It falls back to a Clack picker or plain output in CI, piped output, `TERM=dumb`, or when `NO_COLOR` is set. | Key | Action | | -------- | --------------------------- | | `1` | Home | | `2` | Browse | | `3` | Health | | `4` | Theme | | `5` | Compose | | `6` | Create | | `7` | Settings | | `Ctrl+K` | Command palette | | `Tab` | Switch tabs in detail views | | `Esc` | Close overlays or go back | | `q` | Quit | ## create Scaffold a brand new project with Prototyper UI pre-configured. ```bash bunx @prototyperco/cli create my-app ``` ### What it does 1. Runs `create-next-app` with TypeScript, Tailwind, ESLint, App Router, and src directory 2. Runs `init` inside the new project (tokens, utils, config) 3. Installs starter components: button, input, card, dialog, field 4. Runs a single `install` at the end ### Options | Flag | Description | | ------------------- | ------------------------------------------------------------------------- | | `--template ` | Project template (`nextjs`, `vite`, `remix`, `astro` — default: `nextjs`) | | `--demo` | Include a demo page showcasing the starter components | ### Example ```bash # Default Next.js project bunx @prototyperco/cli create my-app --demo cd my-app pnpm dev # Vite project bunx @prototyperco/cli create my-app --template vite # Remix project bunx @prototyperco/cli create my-app --template remix # Astro project bunx @prototyperco/cli create my-app --template astro ``` --- ## init Add design tokens, utilities, and base styles to your project. ```bash bunx @prototyperco/cli init ``` ### What it does 1. Finds your `globals.css` (checks `app/globals.css`, `src/app/globals.css`, `styles/globals.css`, `src/styles/globals.css`) 2. Merges OKLCH design tokens into it (or replaces existing tokens) 3. Creates `lib/utils.ts` with the `cn()` utility (clsx + tailwind-merge) 4. Writes a `prototyper.json` manifest with your project config 5. Optionally installs AI skills for Claude Code or Cursor ### Options | Flag | Description | | -------------- | ---------------------------------------------------- | | `--css ` | Path to your globals.css file (skips auto-detection) | | `--force` | Skip confirmation prompts | | `--dry-run` | Preview changes without writing files | | `--skills` | Install Claude Code / Cursor skills | | `--no-skills` | Skip skills installation | | `--compose` | Scaffold Compose integration files | | `--json` | Output JSON (for LLM-driven setup) | ### Examples ```bash # Standard setup bunx @prototyperco/cli init # Custom CSS path bunx @prototyperco/cli init --css src/styles/globals.css # Non-interactive with Compose bunx @prototyperco/cli init --force --compose # Preview what would change bunx @prototyperco/cli init --dry-run ``` --- ## add Add components or integrations to your project. ```bash bunx @prototyperco/cli add [components...] ``` ### Behavior - **With arguments**: installs the named components and their dependencies - **Without arguments**: opens an interactive picker (grouped by category) - **With `--all`**: installs every available component Components are written to `components/ui/` (or `src/components/ui/` if a `src/` directory exists). Use `--dir` to override. ### Options | Flag | Description | | ----------------------- | ------------------------------------------------------------------ | | `--dir ` | Components directory (default: `components/` or `src/components/`) | | `--all` | Install all available components | | `--force` | Overwrite existing files without asking | | `--dry-run` | Preview changes without writing files | | `--no-install` | Skip automatic dependency installation | | `--provider ` | AI provider for compose scaffold (`anthropic` or `openai`) | | `--json` | Output JSON (for LLM-driven setup) | ### Examples ```bash # Add a single component bunx @prototyperco/cli add button # Add multiple components bunx @prototyperco/cli add button card dialog select text-field # Add a component from another registry bunx @prototyperco/cli add @acme/fancy-card # Interactive picker bunx @prototyperco/cli add # Install everything bunx @prototyperco/cli add --all # Preview without writing bunx @prototyperco/cli add button --dry-run # Scaffold Compose endpoint bunx @prototyperco/cli add compose --provider anthropic ``` ### Dependency resolution When you install a component, the CLI automatically resolves and installs any registry dependencies. For example, `text-field` depends on `field` — both will be installed. After writing files, the CLI prompts to install npm dependencies (like `@base-ui/react`) unless `--no-install` is passed. --- ## update Check installed components for updates and apply them. ```bash bunx @prototyperco/cli update ``` ### Behavior 1. Scans your `components/ui/` directory for installed `.tsx` files 2. Fetches the latest version of each from the registry 3. Compares local content against the registry version 4. Prompts to update each changed component (or updates all with `--force`) ### Options | Flag | Description | | -------------- | ------------------------------- | | `--dir ` | Components directory | | `--force` | Update all without prompting | | `--dry-run` | Preview changes without writing | | `--json` | Output JSON | ### Examples ```bash # Interactive update bunx @prototyperco/cli update # Update all without prompting bunx @prototyperco/cli update --force # Check what would change bunx @prototyperco/cli update --dry-run ``` > **Note:** If you've customized a component, updating will overwrite your changes. Use `--dry-run` first to see what would change. --- ## search Search for components across registries by name or description. ```bash bunx @prototyperco/cli search [query...] ``` ### Behavior - Fuzzy matches against component name and description - Shows name, description, category, registry, and an installed marker for components already in your project - By default, searches your configured registries. Use `--all` to search all known registries. ### Options | Flag | Description | | -------- | ----------------------------------------------------- | | `--all` | Search all known registries, not just configured ones | | `--json` | Output JSON | ### Examples ```bash # Search for button components bunx @prototyperco/cli search button # Search a specific registry bunx @prototyperco/cli search @acme button # Search all registries bunx @prototyperco/cli search --all button ``` --- ## doctor Check your project health and configuration. ```bash bunx @prototyperco/cli doctor ``` ### Checks The doctor command verifies: | Check | What it verifies | | -------------- | ------------------------------------------------------------------------------------------ | | `globals.css` | CSS file exists and is found | | `Tailwind v4` | `@import "tailwindcss"` is present | | `Tokens` | Prototyper UI token block is installed | | `lib/utils.ts` | Utility file exists | | `Dependencies` | `@base-ui/react`, `clsx`, `tailwind-merge`, `class-variance-authority` are in package.json | | `Components` | Count of installed components (info only) | ### Options | Flag | Description | | -------- | ----------- | | `--json` | Output JSON | ### Example ```bash bunx @prototyperco/cli doctor ``` ``` ✓ Found globals.css at app/globals.css ✓ Tailwind v4 detected ✓ Tokens installed ✓ lib/utils.ts exists ✓ All peer dependencies installed ℹ 12 components installed 4 of 5 checks passed ``` --- ## browse Interactive component catalog browser. Opens the full-screen terminal app directly on Browse when the terminal supports OpenTUI. ```bash bunx @prototyperco/cli browse ``` ### Behavior - Loads the registry catalog and marks installed components when it can read your project config - Shows a component list, category grouping, dependencies, props, variants, import path, and docs where available - Uses the same rich terminal requirements as the no-subcommand app - Falls back to a plain component list when rich terminal rendering is unavailable ```bash bunx @prototyperco/cli browse ``` --- ## diff Show differences between your local components and the latest registry versions. ```bash bunx @prototyperco/cli diff [components...] ``` ### Behavior - **With arguments**: diffs only the named components - **Without arguments**: diffs all installed components ### Options | Flag | Description | | -------------- | -------------------- | | `--dir ` | Components directory | | `--json` | Output JSON | ### Example ```bash # Diff all installed components bunx @prototyperco/cli diff # Diff specific components bunx @prototyperco/cli diff button dialog ``` --- ## inspect Deep analysis of a single component — variants, props, tokens, Base UI primitive, exports, and reverse dependencies. ```bash bunx @prototyperco/cli inspect ``` ### Options | Flag | Description | | -------- | ----------- | | `--json` | Output JSON | ### Example ```bash bunx @prototyperco/cli inspect button ``` ``` Button Category: actions Base UI: @base-ui/react — Button Variants: variant (solid, outline, ghost, link), size (sm, md, lg) Exports: Button Used by: alert-dialog, dialog, form ``` --- ## props Quick reference for a component's props, variants, events, and import path. ```bash bunx @prototyperco/cli props ``` ### Options | Flag | Description | | -------- | ---------------------- | | `--json` | Output structured JSON | ### Example ```bash # Single component bunx @prototyperco/cli props button # Multiple components bunx @prototyperco/cli props button select dialog ``` --- ## suggest Scan your source code for raw HTML patterns that could be replaced with Prototyper UI components. ```bash bunx @prototyperco/cli suggest ``` ### Behavior Scans files in `src/` for common patterns (e.g. `; } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/button.json ``` This will add the following files to your project: - `components/ui/button.tsx` ## Usage ```tsx import { Button } from "@/components/ui/button"; ; ``` ## Examples ### Destructive ```tsx import { Button } from "@/components/ui/button"; export default function ButtonDestructive() { return ; } ``` ### Outline ```tsx import { Button } from "@/components/ui/button"; export default function ButtonOutline() { return ; } ``` ### Secondary ```tsx import { Button } from "@/components/ui/button"; export default function ButtonSecondary() { return ; } ``` ### Ghost ```tsx import { Button } from "@/components/ui/button"; export default function ButtonGhost() { return ; } ``` ### Primary Soft ```tsx import { Button } from "@/components/ui/button"; export default function ButtonPrimarySoft() { return ; } ``` ### Destructive Soft ```tsx import { Button } from "@/components/ui/button"; export default function ButtonDestructiveSoft() { return ; } ``` ### Success ```tsx import { Button } from "@/components/ui/button"; export default function ButtonSuccess() { return ; } ``` ### Warning ```tsx import { Button } from "@/components/ui/button"; export default function ButtonWarning() { return ; } ``` ### Link ```tsx import { buttonVariants } from "@/components/ui/button"; export default function ButtonLink() { return Link; } ``` ### Icon ```tsx import { ChevronRight } from "lucide-react"; import { Button } from "@/components/ui/button"; export default function ButtonIcon() { return ( ); } ``` ### With Icon ```tsx import { Mail } from "lucide-react"; import { Button } from "@/components/ui/button"; export default function ButtonWithIcon() { return ( ); } ``` ### Loading ```tsx import { Loader2 } from "lucide-react"; import { Button } from "@/components/ui/button"; export default function ButtonLoading() { return ( ); } ``` ### Press ```tsx import { Button } from "@/components/ui/button"; export default function ButtonPress() { return ; } ``` ## Styling ### Data Slots Use `data-slot` attributes to target the button in CSS: | Slot name | Element | | --------- | ------------------- | | `button` | The `; ``` ## API Reference ### Button A clickable button element with gradient variants. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `"default" \| "destructive" \| "outline" \| "secondary" \| "ghost" \| "primary-soft" \| "destructive-soft" \| "success" \| "warning" \| "link"` | `"default"` | Visual style variant | | `size` | `"default" \| "xs" \| "sm" \| "lg" \| "icon" \| "icon-xs" \| "icon-sm" \| "icon-lg"` | `"default"` | Size of the button | | `isPending` | `boolean` | - | Shows pending state and sets aria-disabled | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Button content | All [Base UI Button props](https://base-ui.com/react/components/button) are forwarded via `...props`. ### buttonVariants A `cva` helper exported for use outside of the ` ); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/card.json ``` This will add the following files to your project: - `components/ui/card.tsx` ## Usage ```tsx import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, } from "@/components/ui/card"; ``` ```tsx Title Description Content Footer ``` ## Anatomy ```tsx ``` | Sub-component | `data-slot` | Purpose | Required | | ----------------- | ------------------ | ------------------------------------- | -------- | | `Card` | `card` | Root container with surface variants | Yes | | `CardHeader` | `card-header` | Flex column for title and description | No | | `CardTitle` | `card-title` | Heading for the card | No | | `CardDescription` | `card-description` | Supporting text below the title | No | | `CardContent` | `card-content` | Main content area with flex-1 growth | No | | `CardFooter` | `card-footer` | Horizontal flex container for actions | No | ## Examples ### Elevated ```tsx import { Card, CardHeader, CardTitle, CardDescription, CardContent, } from "@/components/ui/card"; export default function CardElevated() { return ( Elevated Card Uses a stronger shadow for more visual prominence.

The elevated variant is ideal for floating panels, popovers, or content that needs to stand out from the page.

); } ``` ### Interactive ```tsx import { Card, CardHeader, CardTitle, CardDescription, } from "@/components/ui/card"; export default function CardInteractive() { return (
Starter Free forever Pro $9/month
); } ``` ### With Form ```tsx import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/text-field"; export default function CardWithForm() { return ( Sign in Enter your credentials to access your account.
); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the card: | Slot name | Element | | ------------------ | -------------------- | | `card` | Root `
` wrapper | | `card-header` | Header container | | `card-title` | Title `

` | | `card-description` | Description `

` | | `card-content` | Content container | | `card-footer` | Footer container | ### Customization Examples ```css /* Make all cards have a larger radius */ [data-slot="card"] { @apply rounded-2xl; } /* Give card titles more weight */ [data-slot="card-title"] { @apply text-lg font-bold; } ``` ```tsx { /* Override styles via className */ } {/* ... */}; ``` ## API Reference ### Card The root container with surface-tier variants. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `"default" \| "secondary" \| "tertiary" \| "elevated" \| "transparent"` | `"default"` | Surface variant controlling background, border, and shadow. | | `interactive` | `boolean` | `false` | Enables hover lift and active press scale effects. | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Card content. | Extends `React.ComponentProps<"div">`. All standard div props are forwarded via `...props`. ### CardHeader Flex column container for title and description. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Header content (typically CardTitle and CardDescription). | Extends `React.ComponentProps<"div">`. All standard div props are forwarded via `...props`. ### CardTitle Card heading rendered as an `

`. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Title text. | Extends `React.ComponentProps<"h3">`. All standard h3 props are forwarded via `...props`. ### CardDescription Muted supporting text rendered as a `

`. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Description text. | Extends `React.ComponentProps<"p">`. All standard p props are forwarded via `...props`. ### CardContent Main content area with `flex-1` growth. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Content elements. | Extends `React.ComponentProps<"div">`. All standard div props are forwarded via `...props`. ### CardFooter Horizontal flex container for action buttons. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Footer content (typically buttons). | Extends `React.ComponentProps<"div">`. All standard div props are forwarded via `...props`. ### cardVariants Use `cardVariants` to apply card styles to non-card elements: ```tsx import { cardVariants } from "@/components/ui/card";

Custom card element
; ``` ## Accessibility ### Keyboard Interactions Card is a non-interactive presentational container and does not have keyboard interactions. When the `interactive` prop is set, the card gains a pointer cursor but remains a `
` -- wrap it in an `` or ` {submitted && (

Submitted:{" "} {submitted}

)} ); } ``` ### Disabled ```tsx import { ColorPicker, ColorPickerArea, ColorPickerContent, ColorPickerInput, ColorPickerSlider, ColorPickerTrigger, } from "@/components/ui/color-picker"; export default function ColorPickerDisabledDemo() { return ( ); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the color picker: | Slot name | Element | | --------------------------- | ---------------------------------- | | `color-picker` | Root wrapper | | `color-picker-trigger` | Trigger button with swatch preview | | `color-picker-content` | Popover panel | | `color-picker-area` | 2D color gradient canvas | | `color-picker-area-thumb` | Draggable dot on the area | | `color-picker-slider` | Hue or alpha slider track | | `color-picker-slider-thumb` | Slider thumb circle | | `color-picker-input` | Hex text input | | `color-picker-eye-dropper` | EyeDropper button | | `color-picker-swatches` | Swatches grid container | | `color-picker-swatch` | Individual swatch button | ### Customization Examples ```css /* Make the color area taller */ [data-slot="color-picker-area"] { @apply aspect-[4/3]; } /* Larger swatches */ [data-slot="color-picker-swatch"] { @apply size-8 rounded-full; } ``` ```tsx { /* Wider popover panel */ } {/* ... */}; ``` ## API Reference ### ColorPicker Root component that manages color state and provides context. | Prop | Type | Default | Description | | --------------- | ------------------------------------ | ----------- | ------------------------------------- | | `value` | `string` | - | Controlled CSS color string | | `defaultValue` | `string` | `"#6366f1"` | Uncontrolled initial color | | `onValueChange` | `(value: string) => void` | - | Called on every change (live) | | `onValueCommit` | `(value: string) => void` | - | Called on pointer up or Enter | | `outputFormat` | `"hex" \| "oklch" \| "rgb" \| "hsl"` | `"hex"` | Format for emitted color strings | | `name` | `string` | - | Hidden input name for form submission | | `disabled` | `boolean` | `false` | Disable all interactions | | `enableAlpha` | `boolean` | `false` | Show alpha channel controls | | `open` | `boolean` | - | Controlled popover open state | | `onOpenChange` | `(open: boolean) => void` | - | Callback when popover opens/closes | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Color picker content | ### ColorPickerTrigger Button that shows a swatch preview and opens the popover. | Prop | Type | Default | Description | | ----------- | -------------------------------- | ------- | ---------------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom trigger content (defaults to hex value) | | `...props` | `PopoverPrimitive.Trigger.Props` | - | All Base UI Popover.Trigger props | ### ColorPickerContent Popover panel wrapping the color controls. | Prop | Type | Default | Description | | ------------ | ------------------------------ | --------- | ------------------------------- | | `sideOffset` | `number` | `8` | Distance from trigger | | `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment relative to trigger | | `className` | `string` | - | Additional CSS classes | | `...props` | `PopoverPrimitive.Popup.Props` | - | All Base UI Popover.Popup props | ### ColorPickerArea 2D gradient area for selecting lightness (Y) and chroma (X). | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | ----------------------------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom thumb (defaults to ColorPickerAreaThumb) | ### ColorPickerAreaThumb Draggable dot positioned within the color area. | Prop | Type | Default | Description | | ----------- | -------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | ### ColorPickerSlider 1D slider for hue or alpha channel. | Prop | Type | Default | Description | | ----------- | ------------------ | ------- | ------------------------------------------------- | | `channel` | `"hue" \| "alpha"` | - | Which channel to control | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom thumb (defaults to ColorPickerSliderThumb) | ### ColorPickerSliderThumb Slider thumb circle. | Prop | Type | Default | Description | | ----------- | -------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | ### ColorPickerInput Text input for typing color values directly. | Prop | Type | Default | Description | | ----------- | -------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | ### ColorPickerEyeDropper Button that activates the browser EyeDropper API. Only renders when the API is available. | Prop | Type | Default | Description | | ----------- | -------- | ------- | ---------------------- | | `className` | `string` | - | Additional CSS classes | ### ColorPickerSwatches Grid container for preset color buttons. | Prop | Type | Default | Description | | ----------- | ----------------- | ------- | -------------------------- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | ColorPickerSwatch elements | ### ColorPickerSwatch Clickable preset color button. | Prop | Type | Default | Description | | ----------- | -------- | ------- | -------------------------------- | | `value` | `string` | - | CSS color string for this preset | | `className` | `string` | - | Additional CSS classes | ## Accessibility ### Keyboard Interactions | Key | Action | | -------------------- | ----------------------------------------------------- | | `Arrow keys` | Move thumb in the color area or adjust slider value | | `Shift + Arrow keys` | Fine-step adjustment | | `Home` | Set chroma to minimum (area) or slider to minimum | | `End` | Set chroma to maximum (area) or slider to maximum | | `PageUp` | Set lightness to maximum (area only) | | `PageDown` | Set lightness to minimum (area only) | | `Enter` | Confirm text input value | | `Tab` | Move focus between area, sliders, input, and swatches | ### ARIA Attributes - The color area and sliders use `role="slider"` with `aria-valuemin`, `aria-valuemax`, and `aria-valuenow`. - `aria-valuetext` on the area provides a human-readable description of the current color position. - `aria-label` is set on each slider to identify the channel (Hue, Alpha). - The EyeDropper button is a standard ` ); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the combobox: | Slot name | Element | | ---------------------- | -------------------------------------- | | `input-group-control` | The text input element | | `combobox-trigger` | Dropdown trigger button | | `combobox-clear` | Clear selection button | | `combobox-content` | Positioned popup panel | | `combobox-list` | Scrollable list container | | `combobox-item` | Individual option | | `combobox-empty` | Empty state message | | `combobox-group` | Group container | | `combobox-group-label` | Group label | | `combobox-separator` | Separator line between groups | | `combobox-chips` | Chips container for multi-select | | `combobox-chip` | Individual chip | | `combobox-chip-remove` | Chip remove button | | `combobox-chips-input` | Input within chips container | | `combobox-value` | Selected value display | | `combobox-icon` | Icon element | | `combobox-status` | Screen-reader status (visually hidden) | | `combobox-arrow` | Popup arrow | | `combobox-backdrop` | Full-screen backdrop | ### Customization Examples ```css /* Widen the popup */ [data-slot="combobox-content"] { @apply min-w-[20rem]; } /* Custom highlighted item style */ [data-slot="combobox-item"][data-highlighted] { @apply bg-primary text-primary-foreground; } ``` ```tsx { /* Override popup alignment */ } {/* ... */} ; ``` ## API Reference ### Combobox Root component that manages filtering, selection, and open/close state. All [Base UI Combobox.Root props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxInput Text input with optional trigger and clear buttons, wrapped in an `InputGroup`. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `showTrigger` | `boolean` | `true` | Show the dropdown trigger button | | `showClear` | `boolean` | `false` | Show the clear selection button | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Additional content after the input | All [Base UI Combobox.Input props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxChipsInput Minimal text input for use within the `ComboboxChips` container. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Input props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxTrigger Button that toggles the popup open or closed. Renders a chevron-down icon by default. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom icon (replaces default chevron) | All [Base UI Combobox.Trigger props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxClear Button that clears the current selection. Renders an X icon by default. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom icon (replaces default X) | All [Base UI Combobox.Clear props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxValue Displays the selected value text. All [Base UI Combobox.Value props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxContent Positioned popup that contains the list. Wraps `Combobox.Portal`, `Combobox.Positioner`, and `Combobox.Popup`. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `side` | `"top" \| "bottom" \| "left" \| "right"` | `"bottom"` | Side of the anchor to position on | | `sideOffset` | `number` | `4` | Distance from the anchor | | `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment along the side axis | | `alignOffset` | `number` | `0` | Offset along the alignment axis | | `anchor` | `ComboboxPrimitive.Positioner.Props["anchor"]` | - | Custom anchor element | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Popup props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxList Scrollable list container for combobox items. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.List props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxItem Individual selectable option. Includes a check icon indicator when selected. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Item content | All [Base UI Combobox.Item props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxEmpty Message shown when no items match the current filter. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Empty props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxGroup Groups related combobox items together. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Group props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxGroupLabel Label for a group of items. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.GroupLabel props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxSeparator Visual separator between groups. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Separator props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxIcon Icon element within the combobox. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Icon props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxChips Container for selected value chips in multi-select mode. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Chips props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxChip Individual chip representing a selected value. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Chip props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxChipRemove Button to remove a chip. Renders an X icon by default. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Custom icon (replaces default X) | All [Base UI Combobox.ChipRemove props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxStatus Screen-reader-only status message that announces changes. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Status props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxArrow Arrow element pointing from the popup to the trigger. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Arrow props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxBackdrop Full-screen backdrop rendered behind the popup. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Combobox.Backdrop props](https://base-ui.com/react/components/combobox) are forwarded via `...props`. ### ComboboxCollection Re-export of `ComboboxPrimitive.Collection` for defining static item collections. ### useComboboxFilter Re-export of `ComboboxPrimitive.useFilter` hook for custom filtering logic. ### useComboboxAnchor Utility hook that returns a ref for anchoring the combobox popup to a custom element. ```tsx import { useComboboxAnchor } from "@/components/ui/combobox"; const anchorRef = useComboboxAnchor(); ``` ## Accessibility ### Keyboard Interactions | Key | Action | | ----------- | --------------------------------------------------------- | | `ArrowDown` | Opens the popup (if closed) or moves to the next item | | `ArrowUp` | Opens the popup (if closed) or moves to the previous item | | `Enter` | Selects the highlighted item and closes the popup | | `Escape` | Closes the popup | | `Home` | Moves to the first item in the list | | `End` | Moves to the last item in the list | | `Tab` | Closes the popup and moves focus to the next element | | `Backspace` | Removes the last chip (in multi-select chips mode) | ### ARIA Attributes - The input has `role="combobox"` with `aria-expanded` indicating popup state. - `aria-activedescendant` tracks the currently highlighted item. - `aria-autocomplete` indicates the filtering behavior. - `ComboboxContent` has `role="listbox"` for the list of options. - `ComboboxItem` has `role="option"` with `aria-selected` for selected state and `aria-disabled` for disabled items. - `ComboboxGroup` uses `role="group"` with `aria-labelledby` linked to the group label. - `ComboboxStatus` provides a live region for screen reader announcements. - `ComboboxClear` has `aria-label="Clear selection"` for screen reader users. # Command Palette > A command palette with search, groups, and keyboard navigation built on Base UI URL: https://prototyper-ui.com/docs/components/command-palette Base UI reference: https://base-ui.com/react/components/dialog ```tsx "use client"; import * as React from "react"; import { CommandPalette, CommandPaletteContent, CommandInput, CommandGroup, CommandItem, CommandEmpty, CommandSeparator, CommandList, } from "@/components/ui/command-palette"; import { Button } from "@/components/ui/button"; export default function CommandPaletteDemo() { const [open, setOpen] = React.useState(false); return ( <> No results found. setOpen(false)}> Calendar setOpen(false)}> Search setOpen(false)}> Settings setOpen(false)} > New File setOpen(false)} > New Window Quit ); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/command-palette.json ``` This will add the following files to your project: - `components/ui/command-palette.tsx` ## Usage ```tsx import { CommandPalette, CommandPaletteContent, CommandInput, CommandGroup, CommandItem, CommandEmpty, CommandList, } from "@/components/ui/command-palette"; No results found. {}}> Search ; ``` ## Anatomy ```tsx ``` | Sub-component | `data-slot` | Purpose | Required | | ----------------------- | ------------------------- | -------------------------------------------------- | -------- | | `CommandPalette` | `command-palette` | Root provider, manages open/close state and search | Yes | | `CommandPaletteContent` | `command-palette-content` | The popup panel with overlay backdrop | Yes | | `CommandInput` | `command-input` | Text input for filtering items | Yes | | `CommandList` | `command-list` | Scrollable container for groups and items | Yes | | `CommandGroup` | `command-group` | Groups related items with an optional heading | No | | `CommandItem` | `command-item` | Individual selectable command item | Yes | | `CommandEmpty` | `command-empty` | Shown when search yields no results | No | | `CommandSeparator` | `command-separator` | Visual divider between groups | No | ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the command palette: | Slot name | Element | | ------------------------- | -------------------------------------- | | `command-palette` | Root provider (no DOM element) | | `command-palette-portal` | Portal wrapper | | `command-palette-overlay` | Backdrop overlay | | `command-palette-content` | The popup panel | | `command-input-wrapper` | Wrapper around the search icon + input | | `command-input` | The search input element | | `command-list` | Scrollable items container | | `command-group` | Group wrapper | | `command-group-heading` | Group heading text | | `command-item` | Individual item row | | `command-shortcut` | Keyboard shortcut badge | | `command-empty` | Empty state message | | `command-separator` | Divider line | ### Customization Examples ```css /* Widen the command palette */ [data-slot="command-palette-content"] { @apply max-w-2xl; } /* Custom item highlight color */ [data-slot="command-item"][data-highlighted] { @apply bg-primary/10; } ``` ```tsx { /* Override styles via className */ } {/* ... */} ; ``` ## API Reference ### CommandPalette Root component that manages dialog state, search state, and item registration. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean` | - | Controlled open state | | `onOpenChange` | `(open: boolean) => void` | - | Callback when open state changes | | `filter` | `(value: string, search: string) => boolean` | - | Custom filter function (defaults to case-insensitive includes) | | `children` | `React.ReactNode` | - | Command palette content | ### CommandPaletteContent The popup panel rendered inside a portal with an overlay backdrop. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Content (input, list, etc.) | All standard `div` props are forwarded via `...props`. ### CommandInput Search input that filters items and handles keyboard navigation. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `placeholder` | `string` | `"Type a command or search..."` | Placeholder text for the input | | `className` | `string` | - | Additional CSS classes | All standard `input` props are forwarded via `...props`. ### CommandList Scrollable container for command groups and items. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Groups, items, separators | All standard `div` props are forwarded via `...props`. ### CommandGroup Groups related items under an optional heading. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `heading` | `string` | - | Group heading label | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Command items | All standard `div` props are forwarded via `...props`. ### CommandItem An individual selectable command. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `value` | `string` | - | Value used for filtering against the search query | | `onSelect` | `() => void` | - | Callback when the item is selected (click or Enter) | | `disabled` | `boolean` | `false` | Whether the item is disabled | | `shortcut` | `string` | - | Keyboard shortcut to display on the right side | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Item content | All standard `div` props are forwarded via `...props`. ### CommandEmpty Placeholder content shown when the search query matches no items. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | `"No results found."` | Custom empty state content | All standard `div` props are forwarded via `...props`. ### CommandSeparator A visual divider between groups. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All standard `div` props are forwarded via `...props`. ## Accessibility ### Keyboard Interactions | Key | Action | | ----------- | -------------------------------------------- | | `ArrowDown` | Moves highlight to the next enabled item | | `ArrowUp` | Moves highlight to the previous enabled item | | `Enter` | Selects the currently highlighted item | | `Escape` | Closes the command palette | | `Tab` | Moves focus to the next focusable element | ### ARIA Attributes - Each `CommandItem` renders with `role="option"` and `aria-selected` reflecting the highlight state. - `aria-disabled` is set on disabled items. - The dialog is modal -- focus is trapped inside while open. - The search input receives auto-focus when the palette opens. # Container > A content constraint wrapper with max-width and padding options. URL: https://prototyper-ui.com/docs/components/container ```tsx import { Container } from "@/components/ui/container"; export default function ContainerDemo() { return (

Default container (max-w-5xl)

Narrower container (max-w-4xl)

Narrow container (max-w-2xl)

); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/container.json ``` This will add the following files to your project: - `components/ui/container.tsx` ## Usage ```tsx import { Container } from "@/components/ui/container"; ``` ```tsx

Content is constrained and centered.

``` Container is a simple `
` that constrains its children to a max-width and adds horizontal padding. Use it inside a Section or on its own when you need to center page content. ## Examples ### Narrow Content ```tsx import { Container } from "@/components/ui/container"; export default function ContainerNarrow() { return (

Article Title

A narrow, centered container is ideal for article-style content. The constrained width keeps line lengths comfortable for reading while the padding ensures breathing room on smaller screens.

Use maxWidth="lg"{" "} or maxWidth="2xl"{" "} depending on your content density.

); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target the container in CSS: | Slot name | Element | | ----------- | ---------------- | | `container` | The `
` root | ### Customization Examples ```css /* Add vertical padding to all containers */ [data-slot="container"] { @apply py-8; } ``` ```tsx Custom styled container ``` ## API Reference ### Container A centered, width-constrained content wrapper. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `maxWidth` | `"sm" \| "md" \| "lg" \| "xl" \| "2xl" \| "4xl" \| "5xl" \| "full"` | `"5xl"` | Maximum width constraint. | | `padding` | `"none" \| "sm" \| "md" \| "lg"` | `"md"` | Horizontal padding. | | `centered` | `boolean` | `true` | Whether to center the container with mx-auto. | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Container content. | Extends `React.ComponentProps<"div">`. All standard div props are forwarded via `...props`. ## Accessibility ### Keyboard Interactions Container is a non-interactive presentational wrapper and does not have keyboard interactions. ### ARIA Attributes - Renders as a plain `
` with no implicit ARIA role. - No additional ARIA attributes are needed for a layout container. # Context Menu > right-click menu with submenus and checkbox/radio items URL: https://prototyper-ui.com/docs/components/context-menu Base UI reference: https://base-ui.com/react/components/menu ```tsx import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, } from "@/components/ui/context-menu"; export default function ContextMenuDemo() { return ( Right click here Back Ctrl+[ Forward Ctrl+] Reload Ctrl+R More Tools Save Page As... Create Shortcut... Name Window... Developer Tools View Page Source Ctrl+U Inspect ); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/context-menu.json ``` This will add the following files to your project: - `components/ui/context-menu.tsx` ## Usage ```tsx import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, } from "@/components/ui/context-menu"; Right click here Item 1 Item 2 ; ``` ## Anatomy ```tsx ``` | Sub-component | `data-slot` | Purpose | Required | | ------------------------- | ---------------------------- | ------------------------------------------ | -------- | | `ContextMenu` | `context-menu` | Root provider, manages open/close state | Yes | | `ContextMenuTrigger` | `context-menu-trigger` | Element that opens the menu on right click | Yes | | `ContextMenuPortal` | `context-menu-portal` | Renders children into a portal | No | | `ContextMenuContent` | `context-menu-content` | The popup panel containing menu items | Yes | | `ContextMenuGroup` | `context-menu-group` | Groups related menu items | No | | `ContextMenuLabel` | `context-menu-label` | Non-interactive label for a group | No | | `ContextMenuItem` | `context-menu-item` | Individual actionable menu item | Yes | | `ContextMenuCheckboxItem` | `context-menu-checkbox-item` | Toggleable checkbox menu item | No | | `ContextMenuRadioGroup` | `context-menu-radio-group` | Groups radio menu items | No | | `ContextMenuRadioItem` | `context-menu-radio-item` | Radio-selectable menu item | No | | `ContextMenuSeparator` | `context-menu-separator` | Visual separator between items | No | | `ContextMenuShortcut` | `context-menu-shortcut` | Keyboard shortcut hint text | No | | `ContextMenuSub` | `context-menu-sub` | Root for a submenu | No | | `ContextMenuSubTrigger` | `context-menu-sub-trigger` | Item that opens a submenu | No | | `ContextMenuSubContent` | `context-menu-sub-content` | Submenu popup panel | No | ## Examples ### Basic ```tsx import { ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, } from "@/components/ui/context-menu"; export default function ContextMenuDemo() { return ( Right click here Back Ctrl+[ Forward Ctrl+] Reload Ctrl+R More Tools Save Page As... Create Shortcut... Name Window... Developer Tools View Page Source Ctrl+U Inspect ); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the context menu: | Slot name | Element | | ---------------------------- | ------------------------------- | | `context-menu` | Root provider (no DOM rendered) | | `context-menu-trigger` | The trigger element | | `context-menu-portal` | Portal wrapper | | `context-menu-content` | The popup panel | | `context-menu-group` | Group wrapper | | `context-menu-label` | Group label | | `context-menu-item` | Individual menu item | | `context-menu-checkbox-item` | Checkbox menu item | | `context-menu-radio-group` | Radio group wrapper | | `context-menu-radio-item` | Radio menu item | | `context-menu-separator` | Visual separator line | | `context-menu-shortcut` | Keyboard shortcut text | | `context-menu-sub` | Submenu root | | `context-menu-sub-trigger` | Submenu trigger item | | `context-menu-sub-content` | Submenu popup panel | ### Customization Examples ```css /* Change menu item highlight color */ [data-slot="context-menu-item"][data-highlighted] { @apply bg-primary text-primary-foreground; } /* Wider menu popup */ [data-slot="context-menu-content"] { @apply min-w-[12rem]; } ``` ```tsx { /* Override styles via className */ } Custom Item ; ``` ## API Reference ### ContextMenu Root component that manages open/close state. Opens on right-click of the trigger. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean` | - | Controlled open state | | `onOpenChange` | `(open: boolean) => void` | - | Callback when open state changes | All [Base UI ContextMenu.Root props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuTrigger Element that opens the context menu when right-clicked. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI ContextMenu.Trigger props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuContent The popup panel containing menu items, rendered inside a portal with a positioner. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment relative to the cursor position | | `alignOffset` | `number` | `4` | Offset from the alignment edge | | `side` | `"top" \| "bottom" \| "left" \| "right"` | `"right"` | Preferred side relative to cursor | | `sideOffset` | `number` | `0` | Gap between cursor and popup | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Menu content | All [Base UI ContextMenu.Popup props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuGroup Groups related menu items together. All [Base UI ContextMenu.Group props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuLabel Non-interactive label for a group of menu items. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `inset` | `boolean` | - | Adds left padding to align with items that have icons | | `className` | `string` | - | Additional CSS classes | All [Base UI ContextMenu.GroupLabel props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuItem Individual actionable menu item. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `"default" \| "destructive"` | `"default"` | Visual style variant | | `inset` | `boolean` | - | Adds left padding to align with items that have icons | | `className` | `string` | - | Additional CSS classes | All [Base UI ContextMenu.Item props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuCheckboxItem Toggleable checkbox menu item with a check indicator. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `checked` | `boolean` | - | Whether the item is checked | | `inset` | `boolean` | - | Adds left padding to align with items that have icons | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Item content | All [Base UI ContextMenu.CheckboxItem props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuRadioGroup Groups radio menu items for single-selection behavior. All [Base UI ContextMenu.RadioGroup props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuRadioItem Radio-selectable menu item within a radio group. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `inset` | `boolean` | - | Adds left padding to align with items that have icons | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Item content | All [Base UI ContextMenu.RadioItem props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuSeparator Visual separator between menu items or groups. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI ContextMenu.Separator props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuShortcut Displays a keyboard shortcut hint aligned to the right of a menu item. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All standard `span` props are forwarded via `...props`. ### ContextMenuSub Root provider for a submenu. All [Base UI ContextMenu.SubmenuRoot props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuSubTrigger Menu item that opens a submenu on hover or keyboard navigation. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `inset` | `boolean` | - | Adds left padding to align with items that have icons | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Trigger content | All [Base UI ContextMenu.SubmenuTrigger props](https://base-ui.com/react/components/menu) are forwarded via `...props`. ### ContextMenuSubContent Popup panel for a submenu, rendered inside a portal with a positioner. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `align` | `"start" \| "center" \| "end"` | `"start"` | Alignment relative to the trigger | | `alignOffset` | `number` | `4` | Offset from the alignment edge | | `side` | `"top" \| "bottom" \| "left" \| "right"` | `"right"` | Preferred side relative to trigger | | `sideOffset` | `number` | `0` | Gap between trigger and popup | | `className` | `string` | - | Additional CSS classes | All `ContextMenuContent` props are forwarded via `...props`. ## Accessibility ### Keyboard Interactions | Key | Action | | ------------ | -------------------------------------------------------- | | `Space` | Activates the focused menu item | | `Enter` | Activates the focused menu item | | `ArrowDown` | Moves focus to the next menu item | | `ArrowUp` | Moves focus to the previous menu item | | `ArrowRight` | Opens a submenu when focused on a sub-trigger | | `ArrowLeft` | Closes a submenu and returns focus to the parent trigger | | `Escape` | Closes the menu | | `Home` | Moves focus to the first menu item | | `End` | Moves focus to the last menu item | ### ARIA Attributes - `ContextMenuContent` receives `role="menu"`. - `ContextMenuItem` receives `role="menuitem"`. - `ContextMenuCheckboxItem` receives `role="menuitemcheckbox"` with `aria-checked`. - `ContextMenuRadioItem` receives `role="menuitemradio"` with `aria-checked`. - `ContextMenuSub` content receives `role="menu"` for nested menus. - `data-disabled` is set on disabled items, which sets `aria-disabled`. - Focus is managed within the menu and returns to the trigger area when the menu closes. # Dialog > A modal dialog with sheet variant built on Base UI URL: https://prototyper-ui.com/docs/components/dialog Base UI reference: https://base-ui.com/react/components/dialog ```tsx import { Button } from "@/components/ui/button"; import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { FieldLabel } from "@/components/ui/field"; import { TextField, Input } from "@/components/ui/text-field"; export default function DialogDemo() { return ( }> Sign up... Sign up
First Name Last Name
}> Save changes
); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/dialog.json ``` This will add the following files to your project: - `components/ui/dialog.tsx` ## Usage ```tsx import { Dialog, DialogTrigger, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; Open Dialog Title Dialog description. ; ``` ## Anatomy ```tsx {/* your content */} ``` | Sub-component | `data-slot` | Purpose | Required | | ------------------- | -------------------- | ---------------------------------------- | -------- | | `Dialog` | `dialog` | Root provider, manages open/close state | Yes | | `DialogTrigger` | `dialog-trigger` | Button that opens the dialog | Yes | | `DialogPortal` | `dialog-portal` | Renders children into a portal | No | | `DialogOverlay` | `dialog-overlay` | Backdrop behind the dialog | No | | `DialogContent` | `dialog-content` | The dialog popup panel | Yes | | `DialogHeader` | `dialog-header` | Flex container for title and description | No | | `DialogTitle` | `dialog-title` | Accessible title for the dialog | Yes | | `DialogDescription` | `dialog-description` | Accessible description for the dialog | No | | `DialogFooter` | `dialog-footer` | Flex container for action buttons | No | | `DialogClose` | `dialog-close` | Button that closes the dialog | No | ## Examples ### Alert Dialog ```tsx import { Button } from "@/components/ui/button"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; export default function AlertDialogDemo() { return ( }> Delete... Delete file This will permanently delete the selected file. Continue? }>Cancel }> Delete ); } ``` ### Sheet ```tsx import { Button } from "@/components/ui/button"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { FieldLabel } from "@/components/ui/field"; import { Switch } from "@/components/ui/switch"; import { TextField, Input } from "@/components/ui/text-field"; export default function DialogSheet() { return ( }> Open Settings Settings Manage your account preferences and notification settings.

Profile

Display Name Email

Notifications

Email notifications
Marketing emails
}>Save changes
); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the dialog: | Slot name | Element | | -------------------- | --------------------------------------- | | `dialog` | Root provider (no DOM element rendered) | | `dialog-trigger` | The trigger button | | `dialog-portal` | Portal wrapper | | `dialog-overlay` | Backdrop overlay | | `dialog-content` | The popup panel | | `dialog-header` | Header container (title + description) | | `dialog-title` | Title heading | | `dialog-description` | Description paragraph | | `dialog-footer` | Footer container (action buttons) | | `dialog-close` | Close button(s) | ### Customization Examples ```css /* Make dialogs wider by default */ [data-slot="dialog-content"] { @apply sm:max-w-lg; } /* Custom overlay color */ [data-slot="dialog-overlay"] { @apply bg-black/30; } ``` ```tsx { /* Override width via className */ } {/* ... */}; ``` ## API Reference ### Dialog Root component that manages open/close state. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean` | - | Controlled open state | | `onOpenChange` | `(open: boolean) => void` | - | Callback when open state changes | | `defaultOpen` | `boolean` | `false` | Initial open state for uncontrolled usage | | `modal` | `boolean` | `true` | Whether the dialog is modal | All [Base UI Dialog.Root props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogTrigger Button that opens the dialog when clicked. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Dialog.Trigger props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogContent The popup panel rendered inside a portal with an overlay backdrop. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `showCloseButton` | `boolean` | `true` | Whether to show the X close button | | `side` | `"top" \| "bottom" \| "left" \| "right"` | - | Turns the dialog into a sheet from this side | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Dialog content | All [Base UI Dialog.Popup props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogHeader Flex column container for title and description. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Header content | All standard `div` props are forwarded via `...props`. ### DialogFooter Flex row container for action buttons. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `showCloseButton` | `boolean` | `false` | Whether to render a "Close" button | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Footer content | All standard `div` props are forwarded via `...props`. ### DialogTitle Accessible title for the dialog, rendered as a heading. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Dialog.Title props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogDescription Accessible description rendered below the title. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Dialog.Description props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogClose Button that closes the dialog when clicked. All [Base UI Dialog.Close props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogOverlay Backdrop overlay behind the dialog. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Dialog.Backdrop props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ### DialogPortal Renders children into a React portal. All [Base UI Dialog.Portal props](https://base-ui.com/react/components/dialog) are forwarded via `...props`. ## Accessibility ### Keyboard Interactions | Key | Action | | ----------- | --------------------------------------------------------------- | | `Escape` | Closes the dialog | | `Tab` | Moves focus to the next focusable element within the dialog | | `Shift+Tab` | Moves focus to the previous focusable element within the dialog | ### ARIA Attributes - `DialogContent` receives `role="dialog"` (or `role="alertdialog"` when used as an alert dialog). - `aria-modal="true"` is set when the dialog is modal. - `aria-labelledby` is automatically linked to `DialogTitle`. - `aria-describedby` is automatically linked to `DialogDescription`. - Focus is trapped inside the dialog while it is open. - Focus returns to the trigger element when the dialog closes. ## Compose This component is available in [`@prototyperco/compose`](/docs/compose). ### Catalog Definition ```typescript title="dialog.catalog.ts" import { z } from "zod"; import { defineComponent } from "@prototyperco/compose/catalog"; export default defineComponent({ description: "A modal dialog or side sheet overlay. Open/close is controlled via a state binding path.", props: z.object({ title: z.string().describe("Dialog heading text"), description: z .string() .optional() .describe("Optional description below the title"), openPath: z .string() .describe("State path (JSON Pointer) for the open/close boolean"), side: z .enum(["top", "bottom", "left", "right"]) .optional() .describe( "When set, renders as a sheet/drawer anchored to this edge instead of a centered modal", ), }), events: [], example: { title: "Confirm action", openPath: "/dialogOpen" }, }); ``` ### Example Spec ```json { "root": "layout", "elements": { "layout": { "type": "Card", "props": { "title": "Dialog Example" }, "children": ["openBtn", "dialog"] }, "openBtn": { "type": "Button", "props": { "label": "Open Dialog" }, "$bindState": { "path": "/dialogOpen", "event": "press", "value": true } }, "dialog": { "type": "Dialog", "props": { "title": "Confirm action", "description": "Are you sure you want to proceed?", "openPath": "/dialogOpen" }, "children": ["confirmBtn"] }, "confirmBtn": { "type": "Button", "props": { "label": "Confirm", "variant": "default" } } } } ``` Learn more in the [Compose documentation](/docs/compose).
# Drawer > slide-in panel anchored to any viewport edge URL: https://prototyper-ui.com/docs/components/drawer Base UI reference: https://base-ui.com/react/components/drawer ```tsx import { Button } from "@/components/ui/button"; import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, } from "@/components/ui/drawer"; export default function DrawerDemo() { return ( }> Open Drawer Move Goal Set your daily activity goal.
350
Calories/day
}> Cancel
); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/drawer.json ``` This will add the following files to your project: - `components/ui/drawer.tsx` ## Usage ```tsx import { Drawer, DrawerTrigger, DrawerContent, DrawerHeader, DrawerTitle, DrawerDescription, } from "@/components/ui/drawer"; Open Drawer Title Drawer description. ; ``` ## Anatomy ```tsx {/* your content */} ``` | Sub-component | `data-slot` | Purpose | Required | | ------------------- | -------------------- | ---------------------------------------- | -------- | | `Drawer` | `drawer` | Root provider, manages open/close state | Yes | | `DrawerTrigger` | `drawer-trigger` | Button that opens the drawer | Yes | | `DrawerPortal` | `drawer-portal` | Renders children into a portal | No | | `DrawerOverlay` | `drawer-overlay` | Backdrop behind the drawer | No | | `DrawerContent` | `drawer-content` | The drawer popup panel | Yes | | `DrawerHeader` | `drawer-header` | Flex container for title and description | No | | `DrawerTitle` | `drawer-title` | Accessible title for the drawer | Yes | | `DrawerDescription` | `drawer-description` | Accessible description for the drawer | No | | `DrawerFooter` | `drawer-footer` | Flex container for action buttons | No | | `DrawerClose` | `drawer-close` | Button that closes the drawer | No | ## Examples ### Directions Use the `direction` prop on `DrawerContent` to slide the drawer in from any edge. ```tsx "use client"; import * as React from "react"; import { Button } from "@/components/ui/button"; import { Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger, } from "@/components/ui/drawer"; const directions = ["top", "right", "bottom", "left"] as const; export default function DrawerSides() { return (
{directions.map((direction) => ( }> {direction.charAt(0).toUpperCase() + direction.slice(1)} Drawer from {direction} This drawer slides in from the {direction}.

Drawer content goes here. You can place any content inside.

}> Close
))}
); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the drawer: | Slot name | Element | | -------------------- | --------------------------------------- | | `drawer` | Root provider (no DOM element rendered) | | `drawer-trigger` | The trigger button | | `drawer-portal` | Portal wrapper | | `drawer-overlay` | Backdrop overlay | | `drawer-content` | The popup panel | | `drawer-header` | Header container (title + description) | | `drawer-title` | Title heading | | `drawer-description` | Description paragraph | | `drawer-footer` | Footer container (action buttons) | | `drawer-close` | Close button(s) | ### Customization Examples ```css /* Make side drawers wider */ [data-slot="drawer-content"][data-drawer-direction="right"], [data-slot="drawer-content"][data-drawer-direction="left"] { @apply sm:max-w-md; } /* Custom overlay color */ [data-slot="drawer-overlay"] { @apply bg-black/30; } ``` ```tsx { /* Override direction via prop */ } {/* ... */}; ``` ## API Reference ### Drawer Root component that manages open/close state. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `open` | `boolean` | - | Controlled open state | | `onOpenChange` | `(open: boolean) => void` | - | Callback when open state changes | | `defaultOpen` | `boolean` | `false` | Initial open state for uncontrolled usage | | `modal` | `boolean` | `true` | Whether the drawer is modal | All [Base UI Drawer.Root props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerTrigger Button that opens the drawer when clicked. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Drawer.Trigger props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerContent The popup panel rendered inside a portal with an overlay backdrop. Includes an automatic drag handle when `direction` is `"bottom"`. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `direction` | `"top" \| "bottom" \| "left" \| "right"` | `"bottom"` | The edge of the viewport the drawer slides in from | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Drawer content | All [Base UI Drawer.Popup props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerHeader Flex column container for title and description. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `direction` | `string` | - | When "bottom" or "top", centers text on mobile | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Header content | All standard `div` props are forwarded via `...props`. ### DrawerFooter Flex column container for action buttons. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | | `children` | `React.ReactNode` | - | Footer content | All standard `div` props are forwarded via `...props`. ### DrawerTitle Accessible title for the drawer, rendered as a heading. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Drawer.Title props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerDescription Accessible description rendered below the title. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Drawer.Description props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerClose Button that closes the drawer when clicked. All [Base UI Drawer.Close props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerOverlay Backdrop overlay behind the drawer. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `className` | `string` | - | Additional CSS classes | All [Base UI Drawer.Backdrop props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ### DrawerPortal Renders children into a React portal. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `children` | `React.ReactNode` | - | Content to render in the portal | All [Base UI Drawer.Portal props](https://base-ui.com/react/components/drawer) are forwarded via `...props`. ## Accessibility ### Keyboard Interactions | Key | Action | | ----------- | --------------------------------------------------------------- | | `Escape` | Closes the drawer | | `Tab` | Moves focus to the next focusable element within the drawer | | `Shift+Tab` | Moves focus to the previous focusable element within the drawer | ### ARIA Attributes - `DrawerContent` receives `role="dialog"`. - `aria-modal="true"` is set when the drawer is modal. - `aria-labelledby` is automatically linked to `DrawerTitle`. - `aria-describedby` is automatically linked to `DrawerDescription`. - Focus is trapped inside the drawer while it is open. - Focus returns to the trigger element when the drawer closes.
# Field > Form field wrapper with label, description, and error message URL: https://prototyper-ui.com/docs/components/field Base UI reference: https://base-ui.com/react/components/field ```tsx import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldDemo() { return ( Email We will never share your email. ); } ``` ## Installation ```bash pnpm dlx shadcn@latest add https://prototyper-ui.com/r/field.json ``` This will add the following files to your project: - `components/ui/field.tsx` ## Usage ```tsx import { Field, FieldLabel, FieldDescription } from "@/components/ui/field"; ``` ```tsx Email Enter your email address. ``` ## Anatomy ```tsx
{/* input, checkbox, or other control */}
``` Or with `FieldGroup` for grouped inputs: ```tsx {/* grouped inputs or controls */} ``` | Sub-component | `data-slot` | Purpose | Required | | ------------------ | ------------------- | --------------------------------------------- | -------- | | `Field` | `field` | Root wrapper, provides layout and orientation | Yes | | `FieldLabel` | `field-label` | Label for the field control | No | | `FieldTitle` | `field-label` | Non-interactive label text (renders as `div`) | No | | `FieldDescription` | `field-description` | Helper/description text | No | | `FieldError` | `field-error` | Validation error message with `role="alert"` | No | | `FieldGroup` | `field-group` | Styled group container for composed inputs | No | | `FieldContent` | `field-content` | Content wrapper for description and error | No | | `FieldSet` | `field-set` | Fieldset element for grouping multiple fields | No | | `FieldLegend` | `field-legend` | Legend for a fieldset | No | | `FieldSeparator` | `field-separator` | Visual separator between fields | No | ## Examples ### Horizontal ```tsx import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldHorizontal() { return ( Username ); } ``` ### Required ```tsx import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldRequired() { return ( Full name Your legal full name. ); } ``` ### Error ```tsx import { Field, FieldError, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldErrorDemo() { return ( Email Please enter a valid email address. ); } ``` ### With Select ```tsx import { Field, FieldDescription, FieldLabel } from "@/components/ui/field"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; export default function FieldWithSelect() { return ( Country Select your country of residence. ); } ``` ### With Checkbox ```tsx import { Checkbox, CheckboxControl, CheckboxIndicator, } from "@/components/ui/checkbox"; import { Field, FieldContent, FieldDescription } from "@/components/ui/field"; export default function FieldWithCheckbox() { return ( Accept terms and conditions You agree to our Terms of Service and Privacy Policy. ); } ``` ### Field Group ```tsx import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldGroupDemo() { return ( Price $ USD ); } ``` ### Fieldset ```tsx import { Field, FieldLabel, FieldLegend, FieldSeparator, FieldSet, } from "@/components/ui/field"; import { Input } from "@/components/ui/text-field"; export default function FieldFieldset() { return (
Shipping Address Street City Zip code
); } ``` ## Styling ### Data Slots Use `data-slot` attributes to target specific parts of the field: | Slot name | Element | | ------------------------- | ------------------------------------- | | `field` | Root wrapper div | | `field-label` | Label element | | `field-description` | Description paragraph | | `field-error` | Error message container | | `field-group` | Grouped input container | | `field-content` | Content wrapper (description + error) | | `field-set` | Fieldset element | | `field-legend` | Legend element | | `field-separator` | Visual separator | | `field-separator-content` | Text inside separator | ### Customization Examples ```css /* Change label styling globally */ [data-slot="field-label"] { @apply text-base font-semibold; } /* Style error messages */ [data-slot="field-error"] { @apply text-xs font-medium; } /* Make field groups pill-shaped */ [data-slot="field-group"] { @apply rounded-full; } ``` ```tsx { /* Override field orientation */ } Name ; ``` ## API Reference ### Field Root wrapper that provides layout direction and grouping for form controls. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `orientation` | `"vertical" \| "horizontal" \| "responsive"` | `"vertical"` | Layout direction of the field. "responsive" switches from vertical to horizontal at the @md container breakpoint. | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Field content. | All standard `div` props are forwarded via `...props`. ### FieldLabel Label element that wraps or precedes a form control. Built on the `Label` component. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `required` | `boolean` | - | Displays a red asterisk (*) after the label text. | | `className` | `string` | - | Additional CSS classes. | | `children` | `React.ReactNode` | - | Label content. | All `Label` props are forwarded via `...props`. ### FieldTitle Non-interactive label text rendered as a `div` instead of a `