{
  "site": {
    "name": "Iconiq UI",
    "url": "https://iconiqui.com",
    "description": "Iconiq UI is an open-source React component library built around the shadcn registry workflow. Browse motion-powered UI primitives, install them as local files, and adapt them directly inside modern interfaces.",
    "llms": {
      "overview": "https://iconiqui.com/llms.txt",
      "full": "https://iconiqui.com/llms-full.txt"
    },
    "catalogs": {
      "aiIndex": "https://iconiqui.com/ai-index.json"
    }
  },
  "guides": [
    {
      "title": "Overview",
      "href": "/",
      "url": "https://iconiqui.com",
      "summary": "Homepage with the full live component playground and the primary installation path for the registry."
    },
    {
      "title": "Introduction",
      "href": "/introduction",
      "url": "https://iconiqui.com/introduction",
      "summary": "Product overview, design principles, and the delivery model behind the Iconiq component library."
    },
    {
      "title": "Installation",
      "href": "/installation",
      "url": "https://iconiqui.com/installation",
      "summary": "Installation guide for the shadcn registry flow, direct registry JSON URLs, and sample component entries."
    },
    {
      "title": "MCP",
      "href": "/mcp",
      "url": "https://iconiqui.com/mcp",
      "summary": "MCP setup guide for connecting Iconiq to AI coding tools through the shadcn registry workflow."
    }
  ],
  "components": [
    {
      "slug": "prompt-box",
      "name": "Prompt Box",
      "href": "/blocks/prompt-box",
      "url": "https://iconiqui.com/blocks/prompt-box",
      "installPackage": "@iconiq/prompt-box",
      "installCommand": "npx shadcn@latest add @iconiq/prompt-box",
      "registryPath": "prompt-box.json",
      "registryUrl": "https://iconiqui.com/r/prompt-box.json",
      "summary": "Expandable prompt surface that grows from a compact pill into a textarea with model controls, attachment action, and send or voice affordances.",
      "apiSections": [
        {
          "id": "prompt-input",
          "title": "PromptInput",
          "summary": "Expandable prompt surface that grows from a compact pill into a textarea with model controls, attachment action, and send or voice affordances.",
          "notes": [
            "Built on Base UI Input — collapsed state uses a read-only field, expanded state renders a textarea through the `render` prop.",
            "Click the collapsed field to expand and focus the prompt input.",
            "Press Enter to submit when the field has content; Shift+Enter inserts a newline.",
            "The expanded surface starts compact and grows with your prompt up to 300px, then scrolls inside the textarea.",
            "Press Escape or blur away with an empty draft to collapse back to the compact pill.",
            "The settings menu shows optional `menuActions`, then featured model rows, submenu rows with current values, and optional more-menu flyouts separated by dividers.",
            "The plus button opens an optional add menu when `plusMenuItems` is provided. Items support icons, keyboard shortcuts, and nested submenus.",
            "The footer reveals the settings popover and plus add menu while expanded.",
            "The trailing action button shows a microphone icon when empty and an arrow icon once text is entered."
          ],
          "fields": [
            {
              "name": "onSubmit",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called with the trimmed prompt when the user presses Enter without Shift or clicks the send button."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Placeholder copy for the collapsed and expanded prompt field."
            },
            {
              "name": "menuActions",
              "type": "PromptMenuAction[]",
              "defaultValue": "",
              "required": false,
              "description": "Optional dropdown actions rendered above setting groups. Each action has `label`, optional `icon`, and `onSelect`."
            },
            {
              "name": "plusMenuItems",
              "type": "PromptPlusMenuItem[]",
              "defaultValue": "",
              "required": false,
              "description": "Items for the plus-button add menu. Actions use `onSelect` with optional `shortcut`. Submenus pass `options` and `onOptionSelect`."
            },
            {
              "name": "settingGroups",
              "type": "PromptSettingGroup[]",
              "defaultValue": "",
              "required": false,
              "description": "Grouped settings for the footer menu. Use `display: \"featured\"` for a selected summary row, `display: \"submenu\"` for a value row with flyout, and `moreMenuLabel` for an extra picker row (e.g. More models). Options support optional `description` text."
            },
            {
              "name": "settings",
              "type": "Record<string, string>",
              "defaultValue": "",
              "required": false,
              "description": "Controlled map of selected values keyed by setting group id."
            },
            {
              "name": "defaultSettings",
              "type": "Record<string, string>",
              "defaultValue": "",
              "required": false,
              "description": "Initial selected values for uncontrolled usage, keyed by setting group id."
            },
            {
              "name": "onSettingsChange",
              "type": "(settings: Record<string, string>) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the user picks a new option in any settings group."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "b-button",
      "name": "Button",
      "href": "/buttons-and-actions/button",
      "url": "https://iconiqui.com/buttons-and-actions/button",
      "installPackage": "@iconiq/b-button",
      "installCommand": "npx shadcn@latest add @iconiq/b-button",
      "registryPath": "b-button.json",
      "registryUrl": "https://iconiqui.com/r/b-button.json",
      "summary": "Base UI button with the shadcn-style variant recipe, spring press feedback, optional intrinsic width animation, and Motion ripple layer.",
      "apiSections": [
        {
          "id": "button",
          "title": "Button",
          "summary": "Base UI button with the shadcn-style variant recipe, spring press feedback, optional intrinsic width animation, and Motion ripple layer.",
          "notes": [
            "Standard button attributes such as onClick, aria-*, name, form, and data-* are forwarded to the underlying motion.button.",
            "The local pointer-down handler calls your onPointerDown first, then respects e.defaultPrevented before deciding whether to enter the pressed state or spawn a ripple.",
            "Pointer, keyboard, and blur handlers keep the pressed state in sync so Space and Enter get the same immediate feedback as pointer input.",
            "animateSize works best on intrinsically sized buttons rather than width-constrained layouts such as w-full.",
            "When you render an icon-only button, add an aria-label so assistive tech still gets an accessible name."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"default\" | \"destructive\" | \"outline\" | \"secondary\" | \"ghost\" | \"link\"",
              "defaultValue": "default",
              "required": false,
              "description": "Chooses the visual recipe from the exported buttonVariants map."
            },
            {
              "name": "linkUnderline",
              "type": "\"motion\" | \"static\"",
              "defaultValue": "\"motion\" (when variant is link)",
              "required": false,
              "description": "Link variant only. motion keeps foreground text with a grey baseline underline that fills darker on hover. static uses the same text size as other variants with hover:underline."
            },
            {
              "name": "size",
              "type": "\"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\"",
              "defaultValue": "default",
              "required": false,
              "description": "Controls the shadcn-style height, padding, gap, radius, and icon sizing for text and icon-only buttons."
            },
            {
              "name": "animateSize",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Animates the button width with a spring as its intrinsic content changes, which is useful for labels like Continue, Saving..., and Saved on the same control."
            },
            {
              "name": "disableRipple",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Skips the pointer ripple when you want only the press-state feedback. Link buttons also skip the ripple by default to avoid a contained splash on text-only actions."
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\"",
              "defaultValue": "button",
              "required": false,
              "description": "Passed directly to the underlying motion.button so the component does not submit forms accidentally by default."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Content rendered above the ripple layer inside a z-10 span."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional icon rendered inline with the label. Nested SVGs inherit the built-in 1rem sizing utility."
            },
            {
              "name": "iconPosition",
              "type": "\"start\" | \"end\"",
              "defaultValue": "\"start\"",
              "required": false,
              "description": "Chooses whether the optional icon renders before or after the button text inside the same inline content row."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged after the generated CVA classes, making it the main escape hatch for one-off layout changes."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Native disabled state. It also prevents ripple creation because the pointer-down handler exits early."
            }
          ]
        },
        {
          "id": "button-variants",
          "title": "buttonVariants",
          "summary": "The CVA recipe exported alongside the component so matching button classes can be reused on links or custom wrappers.",
          "notes": [
            "Variants ship with six visual states and eight size tokens, including icon-only sizes.",
            "Because buttonVariants is a plain CVA export, you can compose it independently from the Button component when you do not want a motion.button element."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"default\" | \"destructive\" | \"outline\" | \"secondary\" | \"ghost\" | \"link\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Visual recipe passed to the CVA helper when composing classes outside the Button component."
            },
            {
              "name": "size",
              "type": "\"default\" | \"xs\" | \"sm\" | \"lg\" | \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Size token passed to the CVA helper for text and icon-only button recipes."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional classes merged after the generated variant and size classes."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "class-variance-authority"
      ]
    },
    {
      "slug": "button-group",
      "name": "Button Group",
      "href": "/buttons-and-actions/button-group",
      "url": "https://iconiqui.com/buttons-and-actions/button-group",
      "installPackage": "@iconiq/button-group",
      "installCommand": "npx shadcn@latest add @iconiq/button-group",
      "registryPath": "button-group.json",
      "registryUrl": "https://iconiqui.com/r/button-group.json",
      "summary": "Compact bordered action button with muted idle text, darker hover text, optional ripple feedback, and shadcn-style size controls.",
      "apiSections": [
        {
          "id": "button-group-button",
          "title": "Button",
          "summary": "Compact bordered action button with muted idle text, darker hover text, optional ripple feedback, and shadcn-style size controls.",
          "notes": [
            "Most standard button props such as type, disabled, onClick, name, value, aria-*, and data-* are forwarded to the underlying motion button.",
            "The public prop surface intentionally leaves out the native drag and CSS animation callback props because they conflict with Motion's own handler names."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Button content rendered inside an inline span so icon-and-label pairs keep consistent spacing across sizes."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root button. Use it for local width, spacing, or surface overrides."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Compacts or expands the control while keeping the same toolbar-style border and hover treatment."
            },
            {
              "name": "disableRipple",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Turns off the click ripple while preserving the rest of the hover and focus styling."
            },
            {
              "name": "showBorder",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Removes the outer border when set to false, which is useful for quieter toolbar-style actions."
            }
          ]
        },
        {
          "id": "button-group-icon-button",
          "title": "IconButton",
          "summary": "Icon-only toolbar action that shares the same compact border, muted idle tone, and optional ripple behavior as Button.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Icon content rendered inside the inline content span. SVG children inherit the built-in size utilities for the active size variant."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the icon button root for size or surface overrides."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Controls the square footprint of the icon button without changing its general look and feel."
            },
            {
              "name": "disableRipple",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables the click ripple for quieter toolbar actions."
            },
            {
              "name": "showBorder",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Removes the outer border when set to false so the icon action can sit more quietly beside a borderless group."
            }
          ]
        },
        {
          "id": "button-group-layout",
          "title": "ButtonGroup",
          "summary": "Slot-aware flex wrapper for arranging adjacent controls with horizontal or vertical rounding rules.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Buttons, icon buttons, ButtonGroupText, ButtonGroupSeparator, ButtonGroupItems, or any other data-slot controls you want to keep together."
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\"",
              "defaultValue": "\"horizontal\"",
              "required": false,
              "description": "Chooses the grouped rounding and shared-border direction used by buttonGroupVariants."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer group. Use it for wrapping, alignment, or local spacing overrides."
            }
          ]
        },
        {
          "id": "button-group-text",
          "title": "ButtonGroupText",
          "summary": "Non-interactive text segment for labeling a group without leaving the shared button-group surface.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Short label or inline content rendered inside the grouped text segment."
            },
            {
              "name": "render",
              "type": "useRender render prop",
              "defaultValue": "",
              "required": false,
              "description": "Optional Base UI render override when you need a different element while keeping the same merged props."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default muted bordered text segment classes."
            }
          ]
        },
        {
          "id": "button-group-separator",
          "title": "ButtonGroupSeparator",
          "summary": "Separator segment for splitting labels, buttons, inputs, and grouped actions inside ButtonGroup.",
          "notes": [],
          "fields": [
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\"",
              "defaultValue": "\"vertical\"",
              "required": false,
              "description": "Controls the separator axis. Vertical separators are the default for horizontal button groups."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the self-stretching separator classes for custom color or spacing."
            }
          ]
        },
        {
          "id": "button-group-items",
          "title": "ButtonGroupItems",
          "summary": "Segmented button shell that converts valid child elements into compact internal buttons with muted idle text and darker hover states.",
          "notes": [
            "Only valid React elements are rendered. Non-element children are ignored.",
            "The child node itself is not preserved; ButtonGroupItems reads each child's props and children, then renders a fresh motion button for that slot.",
            "When showDividers is false, hover feedback moves as a shared spring layer between items instead of flashing independently on each button."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Pass plain button-like elements as children. Their props and children are hoisted into the internal motion buttons rendered by the group."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer segmented wrapper for width or surface overrides."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Sets the shared height, padding, and typography of the grouped buttons."
            },
            {
              "name": "showDividers",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Removes the internal separator lines and the outer wrapper border when set to false, then switches the group to a smoother shared hover surface."
            },
            {
              "name": "disableRipple",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Turns off the ripple for every internal button rendered by the group."
            }
          ]
        },
        {
          "id": "segmented-control",
          "title": "SegmentedControl",
          "summary": "String-based segmented selector with compact sizing, keyboard support, muted idle labels, and a spring-driven selected indicator.",
          "notes": [
            "The control uses radiogroup semantics with arrow-key, Home, and End navigation."
          ],
          "fields": [
            {
              "name": "options",
              "type": "string[]",
              "defaultValue": "",
              "required": true,
              "description": "Ordered list of visible segments. The first option becomes the uncontrolled initial selection when value is not provided."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected option. When provided, the internal state syncs to this prop through an effect."
            },
            {
              "name": "onChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called with the selected option whenever a segment is pressed."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the segmented wrapper for width, alignment, or spacing overrides."
            },
            {
              "name": "layoutId",
              "type": "string",
              "defaultValue": "\"segmented-indicator\"",
              "required": false,
              "description": "Motion layout id used by the selected indicator. Override it when you render multiple segmented controls on the same page and want isolated indicator motion."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Controls the overall density of the segmented control shell and each segment inside it."
            }
          ]
        },
        {
          "id": "button-group-motion",
          "title": "Motion and interaction",
          "summary": "Each export keeps the same tactile feel, but the default presentation is now much more compact and toolbar-like.",
          "notes": [
            "Button, IconButton, and ButtonGroupItems all default to muted text that darkens on hover, which better matches compact shadcn-style controls.",
            "The ButtonGroup wrapper uses the exported buttonGroupVariants CVA recipe, while existing motion-powered controls keep their ripple and shared-hover behavior.",
            "Ripple feedback can now be turned off per surface, which is useful when you want a quieter desktop toolbar feel.",
            "SegmentedControl keeps motion focused on selection changes rather than entrance effects, so the control feels faster and less oversized."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "class-variance-authority"
      ]
    },
    {
      "slug": "flux-button",
      "name": "Flux Button",
      "href": "/buttons-and-actions/flux-button",
      "url": "https://iconiqui.com/buttons-and-actions/flux-button",
      "installPackage": "@iconiq/flux-button",
      "installCommand": "npx shadcn@latest add @iconiq/flux-button",
      "registryPath": "flux-button.json",
      "registryUrl": "https://iconiqui.com/r/flux-button.json",
      "summary": "Async button with idle, loading, and success states, plus b-button visual variants.",
      "apiSections": [
        {
          "id": "flux-button",
          "title": "FluxButton",
          "summary": "Async button with idle, loading, and success states, plus b-button visual variants.",
          "notes": [
            "Built on `@base-ui/react/button` with a Motion render surface, matching the b-button integration pattern.",
            "Locks interaction while loading or showing success without applying disabled opacity, using aria-disabled and pointer-events-none instead.",
            "Motion transitions start only after the first click, so the button renders statically on page load.",
            "Install path is `components/ui/flux-button.tsx` with the `FluxButton` export."
          ],
          "fields": [
            {
              "name": "idleLabel",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Label shown before the action starts."
            },
            {
              "name": "loadingLabel",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Label shown with the built-in loader while onAction is in progress."
            },
            {
              "name": "successLabel",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Label shown after onAction resolves."
            },
            {
              "name": "successIcon",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional icon shown on success. Pass any node, such as a Lucide checkmark. Omit for text-only success."
            },
            {
              "name": "onAction",
              "type": "() => void | Promise<void>",
              "defaultValue": "",
              "required": true,
              "description": "Runs when the button is pressed, drives loading and success states, then returns to idle after successHold."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"outline\" | \"secondary\" | \"ghost\" | \"destructive\" | \"link\"",
              "defaultValue": "default",
              "required": false,
              "description": "Visual style variant. Matches the b-button variant set."
            },
            {
              "name": "successHold",
              "type": "number",
              "defaultValue": "1000",
              "required": false,
              "description": "Milliseconds to hold the success state before returning to the idle label."
            },
            {
              "name": "size",
              "type": "\"xs\" | \"sm\" | \"default\" | \"lg\"",
              "defaultValue": "default",
              "required": false,
              "description": "Height and horizontal padding preset. Matches b-button sizes."
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\"",
              "defaultValue": "button",
              "required": false,
              "description": "Native button type. Use submit inside forms; defaults to button so the control does not submit unless you opt in."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Native disabled state. Also blocks the action flow while true."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the root button element."
            },
            {
              "name": "onClick",
              "type": "React.MouseEventHandler<HTMLButtonElement>",
              "defaultValue": "",
              "required": false,
              "description": "Native click handler forwarded to the underlying button."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react/button",
        "class-variance-authority",
        "lucide-react",
        "motion"
      ]
    },
    {
      "slug": "icon-bar",
      "name": "Icon Bar",
      "href": "/buttons-and-actions/icon-bar",
      "url": "https://iconiqui.com/buttons-and-actions/icon-bar",
      "installPackage": "@iconiq/icon-bar",
      "installCommand": "npx shadcn@latest add @iconiq/icon-bar",
      "registryPath": "icon-bar.json",
      "registryUrl": "https://iconiqui.com/r/icon-bar.json",
      "summary": "Horizontal toolbar of compact icon chips. Hover or focus previews labels; clicking selects one item and keeps it expanded.",
      "apiSections": [
        {
          "id": "icon-bar",
          "title": "IconBar",
          "summary": "Horizontal toolbar of compact icon chips. Hover or focus previews labels; clicking selects one item and keeps it expanded.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string | null",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected item value. Pair with onValueChange for fully controlled selection."
            },
            {
              "name": "defaultValue",
              "type": "string | null",
              "defaultValue": "",
              "required": false,
              "description": "Optional initial selected item when uncontrolled. Omit to start with every chip collapsed until the user clicks one."
            },
            {
              "name": "onValueChange",
              "type": "(value: string | null) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when selection changes. Receives null when the active chip is clicked again to deselect."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names applied to the outer flex container."
            },
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "One or more IconBarItem elements rendered in a single row with consistent spacing."
            }
          ]
        },
        {
          "id": "icon-bar-item",
          "title": "IconBarItem",
          "summary": "Individual pill chip with a Lucide icon and animated label reveal on hover, focus, or selection.",
          "notes": [
            "Only one item stays expanded at a time. Clicking a chip selects it; clicking another moves selection; clicking the active chip again collapses it.",
            "Hover and keyboard focus preview labels on non-selected chips. Give each item a unique value when labels repeat.",
            "In controlled mode, update value from onValueChange (including null on deselect) for the UI to stay in sync."
          ],
          "fields": [
            {
              "name": "icon",
              "type": "LucideIcon",
              "defaultValue": "",
              "required": true,
              "description": "Lucide icon component rendered inside the fixed 36px icon well."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Short text revealed when the chip expands. Keep labels concise so the width animation stays smooth."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Selection identity for this chip. Defaults to label when omitted."
            },
            {
              "name": "onClick",
              "type": "(event: React.MouseEvent<HTMLButtonElement>) => void",
              "defaultValue": "",
              "required": false,
              "description": "Optional click handler fired after selection updates."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables interaction, hover preview, and selection."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the chip button."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react/toggle",
        "@base-ui/react/toggle-group",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "toggle",
      "name": "Toggle",
      "href": "/buttons-and-actions/toggle",
      "url": "https://iconiqui.com/buttons-and-actions/toggle",
      "installPackage": "@iconiq/toggle",
      "installCommand": "npx shadcn@latest add @iconiq/toggle",
      "registryPath": "toggle.json",
      "registryUrl": "https://iconiqui.com/r/toggle.json",
      "summary": "Two-state button with spring press feedback and a muted fill that bounces in when pressed.",
      "apiSections": [
        {
          "id": "toggle",
          "title": "Toggle",
          "summary": "Two-state button with spring press feedback and a muted fill that bounces in when pressed.",
          "notes": [
            "Use aria-label or visible text when the toggle contains only an icon.",
            "Additional primitive props such as value, name, and form attributes are forwarded to the root button."
          ],
          "fields": [
            {
              "name": "pressed",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled pressed state. Pass this when the parent owns whether the toggle is on."
            },
            {
              "name": "defaultPressed",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Initial pressed state for uncontrolled usage. The component manages future toggles internally."
            },
            {
              "name": "onPressedChange",
              "type": "(pressed: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called with the next pressed state whenever the toggle is activated or deactivated."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"outline\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Visual treatment. Outline adds a border for toolbar or segmented layouts."
            },
            {
              "name": "size",
              "type": "\"default\" | \"sm\" | \"lg\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Height, padding, and icon sizing preset for compact toolbars or larger action rows."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables interaction and dims the control while preserving its pressed appearance."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root button for local spacing, width, or color overrides."
            }
          ]
        },
        {
          "id": "toggle-motion",
          "title": "Motion and interaction behavior",
          "summary": "Pressed state drives a horizontal liquid wipe, a one-shot light sheen, and tactile icon motion.",
          "notes": [
            "The muted fill wipes in from the left when pressed and retracts to the right on release with a heavy spring.",
            "Each state change sends a diagonal sheen across the surface once. Outline keeps the same outer border in both states.",
            "Icons scale and squash on press with a spring settle."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "class-variance-authority",
        "motion"
      ]
    },
    {
      "slug": "toggle-group",
      "name": "Toggle Group",
      "href": "/buttons-and-actions/toggle-group",
      "url": "https://iconiqui.com/buttons-and-actions/toggle-group",
      "installPackage": "@iconiq/toggle-group",
      "installCommand": "npx shadcn@latest add @iconiq/toggle-group",
      "registryPath": "toggle-group.json",
      "registryUrl": "https://iconiqui.com/r/toggle-group.json",
      "summary": "Root container for a connected set of toggle buttons with shared variant, size, spacing, and orientation settings.",
      "apiSections": [
        {
          "id": "toggle-group",
          "title": "ToggleGroup",
          "summary": "Root container for a connected set of toggle buttons with shared variant, size, spacing, and orientation settings.",
          "notes": [
            "Default spacing is 4px between items. Pass spacing={0} to remove the gap entirely.",
            "Each item uses the same fluid wipe fill, sheen sweep, and icon press feedback as the standalone Toggle component.",
            "Group items inherit variant and size from context but can override either prop locally."
          ],
          "fields": [
            {
              "name": "type",
              "type": "\"single\" | \"multiple\"",
              "defaultValue": "\"multiple\"",
              "required": false,
              "description": "Selection mode. Multiple allows several active items by default; single keeps one pressed item at a time."
            },
            {
              "name": "value",
              "type": "string | string[]",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selection. Pass a string for single mode or a string array for multiple mode."
            },
            {
              "name": "defaultValue",
              "type": "string | string[]",
              "defaultValue": "",
              "required": false,
              "description": "Initial selection for uncontrolled usage in the matching single or multiple mode."
            },
            {
              "name": "onValueChange",
              "type": "(value: string | string[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called with the next selection whenever an item is pressed or released."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"outline\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Shared visual treatment applied to every item unless an item overrides it locally."
            },
            {
              "name": "size",
              "type": "\"default\" | \"sm\" | \"lg\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Shared height, padding, and icon sizing preset for all group items."
            },
            {
              "name": "spacing",
              "type": "number",
              "defaultValue": "1",
              "required": false,
              "description": "Gap between items in spacing units. Defaults to 1 (4px). Set to 0 to remove the gap."
            },
            {
              "name": "orientation",
              "type": "\"horizontal\" | \"vertical\"",
              "defaultValue": "\"horizontal\"",
              "required": false,
              "description": "Layout direction for the group. Vertical stacks items and adjusts connected border handling."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables the entire group and all nested items."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root group wrapper for local layout or width overrides."
            }
          ]
        },
        {
          "id": "toggle-group-item",
          "title": "ToggleGroupItem",
          "summary": "Individual toggle button inside the group with the same fluid motion as the standalone toggle.",
          "notes": [
            "Items share the standalone toggle fluid motion system: liquid wipe fill, sheen sweep, and icon press squeeze."
          ],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable identifier used when reading or updating the group selection."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"outline\"",
              "defaultValue": "",
              "required": false,
              "description": "Optional local override for the shared group variant treatment."
            },
            {
              "name": "size",
              "type": "\"default\" | \"sm\" | \"lg\"",
              "defaultValue": "",
              "required": false,
              "description": "Optional local override for the shared group size preset."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables this item without affecting the rest of the group."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the item button for local width, color, or spacing overrides."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Icon or label content rendered inside the item. Pair icon-only items with aria-label."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "class-variance-authority",
        "motion"
      ]
    },
    {
      "slug": "avatar",
      "name": "Avatar",
      "href": "/display-and-content/avatar",
      "url": "https://iconiqui.com/display-and-content/avatar",
      "installPackage": "@iconiq/avatar",
      "installCommand": "npx shadcn@latest add @iconiq/avatar",
      "registryPath": "avatar.json",
      "registryUrl": "https://iconiqui.com/r/avatar.json",
      "summary": "Base UI avatar root with shared sizing and an optional tooltip for hover or focus status hints.",
      "apiSections": [
        {
          "id": "avatar",
          "title": "Avatar",
          "summary": "Base UI avatar root with shared sizing and an optional tooltip for hover or focus status hints.",
          "notes": [
            "The root renders data-slot=\"avatar\" and data-size so grouped stacks and badges can respond to the selected size.",
            "The root keeps a circular border overlay with dark/light blend handling and accepts the full Base UI Root props surface."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Compose AvatarImage, AvatarFallback, and an optional AvatarBadge inside the root."
            },
            {
              "name": "size",
              "type": "\"default\" | \"sm\" | \"lg\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Controls the root size and drives badge/fallback sizing through data-size selectors."
            },
            {
              "name": "tooltip",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional short label shown in the Iconiq tooltip surface when the entire avatar is hovered or focused."
            },
            {
              "name": "tooltipSide",
              "type": "\"top\" | \"bottom\" | \"left\" | \"right\"",
              "defaultValue": "\"right\"",
              "required": false,
              "description": "Preferred side for the avatar tooltip bubble. The default collision order is right, left, top, then bottom."
            },
            {
              "name": "tooltipDelay",
              "type": "number",
              "defaultValue": "0.15",
              "required": false,
              "description": "Delay in seconds before the avatar tooltip opens."
            },
            {
              "name": "tooltipClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the tooltip bubble when the avatar tooltip is enabled."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the Base UI avatar root. Use it for local radius, ring, or size overrides."
            }
          ]
        },
        {
          "id": "avatar-image",
          "title": "AvatarImage",
          "summary": "Image slot for the compound avatar, backed by Base UI's image loading behavior.",
          "notes": [],
          "fields": [
            {
              "name": "src",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Image URL passed to the underlying Base UI image primitive."
            },
            {
              "name": "alt",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Accessible text for the image. Pass an empty string only when the avatar is decorative."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the full-size rounded image classes."
            }
          ]
        },
        {
          "id": "avatar-fallback",
          "title": "AvatarFallback",
          "summary": "Fallback slot shown by Base UI while the image is loading, missing, or failed.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Initials, icon, or other compact fallback content centered inside the avatar."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the muted circular fallback classes."
            }
          ]
        },
        {
          "id": "avatar-badge",
          "title": "AvatarBadge",
          "summary": "Absolute green status badge that scales with the root Avatar size. Add tooltip to Avatar when the whole avatar should expose the status hint.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional icon or status mark. Small avatars hide nested SVGs automatically."
            },
            {
              "name": "tooltip",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional short label shown in the Iconiq tooltip surface when only the badge should be the trigger."
            },
            {
              "name": "tooltipSide",
              "type": "\"top\" | \"bottom\" | \"left\" | \"right\"",
              "defaultValue": "\"right\"",
              "required": false,
              "description": "Preferred side for the tooltip bubble. The default collision order is right, left, top, then bottom."
            },
            {
              "name": "tooltipDelay",
              "type": "number",
              "defaultValue": "0.15",
              "required": false,
              "description": "Delay in seconds before the tooltip opens."
            },
            {
              "name": "tooltipClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the tooltip bubble when the badge tooltip is enabled."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the green status badge background, foreground, and ring classes."
            }
          ]
        },
        {
          "id": "avatar-group",
          "title": "AvatarGroup",
          "summary": "Stack wrapper for overlapping avatars and matching overflow count chips.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Avatar and AvatarGroupCount children rendered in an overlapping row."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the negative-space group classes and child avatar rings."
            }
          ]
        },
        {
          "id": "avatar-group-count",
          "title": "AvatarGroupCount",
          "summary": "Overflow count part that follows the largest avatar size used in the group.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Count label or icon shown after the visible avatars."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the muted circular count chip classes."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "badge",
      "name": "Badge",
      "href": "/display-and-content/badge",
      "url": "https://iconiqui.com/display-and-content/badge",
      "installPackage": "@iconiq/badge",
      "installCommand": "npx shadcn@latest add @iconiq/badge",
      "registryPath": "badge.json",
      "registryUrl": "https://iconiqui.com/r/badge.json",
      "summary": "Compact label pill with a shimmer-enabled default variant, a quieter dot variant, and preset color tokens.",
      "apiSections": [
        {
          "id": "badge",
          "title": "Badge",
          "summary": "Compact label pill with a shimmer-enabled default variant, a quieter dot variant, and preset color tokens.",
          "notes": [
            "The component now spreads remaining span props, so ids, data attributes, and click handlers can be attached directly."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Badge content rendered above the optional shimmer layer so labels stay readable while the default variant animates."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "\"\"",
              "required": false,
              "description": "Appended directly to the root badge element. Useful for radius, spacing, or local border overrides."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"dot\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Chooses between the animated filled badge and the quieter outlined badge with a leading status dot."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Controls height, horizontal padding, gap, and label size for denser or roomier badge treatments."
            },
            {
              "name": "color",
              "type": "BadgeColor",
              "defaultValue": "\"gray\"",
              "required": false,
              "description": "Picks a preset palette token. The default variant turns it into a tinted fill, while the dot variant uses it for the status dot and border tint."
            },
            {
              "name": "waveColor",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional shimmer midpoint override for the default variant. When omitted, the sweep derives a subtle tone from the current text color."
            }
          ]
        },
        {
          "id": "badge-variants",
          "title": "badgeVariants",
          "summary": "CVA recipe exported alongside Badge for reusing badge styling on custom elements.",
          "notes": [],
          "fields": [
            {
              "name": "variant",
              "type": "\"default\" | \"dot\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Chooses between the filled badge and dot badge recipes."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Controls height, padding, gap, and label size."
            },
            {
              "name": "color",
              "type": "BadgeColor",
              "defaultValue": "\"gray\"",
              "required": false,
              "description": "Preset palette token applied by the badge recipe."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional classes merged after the generated recipe classes."
            }
          ]
        },
        {
          "id": "badge-colors",
          "title": "badgeColors",
          "summary": "Preset color token map used by Badge and badgeVariants for palette-consistent fills and dot treatments.",
          "notes": [
            "Use the exported BadgeColor type when you want compile-time checks for supported palette tokens."
          ],
          "fields": [
            {
              "name": "keys",
              "type": "BadgeColor",
              "defaultValue": "",
              "required": false,
              "description": "Named palette tokens such as gray, blue, green, amber, red, and purple."
            }
          ]
        },
        {
          "id": "badge-visuals",
          "title": "Visual behavior",
          "summary": "The default variant keeps the original spring-in shimmer treatment, while the dot variant adds a subtle status pulse.",
          "notes": [
            "The default badge fades and scales from 0.95 to 1 on mount over 0.3 seconds.",
            "Its shimmer travels from left to right over 2 seconds, waits 1.5 seconds, then repeats indefinitely.",
            "The dot variant omits the shimmer layer, sizes its leading status dot to match the chosen badge size, and gives it a gentle repeating blink."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "class-variance-authority"
      ]
    },
    {
      "slug": "calendar",
      "name": "Calendar",
      "href": "/display-and-content/calendar",
      "url": "https://iconiqui.com/display-and-content/calendar",
      "installPackage": "@iconiq/calendar",
      "installCommand": "npx shadcn@latest add @iconiq/calendar",
      "registryPath": "calendar.json",
      "registryUrl": "https://iconiqui.com/r/calendar.json",
      "summary": "shadcn-style animated monthly calendar with controlled/uncontrolled month state, day selection, and direct month/year picking.",
      "apiSections": [
        {
          "id": "calendar",
          "title": "Calendar",
          "summary": "shadcn-style animated monthly calendar with controlled/uncontrolled month state, day selection, and direct month/year picking.",
          "notes": [
            "Controlled mode: pass selected/month and respond to onSelect/onMonthChange.",
            "Uncontrolled mode: omit selected/month and optionally seed with defaultSelected/defaultMonth.",
            "The month and year labels open overlay pickers, so users can jump without losing the existing date-grid motion.",
            "When no defaults are provided, the visible month starts from today and selection stays empty until the user picks a date."
          ],
          "fields": [
            {
              "name": "selected",
              "type": "Date",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected day. When provided, the highlighted day is always derived from this prop."
            },
            {
              "name": "defaultSelected",
              "type": "Date",
              "defaultValue": "",
              "required": false,
              "description": "Initial selected day for uncontrolled usage when selected is not provided."
            },
            {
              "name": "onSelect",
              "type": "(date: Date) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the user picks any interactive day, including visible outside-month days."
            },
            {
              "name": "month",
              "type": "Date",
              "defaultValue": "",
              "required": false,
              "description": "Controlled visible month. Prev/next, outside-day, and month/year picker navigation requests flow through onMonthChange."
            },
            {
              "name": "defaultMonth",
              "type": "Date",
              "defaultValue": "",
              "required": false,
              "description": "Initial visible month for uncontrolled usage when month is not provided."
            },
            {
              "name": "onMonthChange",
              "type": "(month: Date) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the user navigates with prev/next, an outside day, or the month/year picker."
            },
            {
              "name": "disabled",
              "type": "(date: Date) => boolean",
              "defaultValue": "",
              "required": false,
              "description": "Marks dates as non-interactive. Disabled days keep the same visuals but cannot be selected."
            },
            {
              "name": "locale",
              "type": "Locale",
              "defaultValue": "",
              "required": false,
              "description": "Optional date-fns locale used for month labels, weekday headers, selected-date copy, and spoken date labels."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "",
              "required": false,
              "description": "Controls the overall calendar scale, including the card width, spacing, nav controls, weekday row, and day cell sizing. Defaults to sm."
            },
            {
              "name": "weekStartsOn",
              "type": "0 | 1 | 2 | 3 | 4 | 5 | 6",
              "defaultValue": "",
              "required": false,
              "description": "Overrides the first day of the week for both the weekday header and rendered month grid."
            },
            {
              "name": "minYear",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Optional lower bound for selectable years in the year picker."
            },
            {
              "name": "maxYear",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Optional upper bound for selectable years in the year picker."
            }
          ]
        },
        {
          "id": "calendar-grid",
          "title": "Date math and layout behavior",
          "summary": "The grid is rebuilt with date-fns whenever the visible month changes.",
          "notes": [
            "The rendered range runs from startOfWeek(startOfMonth(currentMonth)) through endOfWeek(endOfMonth(currentMonth)), so leading and trailing days from adjacent months are always visible.",
            "Days outside the active month remain visible for context and can still be selected. Choosing one switches the visible month and selects that day, unless the date is marked unavailable through disabled.",
            "Weekday headers and the grid start day now follow the provided locale/weekStartsOn settings instead of being hardcoded to English Sunday-first output."
          ],
          "fields": []
        },
        {
          "id": "calendar-motion-a11y",
          "title": "Motion and interaction model",
          "summary": "Month transitions, selected-day changes, and the live selection summary each animate independently.",
          "notes": [
            "Prev and next controls are real buttons with aria-label values, and each in-month day is rendered as a button with hover and tap motion.",
            "Month/year picker overlays use the same smooth easing as the date grid, while directional grid changes keep the existing staggered day entrance.",
            "The selected day highlight uses a shared layoutId of selected-day so the active surface glides between dates instead of remounting abruptly.",
            "Keyboard users can move through the month with arrow keys, Home/End, and PageUp/PageDown, while the calendar exposes clearer spoken date labels and a live selected-date summary.",
            "This is still not a full calendar input primitive: there is no range or multi-select mode."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react",
        "date-fns"
      ]
    },
    {
      "slug": "card",
      "name": "Card",
      "href": "/display-and-content/card",
      "url": "https://iconiqui.com/display-and-content/card",
      "installPackage": "@iconiq/card",
      "installCommand": "npx shadcn@latest add @iconiq/card",
      "registryPath": "card.json",
      "registryUrl": "https://iconiqui.com/r/card.json",
      "summary": "Compound card surface with optional interactive lift, Motion-smoothed layout transitions, and shared header, action, content, and footer slots.",
      "apiSections": [],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "carousel",
      "name": "Carousel",
      "href": "/display-and-content/carousel",
      "url": "https://iconiqui.com/display-and-content/carousel",
      "installPackage": "@iconiq/carousel",
      "installCommand": "npx shadcn@latest add @iconiq/carousel",
      "registryPath": "carousel.json",
      "registryUrl": "https://iconiqui.com/r/carousel.json",
      "summary": "Embla-powered carousel with aspect-ratio presets and horizontal or vertical slides. Built with embla-carousel-react and Lucide.",
      "apiSections": [],
      "dependencies": [
        "embla-carousel-react",
        "lucide-react"
      ]
    },
    {
      "slug": "charts",
      "name": "Charts",
      "href": "/display-and-content/charts",
      "url": "https://iconiqui.com/display-and-content/charts",
      "installPackage": "@iconiq/charts",
      "installCommand": "npx shadcn@latest add @iconiq/charts",
      "registryPath": "charts.json",
      "registryUrl": "https://iconiqui.com/r/charts.json",
      "summary": "Theme-aware Recharts shell that maps ChartConfig tokens to CSS variables, applies registry chart colors, and eases the surface in with fluid motion.",
      "apiSections": [
        {
          "id": "chart-container",
          "title": "ChartContainer",
          "summary": "Theme-aware Recharts shell that maps ChartConfig tokens to CSS variables, applies registry chart colors, and eases the surface in with fluid motion.",
          "notes": [
            "ChartContainer ships its own local --chart-1 through --chart-5 defaults, so chart installs do not need a shared theme helper.",
            "Pair ChartContainer with Recharts primitives and ChartTooltip / ChartLegend helpers rather than Radix UI or Base UI wrappers."
          ],
          "fields": [
            {
              "name": "config",
              "type": "ChartConfig",
              "defaultValue": "",
              "required": true,
              "description": "Series labels and colors. Use var(--chart-1) style tokens or per-key theme overrides; ChartStyle writes --color-{key} variables scoped to this chart instance."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Recharts chart markup, usually a BarChart, LineChart, or AreaChart wrapped by ResponsiveContainer through this container."
            },
            {
              "name": "id",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional stable id for the generated data-chart attribute and scoped CSS variables."
            },
            {
              "name": "initialDimension",
              "type": "{ width: number; height: number }",
              "defaultValue": "",
              "required": false,
              "description": "Optional fallback size for ResponsiveContainer before the first measure. By default the chart fills its parent (100% width/height) with a debounced resize handler."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the chart shell alongside the chart component's local theme tokens."
            }
          ]
        },
        {
          "id": "chart-bar",
          "title": "ChartBar",
          "summary": "Thin Recharts Bar wrapper with restrained ease-out growth timing tuned for the Iconiq motion profile.",
          "notes": [
            "Use fill=\"var(--color-desktop)\" (or your config key) so bars pick up ChartConfig colors.",
            "Bar growth runs once on first paint; resize uses a debounced container and skips repeat bar animations so narrowing the viewport stays stable."
          ],
          "fields": [
            {
              "name": "seriesIndex",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Offsets bar growth start time for multi-series charts so each series eases in with a short stagger."
            },
            {
              "name": "...props",
              "type": "Recharts Bar props",
              "defaultValue": "",
              "required": false,
              "description": "Forwards the full Bar API. animationDuration (~480ms), ease-out easing, and isAnimationActive inherit calm defaults unless you override them."
            }
          ]
        },
        {
          "id": "chart-tooltip",
          "title": "ChartTooltip",
          "summary": "Recharts tooltip primitive wired to the shared Iconiq chart tooltip content shell.",
          "notes": [],
          "fields": [
            {
              "name": "content",
              "type": "ReactNode | ComponentType",
              "defaultValue": "",
              "required": false,
              "description": "Tooltip renderer. Defaults to ChartTooltipContent when omitted."
            },
            {
              "name": "cursor",
              "type": "boolean | object",
              "defaultValue": "",
              "required": false,
              "description": "Recharts cursor configuration for hover feedback."
            }
          ]
        },
        {
          "id": "chart-tooltip-content",
          "title": "ChartTooltipContent",
          "summary": "Styled tooltip content shell with a soft spring entrance and dashed, dot, or line indicators.",
          "notes": [],
          "fields": [
            {
              "name": "indicator",
              "type": "\"dot\" | \"line\" | \"dashed\"",
              "defaultValue": "\"dot\"",
              "required": false,
              "description": "Marker style rendered beside each tooltip row."
            },
            {
              "name": "hideLabel",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Suppresses the formatted label block above the value rows."
            },
            {
              "name": "hideIndicator",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Hides the color marker when you only want text values."
            },
            {
              "name": "labelFormatter",
              "type": "(value, payload) => ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Custom formatter for the tooltip label row."
            },
            {
              "name": "formatter",
              "type": "Recharts formatter",
              "defaultValue": "",
              "required": false,
              "description": "Optional per-row formatter; when omitted, the default label and value layout is used."
            }
          ]
        },
        {
          "id": "chart-legend",
          "title": "ChartLegend",
          "summary": "Recharts legend primitive wired to the shared Iconiq legend content shell.",
          "notes": [],
          "fields": [
            {
              "name": "content",
              "type": "ReactNode | ComponentType",
              "defaultValue": "",
              "required": false,
              "description": "Legend renderer. Defaults to ChartLegendContent when omitted."
            },
            {
              "name": "verticalAlign",
              "type": "\"top\" | \"bottom\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Adjusts legend spacing relative to the chart."
            }
          ]
        },
        {
          "id": "chart-legend-content",
          "title": "ChartLegendContent",
          "summary": "Legend content shell with a quiet fade-and-rise entrance that matches the chart surface motion.",
          "notes": [],
          "fields": [
            {
              "name": "hideIcon",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Hides config icons and falls back to the color swatch derived from the series color."
            },
            {
              "name": "verticalAlign",
              "type": "\"top\" | \"bottom\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Adjusts legend spacing relative to the chart."
            }
          ]
        }
      ],
      "dependencies": [
        "recharts",
        "motion"
      ]
    },
    {
      "slug": "date-picker",
      "name": "Date Picker",
      "href": "/display-and-content/date-picker",
      "url": "https://iconiqui.com/display-and-content/date-picker",
      "installPackage": "@iconiq/date-picker",
      "installCommand": "npx shadcn@latest add @iconiq/date-picker",
      "registryPath": "date-picker.json",
      "registryUrl": "https://iconiqui.com/r/date-picker.json",
      "summary": "Collapsible date field with a formatted trigger button and the shared Iconiq Calendar panel underneath.",
      "apiSections": [
        {
          "id": "date-picker",
          "title": "DatePicker",
          "summary": "Collapsible date field with a formatted trigger button and the shared Iconiq Calendar panel underneath.",
          "notes": [
            "Also exported as `AnimatedDatePicker` for backwards compatibility.",
            "The trigger formats the selected date as `EEE, MMM d, yyyy` and toggles the panel open and closed.",
            "Choosing a date closes the panel automatically while keeping the visible month aligned with the selected value.",
            "Click outside or press Escape to close the panel. The embedded Calendar stays mounted after the first open to avoid repeat entrance motion.",
            "Install the `calendar` registry entry alongside `date-picker` so `@/components/ui/calendar` resolves in consumer apps."
          ],
          "fields": [
            {
              "name": "value",
              "type": "Date | null",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected date. When provided, the trigger and embedded Calendar both reflect this value."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "Select a date",
              "required": false,
              "description": "Copy shown in the trigger when no date is selected."
            },
            {
              "name": "onChange",
              "type": "(date: Date) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the user picks a date from the embedded Calendar."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names applied to the outer wrapper."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Whether the Calendar panel starts expanded on first render."
            },
            {
              "name": "calendarProps",
              "type": "Omit<CalendarProps, 'selected' | 'defaultSelected' | 'onSelect' | 'month' | 'onMonthChange'>",
              "defaultValue": "",
              "required": false,
              "description": "Props forwarded to the embedded Calendar, such as size, locale, disabled, weekStartsOn, minYear, and maxYear."
            }
          ]
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react",
        "date-fns"
      ]
    },
    {
      "slug": "liquid-marquee",
      "name": "Liquid Marquee",
      "href": "/display-and-content/liquid-marquee",
      "url": "https://iconiqui.com/display-and-content/liquid-marquee",
      "installPackage": "@iconiq/liquid-marquee",
      "installCommand": "npx shadcn@latest add @iconiq/liquid-marquee",
      "registryPath": "liquid-marquee.json",
      "registryUrl": "https://iconiqui.com/r/liquid-marquee.json",
      "summary": "Seamless horizontal marquee that duplicates its children into a looping track, animates with requestAnimationFrame, and applies an SVG liquid distortion filter with gradient edge fades.",
      "apiSections": [
        {
          "id": "liquid-marquee",
          "title": "LiquidMarquee",
          "summary": "Seamless horizontal marquee that duplicates its children into a looping track, animates with requestAnimationFrame, and applies an SVG liquid distortion filter with gradient edge fades.",
          "notes": [
            "The track duplicates `children` once to create a seamless loop and resets position when one copy scrolls fully out of view.",
            "Liquid distortion is powered by inline SVG filters (`feTurbulence` + `feDisplacementMap`) applied to the moving track.",
            "Gradient masks on the left and right edges use `from-background`, so the fade matches your page surface color.",
            "Multiple instances on one page share the same SVG filter ids; keep one marquee per view or fork the filter ids if you need several on the same screen."
          ],
          "fields": [
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered twice inside the scrolling track. A single horizontal row of labels, logos, or cards works best."
            },
            {
              "name": "speed",
              "type": "number",
              "defaultValue": "45",
              "required": false,
              "description": "Scroll speed in pixels per second. Higher values move the track faster."
            },
            {
              "name": "direction",
              "type": "\"left\" | \"right\"",
              "defaultValue": "left",
              "required": false,
              "description": "Sets the scroll direction. `left` moves content toward the left edge; `right` reverses the flow."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the overflow container for height, spacing, or background styling."
            },
            {
              "name": "pauseOnHover",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "When true, pointer hover pauses the animation until the cursor leaves the marquee."
            }
          ]
        }
      ],
      "dependencies": []
    },
    {
      "slug": "progress",
      "name": "Progress",
      "href": "/display-and-content/progress",
      "url": "https://iconiqui.com/display-and-content/progress",
      "installPackage": "@iconiq/progress",
      "installCommand": "npx shadcn@latest add @iconiq/progress",
      "registryPath": "progress.json",
      "registryUrl": "https://iconiqui.com/r/progress.json",
      "summary": "Progress component documentation.",
      "apiSections": [],
      "dependencies": []
    },
    {
      "slug": "rolling-digits",
      "name": "Rolling Digits",
      "href": "/display-and-content/rolling-digits",
      "url": "https://iconiqui.com/display-and-content/rolling-digits",
      "installPackage": "@iconiq/rolling-digits",
      "installCommand": "npx shadcn@latest add @iconiq/rolling-digits",
      "registryPath": "rolling-digits.json",
      "registryUrl": "https://iconiqui.com/r/rolling-digits.json",
      "summary": "Inline animated counter that swaps digits with spring-driven blur, scale, and vertical motion while exiting the previous character.",
      "apiSections": [
        {
          "id": "rolling-digits",
          "title": "RollingDigits",
          "summary": "Inline animated counter that swaps digits with spring-driven blur, scale, and vertical motion while exiting the previous character.",
          "notes": [
            "Non-digit characters from locale separators or custom formatters render as static spans and do not animate.",
            "The visual layer is `aria-hidden`; screen readers receive the formatted number through an `sr-only` span.",
            "When `startOnView` is enabled, the ticker displays zero until the container crosses the viewport threshold (`once: true`, `amount: 0.6`).",
            "Each digit keeps a short exit queue so the previous character can blur and slide out while the next one springs into place.",
            "Layer symbols such as `%` or `$` beside the component in your layout, or include them through `format`."
          ],
          "fields": [
            {
              "name": "value",
              "type": "number",
              "defaultValue": "",
              "required": true,
              "description": "Target number to display. The component rounds to the nearest integer before formatting."
            },
            {
              "name": "pad",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Minimum digit width passed to `String.padStart`. Useful for clock-style or fixed-width counters."
            },
            {
              "name": "animationDelay",
              "type": "number",
              "defaultValue": "80",
              "required": false,
              "description": "Milliseconds between queued value steps when `value` changes faster than the animation can finish."
            },
            {
              "name": "startOnView",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "When true, playback waits until the component enters the viewport once before animating from zero."
            },
            {
              "name": "locale",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "When true, formats the rounded value with `toLocaleString()` before splitting digits."
            },
            {
              "name": "format",
              "type": "(value: number) => string",
              "defaultValue": "",
              "required": false,
              "description": "Custom formatter that runs before padding. Overrides `locale` when both are provided."
            },
            {
              "name": "gap",
              "type": "number",
              "defaultValue": "2",
              "required": false,
              "description": "Pixel gap between rendered characters in the digit row."
            },
            {
              "name": "direction",
              "type": "\"dynamic\" | \"up\" | \"down\"",
              "defaultValue": "dynamic",
              "required": false,
              "description": "Controls whether incoming digits slide up or down. `dynamic` compares the previous and next digit values."
            },
            {
              "name": "enterStiffness",
              "type": "number",
              "defaultValue": "170",
              "required": false,
              "description": "Spring stiffness for incoming digit motion."
            },
            {
              "name": "enterDamping",
              "type": "number",
              "defaultValue": "10",
              "required": false,
              "description": "Spring damping for incoming digit motion."
            },
            {
              "name": "exitStiffness",
              "type": "number",
              "defaultValue": "170",
              "required": false,
              "description": "Spring stiffness for outgoing digit motion."
            },
            {
              "name": "exitDamping",
              "type": "number",
              "defaultValue": "15",
              "required": false,
              "description": "Spring damping for outgoing digit motion."
            },
            {
              "name": "enterY",
              "type": "number",
              "defaultValue": "32",
              "required": false,
              "description": "Vertical offset in pixels used when a digit enters."
            },
            {
              "name": "enterBlur",
              "type": "number",
              "defaultValue": "52",
              "required": false,
              "description": "Peak blur in pixels applied when a digit enters."
            },
            {
              "name": "enterScale",
              "type": "number",
              "defaultValue": "0.7",
              "required": false,
              "description": "Starting scale applied when a digit enters."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer inline-flex span that wraps the readable and visual layers."
            },
            {
              "name": "digitClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto each animated digit cell wrapper for per-digit styling."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "skeleton",
      "name": "Skeleton",
      "href": "/display-and-content/skeleton",
      "url": "https://iconiqui.com/display-and-content/skeleton",
      "installPackage": "@iconiq/skeleton",
      "installCommand": "npx shadcn@latest add @iconiq/skeleton",
      "registryPath": "skeleton.json",
      "registryUrl": "https://iconiqui.com/r/skeleton.json",
      "summary": "Lightweight loading placeholder that renders a muted block with an optional shimmer pass layered above it.",
      "apiSections": [
        {
          "id": "skeleton",
          "title": "ShimmerSkeleton",
          "summary": "Lightweight loading placeholder that renders a muted block with an optional shimmer pass layered above it.",
          "notes": [
            "The component always renders role='status' and aria-label='Loading' on the root placeholder.",
            "The shimmer uses a local keyframes definition and a gradient overlay span, so there are no runtime dependencies beyond React.",
            "Use rounded='full' for avatar placeholders and the default rounded='md' or rounded='lg' for cards and text blocks."
          ],
          "fields": [
            {
              "name": "rounded",
              "type": "\"none\" | \"sm\" | \"md\" | \"lg\" | \"full\"",
              "defaultValue": "md",
              "required": false,
              "description": "Chooses the corner radius utility applied to the placeholder surface."
            },
            {
              "name": "animate",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether the shimmer overlay is rendered. Set it to false when you want a static loading block."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root div so you can control width, height, spacing, colors, and any extra local styling."
            },
            {
              "name": "HTML div props",
              "type": "HTMLAttributes<HTMLDivElement>",
              "defaultValue": "",
              "required": false,
              "description": "Standard div attributes such as style, data-*, aria-*, id, and event handlers are forwarded to the root element."
            }
          ]
        },
        {
          "id": "skeleton-registry",
          "title": "Registry bundle",
          "summary": "Install the exact registry entry shown on the right when you want the component file with no additional runtime dependencies.",
          "registryPath": "skeleton.json",
          "notes": [
            "No runtime dependencies."
          ],
          "fields": []
        }
      ],
      "dependencies": []
    },
    {
      "slug": "spinner",
      "name": "Spinner",
      "href": "/display-and-content/spinner",
      "url": "https://iconiqui.com/display-and-content/spinner",
      "installPackage": "@iconiq/spinner",
      "installCommand": "npx shadcn@latest add @iconiq/spinner",
      "registryPath": "spinner.json",
      "registryUrl": "https://iconiqui.com/r/spinner.json",
      "summary": "Default export for a lightweight loading indicator built around an output element.",
      "apiSections": [
        {
          "id": "spinner",
          "title": "Spinner",
          "summary": "Default export for a lightweight loading indicator built around an output element.",
          "notes": [
            "The ring variant uses motion.create('output'), while the dots variant renders a plain output element with animated child spans.",
            "Both variants ship with aria-label=\"Loading\" and aria-live=\"polite\". The component does not currently accept a custom accessible label prop.",
            "No additional DOM props are forwarded beyond className, so wrap the component if you need extra data attributes or inline event handlers."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"ring\" | \"dots\"",
              "defaultValue": "ring",
              "required": false,
              "description": "Chooses between the rotating circular border and the three bouncing dots treatment."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root output element so you can resize or recolor the spinner with Tailwind utilities."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "table",
      "name": "Table",
      "href": "/display-and-content/table",
      "url": "https://iconiqui.com/display-and-content/table",
      "installPackage": "@iconiq/table",
      "installCommand": "npx shadcn@latest add @iconiq/table",
      "registryPath": "table.json",
      "registryUrl": "https://iconiqui.com/r/table.json",
      "summary": "Root provider for the animated table primitives. It sets the shared column template so header and body rows stay aligned.",
      "apiSections": [
        {
          "id": "table",
          "title": "Table",
          "summary": "Root provider for the animated table primitives. It sets the shared column template so header and body rows stay aligned.",
          "notes": [
            "The canonical JSX export is `Table`, and the lowercase `table` alias still ships for backward compatibility.",
            "The file also exports `TABLE_DEFAULT_COLUMNS`, `TableAlign`, `TableRowVariant`, and `TableSortDirection` for stronger TypeScript reuse in app code.",
            "The registry component no longer owns demo data, search state, or add/remove actions. Those behaviors are expected to live in app code.",
            "The installed primitive now renders a native table, header, body, rows, and cells while preserving the original grid-driven layout API."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Compose TableHeader, TableBody, TableRow, TableHead, TableCell, and optional helper primitives inside the root."
            },
            {
              "name": "columns",
              "type": "string",
              "defaultValue": "\"minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1fr)\"",
              "required": false,
              "description": "Shared grid-template-columns value applied to every header and body row so the native table semantics still keep the custom grid layout aligned."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the native table element when you need to adjust width, spacing, or placement."
            }
          ]
        },
        {
          "id": "table-toolbar",
          "title": "TableToolbar",
          "summary": "Optional layout helper for the control row above the table, matching the original spacing and alignment treatment.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Usually a search field, actions, filters, or bulk controls placed above the table."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the toolbar wrapper."
            }
          ]
        },
        {
          "id": "table-header",
          "title": "TableHeader",
          "summary": "Native table head wrapper for the column labels and sort controls.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Usually one header TableRow."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the header wrapper."
            }
          ]
        },
        {
          "id": "table-body",
          "title": "TableBody",
          "summary": "Native table body wrapper that adds LayoutGroup and AnimatePresence so row insertions, removals, and reordering stay animated.",
          "notes": [
            "Exit animations for removed rows only run when body rows are rendered as direct children of TableBody."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "One or more TableRow elements, plus optional TableEmpty when no rows are visible."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the body wrapper."
            }
          ]
        },
        {
          "id": "table-row",
          "title": "TableRow",
          "summary": "Motion-enabled native table row used for both header and body layouts.",
          "notes": [
            "Every row reads the shared columns string from Table and applies it as grid-template-columns.",
            "Rows expose `data-slot=\"table-row\"`, plus `data-variant` and `data-hoverable`, which makes local styling overrides easier after installation."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"header\" | \"body\"",
              "defaultValue": "body",
              "required": false,
              "description": "Header rows skip mount and exit motion, while body rows keep the original motion defaults."
            },
            {
              "name": "index",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Optional row index used to apply a subtle stagger to body row entry motion."
            },
            {
              "name": "hoverable",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "When true, body rows get the muted hover wash. Defaults to false so informational rows do not imply clickability."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the row shell for spacing or color overrides."
            },
            {
              "name": "Motion tr props",
              "type": "ComponentPropsWithoutRef<typeof motion.tr>",
              "defaultValue": "",
              "required": false,
              "description": "Additional motion.tr props such as layout, transition, whileHover, and exit can still be passed directly."
            }
          ]
        },
        {
          "id": "table-head",
          "title": "TableHead",
          "summary": "Native header cell wrapper for labels, sort buttons, and right-aligned controls.",
          "notes": [],
          "fields": [
            {
              "name": "align",
              "type": "\"left\" | \"right\"",
              "defaultValue": "left",
              "required": false,
              "description": "Controls left or right alignment for the header cell content."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Header label or a custom control such as TableSortButton. When used with TableSortButton, the column header also receives the correct aria-sort state."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the header cell wrapper."
            }
          ]
        },
        {
          "id": "table-cell",
          "title": "TableCell",
          "summary": "Native body cell wrapper for row content, status pills, numeric values, and row actions.",
          "notes": [],
          "fields": [
            {
              "name": "align",
              "type": "\"left\" | \"right\"",
              "defaultValue": "left",
              "required": false,
              "description": "Controls left or right alignment for the cell content."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Rendered cell content."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the cell wrapper."
            }
          ]
        },
        {
          "id": "table-caption",
          "title": "TableCaption",
          "summary": "Low-emphasis native table caption below the table, matching the original entry count styling.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Caption copy, summary text, or count information."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the caption paragraph."
            }
          ]
        },
        {
          "id": "table-empty",
          "title": "TableEmpty",
          "summary": "Animated empty-state row for zero-result or no-data states inside TableBody.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Empty-state copy or a richer no-data message."
            },
            {
              "name": "colSpan",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Overrides the automatically derived column span when the empty row should cover a different number of columns."
            },
            {
              "name": "Motion tr props",
              "type": "ComponentPropsWithoutRef<typeof motion.tr>",
              "defaultValue": "",
              "required": false,
              "description": "You can still override animate, initial, transition, or className when customizing the empty state row."
            }
          ]
        },
        {
          "id": "table-sort-button",
          "title": "TableSortButton",
          "summary": "Optional header helper with a larger hit area, clearer active state, and direction animation.",
          "notes": [
            "The helper defaults to type='button', so it stays safe inside forms."
          ],
          "fields": [
            {
              "name": "active",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Strengthens the visual treatment and enables the active sort direction state for the parent column header."
            },
            {
              "name": "direction",
              "type": "\"asc\" | \"desc\"",
              "defaultValue": "asc",
              "required": false,
              "description": "Rotates the chevron when the current active sort direction is descending."
            },
            {
              "name": "align",
              "type": "\"left\" | \"right\"",
              "defaultValue": "left",
              "required": false,
              "description": "Keeps the sort button aligned with the header cell it lives in, including full-width right-aligned targets."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Visible sort label."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the button wrapper."
            }
          ]
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "verified-badge",
      "name": "Verified Badge",
      "href": "/display-and-content/verified-badge",
      "url": "https://iconiqui.com/display-and-content/verified-badge",
      "installPackage": "@iconiq/verified-badge",
      "installCommand": "npx shadcn@latest add @iconiq/verified-badge",
      "registryPath": "verified-badge.json",
      "registryUrl": "https://iconiqui.com/r/verified-badge.json",
      "summary": "Inline X-style verified scallop with a check. Use shimmer or static variants.",
      "apiSections": [
        {
          "id": "verified-badge",
          "title": "VerifiedBadge",
          "summary": "Inline X-style verified scallop with a check. Use shimmer or static variants.",
          "notes": [
            "Extends native `span` props (`id`, `onClick`, `data-*`, tooltips, and other `aria-*` attributes) via prop spreading on the root.",
            "Default color lives on the root span (`text-[hsl(203,89%,57%)]`); scallop paths use `currentColor` so `cn` can override via `className`.",
            "The `shimmer` variant uses Motion to sweep a highlight across the scallop (0.5s pass, 1.5s pause between repeats).",
            "Root uses `role=\"img\"` with `aria-label`; inner SVG shapes are `aria-hidden`.",
            "Install path is `components/ui/verified-badge.tsx` with the `VerifiedBadge` export."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"shimmer\" | \"static\"",
              "defaultValue": "shimmer",
              "required": false,
              "description": "Use `shimmer` for a sweeping highlight across the scallop or `static` for a fixed badge."
            },
            {
              "name": "size",
              "type": "number",
              "defaultValue": "64",
              "required": false,
              "description": "Width and height in pixels for the outer badge; the check scales to half this value."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root span. Pass a `text-*` class to override the default Twitter-blue scallop color."
            },
            {
              "name": "aria-label",
              "type": "string",
              "defaultValue": "Verified",
              "required": false,
              "description": "Announced to screen readers. Override when the badge conveys a different status."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "alert",
      "name": "Alert",
      "href": "/feedback-and-alerts/alert",
      "url": "https://iconiqui.com/feedback-and-alerts/alert",
      "installPackage": "@iconiq/alert",
      "installCommand": "npx shadcn@latest add @iconiq/alert",
      "registryPath": "alert.json",
      "registryUrl": "https://iconiqui.com/r/alert.json",
      "summary": "Root container for a single notice. Uses a compact grid layout with optional leading icon, compound title and description slots, legacy prop support, and inline or toast behavior.",
      "apiSections": [
        {
          "id": "alert",
          "title": "Alert",
          "summary": "Root container for a single notice. Uses a compact grid layout with optional leading icon, compound title and description slots, legacy prop support, and inline or toast behavior.",
          "notes": [
            "Use size for preset widths or pass width for a custom max width. md defaults to 400px.",
            "Every positioned alert snaps to a full-width top placement on small screens, then switches to the requested corner at the sm breakpoint.",
            "Inline alerts use role=\"alert\"; toast alerts use role=\"status\" with aria-live=\"polite\" and keep title and message linked with aria-labelledby and aria-describedby.",
            "The alert keeps its own visible state internally when dismissal is enabled, so toast usage is designed for fire-and-forget notifications rather than parent-controlled open state.",
            "Hovering or focusing the alert pauses auto-dismiss, which gives people more time to read and makes the close target less stressful to hit."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Preferred compound API. Pass an optional leading icon followed by AlertTitle and AlertDescription."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Legacy leading visual prop. Compound children can also provide the leading icon as the first child."
            },
            {
              "name": "title",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Legacy title prop rendered with the same AlertTitle styling. Prefer AlertTitle for new code."
            },
            {
              "name": "message",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Legacy description prop rendered with the same AlertDescription styling. Prefer AlertDescription for new code."
            },
            {
              "name": "action",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional action row rendered beneath the message, useful for a single follow-up button or link such as Undo or View details."
            },
            {
              "name": "appearance",
              "type": "\"default\" | \"destructive\" | \"warning\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Visual tone for the alert surface. Destructive shifts toward error colors; warning uses a warm amber surface with muted description text."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\" | \"xl\"",
              "defaultValue": "\"md\"",
              "required": false,
              "description": "Preset max width for inline and toast alerts. sm is 320px, md is 400px, lg is 480px, and xl is 560px."
            },
            {
              "name": "width",
              "type": "string | number",
              "defaultValue": "",
              "required": false,
              "description": "Custom max width. Pass a CSS length such as 28rem or a pixel number. Overrides size when set."
            },
            {
              "name": "dismissible",
              "type": "boolean",
              "defaultValue": "legacy: true; compound inline: false",
              "required": false,
              "description": "Controls whether the close button is rendered. Compound inline alerts are static by default; toast and legacy prop alerts remain dismissible unless you opt out."
            },
            {
              "name": "variant",
              "type": "\"inline\" | \"toast\"",
              "defaultValue": "\"inline\"",
              "required": false,
              "description": "Explicitly chooses layout behavior. Toasts portal to document.body and use fixed viewport positioning, while inline alerts stay in normal document flow."
            },
            {
              "name": "position",
              "type": "\"top-left\" | \"top-center\" | \"top-right\" | \"bottom-left\" | \"bottom-center\" | \"bottom-right\"",
              "defaultValue": "",
              "required": false,
              "description": "Optional toast placement. Providing a position also upgrades the component to toast behavior, and omitted toast positions default to top-right."
            },
            {
              "name": "timeout",
              "type": "number",
              "defaultValue": "legacy/toast: 5000; compound inline: 0",
              "required": false,
              "description": "Auto-dismiss delay in milliseconds. Passing 0 disables the timer; compound inline alerts default to no timer so static notices stay visible."
            },
            {
              "name": "onDismiss",
              "type": "() => void",
              "defaultValue": "",
              "required": false,
              "description": "Called after the component finishes its exit transition, regardless of whether dismissal came from the close button or the timeout effect."
            }
          ]
        },
        {
          "id": "alert-title",
          "title": "AlertTitle",
          "summary": "Primary line for the compound alert API. Renders in the second grid column beside the optional icon.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Short title or inline formatted heading content."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the title typography classes for one-off styling."
            }
          ]
        },
        {
          "id": "alert-description",
          "title": "AlertDescription",
          "summary": "Secondary line for the compound alert API. Renders beneath the title in the second grid column and links to the root with aria-describedby.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Supporting message content. Keep it concise for compact inline notices and toast updates."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the description typography classes for one-off styling."
            }
          ]
        },
        {
          "id": "alert-lifecycle",
          "title": "Motion and lifecycle",
          "summary": "Alert uses AnimatePresence for mount and exit, with separate variants for the container, icon, and text stack.",
          "notes": [
            "Entry uses long fluid easing on opacity, vertical drift, scale, and blur so the alert settles in rather than snapping.",
            "Exit keeps the same direction with a softer, slightly slower fade so dismissal still feels continuous.",
            "Child text and the icon only fade on exit, which keeps the container motion cohesive.",
            "The timeout effect is cleared on cleanup, so unmounting or rerendering the alert does not leak timers.",
            "When position is set, the component waits until after mount before calling createPortal to avoid touching document during server render.",
            "Dismissal callbacks wait until the exit transition completes, so parent cleanup does not cut off the visual exit early."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "class-variance-authority"
      ]
    },
    {
      "slug": "typography",
      "name": "Typography",
      "href": "/foundation/typography",
      "url": "https://iconiqui.com/foundation/typography",
      "installPackage": "@iconiq/typography",
      "installCommand": "npx shadcn@latest add @iconiq/typography",
      "registryPath": "typography.json",
      "registryUrl": "https://iconiqui.com/r/typography.json",
      "summary": "Single text primitive that keeps the full type scale in one place, with semantic element defaults derived from the selected variant.",
      "apiSections": [
        {
          "id": "typography",
          "title": "Typography",
          "summary": "Single text primitive that keeps the full type scale in one place, with semantic element defaults derived from the selected variant.",
          "notes": [
            "Heading variants default to their matching h1 through h6 tags.",
            "Label, paragraph, subheading, and doc variants default to paragraph tags so they remain flexible in flow content.",
            "The scale metadata is exported from the same file as the component, which keeps docs previews and the runtime component aligned."
          ],
          "fields": [
            {
              "name": "variant",
              "type": "\"h1\" | \"h2\" | \"h3\" | \"h4\" | \"h5\" | \"h6\" | \"label-xl\" | \"label-lg\" | \"label-md\" | \"label-sm\" | \"label-xs\" | \"paragraph-xl\" | \"paragraph-lg\" | \"paragraph-md\" | \"paragraph-sm\" | \"paragraph-xs\" | \"subheading-md\" | \"subheading-sm\" | \"subheading-xs\" | \"subheading-2xs\" | \"doc-label\" | \"doc-paragraph\"",
              "defaultValue": "\"paragraph-md\"",
              "required": false,
              "description": "Chooses one of the exported typography recipes. Each variant locks in the exact font size, line height, weight, and letter spacing from the scale."
            },
            {
              "name": "as",
              "type": "React.ElementType",
              "defaultValue": "",
              "required": false,
              "description": "Overrides the rendered HTML tag when the default semantic element for the chosen variant is not the one you want in a specific layout."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Text or inline content rendered with the selected recipe."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged after the variant classes so local color, spacing, or layout adjustments can be layered on top without forking the scale."
            }
          ]
        },
        {
          "id": "typography-scale",
          "title": "Scale structure",
          "summary": "The component ships with grouped metadata for titles, labels, paragraphs, subheadings, and documentation copy.",
          "notes": [
            "Use label variants for interface emphasis, paragraph variants for reading copy, subheading variants for overlines or small section leads, and doc variants when you need a looser editorial line height.",
            "Letter spacing values are encoded in em units so the browser scales tracking proportionally with the selected font size."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "class-variance-authority"
      ]
    },
    {
      "slug": "b-autocomplete",
      "name": "Autocomplete",
      "href": "/inputs-and-forms/autocomplete",
      "url": "https://iconiqui.com/inputs-and-forms/autocomplete",
      "installPackage": "@iconiq/b-autocomplete",
      "installCommand": "npx shadcn@latest add @iconiq/b-autocomplete",
      "registryPath": "b-autocomplete.json",
      "registryUrl": "https://iconiqui.com/r/b-autocomplete.json",
      "summary": "Root autocomplete controller. Compose AutocompleteInput, AutocompleteContent, AutocompleteList, and AutocompleteItem inside it.",
      "apiSections": [
        {
          "id": "autocomplete",
          "title": "Autocomplete",
          "summary": "Root autocomplete controller. Compose AutocompleteInput, AutocompleteContent, AutocompleteList, and AutocompleteItem inside it.",
          "notes": [
            "Built on Base UI Autocomplete with list filtering, keyboard navigation, and a sliding highlight treatment.",
            "Radix UI does not ship a dedicated autocomplete primitive, so this install is Base UI only.",
            "Pass value and onValueChange for controlled input text. The popup opens while typing by default, not on focus.",
            "Object items require itemToStringValue. Use isItemEqualToValue if selection highlight behaves incorrectly."
          ],
          "fields": [
            {
              "name": "items",
              "type": "readonly Item[]",
              "defaultValue": "",
              "required": false,
              "description": "Item collection used for list filtering. Pass a flat array or grouped items for sectioned results."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled input text shown in the field."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial input text for uncontrolled usage."
            },
            {
              "name": "onValueChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the input text changes from typing or when a suggestion is accepted."
            },
            {
              "name": "itemToStringValue",
              "type": "(item: Item) => string",
              "defaultValue": "",
              "required": false,
              "description": "Maps each item to the string used for filtering and the committed input value."
            },
            {
              "name": "mode",
              "type": "\"list\" | \"both\" | \"inline\" | \"none\"",
              "defaultValue": "\"list\"",
              "required": false,
              "description": "Controls filtering and inline completion while navigating suggestions."
            },
            {
              "name": "autoHighlight",
              "type": "boolean | \"always\"",
              "defaultValue": "true",
              "required": false,
              "description": "Automatically highlights the first matching item while typing."
            },
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled popup state. Pair with onOpenChange."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean, eventDetails) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the suggestion panel opens or closes. Use with open for controlled popup state."
            },
            {
              "name": "openOnInputClick",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "When true, clicking the input opens the suggestion panel even before typing."
            },
            {
              "name": "isItemEqualToValue",
              "type": "(item: Item, value: Item) => boolean",
              "defaultValue": "",
              "required": false,
              "description": "Custom equality for object items. Use when items are recreated on each render."
            }
          ]
        },
        {
          "id": "autocomplete-input",
          "title": "AutocompleteInput",
          "summary": "Styled input shell with border, focus ring, and optional clear control. The suggestion panel opens while typing, not on focus or click.",
          "notes": [],
          "fields": [
            {
              "name": "label",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional field label rendered above the input and linked with htmlFor."
            },
            {
              "name": "labelClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the field label."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Shown when the input is empty."
            },
            {
              "name": "showClear",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether AutocompleteClear is rendered."
            },
            {
              "name": "showTrigger",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "When true, renders a chevron trigger that toggles the suggestion panel."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables the input and clear button."
            }
          ]
        },
        {
          "id": "autocomplete-content",
          "title": "AutocompleteContent",
          "summary": "Portaled suggestion panel with a subtle fade-slide entrance and anchored width.",
          "notes": [],
          "fields": [
            {
              "name": "side",
              "type": "\"top\" | \"right\" | \"bottom\" | \"left\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Preferred side for the popup."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "6",
              "required": false,
              "description": "Distance between the input and the popup."
            }
          ]
        },
        {
          "id": "autocomplete-list",
          "title": "AutocompleteList",
          "summary": "Scrollable suggestion list rendered inside AutocompleteContent.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode | ((item, index) => ReactNode)",
              "defaultValue": "",
              "required": true,
              "description": "Render explicit AutocompleteItem children or a render function when using the root items prop."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default list spacing and scroll classes."
            }
          ]
        },
        {
          "id": "autocomplete-item",
          "title": "AutocompleteItem",
          "summary": "Suggestion row with optional description and a spring-driven highlight fill.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "Item",
              "defaultValue": "",
              "required": true,
              "description": "Item value passed to Base UI for selection handling."
            },
            {
              "name": "description",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional secondary line below the primary label."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "b-checkbox",
      "name": "Checkbox",
      "href": "/inputs-and-forms/checkbox",
      "url": "https://iconiqui.com/inputs-and-forms/checkbox",
      "installPackage": "@iconiq/b-checkbox",
      "installCommand": "npx shadcn@latest add @iconiq/b-checkbox",
      "registryPath": "b-checkbox.json",
      "registryUrl": "https://iconiqui.com/r/b-checkbox.json",
      "summary": "Single checkbox with controlled or uncontrolled state, a visually hidden native input, and an optional inline label.",
      "apiSections": [
        {
          "id": "checkbox",
          "title": "Checkbox",
          "summary": "Single checkbox with controlled or uncontrolled state, a visually hidden native input, and an optional inline label.",
          "notes": [
            "The component supports both controlled and uncontrolled usage, but `checked` becomes the source of truth whenever it is provided.",
            "There is no disabled or indeterminate state in this version, so more complex form behavior still needs a wrapper or extension.",
            "The full row stays clickable because the custom control and optional label both live inside a native label element."
          ],
          "fields": [
            {
              "name": "checked",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled checked state. When you pass this prop, the component always renders from it and stops mutating its own internal state."
            },
            {
              "name": "defaultChecked",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Initial state for uncontrolled usage. It is only read on the first render."
            },
            {
              "name": "onCheckedChange",
              "type": "(checked: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called with the next boolean value each time the checkbox is toggled."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional text rendered to the right of the box inside the same clickable label wrapper."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root label so you can reposition the row or override spacing."
            },
            {
              "name": "id",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Passed to the hidden input and linked from the wrapping label for explicit form-field association."
            }
          ]
        },
        {
          "id": "checkbox-motion",
          "title": "Motion and accessibility",
          "summary": "Visual feedback comes from Motion while input semantics still come from the hidden native checkbox element.",
          "notes": [
            "The box animates its border and fill between theme tokens, then the checkmark path draws in or out based on the next state.",
            "Tap feedback briefly compresses the control, while the label subtly dims when the row is checked.",
            "Keyboard toggling and screen-reader semantics still travel through the native input, even though the visible box is custom rendered."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-checkbox-group",
      "name": "Checkbox Group",
      "href": "/inputs-and-forms/checkbox-group",
      "url": "https://iconiqui.com/inputs-and-forms/checkbox-group",
      "installPackage": "@iconiq/b-checkbox-group",
      "installCommand": "npx shadcn@latest add @iconiq/b-checkbox-group",
      "registryPath": "b-checkbox-group.json",
      "registryUrl": "https://iconiqui.com/r/b-checkbox-group.json",
      "summary": "Each option row is described with a plain object and rendered as an animated button.",
      "apiSections": [
        {
          "id": "checkbox-option",
          "title": "CheckboxGroupOption",
          "summary": "Each option row is described with a plain object and rendered as an animated button.",
          "notes": [],
          "fields": [
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Primary copy shown for the row."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable identifier used when checking whether the row is selected and when producing the next selection array."
            },
            {
              "name": "description",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional secondary text rendered below the label."
            },
            {
              "name": "group",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional section label used to chunk long lists into named groups when adjacent options share the same value."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables the row button and blocks hover, active, and toggle behavior for that option."
            },
            {
              "name": "disabledReason",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional explainer rendered below disabled rows so users understand why the choice is unavailable."
            }
          ]
        },
        {
          "id": "checkbox-group",
          "title": "CheckboxGroup",
          "summary": "Animated multi-select list with optimistic toggle feedback, stable output ordering, and optional disclosure for longer option sets.",
          "notes": [
            "The component previews the next state immediately after a click, then re-syncs with whatever value the parent sends back.",
            "If a selected option would be hidden by maxVisible, the list stays expanded so users do not lose track of active choices.",
            "Rows are buttons, not native checkbox inputs, so form submission and checkbox semantics are not provided out of the box."
          ],
          "fields": [
            {
              "name": "options",
              "type": "CheckboxGroupOption[]",
              "defaultValue": "",
              "required": true,
              "description": "Array of rows to render, in display order."
            },
            {
              "name": "value",
              "type": "string[]",
              "defaultValue": "[]",
              "required": false,
              "description": "Current selected values. The prop remains the source of truth, while the component renders an immediate optimistic preview after each click."
            },
            {
              "name": "onChange",
              "type": "(value: string[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Receives the next selected values array after a row is toggled, normalized back into the original display order."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root flex column wrapper."
            },
            {
              "name": "maxVisible",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Optional progressive-disclosure cap. When provided, the list initially renders up to this many rows and reveals the rest with a built-in toggle."
            },
            {
              "name": "showMoreLabel",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional label prefix for the disclosure button shown when maxVisible hides rows."
            },
            {
              "name": "showLessLabel",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional label used when the disclosure button collapses the list back down."
            }
          ]
        },
        {
          "id": "checkbox-motion",
          "title": "Motion and accessibility",
          "summary": "The component leans on hover surfaces and AnimatePresence rather than native checkbox UI.",
          "notes": [
            "Selection is represented by a Lucide Check icon instead of a filled checkbox background.",
            "There is no role='group', role='checkbox', or aria-checked wiring in this version, so accessibility-sensitive forms should add hidden inputs or extend the component."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "color-picker",
      "name": "Color Picker",
      "href": "/inputs-and-forms/color-picker",
      "url": "https://iconiqui.com/inputs-and-forms/color-picker",
      "installPackage": "@iconiq/color-picker",
      "installCommand": "npx shadcn@latest add @iconiq/color-picker",
      "registryPath": "color-picker.json",
      "registryUrl": "https://iconiqui.com/r/color-picker.json",
      "summary": "Self-contained HSV panel with saturation field, hue/alpha sliders, multi-format readouts, and EyeDropper.",
      "apiSections": [
        {
          "id": "color-picker",
          "title": "ColorPicker",
          "summary": "Self-contained HSV panel with saturation field, hue/alpha sliders, multi-format readouts, and EyeDropper.",
          "notes": [
            "Install with npx shadcn@latest add https://iconiqui.com/r/color-picker.json (requires lucide-react, motion, and a cn helper).",
            "Theme tokens are embedded on the root node so the picker works without iconiq-theme, though it still maps cleanly to shadcn semantic colors.",
            "The saturation square, hue slider, and alpha slider share one RGB source of truth. Slider drags emit on pointer up to stay stable in controlled mode.",
            "Format switching exposes editable HEX, RGB, HSL, and OKLCH channels. Values commit on blur or Enter so partial typing does not fight the live color state.",
            "EyeDropper support depends on the browser API (Chrome/Edge). Use onEyedropperUnsupported for user-facing feedback.",
            "FluidColorPicker remains exported as a backward-compatible alias for older imports."
          ],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled hex color such as #3B82F6. When provided, the picker syncs its internal state to this value."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "#3B82F6",
              "required": false,
              "description": "Starting color for uncontrolled usage. Ignored when value is supplied."
            },
            {
              "name": "onChange",
              "type": "(color: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the color settles (pointer up on sliders, blur/Enter on inputs). Emits #RRGGBB, or #RRGGBBAA when alpha is below 100%."
            },
            {
              "name": "defaultAlpha",
              "type": "number",
              "defaultValue": "100",
              "required": false,
              "description": "Starting alpha percentage (0–100) for uncontrolled usage when defaultValue has no alpha channel."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables picker interaction and lowers shell opacity."
            },
            {
              "name": "showEyedropper",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Shows or hides the pipette control in the footer row."
            },
            {
              "name": "onEyedropperUnsupported",
              "type": "() => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when EyeDropper is unavailable. No alert dialog is shown by default."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer picker shell for width, shadow, or layout overrides."
            }
          ]
        }
      ],
      "dependencies": [
        "lucide-react",
        "motion"
      ]
    },
    {
      "slug": "b-combobox",
      "name": "Combobox",
      "href": "/inputs-and-forms/combobox",
      "url": "https://iconiqui.com/inputs-and-forms/combobox",
      "installPackage": "@iconiq/b-combobox",
      "installCommand": "npx shadcn@latest add @iconiq/b-combobox",
      "registryPath": "b-combobox.json",
      "registryUrl": "https://iconiqui.com/r/b-combobox.json",
      "summary": "Root combobox controller. Compose ComboboxInput, ComboboxContent, ComboboxList, and ComboboxItem inside it.",
      "apiSections": [
        {
          "id": "combobox",
          "title": "Combobox",
          "summary": "Root combobox controller. Compose ComboboxInput, ComboboxContent, ComboboxList, and ComboboxItem inside it.",
          "notes": [
            "The root wraps Base UI's combobox primitive with the same Iconiq motion layer used by the previous wrapper.",
            "Filtering, selection, typeahead, keyboard navigation, and clear behavior are delegated to Base UI while the visual treatment stays Iconiq."
          ],
          "fields": [
            {
              "name": "items",
              "type": "readonly Item[]",
              "defaultValue": "",
              "required": false,
              "description": "Optional item collection used by Base UI for filtering and render-function lists."
            },
            {
              "name": "value",
              "type": "Item | Item[] | null",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value. Use an array when multiple is true."
            },
            {
              "name": "defaultValue",
              "type": "Item | Item[] | null",
              "defaultValue": "",
              "required": false,
              "description": "Initial selected value for uncontrolled usage."
            },
            {
              "name": "onValueChange",
              "type": "(value: Item | Item[] | null) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when an item is selected, a chip is removed, or the clear action resets the selection."
            },
            {
              "name": "itemToStringLabel",
              "type": "(item: Item) => string",
              "defaultValue": "",
              "required": false,
              "description": "Maps object values to the label shown in the input and used for text filtering."
            },
            {
              "name": "itemToStringValue",
              "type": "(item: Item) => string",
              "defaultValue": "",
              "required": false,
              "description": "Maps object values to the hidden form value."
            },
            {
              "name": "inputValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled search text. Leave uncontrolled for Base UI to manage query state."
            },
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled popup state. Pair with onOpenChange."
            }
          ]
        },
        {
          "id": "combobox-input",
          "title": "ComboboxInput",
          "summary": "Styled input shell with the previous border, focus ring, clear button, and rotating trigger icon.",
          "notes": [],
          "fields": [
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Shown when no item is selected and the input is empty."
            },
            {
              "name": "showClear",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether ComboboxClear is rendered in the input."
            },
            {
              "name": "showTrigger",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether the rotating trigger icon is rendered in the input."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the input shell so width and local layout can be adjusted."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables the input, clear button, and trigger while applying the previous reduced-opacity presentation."
            }
          ]
        },
        {
          "id": "combobox-content",
          "title": "ComboboxContent",
          "summary": "Portaled dropdown surface with the previous white/dark panel, border, shadow, and fade-slide motion.",
          "notes": [
            "The popup remains mounted while closing so the motion exit can complete before Base UI unmounts it.",
            "The panel width matches the input anchor and the list scrolls at the same max height as before."
          ],
          "fields": [
            {
              "name": "side",
              "type": "\"top\" | \"right\" | \"bottom\" | \"left\" | \"inline-start\" | \"inline-end\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Preferred side for the popup."
            },
            {
              "name": "align",
              "type": "\"start\" | \"center\" | \"end\"",
              "defaultValue": "\"start\"",
              "required": false,
              "description": "Popup alignment relative to the input anchor."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "4",
              "required": false,
              "description": "Gap between the input shell and dropdown."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the animated popup panel."
            }
          ]
        },
        {
          "id": "combobox-list",
          "title": "ComboboxList",
          "summary": "Scrollable item list rendered inside ComboboxContent with the previous max-height and motion treatment.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode | ((item, index) => ReactNode)",
              "defaultValue": "",
              "required": true,
              "description": "Render explicit children or a render function when using the root items prop."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default list spacing and scroll classes."
            }
          ]
        },
        {
          "id": "combobox-item",
          "title": "ComboboxItem",
          "summary": "Animated row with active highlight, optional description layout, and selected checkmark spring.",
          "notes": [
            "ComboboxEmpty, ComboboxGroup, ComboboxLabel, ComboboxSeparator, ComboboxCollection, and chip helpers are exported for larger compositions.",
            "Keyboard navigation and filtering are handled by Base UI; the visual hover highlight and checkmark animation stay Iconiq."
          ],
          "fields": [
            {
              "name": "value",
              "type": "Item",
              "defaultValue": "",
              "required": true,
              "description": "Stable value used by Base UI for selection."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Primary item label content."
            },
            {
              "name": "description",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional secondary line rendered below the item label, matching the prior option description UI."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default row layout and motion classes."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "file-upload",
      "name": "File Upload",
      "href": "/inputs-and-forms/file-upload",
      "url": "https://iconiqui.com/inputs-and-forms/file-upload",
      "installPackage": "@iconiq/file-upload",
      "installCommand": "npx shadcn@latest add @iconiq/file-upload",
      "registryPath": "file-upload.json",
      "registryUrl": "https://iconiqui.com/r/file-upload.json",
      "summary": "Drag-and-drop uploader with an internal queue, hidden file input, keyboard-triggerable drop zone, and callback hooks for parent integrations.",
      "apiSections": [
        {
          "id": "file-upload",
          "title": "FileUpload",
          "summary": "Drag-and-drop uploader with an internal queue, hidden file input, keyboard-triggerable drop zone, and callback hooks for parent integrations.",
          "notes": [
            "The drop zone is keyboard accessible and opens the hidden file input on Enter or Space.",
            "Both drag-and-drop and click-to-browse flow through the same queue logic, so accept filtering and max file limits stay consistent."
          ],
          "fields": [
            {
              "name": "accept",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional accept string passed to the hidden file input and also enforced for dropped files, including MIME types like image/* and extensions like .pdf."
            },
            {
              "name": "multiple",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Allows selecting or dropping multiple files. When set to false, the next selection replaces the existing queue."
            },
            {
              "name": "maxFiles",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Caps the queue length. New files are prepended, and anything beyond the limit is trimmed from the end."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables click, drag, keyboard activation, and the hidden file input without changing the component structure."
            },
            {
              "name": "name",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Passes a form field name through to the hidden file input for form integrations."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Adds classes to the outer wrapper without changing the component internals."
            },
            {
              "name": "onFilesChange",
              "type": "(files: File[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when files are added or removed from the queue. It does not fire on every progress tick."
            },
            {
              "name": "onFileRemove",
              "type": "(file: File, nextFiles: File[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called after a queued file is removed. The second argument contains the remaining files in queue order."
            },
            {
              "name": "onUploadComplete",
              "type": "(files: File[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called once the current queue reaches 100% completion for every item."
            }
          ]
        },
        {
          "id": "file-upload-behavior",
          "title": "Built-in behavior",
          "summary": "The component still owns its progress visuals and preview lifecycle, even when you attach callbacks from parent code.",
          "notes": [
            "Preview object URLs are cleaned up on remove and during component unmount.",
            "Each queue item id is built from the file name, file size, and a random suffix to reduce collisions between repeated uploads."
          ],
          "fields": [
            {
              "name": "progress state",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Each added file starts in an uploading state and advances through the built-in simulated progress loop until it reaches done."
            },
            {
              "name": "image previews",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Image files receive object URL previews and render as thumbnails; non-image files fall back to a file icon surface."
            },
            {
              "name": "remove action",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Each queued file can be removed individually from the trailing action button, with preview URLs revoked immediately."
            }
          ]
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "input-otp",
      "name": "Input OTP",
      "href": "/inputs-and-forms/input-otp",
      "url": "https://iconiqui.com/inputs-and-forms/input-otp",
      "installPackage": "@iconiq/input-otp",
      "installCommand": "npx shadcn@latest add @iconiq/input-otp",
      "registryPath": "input-otp.json",
      "registryUrl": "https://iconiqui.com/r/input-otp.json",
      "summary": "Root wrapper around Base UI OTP Field that owns the shared value, completion state, and keyboard/paste behavior for every slot.",
      "apiSections": [
        {
          "id": "otp",
          "title": "OTP",
          "summary": "Root wrapper around Base UI OTP Field that owns the shared value, completion state, and keyboard/paste behavior for every slot.",
          "notes": [
            "Built on `OTPFieldPreview` from `@base-ui/react/otp-field`.",
            "Prefer `OTPSlots` so slot count always matches `length`, or render one `OTPSlot` per character manually.",
            "Supports `autoSubmit`, `mask`, `normalizeValue`, and `onValueInvalid` from the underlying Base UI root."
          ],
          "fields": [
            {
              "name": "length",
              "type": "number",
              "defaultValue": "",
              "required": true,
              "description": "Number of OTP characters. Required so Base UI can clamp values, detect completion, and manage focus order."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled OTP string. Pair with `onValueChange` when the parent owns the code."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial value for uncontrolled usage."
            },
            {
              "name": "onValueChange",
              "type": "(value: string, eventDetails) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the OTP value changes from typing, paste, backspace, or keyboard navigation."
            },
            {
              "name": "onValueComplete",
              "type": "(value: string, eventDetails) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when all slots are filled, including when a complete code is pasted."
            },
            {
              "name": "validationType",
              "type": "\"numeric\" | \"alpha\" | \"alphanumeric\" | \"none\"",
              "defaultValue": "\"numeric\"",
              "required": false,
              "description": "Built-in validation applied before values are stored. Use `alphanumeric` for backup or recovery codes."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables interaction across every slot."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes merged onto the root flex container."
            },
            {
              "name": "containerClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Legacy alias merged onto the root container alongside `className`."
            }
          ]
        },
        {
          "id": "otp-slots",
          "title": "OTPSlots",
          "summary": "Convenience layout that renders the correct number of slots from the parent `OTP` length, with an optional separator.",
          "notes": [
            "Must be rendered inside `OTP` so it can read the configured `length`.",
            "Adds `aria-label` to every slot after the first one for screen reader context."
          ],
          "fields": [
            {
              "name": "separatorAfter",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Inserts `OTPSeparator` before the slot at this zero-based index, such as `3` for a 3-3 grouped code."
            },
            {
              "name": "slotClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes forwarded to every rendered `OTPSlot`."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes merged onto the internal `OTPGroup` wrapper."
            }
          ]
        },
        {
          "id": "otp-slot",
          "title": "OTPSlot",
          "summary": "Animated character cell with spring focus ring, pop-in digit motion, and a pulsing caret on the active empty slot.",
          "notes": [
            "The real input is visually hidden but remains focusable for typing, paste, and mobile one-time-code autofill.",
            "Slot order is determined by render order; the legacy `index` prop is accepted but ignored."
          ],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes merged onto the animated slot surface."
            },
            {
              "name": "aria-label",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Accessible label for slots after the first one. The first slot inherits the field label from `OTP` or a surrounding `<label>`."
            }
          ]
        },
        {
          "id": "otp-group",
          "title": "OTPGroup",
          "summary": "Optional layout wrapper that groups slots with consistent spacing when you need multiple visual clusters.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes merged onto the group flex container."
            }
          ]
        },
        {
          "id": "otp-separator",
          "title": "OTPSeparator",
          "summary": "Accessible separator between OTP groups, rendered with the dotted divider used in the Iconiq preview.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Classes merged onto the separator element."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-radio-group",
      "name": "Radio Group",
      "href": "/inputs-and-forms/radio-group",
      "url": "https://iconiqui.com/inputs-and-forms/radio-group",
      "installPackage": "@iconiq/b-radio-group",
      "installCommand": "npx shadcn@latest add @iconiq/b-radio-group",
      "registryPath": "b-radio-group.json",
      "registryUrl": "https://iconiqui.com/r/b-radio-group.json",
      "summary": "Options are plain objects consumed by the RadioGroup component.",
      "apiSections": [
        {
          "id": "radio-option",
          "title": "Radio option shape",
          "summary": "Options are plain objects consumed by the RadioGroup component.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Unique identifier for the option and the selected value reported through onChange."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Primary line shown for the option."
            },
            {
              "name": "description",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional secondary line shown below the label with reduced emphasis."
            }
          ]
        },
        {
          "id": "radio-group",
          "title": "RadioGroup",
          "summary": "Single-choice selector with animated rows, native radio inputs, and support for both controlled and uncontrolled state.",
          "notes": [
            "If options is empty, the component returns null rather than rendering an empty radiogroup.",
            "In uncontrolled mode, the selected value normalizes back to the first available option if the current selection disappears from the options array."
          ],
          "fields": [
            {
              "name": "options",
              "type": "{ value: string; label: string; description?: string }[]",
              "defaultValue": "",
              "required": true,
              "description": "Available choices in display order."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial uncontrolled selection. If omitted or invalid, the component falls back to the first option."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value. When provided, parent state owns selection and the component only reports changes."
            },
            {
              "name": "onChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever a user selects a row."
            },
            {
              "name": "name",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Shared radio input name. If omitted, the component generates one per instance."
            },
            {
              "name": "layoutId",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Motion layout id used by the selected row highlight. Override it only when you want to intentionally share that highlight between groups."
            },
            {
              "name": "\"aria-label\"",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Accessible name for the radiogroup. Provide this or aria-labelledby so assistive tech can announce the set clearly."
            },
            {
              "name": "\"aria-labelledby\"",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "ID of external text that labels the radiogroup. Use this instead of aria-label when visible copy already exists."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root wrapper for spacing or sizing adjustments."
            }
          ]
        },
        {
          "id": "radio-motion-a11y",
          "title": "Motion and accessibility",
          "summary": "The component wraps native radio inputs in an animated label shell so keyboard, form, and screen-reader behavior stay intact.",
          "notes": [
            "The root keeps radiogroup semantics and each input supports Arrow keys plus Home and End navigation with a single tab stop inside the set.",
            "Each instance gets its own highlight layoutId by default, so separate groups on the same page do not animate across each other unless you opt into a shared layoutId."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-select",
      "name": "Select",
      "href": "/inputs-and-forms/select",
      "url": "https://iconiqui.com/inputs-and-forms/select",
      "installPackage": "@iconiq/b-select",
      "installCommand": "npx shadcn@latest add @iconiq/b-select",
      "registryPath": "b-select.json",
      "registryUrl": "https://iconiqui.com/r/b-select.json",
      "summary": "Root select controller. Compose SelectTrigger, SelectValue, SelectContent, and SelectItem inside it.",
      "apiSections": [
        {
          "id": "select",
          "title": "Select",
          "summary": "Root select controller. Compose SelectTrigger, SelectValue, SelectContent, and SelectItem inside it.",
          "notes": [
            "The root wraps the provider primitive in the Iconiq motion layer so child parts share one animation setup.",
            "Selection and open state can be controlled or uncontrolled while still preserving primitive keyboard navigation and typeahead."
          ],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value. Leave unset with defaultValue for uncontrolled usage."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial selected value for uncontrolled usage."
            },
            {
              "name": "onValueChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a SelectItem is chosen. The menu closes immediately afterward."
            },
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled popup state. Pair with onOpenChange when parent state owns the menu."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Initial popup state for uncontrolled usage."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the trigger, keyboard, item choice, or outside interaction opens or closes the menu."
            }
          ]
        },
        {
          "id": "select-trigger",
          "title": "SelectTrigger",
          "summary": "Button that opens the menu and hosts SelectValue plus the animated chevron.",
          "notes": [
            "The trigger keeps the previous press spring, hover color, focus ring, and chevron rotation."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Usually a SelectValue. The chevron icon is appended automatically."
            },
            {
              "name": "size",
              "type": "\"sm\" | \"default\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Data attribute hook for compact trigger variants without changing the default Iconiq styling."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the trigger button. Use it for local width such as w-full max-w-48."
            }
          ]
        },
        {
          "id": "select-value",
          "title": "SelectValue",
          "summary": "Inline label for the current selection, with placeholder support from the underlying primitive.",
          "notes": [],
          "fields": [
            {
              "name": "placeholder",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Shown in the trigger when no item is selected."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the value span. The default keeps text truncated inside the trigger."
            }
          ]
        },
        {
          "id": "select-overlay",
          "title": "SelectContent",
          "summary": "Portaled menu surface with the previous Iconiq dropdown fade, slide, and viewport clamping.",
          "notes": [
            "The popup is portaled, width-matches the trigger by default, and caps height at 320px before scrolling.",
            "Scroll up/down arrow slots are included for long menus while the panel keeps the same entry and exit animation."
          ],
          "fields": [
            {
              "name": "side",
              "type": "\"top\" | \"right\" | \"bottom\" | \"left\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Preferred side for the menu before collision handling."
            },
            {
              "name": "align",
              "type": "\"start\" | \"center\" | \"end\"",
              "defaultValue": "\"start\"",
              "required": false,
              "description": "Horizontal alignment against the trigger or anchor."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "8",
              "required": false,
              "description": "Gap between trigger and menu. The default matches the prior select spacing."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the animated menu panel for local max height, width, or surface overrides."
            }
          ]
        },
        {
          "id": "select-item",
          "title": "SelectItem",
          "summary": "Selectable row with primitive keyboard behavior plus the previous active-row highlight and checkmark motion.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable value reported through onValueChange and used to determine the selected checkmark."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Item label content. Primitive ItemText also feeds the selected trigger value."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional leading icon rendered inline with the item label and selected trigger value."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Prevents the item from receiving selection."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the row while preserving the animated active highlight and selected checkmark."
            }
          ]
        },
        {
          "id": "select-group",
          "title": "SelectGroup",
          "summary": "Section wrapper for grouped options inside SelectContent.",
          "notes": [
            "SelectGroup adds the same section spacing as the previous grouped option renderer."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "SelectItem rows or nested option content rendered inside the grouped section."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default grouped section spacing classes."
            }
          ]
        },
        {
          "id": "select-label",
          "title": "SelectLabel",
          "summary": "Compact section label rendered above grouped SelectItem rows.",
          "notes": [
            "SelectLabel keeps the compact uppercase section label treatment."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Section label text rendered above a SelectGroup."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the uppercase section label typography classes."
            }
          ]
        },
        {
          "id": "select-separator",
          "title": "SelectSeparator",
          "summary": "Non-interactive divider between item clusters inside the menu.",
          "notes": [
            "SelectSeparator renders a non-interactive border-token divider between item clusters."
          ],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default border-token divider classes."
            }
          ]
        },
        {
          "id": "select-scroll-up",
          "title": "SelectScrollUpButton",
          "summary": "Scroll affordance rendered above long SelectContent lists.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default scroll button layout classes."
            }
          ]
        },
        {
          "id": "select-scroll-down",
          "title": "SelectScrollDownButton",
          "summary": "Scroll affordance rendered below long SelectContent lists.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default scroll button layout classes."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "b-slider",
      "name": "Slider",
      "href": "/inputs-and-forms/slider",
      "url": "https://iconiqui.com/inputs-and-forms/slider",
      "installPackage": "@iconiq/b-slider",
      "installCommand": "npx shadcn@latest add @iconiq/b-slider",
      "registryPath": "b-slider.json",
      "registryUrl": "https://iconiqui.com/r/b-slider.json",
      "summary": "Pointer-driven range control with optional controlled or uncontrolled value management.",
      "apiSections": [
        {
          "id": "slider",
          "title": "Slider",
          "summary": "Pointer-driven range control with optional controlled or uncontrolled value management.",
          "notes": [
            "When value is undefined, the component stores the current value internally and updates it during drag operations.",
            "The displayed value is derived from the animated motion value, so the readout stays in sync with the spring animation rather than jumping immediately.",
            "Touch interaction keeps vertical page scrolling available with pan-y while still supporting horizontal dragging on the slider itself."
          ],
          "fields": [
            {
              "name": "value",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Controlled value. When provided, the parent owns the current position."
            },
            {
              "name": "defaultValue",
              "type": "number",
              "defaultValue": "50",
              "required": false,
              "description": "Initial internal value used when value is not supplied."
            },
            {
              "name": "min",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Lower bound used for clamping and display mapping."
            },
            {
              "name": "max",
              "type": "number",
              "defaultValue": "100",
              "required": false,
              "description": "Upper bound used for clamping and display mapping."
            },
            {
              "name": "step",
              "type": "number",
              "defaultValue": "1",
              "required": false,
              "description": "Step size applied after translating pointer position into a raw numeric value."
            },
            {
              "name": "onChange",
              "type": "(value: number) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called for live value updates from pointer or keyboard input when the snapped value actually changes."
            },
            {
              "name": "onValueCommit",
              "type": "(value: number) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when an interaction is committed, such as releasing a drag or finishing a keyboard step."
            },
            {
              "name": "showValue",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether the live numeric readout is shown on the right side of the label row."
            },
            {
              "name": "valueDecimals",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Controls how many decimal places are shown in the readout when you want precision without custom formatting."
            },
            {
              "name": "formatValue",
              "type": "(value: number) => string",
              "defaultValue": "",
              "required": false,
              "description": "Optional formatter for the visible readout and aria-valuetext, useful for units such as dB, percent, or milliseconds."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional label shown on the left side of the header row above the track."
            },
            {
              "name": "ariaLabel",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Accessible name used when no visible label is rendered for the slider."
            },
            {
              "name": "ariaLabelledBy",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "ID of an external label element that should be announced instead of the built-in label."
            },
            {
              "name": "marks",
              "type": "{ value: number; label?: string }[]",
              "defaultValue": "",
              "required": false,
              "description": "Optional tick marks rendered below the track so large ranges can include landmarks like Low, Medium, and High."
            }
          ]
        },
        {
          "id": "slider-interaction",
          "title": "Interaction model",
          "summary": "Slider supports pointer, keyboard, and screen-reader friendly range semantics.",
          "notes": [
            "The thumb and filled track animate with springs whenever the current value changes.",
            "Pointer capture is taken on pointer down and released on pointer up or cancel, which keeps dragging stable even when the pointer leaves the track.",
            "Keyboard support includes Arrow keys for step changes, Page Up and Page Down for larger jumps, and Home and End for min and max."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-switch",
      "name": "Switch",
      "href": "/inputs-and-forms/switch",
      "url": "https://iconiqui.com/inputs-and-forms/switch",
      "installPackage": "@iconiq/b-switch",
      "installCommand": "npx shadcn@latest add @iconiq/b-switch",
      "registryPath": "b-switch.json",
      "registryUrl": "https://iconiqui.com/r/b-switch.json",
      "summary": "Binary on or off control built on Radix Switch, with a motion-driven thumb travel, foreground fill sweep, and optional inline label.",
      "apiSections": [
        {
          "id": "switch",
          "title": "Switch",
          "summary": "Binary on or off control built on Radix Switch, with a motion-driven thumb travel, foreground fill sweep, and optional inline label.",
          "notes": [
            "Additional Radix switch props such as aria-label, name, value, required, and form are forwarded to the root control.",
            "If you provide label, the component wraps the control in a native label element so clicking the text also toggles the switch."
          ],
          "fields": [
            {
              "name": "checked",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled checked state. Pass this when the parent owns the current on or off value."
            },
            {
              "name": "defaultChecked",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Initial checked state for uncontrolled usage. The component keeps its local animation state in sync with this mode too."
            },
            {
              "name": "onCheckedChange",
              "type": "(checked: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the switch changes state, after the thumb and fill animation sequence starts."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables pointer and keyboard interaction, and dims the switch and optional label together."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional inline text rendered beside the switch. When omitted, the component returns only the switch control itself."
            },
            {
              "name": "labelSide",
              "type": "\"left\" | \"right\"",
              "defaultValue": "right",
              "required": false,
              "description": "Controls which side of the switch the optional label text appears on."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the Radix root element for local spacing or surface overrides."
            }
          ]
        },
        {
          "id": "switch-motion",
          "title": "Motion and interaction behavior",
          "summary": "The switch uses separate motion values for thumb travel, thumb squash, and track fill opacity so the state change feels tactile without becoming noisy.",
          "notes": [
            "Pointer press slightly flattens the thumb before release, then the thumb snaps back with a softer bounce after the state change.",
            "The dark foreground fill fades in as the thumb travels right, rather than swapping track color instantly.",
            "Controlled and uncontrolled usage both keep the thumb animation synchronized with the underlying Radix state."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "theme-toggle",
      "name": "Theme Toggle",
      "href": "/inputs-and-forms/theme-toggle",
      "url": "https://iconiqui.com/inputs-and-forms/theme-toggle",
      "installPackage": "@iconiq/theme-toggle",
      "installCommand": "npx shadcn@latest add @iconiq/theme-toggle",
      "registryPath": "theme-toggle.json",
      "registryUrl": "https://iconiqui.com/r/theme-toggle.json",
      "summary": "Client-only pill switch that toggles light and dark mode by adding or removing the `dark` class on `document.documentElement`, with sun and moon icons inside a sliding knob.",
      "apiSections": [
        {
          "id": "theme-toggle",
          "title": "ThemeToggle",
          "summary": "Client-only pill switch that toggles light and dark mode by adding or removing the `dark` class on `document.documentElement`, with sun and moon icons inside a sliding knob.",
          "notes": [
            "On mount, the control reads `prefers-color-scheme: dark` and syncs both local state and the document `dark` class.",
            "Before hydration completes, a neutral placeholder button is rendered to avoid layout shift while keeping an accessible name.",
            "The toggle manages theme locally via the `dark` class; pair it with your own CSS variables or Tailwind dark mode setup.",
            "Install path is `components/ui/theme-toggle.tsx` with the `ThemeToggle` export."
          ],
          "fields": [
            {
              "name": "size",
              "type": "\"sm\" | \"md\" | \"lg\"",
              "defaultValue": "md",
              "required": false,
              "description": "Controls track, knob, and icon dimensions. Use `sm` in compact toolbars and `lg` for hero or settings layouts."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the root button for spacing or layout in your header or settings panel."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react/toggle",
        "lucide-react"
      ]
    },
    {
      "slug": "b-collapsible",
      "name": "Collapsible",
      "href": "/layout-and-toolbars/collapsible",
      "url": "https://iconiqui.com/layout-and-toolbars/collapsible",
      "installPackage": "@iconiq/b-collapsible",
      "installCommand": "npx shadcn@latest add @iconiq/b-collapsible",
      "registryPath": "b-collapsible.json",
      "registryUrl": "https://iconiqui.com/r/b-collapsible.json",
      "summary": "Collapsible with the same Iconiq API layered over Base UI primitives, preserving the same height, icon, and content transitions as the Radix version.",
      "apiSections": [],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "infiniteribbon",
      "name": "Infinite Ribbon",
      "href": "/layout-and-toolbars/infiniteribbon",
      "url": "https://iconiqui.com/layout-and-toolbars/infiniteribbon",
      "installPackage": "@iconiq/infiniteribbon",
      "installCommand": "npx shadcn@latest add @iconiq/infiniteribbon",
      "registryPath": "infiniteribbon.json",
      "registryUrl": "https://iconiqui.com/r/infiniteribbon.json",
      "summary": "Full-width looping announcement ribbon with repeated content, optional reverse direction, and diagonal rotation controls.",
      "apiSections": [],
      "dependencies": []
    },
    {
      "slug": "b-selection-toolbar",
      "name": "Selection Toolbar",
      "href": "/layout-and-toolbars/selection-toolbar",
      "url": "https://iconiqui.com/layout-and-toolbars/selection-toolbar",
      "installPackage": "@iconiq/b-selection-toolbar",
      "installCommand": "npx shadcn@latest add @iconiq/b-selection-toolbar",
      "registryPath": "b-selection-toolbar.json",
      "registryUrl": "https://iconiqui.com/r/b-selection-toolbar.json",
      "summary": "Floating formatting toolbar for editable text. It watches document selection, shows itself only when the selection lives inside the provided container, and exposes bold, italic, and underline actions.",
      "apiSections": [
        {
          "id": "selectiontoolbar",
          "title": "SelectionToolbar",
          "summary": "Floating formatting toolbar for editable text. It watches document selection, shows itself only when the selection lives inside the provided container, and exposes bold, italic, and underline actions.",
          "notes": [
            "The toolbar listens to document-level selectionchange and mousedown events, so it updates as the selection moves and closes when people click away.",
            "Formatting actions run on mousedown instead of click so the active text selection is preserved while bold, italic, or underline is applied.",
            "Active states are read from document.queryCommandState for the same three formatting commands the toolbar exposes."
          ],
          "fields": [
            {
              "name": "containerRef",
              "type": "React.RefObject<HTMLElement | null>",
              "defaultValue": "",
              "required": true,
              "description": "Ref pointing at the editable container whose text selection should drive the toolbar. Selections outside this element immediately hide the toolbar."
            }
          ]
        },
        {
          "id": "selectiontoolbar-positioning",
          "title": "Positioning and editing behavior",
          "summary": "The toolbar positions itself from the live range rectangle returned by the browser selection API and applies formatting through the native rich-text command pipeline.",
          "notes": [
            "Coordinates are derived from Range.getBoundingClientRect plus the current page scroll offset, which keeps the toolbar visually anchored to the selected phrase.",
            "Because the toolbar uses page-level coordinates, it works best when rendered in a non-clipping part of the tree rather than inside a tightly overflow-hidden local wrapper.",
            "The current implementation depends on document.execCommand for inline formatting. That makes it convenient for lightweight editable surfaces, but apps with a custom text model may want to fork the behavior."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "lucide-react"
      ]
    },
    {
      "slug": "separator",
      "name": "Separator",
      "href": "/layout-and-toolbars/separator",
      "url": "https://iconiqui.com/layout-and-toolbars/separator",
      "installPackage": "@iconiq/separator",
      "installCommand": "npx shadcn@latest add @iconiq/separator",
      "registryPath": "separator.json",
      "registryUrl": "https://iconiqui.com/r/separator.json",
      "summary": "Separator component documentation.",
      "apiSections": [],
      "dependencies": []
    },
    {
      "slug": "b-accordion",
      "name": "Accordion",
      "href": "/navigation/accordion",
      "url": "https://iconiqui.com/navigation/accordion",
      "installPackage": "@iconiq/b-accordion",
      "installCommand": "npx shadcn@latest add @iconiq/b-accordion",
      "registryPath": "b-accordion.json",
      "registryUrl": "https://iconiqui.com/r/b-accordion.json",
      "summary": "Each row is described by a simple object and rendered as a single-expand accordion item.",
      "apiSections": [
        {
          "id": "accordion-item",
          "title": "AccordionItem",
          "summary": "Each row is described by a simple object and rendered as a single-expand accordion item.",
          "notes": [],
          "fields": [
            {
              "name": "id",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable key used for React rendering, internal open-state comparison, and the generated aria-controls id."
            },
            {
              "name": "title",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Text shown in the trigger row."
            },
            {
              "name": "content",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Body copy shown inside the open panel with a horizontal masked wipe and a soft lift into place."
            }
          ]
        },
        {
          "id": "accordion",
          "title": "Accordion",
          "summary": "Stateful accordion component with internal open state and no controlled API.",
          "notes": [
            "Clicking an already open row closes it again by removing that item id from the internal open-state list.",
            "Single-open is the default behavior; pass multiple when you want a keep-open FAQ or settings list.",
            "There is no prop for default open or controlled open behavior in this implementation.",
            "The quiet variant keeps the same state model and API, but swaps in a lighter inline disclosure style."
          ],
          "fields": [
            {
              "name": "items",
              "type": "AccordionItem[]",
              "defaultValue": "",
              "required": true,
              "description": "Rows to render in order."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the max-w-2xl root wrapper so you can stretch or reposition the accordion in your layout."
            },
            {
              "name": "multiple",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Allows several rows to stay open at once. When omitted, opening one row closes the previously open row."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"quiet\"",
              "defaultValue": "\"default\"",
              "required": false,
              "description": "Switches between the plain divided list and the quieter inline plus/minus treatment."
            }
          ]
        },
        {
          "id": "accordion-motion",
          "title": "Motion and accessibility",
          "summary": "The accordion uses native buttons and animated height transitions rather than a headless primitive.",
          "notes": [
            "Each trigger button sets aria-expanded and aria-controls, and each open panel receives a matching id.",
            "The quiet variant uses a minimal plus/minus label while preserving the same keyboard, state, and content motion behavior.",
            "The content body reveals through a horizontal clipped wipe while the paragraph settles upward with a soft blur fade.",
            "Keyboard support is limited to standard button tab and click semantics; there is no arrow-key roving between items."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "breadcrumbs",
      "name": "Breadcrumbs",
      "href": "/navigation/breadcrumbs",
      "url": "https://iconiqui.com/navigation/breadcrumbs",
      "installPackage": "@iconiq/breadcrumbs",
      "installCommand": "npx shadcn@latest add @iconiq/breadcrumbs",
      "registryPath": "breadcrumbs.json",
      "registryUrl": "https://iconiqui.com/r/breadcrumbs.json",
      "summary": "Root semantic navigation wrapper for a breadcrumb trail.",
      "apiSections": [
        {
          "id": "breadcrumb",
          "title": "Breadcrumb",
          "summary": "Root semantic navigation wrapper for a breadcrumb trail.",
          "notes": [
            "The root nav always uses aria-label=\"breadcrumb\".",
            "Compose BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, and BreadcrumbSeparator inside the root."
          ],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the nav element for placement inside headers, toolbars, and page shells."
            }
          ]
        },
        {
          "id": "breadcrumb-list",
          "title": "BreadcrumbList",
          "summary": "Animated ordered list that lays out breadcrumb segments and separators.",
          "notes": [
            "Layout changes are animated with Motion, and AnimatePresence uses popLayout so inserted or removed items keep the trail fluid."
          ],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default flex wrapping, spacing, and muted text styles."
            }
          ]
        },
        {
          "id": "breadcrumb-item",
          "title": "BreadcrumbItem",
          "summary": "Animated list item wrapper for each breadcrumb segment.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the inline-flex item layout. Dynamic items should receive stable React keys when rendered from arrays."
            }
          ]
        },
        {
          "id": "breadcrumb-link",
          "title": "BreadcrumbLink",
          "summary": "Base UI render-compatible link for navigable breadcrumb segments.",
          "notes": [],
          "fields": [
            {
              "name": "href",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Destination for the linked segment. You can also compose a router link with the render prop."
            },
            {
              "name": "render",
              "type": "ReactElement | render function",
              "defaultValue": "",
              "required": false,
              "description": "Optional Base UI render override for composing with framework-specific links while preserving merged props."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default color transition and hover foreground treatment."
            }
          ]
        },
        {
          "id": "breadcrumb-page",
          "title": "BreadcrumbPage",
          "summary": "Current page segment rendered as disabled link-like text with aria-current.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default foreground current-page text style."
            }
          ]
        },
        {
          "id": "breadcrumb-separator",
          "title": "BreadcrumbSeparator",
          "summary": "Animated visual separator between breadcrumb items, defaulting to a chevron icon.",
          "notes": [
            "Separators render with role='presentation' and aria-hidden."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional custom separator content. When omitted, ChevronRightIcon is rendered."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default icon sizing class for separator icons."
            }
          ]
        },
        {
          "id": "breadcrumb-ellipsis",
          "title": "BreadcrumbEllipsis",
          "summary": "Compact overflow marker for collapsed breadcrumb paths.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default 20px square centered icon layout."
            }
          ]
        },
        {
          "id": "breadcrumbs-a11y",
          "title": "Accessibility and motion",
          "summary": "The compound API keeps semantic breadcrumb structure while layering Motion on top.",
          "notes": [
            "BreadcrumbList wraps the trail in an ordered list.",
            "BreadcrumbItem, BreadcrumbSeparator, and BreadcrumbEllipsis keep the same subtle fade, slide, and layout transitions from the previous implementation.",
            "BreadcrumbPage marks the final segment with aria-current='page'."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "command-palette",
      "name": "Command Palette",
      "href": "/navigation/command-palette",
      "url": "https://iconiqui.com/navigation/command-palette",
      "installPackage": "@iconiq/command-palette",
      "installCommand": "npx shadcn@latest add @iconiq/command-palette",
      "registryPath": "command-palette.json",
      "registryUrl": "https://iconiqui.com/r/command-palette.json",
      "summary": "Keyboard-first command menu built on Radix Dialog with grouped items, fuzzy search, arrow-key navigation, and optional built-in theme actions.",
      "apiSections": [
        {
          "id": "command-palette",
          "title": "CommandPalette",
          "summary": "Keyboard-first command menu built on Radix Dialog with grouped items, fuzzy search, arrow-key navigation, and optional built-in theme actions.",
          "notes": [
            "Items with href navigate through Next.js router.push. Items with action run a callback and close the palette.",
            "Search matches every whitespace-separated term against the label, description, and keywords haystack.",
            "The palette closes automatically on route changes when used inside a Next.js App Router app.",
            "Requires next-themes ThemeProvider when showThemeGroup is enabled."
          ],
          "fields": [
            {
              "name": "groups",
              "type": "CommandMenuGroupDef[]",
              "defaultValue": "[]",
              "required": false,
              "description": "Grouped command items. Each group has a heading and an items array with label, optional href or action, icon, keywords, and description."
            },
            {
              "name": "showThemeGroup",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "When true, appends Light, Dark, and System theme actions that call next-themes setTheme."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "\"Search components, pages, actions…\"",
              "required": false,
              "description": "Placeholder copy for the search field."
            },
            {
              "name": "shortcutKey",
              "type": "string",
              "defaultValue": "\"k\"",
              "required": false,
              "description": "Letter used with Cmd on macOS or Ctrl elsewhere to toggle the palette globally."
            },
            {
              "name": "contentDelay",
              "type": "number",
              "defaultValue": "150",
              "required": false,
              "description": "Milliseconds to wait before revealing the results panel after the dialog opens."
            },
            {
              "name": "trigger",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Custom trigger node. When provided, it replaces the default search button and receives an open handler."
            },
            {
              "name": "triggerProps",
              "type": "CommandMenuTriggerProps",
              "defaultValue": "",
              "required": false,
              "description": "Props for the default trigger button, including label, shortcut badge visibility, and className."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the dialog content panel."
            },
            {
              "name": "emptyMessage",
              "type": "string",
              "defaultValue": "\"No results found.\"",
              "required": false,
              "description": "Copy shown when the current query matches no items."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-dialog",
        "lucide-react",
        "motion",
        "next-themes"
      ]
    },
    {
      "slug": "faq-pro",
      "name": "FAQ Pro",
      "href": "/navigation/faq-pro",
      "url": "https://iconiqui.com/navigation/faq-pro",
      "installPackage": "@iconiq/faq-pro",
      "installCommand": "npx shadcn@latest add @iconiq/faq-pro",
      "registryPath": "faq-pro.json",
      "registryUrl": "https://iconiqui.com/r/faq-pro.json",
      "summary": "Searchable FAQ accordion with rounded cards, animated panels, query highlighting, and automatic expansion for filtered results.",
      "apiSections": [
        {
          "id": "faq-pro",
          "title": "FaqPro",
          "summary": "Searchable FAQ accordion with rounded cards, animated panels, query highlighting, and automatic expansion for filtered results.",
          "notes": [
            "Search filters by question and answer text. The first matching row opens automatically while you type.",
            "Only one FAQ panel can be open at a time. Clicking another item closes the previous one.",
            "Matched substrings render inside a highlight mark in both the question and answer.",
            "When the query is cleared, the list returns to the default open state controlled by defaultOpenFirst."
          ],
          "fields": [
            {
              "name": "items",
              "type": "FaqProItem[]",
              "defaultValue": "",
              "required": true,
              "description": "Array of `{ id, question, answer }` entries. Each id must be unique within the list."
            },
            {
              "name": "searchPlaceholder",
              "type": "string",
              "defaultValue": "Search FAQs...",
              "required": false,
              "description": "Placeholder copy for the search field."
            },
            {
              "name": "defaultOpenFirst",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Opens the first item when there is no active search query."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names applied to the root container."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react/accordion",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "file-tree",
      "name": "File Tree",
      "href": "/navigation/file-tree",
      "url": "https://iconiqui.com/navigation/file-tree",
      "installPackage": "@iconiq/file-tree",
      "installCommand": "npx shadcn@latest add @iconiq/file-tree",
      "registryPath": "file-tree.json",
      "registryUrl": "https://iconiqui.com/r/file-tree.json",
      "summary": "Root provider for the compound file tree. Tracks expanded folders, hover highlight bounds, and shared visual settings.",
      "apiSections": [
        {
          "id": "file-tree",
          "title": "FileTree",
          "summary": "Root provider for the compound file tree. Tracks expanded folders, hover highlight bounds, and shared visual settings.",
          "notes": [
            "Wrap `FileTreeList` and nested `FileTreeItem` components inside the root provider.",
            "Hovering any row updates a single animated highlight that follows the active item inside the tree container."
          ],
          "fields": [
            {
              "name": "defaultExpandedIds",
              "type": "string[]",
              "defaultValue": "[]",
              "required": false,
              "description": "Folder node ids that should start expanded on first render."
            },
            {
              "name": "highlightColor",
              "type": "string",
              "defaultValue": "#3b82f6",
              "required": false,
              "description": "Text color applied to items with `highlight` on `FileTreeItem`."
            },
            {
              "name": "indentSize",
              "type": "number",
              "defaultValue": "24",
              "required": false,
              "description": "Horizontal indent in pixels for each nested folder level."
            },
            {
              "name": "showIcons",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Whether to render icons. File icons are inferred from the label extension when no custom icon is provided."
            },
            {
              "name": "onNodeClick",
              "type": "(nodeId: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a file or folder row is activated."
            },
            {
              "name": "onNodeExpand",
              "type": "(nodeId: string, expanded: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a folder branch opens or closes."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names applied to the bordered root container."
            },
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Usually a single `FileTreeList` with nested `FileTreeItem` rows."
            }
          ]
        },
        {
          "id": "file-tree-list",
          "title": "FileTreeList",
          "summary": "Semantic tree container for top-level and nested file rows. Supports Base UI `render` composition instead of Radix Slot.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default vertical stack layout."
            },
            {
              "name": "render",
              "type": "ReactElement | ((props) => ReactElement)",
              "defaultValue": "",
              "required": false,
              "description": "Optional Base UI render override for the list container element."
            }
          ]
        },
        {
          "id": "file-tree-item",
          "title": "FileTreeItem",
          "summary": "Single file or folder row. Nested children render as an animated branch when the row is expandable.",
          "notes": [
            "Folder rows use Base UI Button for the toggle control while file rows remain static display rows.",
            "Folder icons swap with a spring transition, and child lists animate open and closed with height and opacity motion."
          ],
          "fields": [
            {
              "name": "nodeId",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable unique id used for expand state, callbacks, and tree semantics."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Display label for the row. File extension is used to pick a default icon."
            },
            {
              "name": "icon",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional custom icon node rendered before the label."
            },
            {
              "name": "hasChildren",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Marks the row as a branch even when it has no nested children yet. Otherwise inferred from child items."
            },
            {
              "name": "highlight",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "When true, tints the row with `highlightColor` to mark it as new or relevant."
            },
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Nested `FileTreeItem` rows rendered when the branch is expanded."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "tabs",
      "name": "Tabs",
      "href": "/navigation/tabs",
      "url": "https://iconiqui.com/navigation/tabs",
      "installPackage": "@iconiq/tabs",
      "installCommand": "npx shadcn@latest add @iconiq/tabs",
      "registryPath": "tabs.json",
      "registryUrl": "https://iconiqui.com/r/tabs.json",
      "summary": "Radix tabs root with a shared spring transition config for the sliding active pill. Supports controlled and uncontrolled usage.",
      "apiSections": [
        {
          "id": "tabs",
          "title": "Tabs",
          "summary": "Radix tabs root with a shared spring transition config for the sliding active pill. Supports controlled and uncontrolled usage.",
          "notes": [
            "Each Tabs instance uses a unique layoutId so multiple tab bars on one page do not share pill animations.",
            "Use controlled state with value and onValueChange, or pass defaultValue for uncontrolled usage."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Compose TabsList, TabsTrigger, and TabsContent inside the root."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial active tab for uncontrolled usage when you do not manage value in React state."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled active tab value."
            },
            {
              "name": "onValueChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a trigger activates a different tab through click or keyboard interaction."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the Radix tabs root wrapper."
            }
          ]
        },
        {
          "id": "tabs-list",
          "title": "TabsList",
          "summary": "Full-width segmented rail with rounded neutral background and padding for the trigger row.",
          "notes": [
            "Uses a rounded neutral surface in light and dark mode with overflow hidden so the active pill stays clipped cleanly."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Usually a row of TabsTrigger elements."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the inline-flex rail around the triggers."
            }
          ]
        },
        {
          "id": "tabs-trigger",
          "title": "TabsTrigger",
          "summary": "Interactive tab button with a shared layoutId pill behind the active trigger and mix-blend-exclusion label treatment.",
          "notes": [
            "The active trigger renders a motion.div with layoutId active-tab-bg that slides between tabs with spring motion.",
            "Inactive triggers fade slightly on hover while keeping the label readable through mix-blend-exclusion."
          ],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Unique tab identifier used for active state and content matching."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Label content rendered inside the trigger button."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the trigger button for local spacing, typography, or active-state overrides."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Prevents the trigger from receiving focus or changing the active tab."
            }
          ]
        },
        {
          "id": "tabs-content",
          "title": "TabsContent",
          "summary": "Radix content panel tied to a matching trigger value below the tab list.",
          "notes": [
            "Radix handles mounting and visibility for the active panel.",
            "Standard Radix content props such as forceMount are forwarded through the primitive."
          ],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Matches the corresponding TabsTrigger value."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Panel body shown when the content value is active."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the rendered content panel element."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-tabs",
        "motion"
      ]
    },
    {
      "slug": "b-alert-dialog",
      "name": "Alert Dialog",
      "href": "/overlay-and-popups/alert-dialog",
      "url": "https://iconiqui.com/overlay-and-popups/alert-dialog",
      "installPackage": "@iconiq/b-alert-dialog",
      "installCommand": "npx shadcn@latest add @iconiq/b-alert-dialog",
      "registryPath": "b-alert-dialog.json",
      "registryUrl": "https://iconiqui.com/r/b-alert-dialog.json",
      "summary": "Alert dialog with a shared Iconiq trigger, content, cancel, and action API layered over Base UI primitives, plus Motion-backed confirm-state transitions.",
      "apiSections": [],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-context-menu",
      "name": "Context Menu",
      "href": "/overlay-and-popups/context-menu",
      "url": "https://iconiqui.com/overlay-and-popups/context-menu",
      "installPackage": "@iconiq/b-context-menu",
      "installCommand": "npx shadcn@latest add @iconiq/b-context-menu",
      "registryPath": "b-context-menu.json",
      "registryUrl": "https://iconiqui.com/r/b-context-menu.json",
      "summary": "Root provider that coordinates open state and the shared motion shell used by the trigger, content, and item primitives.",
      "apiSections": [
        {
          "id": "context-menu",
          "title": "ContextMenu",
          "summary": "Root provider that coordinates open state and the shared motion shell used by the trigger, content, and item primitives.",
          "notes": [
            "Compose ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuSub, and the other exported parts inside the root.",
            "The menu opens from right click or long press on the trigger surface. Shift+F10 and the Context Menu key also open it from keyboard focus.",
            "Open and defaultOpen are supported on the Base UI install. The Radix install mirrors open changes through onOpenChange but keeps open state internal to the primitive.",
            "Content is portaled and collision-aware. The Iconiq shell keeps the original panel spring, row entrance, and active highlight motion."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Compose ContextMenuTrigger, ContextMenuContent, and item primitives such as ContextMenuItem or ContextMenuSub inside the root."
            },
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled open state for the menu surface. Supported on the Base UI install."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Initial open state for uncontrolled usage on the Base UI install."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the trigger, outside interaction, or Escape key changes the open state."
            }
          ]
        },
        {
          "id": "context-menu-trigger",
          "title": "ContextMenuTrigger",
          "summary": "Interactive surface that opens the menu on right click, long press, or keyboard context-menu shortcuts.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Trigger content rendered inside the context-click target."
            },
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Merges trigger behavior onto the single child element instead of rendering a wrapper element."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the trigger surface, including the focus ring and theme token scope."
            }
          ]
        },
        {
          "id": "context-menu-content",
          "title": "ContextMenuContent",
          "summary": "Portaled menu panel that renders the composed item tree with the Iconiq border, shadow, and motion treatment.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Menu body content such as groups, items, separators, checkbox rows, and nested submenus."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the animated panel shell. Use width utilities such as w-48 when you want a fixed menu width."
            },
            {
              "name": "collisionPadding",
              "type": "number",
              "defaultValue": "8",
              "required": false,
              "description": "Viewport padding used while the underlying primitive resolves collision-aware placement."
            }
          ]
        },
        {
          "id": "context-menu-item",
          "title": "ContextMenuItem",
          "summary": "Interactive menu row with the Iconiq active highlight, row entrance motion, and optional destructive styling.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Row content. Pair with ContextMenuShortcut when you want trailing keyboard hints."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"destructive\"",
              "defaultValue": "default",
              "required": false,
              "description": "Switches the row into the destructive color treatment used for irreversible actions."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Dims the row and blocks pointer and keyboard selection."
            },
            {
              "name": "inset",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Adds extra start padding so the row aligns with checkbox and radio items."
            },
            {
              "name": "onSelect",
              "type": "(event: Event) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the row is activated."
            }
          ]
        },
        {
          "id": "context-menu-shortcut",
          "title": "ContextMenuShortcut",
          "summary": "Trailing helper text for keyboard hints. It stays muted until the parent row is focused.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Shortcut copy such as ⌘R or Del."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the trailing shortcut span."
            }
          ]
        },
        {
          "id": "context-menu-sub",
          "title": "ContextMenuSub",
          "summary": "Nested submenu root. Pair ContextMenuSubTrigger with ContextMenuSubContent to build secondary menus such as More Tools.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Submenu trigger and content parts rendered inside the parent menu."
            }
          ]
        },
        {
          "id": "context-menu-checkbox-item",
          "title": "ContextMenuCheckboxItem",
          "summary": "Toggle row with a trailing check indicator and the same Iconiq row motion treatment as ContextMenuItem.",
          "notes": [],
          "fields": [
            {
              "name": "checked",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controls whether the row renders in the checked state."
            },
            {
              "name": "onCheckedChange",
              "type": "(checked: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the row toggles between checked and unchecked."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Dims the row and blocks pointer and keyboard selection."
            },
            {
              "name": "inset",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Adds extra start padding to align with sibling rows."
            }
          ]
        },
        {
          "id": "context-menu-radio-group",
          "title": "ContextMenuRadioGroup",
          "summary": "Single-select group for ContextMenuRadioItem rows. Use ContextMenuLabel above the options when you need a section heading.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value for the radio group."
            },
            {
              "name": "onValueChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a radio row is selected."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "b-dialog",
      "name": "Dialog",
      "href": "/overlay-and-popups/dialog",
      "url": "https://iconiqui.com/overlay-and-popups/dialog",
      "installPackage": "@iconiq/b-dialog",
      "installCommand": "npx shadcn@latest add @iconiq/b-dialog",
      "registryPath": "b-dialog.json",
      "registryUrl": "https://iconiqui.com/r/b-dialog.json",
      "summary": "Dialog, DialogTrigger, DialogClose, and DialogPortal are direct re-exports of the matching Radix dialog primitives.",
      "apiSections": [
        {
          "id": "dialog-root",
          "title": "Dialog",
          "summary": "Dialog, DialogTrigger, DialogClose, and DialogPortal are direct re-exports of the matching Radix dialog primitives.",
          "notes": [
            "Any remaining Dialog.Root props continue to work because the root export is the Radix primitive itself.",
            "Accessibility and focus-trap behavior come from Radix rather than additional wrapper logic here."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled open state on the Dialog root when you want the parent component to own visibility."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Uncontrolled initial state forwarded to Radix Dialog.Root."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever Radix requests a state change through triggers, overlay clicks, or escape key handling."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Composition surface for the trigger, content, and any related dialog helpers."
            }
          ]
        },
        {
          "id": "dialog-content",
          "title": "DialogContent",
          "summary": "Motion-enhanced content wrapper built around DialogPrimitive.Content and AnimatePresence.",
          "notes": [
            "Accessibility props and Radix callbacks such as onEscapeKeyDown, onPointerDownOutside, aria-describedby, and aria-labelledby are forwarded to DialogPrimitive.Content.",
            "DialogContent always renders its own close button in the top-right corner using DialogPrimitive.Close and the Lucide X icon."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controls whether the animated portal branch renders at all. In practice this must mirror the root open state for the content to appear and exit correctly."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the inner motion panel rather than the full-screen DialogPrimitive.Content wrapper."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered inside the animated panel. Each direct child is wrapped in its own motion.div for staggered entry."
            }
          ]
        },
        {
          "id": "dialog-trigger",
          "title": "DialogTrigger",
          "summary": "Radix trigger export used to open the dialog from any custom element.",
          "notes": [
            "Because DialogTrigger comes directly from Radix, it also accepts the remaining primitive props for event handling and accessibility wiring."
          ],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Lets you turn a custom button or link into the trigger without adding an extra wrapper element."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the trigger primitive."
            }
          ]
        },
        {
          "id": "dialog-close",
          "title": "DialogClose",
          "summary": "Radix close export used to dismiss the dialog from any custom control.",
          "notes": [
            "DialogContent also renders its own close button in the top-right corner using DialogClose and the Lucide X icon."
          ],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Lets you turn an existing button or link into the close control without adding an extra wrapper element."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the close primitive."
            }
          ]
        },
        {
          "id": "dialog-portal",
          "title": "DialogPortal",
          "summary": "Radix portal export for rendering dialog content outside the current DOM hierarchy.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Portal content such as overlay and dialog panel primitives."
            },
            {
              "name": "container",
              "type": "HTMLElement",
              "defaultValue": "",
              "required": false,
              "description": "Optional mount target for the portal. Defaults to document.body."
            }
          ]
        },
        {
          "id": "dialog-header",
          "title": "DialogHeader",
          "summary": "Layout helper for the title area at the top of dialog content.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered inside the header container."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the helper wrapper so spacing and alignment can be adjusted per dialog."
            }
          ]
        },
        {
          "id": "dialog-footer",
          "title": "DialogFooter",
          "summary": "Layout helper for actions or supporting context at the bottom of dialog content.",
          "notes": [
            "Both header and footer helpers accept the normal div HTML attribute surface in addition to className and children."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered inside the footer container."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the helper wrapper so spacing and alignment can be adjusted per dialog."
            }
          ]
        },
        {
          "id": "dialog-title",
          "title": "DialogTitle",
          "summary": "Semantic title helper forwarded to the matching Radix title primitive.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Text or inline markup rendered inside the title primitive."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default title styles."
            }
          ]
        },
        {
          "id": "dialog-description",
          "title": "DialogDescription",
          "summary": "Semantic description helper forwarded to the matching Radix description primitive.",
          "notes": [
            "Both title and description helpers forward refs to the underlying Radix primitives."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Text or inline markup rendered inside the description primitive."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default description styles."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "@radix-ui/react-slot",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "drawer",
      "name": "Drawer",
      "href": "/overlay-and-popups/drawer",
      "url": "https://iconiqui.com/overlay-and-popups/drawer",
      "installPackage": "@iconiq/drawer",
      "installCommand": "npx shadcn@latest add @iconiq/drawer",
      "registryPath": "drawer.json",
      "registryUrl": "https://iconiqui.com/r/drawer.json",
      "summary": "Vaul-backed drawer root that coordinates open state, drag gestures, overlay dismissal, focus management, and side-based placement for the compound parts.",
      "apiSections": [
        {
          "id": "drawer",
          "title": "Drawer",
          "summary": "Vaul-backed drawer root that coordinates open state, drag gestures, overlay dismissal, focus management, and side-based placement for the compound parts.",
          "notes": [
            "The root accepts the full Vaul Root prop surface, including drag callbacks, activeSnapPoint, closeThreshold, shouldScaleBackground, and container.",
            "Direction defaults to bottom at the Vaul layer, while the docs preview switches between bottom on small screens and right on larger screens."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Optional controlled open state. Pair it with onOpenChange when parent state should own the drawer lifecycle."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Initial open state for uncontrolled usage. Vaul skips the first enter animation when the drawer is mounted open."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the drawer opens or closes from the trigger, overlay, Escape key, close part, or drag release."
            },
            {
              "name": "direction",
              "type": "\"left\" | \"right\" | \"top\" | \"bottom\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Chooses the drawer edge and matching Vaul slide direction. The content classes style each direction with the appropriate inset and rounded leading edge."
            },
            {
              "name": "modal",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Keeps focus and outside interaction modal while the drawer is open. Set false for non-modal command surfaces."
            },
            {
              "name": "dismissible",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Allows overlay click, Escape, and drag gestures to close the drawer. Controlled drawers can disable this when a flow must be completed explicitly."
            },
            {
              "name": "snapPoints",
              "type": "(number | string)[]",
              "defaultValue": "",
              "required": false,
              "description": "Optional Vaul snap points for stepped drawer heights or widths. Values may be percentages or px strings."
            }
          ]
        },
        {
          "id": "drawer-trigger",
          "title": "DrawerTrigger",
          "summary": "Opens the drawer from a button, link, or custom interactive target.",
          "notes": [],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Use when a local button or link should remain the visible trigger element."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the trigger primitive."
            }
          ]
        },
        {
          "id": "drawer-portal",
          "title": "DrawerPortal",
          "summary": "Portal wrapper for drawer overlay and panel content. DrawerContent composes it automatically in the common path.",
          "notes": [
            "DrawerPortal is kept as an exported part for API symmetry, while DrawerContent composes it automatically for the common overlay-plus-panel path."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Overlay and panel content rendered outside the page flow."
            }
          ]
        },
        {
          "id": "drawer-overlay",
          "title": "DrawerOverlay",
          "summary": "Full-screen overlay rendered behind the drawer panel.",
          "notes": [],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default overlay tint and blur classes."
            }
          ]
        },
        {
          "id": "drawer-content",
          "title": "DrawerContent",
          "summary": "Portals the overlay and animated panel, applies direction-aware layout classes, and renders the optional bottom drag handle.",
          "notes": [
            "DrawerContent marks rendered children as non-draggable so selecting text inside the panel does not trigger Vaul's drag-to-close gesture."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Drawer body content rendered inside the animated panel."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the direction-aware panel geometry and surface classes."
            }
          ]
        },
        {
          "id": "drawer-close",
          "title": "DrawerClose",
          "summary": "Closes the drawer from a button or custom interactive target.",
          "notes": [],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Use asChild to turn an existing footer action into the close control."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the close primitive."
            }
          ]
        },
        {
          "id": "drawer-header",
          "title": "DrawerHeader",
          "summary": "Layout helper for the title area at the top of the drawer panel.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Header content such as DrawerTitle and DrawerDescription."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default header spacing classes."
            }
          ]
        },
        {
          "id": "drawer-footer",
          "title": "DrawerFooter",
          "summary": "Layout helper for actions or supporting context at the bottom of the drawer.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Footer actions or supporting context."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default footer spacing classes."
            }
          ]
        },
        {
          "id": "drawer-title",
          "title": "DrawerTitle",
          "summary": "Accessible heading part forwarded to Vaul's dialog title primitive.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Drawer heading content."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default title typography classes."
            }
          ]
        },
        {
          "id": "drawer-description",
          "title": "DrawerDescription",
          "summary": "Accessible helper text part forwarded to Vaul's dialog description primitive.",
          "notes": [
            "DrawerTitle and DrawerDescription should be included inside DrawerHeader when the panel needs accessible labeling."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Supporting description copy beneath the drawer title."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default description typography classes."
            }
          ]
        },
        {
          "id": "drawer-motion-layout",
          "title": "Motion and layout",
          "summary": "The component leans on Vaul's drag-aware transform animation, then adds softer overlay timing, tuned animation duration, and direction-specific panel geometry.",
          "notes": [
            "Bottom drawers show the handle by default; top, left, and right drawers keep the content surface clean unless you add your own handle.",
            "DrawerContent marks rendered children as non-draggable so selecting text inside the panel does not trigger Vaul's drag-to-close gesture.",
            "Top and bottom drawers cap at 80vh, while left and right drawers use a three-quarter width with a small-screen max width at the sm breakpoint."
          ],
          "fields": [
            {
              "name": "overlay",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "A fixed full-screen overlay fades in behind the drawer and uses a subtle black tint with backdrop blur support."
            },
            {
              "name": "content",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "The panel gets a fluid cubic-bezier open curve, a shorter close duration, GPU-friendly transform hints, and a slightly extended initial transform for a softer arrival."
            }
          ]
        }
      ],
      "dependencies": [
        "vaul"
      ]
    },
    {
      "slug": "r-dropdown",
      "name": "Dropdown",
      "href": "/overlay-and-popups/dropdown",
      "url": "https://iconiqui.com/overlay-and-popups/dropdown",
      "installPackage": "@iconiq/r-dropdown",
      "installCommand": "npx shadcn@latest add @iconiq/r-dropdown",
      "registryPath": "r-dropdown.json",
      "registryUrl": "https://iconiqui.com/r/r-dropdown.json",
      "summary": "Root provider that coordinates open state, selected value state, and the shared behavior used by the trigger, content, and item primitives.",
      "apiSections": [
        {
          "id": "dropdown",
          "title": "Dropdown",
          "summary": "Root provider that coordinates open state, selected value state, and the shared behavior used by the trigger, content, and item primitives.",
          "notes": [
            "The menu stays local to the trigger wrapper and is absolutely positioned under it instead of being portaled to document.body.",
            "Escape and outside clicks close the menu. This version does not ship a full roving-focus keyboard model like Radix dropdown-menu.",
            "While open, users can move through items with Arrow keys, Home, End, or typeahead matching based on each item's visible label or textValue."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Compose DropdownTrigger, DropdownContent, DropdownItem, and optional helpers like DropdownValue or DropdownSeparator inside the root."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value for the select variant. Action mode usually leaves this unset."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial selected value for uncontrolled select usage."
            },
            {
              "name": "onValueChange",
              "type": "(value: string | undefined) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a select item updates the current value."
            },
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled open state for the menu surface."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Initial open state for uncontrolled usage."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever the trigger, outside click handling, or Escape key changes the open state."
            },
            {
              "name": "variant",
              "type": "\"select\" | \"action\"",
              "defaultValue": "select",
              "required": false,
              "description": "Use select when items should commit a persistent value with a checkmark, or action when items should behave like immediate commands."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer relative wrapper around the trigger and content."
            }
          ]
        },
        {
          "id": "dropdown-trigger",
          "title": "DropdownTrigger",
          "summary": "Interactive trigger button that opens and closes the menu. It works with plain children, DropdownValue, or custom trigger content like an avatar.",
          "notes": [
            "The trigger is always rendered as a button in this version, so custom trigger visuals should be passed as children and styled with className."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Trigger content. In select mode this usually includes DropdownValue, while action menus can pass custom content such as an avatar or label row."
            },
            {
              "name": "showChevron",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Hides the default chevron when you want a cleaner custom trigger, such as an avatar-only action menu."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the trigger button shell."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Prevents opening and dims the trigger styling."
            }
          ]
        },
        {
          "id": "dropdown-value",
          "title": "DropdownValue",
          "summary": "Small helper for select mode that reads the current value from context and prints the matching item label or a placeholder.",
          "notes": [
            "DropdownValue is only useful in select mode. Action menus usually provide their own trigger content instead."
          ],
          "fields": [
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "\"Select an option\"",
              "required": false,
              "description": "Text shown when no matching selected value is currently registered."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the rendered span inside the trigger."
            }
          ]
        },
        {
          "id": "dropdown-content",
          "title": "DropdownContent",
          "summary": "Animated menu surface that positions itself under the trigger and renders the item list for either variant.",
          "notes": [
            "The content stays mounted only while the menu is open, animates its bounds as labels or groups change, and constrains long menus with internal scrolling.",
            "The surface always opens below the trigger and still clamps horizontally to stay inside the viewport."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Usually DropdownItem children, with optional DropdownSeparator nodes between groups."
            },
            {
              "name": "align",
              "type": "\"start\" | \"center\" | \"end\"",
              "defaultValue": "start",
              "required": false,
              "description": "Horizontal alignment relative to the trigger wrapper."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "8",
              "required": false,
              "description": "Vertical gap between the trigger and the dropdown surface."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the dropdown surface, which is useful for setting a custom width or changing shadows in docs/examples."
            }
          ]
        },
        {
          "id": "dropdown-item",
          "title": "DropdownItem",
          "summary": "Single interactive row used by both variants. In select mode it can register a value, and in action mode it acts like a plain command item.",
          "notes": [
            "Select items do not render a filled selected background in this version; only the trailing checkmark indicates the chosen value.",
            "If you omit value in select mode, the item behaves like a plain closing action and will not update the current value."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Row content. You can place icons inline before the label for action menus or richer item layouts."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Selection key for select mode. When it matches the root value, the item renders the checkmark state."
            },
            {
              "name": "textValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional explicit label used by DropdownValue and typeahead when your item children are not plain text."
            },
            {
              "name": "onClick",
              "type": "(event: MouseEvent<HTMLButtonElement>) => void",
              "defaultValue": "",
              "required": false,
              "description": "Runs before the item closes the menu. Action menus typically use this for immediate commands like profile or logout."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Prevents interaction and dims the row."
            }
          ]
        },
        {
          "id": "dropdown-group",
          "title": "DropdownGroup",
          "summary": "Optional wrapper for chunking larger menus into sections, with or without a visible label.",
          "notes": [
            "Label is optional. Without it, the wrapper only provides spacing unless you also pass aria-label or aria-labelledby.",
            "If you provide label, the wrapper upgrades to role=group and wires aria-labelledby automatically."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Usually one or more DropdownItem nodes. Add label when you want a visible heading, or omit it when you just want grouped spacing."
            },
            {
              "name": "label",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional convenience heading rendered with DropdownLabel styling and linked to the group for assistive technologies."
            },
            {
              "name": "labelClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the generated section heading when you want to tweak its spacing or tone."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the group wrapper. The base version adds light vertical spacing between grouped rows."
            }
          ]
        },
        {
          "id": "dropdown-label",
          "title": "DropdownLabel",
          "summary": "Standalone non-interactive heading helper for advanced content layouts or custom grouping patterns.",
          "notes": [
            "Use this directly when you want a heading style without the convenience wrapper supplied by DropdownGroup."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Short section text such as Product, Billing, or Workspace settings."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the rendered div when you want to adjust spacing, weight, or casing locally."
            }
          ]
        },
        {
          "id": "dropdown-separator",
          "title": "DropdownSeparator",
          "summary": "Simple divider for grouping related items inside the content surface.",
          "notes": [
            "The base separator uses the shared border token and a small vertical margin between item groups."
          ],
          "fields": [
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the divider element when you want to adjust spacing or tone locally."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-dropdown-menu",
        "@radix-ui/react-scroll-area",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "b-hover-card",
      "name": "Hover Card",
      "href": "/overlay-and-popups/hover-card",
      "url": "https://iconiqui.com/overlay-and-popups/hover-card",
      "installPackage": "@iconiq/b-hover-card",
      "installCommand": "npx shadcn@latest add @iconiq/b-hover-card",
      "registryPath": "b-hover-card.json",
      "registryUrl": "https://iconiqui.com/r/b-hover-card.json",
      "summary": "Stateful wrapper that opens a callout on delayed hover or immediate focus, then closes it once pointer and focus both leave the hover-card region.",
      "apiSections": [
        {
          "id": "hover-card",
          "title": "HoverCard",
          "summary": "Stateful wrapper that opens a callout on delayed hover or immediate focus, then closes it once pointer and focus both leave the hover-card region.",
          "notes": [
            "Open state is internal only. This implementation does not expose a controlled open prop or state-change callback.",
            "The root manages hover and focus timing while Radix Popover handles portal-based positioning and collision avoidance.",
            "Pending timers are cleared before every new open or close request and again during unmount cleanup."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Composition surface for the trigger and content primitives rendered inside the hover card root."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the inline-flex wrapper that groups the trigger and content primitives."
            },
            {
              "name": "openDelay",
              "type": "number",
              "defaultValue": "80",
              "required": false,
              "description": "Delay in milliseconds before the card opens after pointer entry. Keyboard focus opens immediately."
            },
            {
              "name": "closeDelay",
              "type": "number",
              "defaultValue": "120",
              "required": false,
              "description": "Delay in milliseconds before the card closes after pointer exit. Blur closes immediately unless focus is still moving within the card."
            }
          ]
        },
        {
          "id": "hover-card-trigger",
          "title": "HoverCardTrigger",
          "summary": "Trigger surface that renders a button by default or forwards behavior into a custom child through Radix Slot.",
          "notes": [
            "When asChild is false, the component renders a plain button with type='button', a larger default hit area, and a visible focus ring.",
            "The trigger is also used as the positioning anchor and automatically receives aria-expanded, aria-controls, and aria-haspopup.",
            "Standard button props such as disabled, onClick, aria-*, and data-* are forwarded to the rendered trigger element."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the trigger or by the child passed through asChild."
            },
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Lets you supply your own trigger element while keeping the hover-card trigger behavior and class merging."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the rendered trigger element for local layout or visual styling."
            }
          ]
        },
        {
          "id": "hover-card-content",
          "title": "HoverCardContent",
          "summary": "Animated content panel with collision-aware positioning, side and align controls, and a spring-driven scale and directional offset fade.",
          "notes": [
            "Additional motion.div props such as style, role, onClick, aria-*, and data-* are forwarded, but initial, animate, exit, and transition are reserved by the component.",
            "The panel is portaled through Radix Popover content, so it can escape overflow-hidden ancestors and reposition near viewport edges.",
            "Focus can move from the trigger into interactive content without immediately closing the card.",
            "By default the content is centered below the trigger with a fixed w-72 width, no drop shadow, and a 12px hover bridge across the trigger-to-panel gap."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered inside the hover card panel."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the motion.div panel so width, spacing, or surface styles can be adjusted."
            },
            {
              "name": "side",
              "type": "\"top\" | \"right\" | \"bottom\" | \"left\"",
              "defaultValue": "\"bottom\"",
              "required": false,
              "description": "Preferred side for the panel before collision handling adjusts the placement."
            },
            {
              "name": "align",
              "type": "\"start\" | \"center\" | \"end\"",
              "defaultValue": "\"center\"",
              "required": false,
              "description": "Horizontal or vertical alignment relative to the trigger, depending on side."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "12",
              "required": false,
              "description": "Gap between trigger and panel. The component also extends an invisible hover bridge through that gap to reduce accidental closes."
            },
            {
              "name": "alignOffset",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Additional offset applied along the alignment axis."
            },
            {
              "name": "avoidCollisions",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Enables Radix collision handling so the card can shift or flip when space is tight."
            },
            {
              "name": "collisionPadding",
              "type": "number | Partial<Record<Side, number>>",
              "defaultValue": "12",
              "required": false,
              "description": "Padding from viewport edges used during collision detection."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-popover",
      "name": "Popover",
      "href": "/overlay-and-popups/popover",
      "url": "https://iconiqui.com/overlay-and-popups/popover",
      "installPackage": "@iconiq/b-popover",
      "installCommand": "npx shadcn@latest add @iconiq/b-popover",
      "registryPath": "b-popover.json",
      "registryUrl": "https://iconiqui.com/r/b-popover.json",
      "summary": "Thin wrapper around `PopoverPrimitive.Root` that mirrors the resolved open state into local context so `PopoverContent` can infer presence automatically.",
      "apiSections": [
        {
          "id": "popover-root",
          "title": "Popover",
          "summary": "Thin wrapper around `PopoverPrimitive.Root` that mirrors the resolved open state into local context so `PopoverContent` can infer presence automatically.",
          "notes": [
            "Remaining root props such as `modal` continue to flow through to the underlying Radix popover root."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled open state on the Radix root when you want React state to own visibility."
            },
            {
              "name": "defaultOpen",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Uncontrolled initial state forwarded to the underlying Radix popover root."
            },
            {
              "name": "onOpenChange",
              "type": "(open: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever Radix requests a state change through the trigger, outside interaction, or escape handling."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Composition surface for the trigger, optional anchor, and content primitives."
            }
          ]
        },
        {
          "id": "popover-trigger",
          "title": "PopoverTrigger",
          "summary": "Light wrapper around the Radix trigger with a larger default hit area when not using asChild.",
          "notes": [
            "When you render an icon-only trigger with asChild, keep the interactive target around 40-44px so the hit area stays comfortable on touch and pointer devices."
          ],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Lets you render your own button, link, or wrapper element without adding an extra DOM node."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the trigger primitive."
            }
          ]
        },
        {
          "id": "popover-anchor",
          "title": "PopoverAnchor",
          "summary": "Radix positioning anchor used when the popover should attach to a non-trigger element.",
          "notes": [
            "PopoverAnchor still accepts the remaining primitive props for event handling and accessibility wiring."
          ],
          "fields": [
            {
              "name": "asChild",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Lets you render your own anchor element without adding an extra DOM node."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Layout content rendered by the anchor primitive."
            }
          ]
        },
        {
          "id": "popover-content",
          "title": "PopoverContent",
          "summary": "Animated content wrapper built on Radix Popover.Content and AnimatePresence.",
          "notes": [
            "Remaining Radix content props are forwarded through to PopoverPrimitive.Content, including side, collisionPadding, onEscapeKeyDown, and accessibility props.",
            "The component always renders inside a Radix portal, reads the resolved placement for direction-aware motion, and uses the Radix transform-origin CSS variable so scaling stays anchored to the trigger.",
            "The panel ships without drop shadow so the surface stays flat against the page.",
            "Content size changes animate while the popover is open, so progressive disclosure and copy swaps do not snap abruptly.",
            "Entry and exit animation are owned internally, so Motion-specific props such as initial, animate, exit, and transition are not part of the public prop surface."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Accepted for backwards compatibility, but no longer required. The nearest `Popover` root state now drives content presence automatically."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content rendered inside the animated panel."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the motion.div panel for local width, spacing, or surface overrides."
            },
            {
              "name": "align",
              "type": "\"start\" | \"center\" | \"end\"",
              "defaultValue": "center",
              "required": false,
              "description": "Forwarded to Radix Popover.Content to control horizontal alignment relative to the trigger or anchor."
            },
            {
              "name": "sideOffset",
              "type": "number",
              "defaultValue": "8",
              "required": false,
              "description": "Forwarded to Radix Popover.Content to control the gap between the anchor and the floating panel."
            },
            {
              "name": "collisionPadding",
              "type": "number | Partial<Record<Side, number>>",
              "defaultValue": "12",
              "required": false,
              "description": "Adds a little default breathing room from the viewport edge before collision handling nudges the popover inward."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "b-tooltip",
      "name": "Tooltip",
      "href": "/overlay-and-popups/tooltip",
      "url": "https://iconiqui.com/overlay-and-popups/tooltip",
      "installPackage": "@iconiq/b-tooltip",
      "installCommand": "npx shadcn@latest add @iconiq/b-tooltip",
      "registryPath": "b-tooltip.json",
      "registryUrl": "https://iconiqui.com/r/b-tooltip.json",
      "summary": "Animated tooltip with a canonical Tooltip export. It owns its own open state, expects a single trigger element, and toggles in response to hover and focus events.",
      "apiSections": [
        {
          "id": "tooltip",
          "title": "Tooltip",
          "summary": "Animated tooltip with a canonical Tooltip export. It owns its own open state, expects a single trigger element, and toggles in response to hover and focus events.",
          "notes": [
            "The trigger forwards onMouseEnter, onMouseLeave, onFocus, and onBlur directly into the child element through Radix Slot.",
            "The timeout used for delayed open is cleared on leave and again on unmount.",
            "Development builds warn when tooltip content grows beyond a short single-line hint."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactElement",
              "defaultValue": "",
              "required": true,
              "description": "A single trigger element that receives hover, focus, and aria-describedby props through a slotted wrapper."
            },
            {
              "name": "content",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Short, non-interactive tooltip copy rendered inside the animated bubble. Use Popover for longer or richer content."
            },
            {
              "name": "side",
              "type": "\"top\" | \"bottom\" | \"left\" | \"right\"",
              "defaultValue": "top",
              "required": false,
              "description": "Preferred popup side passed into the collision-aware Radix popover positioner."
            },
            {
              "name": "delay",
              "type": "number",
              "defaultValue": "0.15",
              "required": false,
              "description": "Open delay in seconds. The implementation multiplies it by 1000 before scheduling the timer."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the tooltip bubble for local surface styling overrides."
            }
          ]
        },
        {
          "id": "tooltip-positioning",
          "title": "Positioning and accessibility",
          "summary": "This tooltip is portaled through Radix Popover so it can avoid viewport collisions and escape clipping parents.",
          "notes": [
            "The trigger receives an aria-describedby link to the active tooltip bubble.",
            "The popup uses avoidCollisions with collisionPadding=12 and sideOffset=10.",
            "The arrow is a rotated square whose placement follows the resolved data-side from Radix positioning."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@base-ui/react",
        "motion"
      ]
    },
    {
      "slug": "radial-button",
      "name": "Radial Button",
      "href": "/special-one/radial-button",
      "url": "https://iconiqui.com/special-one/radial-button",
      "installPackage": "@iconiq/radial-button",
      "installCommand": "npx shadcn@latest add @iconiq/radial-button",
      "registryPath": "radial-button.json",
      "registryUrl": "https://iconiqui.com/r/radial-button.json",
      "summary": "Ref-forwarding motion button with a radial fill, press feedback, and native form support. Hover, focus-visible, pointer-down, and keyboard activation spread the fill from the entry point.",
      "apiSections": [
        {
          "id": "radial-button",
          "title": "RadialButton",
          "summary": "Ref-forwarding motion button with a radial fill, press feedback, and native form support. Hover, focus-visible, pointer-down, and keyboard activation spread the fill from the entry point.",
          "notes": [
            "Standard button attributes such as aria-*, autoFocus, formAction, formEncType, formMethod, formNoValidate, formTarget, and data-* are forwarded to the underlying motion.button.",
            "Pointer-down sets the fill origin at the click point and enters a pressed state; pointer-up, pointer-leave, pointer-cancel, and blur clear it.",
            "Space and Enter mirror the pressed and fill state for keyboard users. Space calls preventDefault so the page does not scroll while the button is focused.",
            "Uses card/muted surfaces in dark mode, a foreground fill in light mode, and a neutral-50 fill in dark mode so resting and filled states stay legible.",
            "Icon-only usage should include aria-label or aria-labelledby for an accessible name."
          ],
          "fields": [
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Button label or custom content rendered above the animated fill layer."
            },
            {
              "name": "type",
              "type": "\"button\" | \"submit\" | \"reset\"",
              "defaultValue": "button",
              "required": false,
              "description": "Native button type. Defaults to button so the control does not submit a form unless you opt in."
            },
            {
              "name": "loading",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Sets aria-busy and disables interaction while a form or async action is in progress."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Native disabled state. Also suppresses fill, press, and ripple-like feedback."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional class names merged onto the root button element."
            },
            {
              "name": "onClick",
              "type": "React.MouseEventHandler<HTMLButtonElement>",
              "defaultValue": "",
              "required": false,
              "description": "Native click handler forwarded to the underlying button."
            },
            {
              "name": "name",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Form field name submitted with the parent form."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional submitted value when type is submit."
            },
            {
              "name": "form",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Associates the button with a form element by id."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "dia-text",
      "name": "Dia Text",
      "href": "/texts/dia-text",
      "url": "https://iconiqui.com/texts/dia-text",
      "installPackage": "@iconiq/dia-text",
      "installCommand": "npx shadcn@latest add @iconiq/dia-text",
      "registryPath": "dia-text.json",
      "registryUrl": "https://iconiqui.com/r/dia-text.json",
      "summary": "Animated inline text reveal with a sweeping gradient band, repeat controls, and optional fixed-width rotation for motion-driven typography.",
      "apiSections": [],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "morph-texts",
      "name": "Morph Text",
      "href": "/texts/morph-texts",
      "url": "https://iconiqui.com/texts/morph-texts",
      "installPackage": "@iconiq/morph-texts",
      "installCommand": "npx shadcn@latest add @iconiq/morph-texts",
      "registryPath": "morph-texts.json",
      "registryUrl": "https://iconiqui.com/r/morph-texts.json",
      "summary": "Cycling headline treatment that morphs between words with blur, scale, and an SVG goo filter while optionally revealing subtext beneath the rotator.",
      "apiSections": [
        {
          "id": "morph-texts",
          "title": "MorphText",
          "summary": "Cycling headline treatment that morphs between words with blur, scale, and an SVG goo filter while optionally revealing subtext beneath the rotator.",
          "notes": [
            "The active word is announced through aria-live=polite so screen readers can follow the rotation.",
            "Each instance generates a unique SVG filter id so multiple MorphText components can coexist on one page."
          ],
          "fields": [
            {
              "name": "words",
              "type": "string[]",
              "defaultValue": "",
              "required": true,
              "description": "Words or short phrases to cycle through. The component advances to the next entry on each interval tick."
            },
            {
              "name": "interval",
              "type": "number",
              "defaultValue": "3000",
              "required": false,
              "description": "Milliseconds each word stays active before the next morph transition begins."
            },
            {
              "name": "subtext",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional supporting line rendered below the morphing word with a delayed fade-up entrance."
            },
            {
              "name": "fontSize",
              "type": "string",
              "defaultValue": "\"clamp(3rem, 15vw, 10rem)\"",
              "required": false,
              "description": "CSS font-size value applied to the morphing headline container."
            },
            {
              "name": "fontFamily",
              "type": "string",
              "defaultValue": "\"Space Grotesk\", sans-serif",
              "required": false,
              "description": "CSS font-family value applied to the headline and subtext."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root wrapper for layout and color overrides."
            },
            {
              "name": "textClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the morphing text container when you need local typography overrides."
            },
            {
              "name": "subtextClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the optional subtext element."
            }
          ]
        },
        {
          "id": "morph-texts-motion",
          "title": "Morph transition behavior",
          "summary": "Word changes are driven by AnimatePresence and Motion variants that overlap enter and exit states so the goo filter can blend the outgoing and incoming text.",
          "notes": [
            "Enter and exit animate opacity, blur, and scale over roughly 0.9 seconds with an ease-in-out curve.",
            "When only one word is provided, the interval timer is skipped and the headline stays static."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "reveal-text",
      "name": "Reveal Text",
      "href": "/texts/reveal-text",
      "url": "https://iconiqui.com/texts/reveal-text",
      "installPackage": "@iconiq/reveal-text",
      "installCommand": "npx shadcn@latest add @iconiq/reveal-text",
      "registryPath": "reveal-text.json",
      "registryUrl": "https://iconiqui.com/r/reveal-text.json",
      "summary": "Staggered text reveal that animates each word or character upward with blur and opacity, with optional viewport-triggered playback and reduced-motion fallbacks.",
      "apiSections": [
        {
          "id": "reveal-text",
          "title": "RevealText",
          "summary": "Staggered text reveal that animates each word or character upward with blur and opacity, with optional viewport-triggered playback and reduced-motion fallbacks.",
          "notes": [
            "Reduced-motion users receive a shorter opacity-only reveal while preserving readable timing.",
            "Duplicate words or characters on the same line receive stable keys so repeated units still animate independently."
          ],
          "fields": [
            {
              "name": "text",
              "type": "string | string[]",
              "defaultValue": "",
              "required": true,
              "description": "Copy to reveal. Pass one string or multiple lines; each line renders on its own block row."
            },
            {
              "name": "as",
              "type": "React.ElementType",
              "defaultValue": "\"span\"",
              "required": false,
              "description": "Root element type for the reveal container while preserving the same split and stagger behavior."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root container for typography, spacing, and layout overrides."
            },
            {
              "name": "split",
              "type": "\"word\" | \"char\"",
              "defaultValue": "\"word\"",
              "required": false,
              "description": "Controls whether the animation staggers by word or by individual character."
            },
            {
              "name": "stagger",
              "type": "number",
              "defaultValue": "0.09",
              "required": false,
              "description": "Delay in seconds added between each word or character in the sequence."
            },
            {
              "name": "delay",
              "type": "number",
              "defaultValue": "0",
              "required": false,
              "description": "Base delay in seconds before the first unit begins animating."
            },
            {
              "name": "blur",
              "type": "number",
              "defaultValue": "12",
              "required": false,
              "description": "Starting blur amount in pixels for each unit before it settles into focus."
            },
            {
              "name": "yOffset",
              "type": "string | number",
              "defaultValue": "\"40%\"",
              "required": false,
              "description": "Starting vertical offset for each unit. Accepts Motion-friendly values such as percentages or pixel lengths."
            },
            {
              "name": "spring",
              "type": "{ stiffness?: number; damping?: number; mass?: number }",
              "defaultValue": "",
              "required": false,
              "description": "Optional spring overrides for the vertical settle motion on each unit."
            },
            {
              "name": "once",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "When whileInView is enabled, controls whether the in-view trigger should fire only once."
            },
            {
              "name": "whileInView",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "When true, the reveal waits until the root enters the viewport before animating."
            },
            {
              "name": "children",
              "type": "React.ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional content rendered after the animated text lines inside the root container."
            }
          ]
        },
        {
          "id": "reveal-text-motion",
          "title": "Reveal transition behavior",
          "summary": "Each unit animates y, opacity, and filter on independent timelines so the blur fade can trail slightly behind the spring settle.",
          "notes": [
            "Word mode preserves spaces between tokens with non-breaking space spans.",
            "Character mode uses Array.from so multi-byte characters split correctly."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "shimmer-text",
      "name": "Shimmer Text",
      "href": "/texts/shimmer-text",
      "url": "https://iconiqui.com/texts/shimmer-text",
      "installPackage": "@iconiq/shimmer-text",
      "installCommand": "npx shadcn@latest add @iconiq/shimmer-text",
      "registryPath": "shimmer-text.json",
      "registryUrl": "https://iconiqui.com/r/shimmer-text.json",
      "summary": "Animated shimmer text with a sweeping highlight band, adjustable spread, and configurable loop speed for emphasis-heavy copy.",
      "apiSections": [],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "text-loop",
      "name": "Text Loop",
      "href": "/texts/text-loop",
      "url": "https://iconiqui.com/texts/text-loop",
      "installPackage": "@iconiq/text-loop",
      "installCommand": "npx shadcn@latest add @iconiq/text-loop",
      "registryPath": "text-loop.json",
      "registryUrl": "https://iconiqui.com/r/text-loop.json",
      "summary": "Cycling text with vertical slide transitions—pass your own items and interval for rotating headlines or status copy.",
      "apiSections": [],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "text-inertia",
      "name": "Text Inertia",
      "href": "/texts/text-inertia",
      "url": "https://iconiqui.com/texts/text-inertia",
      "installPackage": "@iconiq/text-inertia",
      "installCommand": "npx shadcn@latest add @iconiq/text-inertia",
      "registryPath": "text-inertia.json",
      "registryUrl": "https://iconiqui.com/r/text-inertia.json",
      "summary": "Pointer-reactive word treatment that tracks local cursor velocity, applies that momentum to the hovered word, and springs the word back into place.",
      "apiSections": [
        {
          "id": "text-inertia",
          "title": "TextInertia",
          "summary": "Pointer-reactive word treatment that tracks local cursor velocity, applies that momentum to the hovered word, and springs the word back into place.",
          "notes": [
            "The component forwards standard div props except children; the rendered words always come from the text prop.",
            "The root receives an aria-label with the full text, while individual animated word spans are hidden from assistive technology."
          ],
          "fields": [
            {
              "name": "text",
              "type": "string",
              "defaultValue": "\"Interfaces remember momentum\"",
              "required": false,
              "description": "The phrase to render. The component splits it into words and keeps those word wrappers stable for hover-driven motion."
            },
            {
              "name": "intensity",
              "type": "number",
              "defaultValue": "1",
              "required": false,
              "description": "Scales how strongly cursor velocity affects each hovered word. Values just above 1 feel more kinetic; lower values stay calmer."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root word group for typography, color, alignment, and layout overrides."
            },
            {
              "name": "wordClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto each animated word span when you need per-word styling without changing the root layout."
            }
          ]
        },
        {
          "id": "text-inertia-motion",
          "title": "Pointer velocity behavior",
          "summary": "Text Inertia uses Motion values and spring animations instead of a runtime DOM-splitting animation plugin.",
          "notes": [
            "Pointer movement over the root records x/y velocity, and entering a word maps that velocity to x, y, and rotation offsets.",
            "Each word immediately settles back to x=0, y=0, and rotate=0 with a spring, which creates the inertial feel with only Motion.",
            "The text is split with React during render, so there is no document query or third-party DOM splitting step."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "typewriter",
      "name": "Typewriter",
      "href": "/texts/typewriter",
      "url": "https://iconiqui.com/texts/typewriter",
      "installPackage": "@iconiq/typewriter",
      "installCommand": "npx shadcn@latest add @iconiq/typewriter",
      "registryPath": "typewriter.json",
      "registryUrl": "https://iconiqui.com/r/typewriter.json",
      "summary": "Looping typewriter text effect that types a string character by character, briefly swaps in glitch characters, and finishes each pass with a blinking cursor.",
      "apiSections": [
        {
          "id": "typewriter",
          "title": "TextTypewriter",
          "summary": "Looping typewriter text effect that types a string character by character, briefly swaps in glitch characters, and finishes each pass with a blinking cursor.",
          "notes": [
            "The rendered text is announced with aria-live=polite so updates can be surfaced without replacing surrounding content."
          ],
          "fields": [
            {
              "name": "children",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "The text content to type. The component expects a single string because the animation advances through each character in order."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root wrapper for local typography, color, spacing, or alignment classes."
            },
            {
              "name": "duration",
              "type": "number",
              "defaultValue": "3",
              "required": false,
              "description": "Scales the scheduled typing and glitch delays. Lower values make each pass faster; higher values slow the sequence down."
            }
          ]
        },
        {
          "id": "typewriter-motion",
          "title": "Typing and glitch behavior",
          "summary": "The animation schedules a small sequence of per-character timeouts, occasionally inserts a wrong character, removes it, then types the intended character before continuing.",
          "notes": [
            "After the full string is typed, the cursor briefly returns and the sequence starts again from an empty string.",
            "Spaces are typed directly without the wrong-character substitution, which keeps word breaks stable during the effect.",
            "Unmount cleanup clears every pending timeout, so remounting the preview or leaving the page does not leave animation work behind."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    }
  ],
  "generatedAt": "2026-06-17T06:22:42.280Z"
}