{
  "site": {
    "name": "Iconiq",
    "url": "https://iconiqui.com",
    "description": "Iconiq is an open-source React component library built around the shadcn registry workflow. Browse polished 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."
    },
    {
      "title": "Changelog",
      "href": "/changelog",
      "url": "https://iconiqui.com/changelog",
      "summary": "Release notes rendered from the local changelog source file, covering added, updated, and fixed work."
    }
  ],
  "components": [
    {
      "slug": "accordion",
      "name": "Accordion",
      "href": "/components/accordion",
      "url": "https://iconiqui.com/components/accordion",
      "installPackage": "@iconiq/accordion",
      "installCommand": "npx shadcn@latest add @iconiq/accordion",
      "registryPath": "accordion.json",
      "registryUrl": "https://iconiqui.com/r/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 one internal openId value and no controlled API.",
          "notes": [
            "Clicking an already open row closes it again because toggle compares against the current openId.",
            "There is no prop for default open, controlled open, or multiple-open behavior in this implementation."
          ],
          "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."
            }
          ]
        },
        {
          "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 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": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "alert",
      "name": "Alert",
      "href": "/components/alert",
      "url": "https://iconiqui.com/components/alert",
      "installPackage": "@iconiq/alert",
      "installCommand": "npx shadcn@latest add @iconiq/alert",
      "registryPath": "alert.json",
      "registryUrl": "https://iconiqui.com/r/alert.json",
      "summary": "Default export for a single dismissible notice. It can render inline with surrounding content or portal to the viewport when you provide a position.",
      "apiSections": [
        {
          "id": "alert",
          "title": "Alert",
          "summary": "Default export for a single dismissible notice. It can render inline with surrounding content or portal to the viewport when you provide a position.",
          "notes": [
            "Every positioned alert snaps to a full-width top placement on small screens, then switches to the requested corner at the sm breakpoint.",
            "The alert keeps its own visible state internally, so it is designed for fire-and-forget notifications rather than parent-controlled open state."
          ],
          "fields": [
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Leading visual passed straight into the icon slot. The wrapper applies fallback sizing to nested SVGs so Lucide icons land around 18px without extra setup."
            },
            {
              "name": "title",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Primary line rendered in the stronger label style."
            },
            {
              "name": "message",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Secondary copy rendered below the title with a lighter foreground tone."
            },
            {
              "name": "dismissible",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether the close button is rendered. Disabling it removes manual dismissal only; timeout still applies unless it is set to 0."
            },
            {
              "name": "position",
              "type": "\"top-left\" | \"top-center\" | \"top-right\" | \"bottom-left\" | \"bottom-center\" | \"bottom-right\"",
              "defaultValue": "",
              "required": false,
              "description": "When present, the component portals to document.body and uses fixed positioning classes. When omitted, the alert stays in normal flow and maxes out at max-w-sm."
            },
            {
              "name": "timeout",
              "type": "number",
              "defaultValue": "10000",
              "required": false,
              "description": "Auto-dismiss delay in milliseconds. Passing 0 disables the timer and removes the progress-bar countdown."
            },
            {
              "name": "onDismiss",
              "type": "() => void",
              "defaultValue": "",
              "required": false,
              "description": "Called after the component marks itself hidden, regardless of whether dismissal came from the close button or the timeout effect."
            }
          ]
        },
        {
          "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 direction is derived from position: top placements slide down slightly, bottom placements rise upward, and inline alerts use a smaller upward offset.",
            "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."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "avatar",
      "name": "Avatar",
      "href": "/components/avatar",
      "url": "https://iconiqui.com/components/avatar",
      "installPackage": "@iconiq/avatar",
      "installCommand": "npx shadcn@latest add @iconiq/avatar",
      "registryPath": "avatar.json",
      "registryUrl": "https://iconiqui.com/r/avatar.json",
      "summary": "Compact motion avatar with a canonical Avatar export, optional image source, and fallback text for empty states.",
      "apiSections": [
        {
          "id": "avatar",
          "title": "Avatar",
          "summary": "Compact motion avatar with a canonical Avatar export, optional image source, and fallback text for empty states.",
          "notes": [
            "The component does not forward refs or arbitrary DOM props; the public surface is only src, fallback, and className.",
            "The root is a motion.div with pointer-style hover and tap animation, but it is not a button or link by itself."
          ],
          "fields": [
            {
              "name": "src",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Image URL rendered into a framework-agnostic img element. When present, the image fills the 42x42 circular mask with a blur-and-clip reveal animation."
            },
            {
              "name": "fallback",
              "type": "string",
              "defaultValue": "?",
              "required": false,
              "description": "Text rendered in the center when no src is provided, typically initials or a short placeholder character."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root motion.div. The base component already fixes the size to 42x42 and applies the circular overflow mask."
            }
          ]
        },
        {
          "id": "avatar-image-motion",
          "title": "Image and motion behavior",
          "summary": "Motion behavior changes slightly when reduced motion is enabled, but the same two rendering paths stay intact.",
          "notes": [
            "The image path always uses a fixed alt value of \"Avatar\" plus width and height of 42, so this version is best suited to decorative or generic avatars.",
            "Hover adds a soft lift and pulse ring, while tap slightly compresses the root when reduced motion is not requested.",
            "Without src, the fallback text springs in over the primary-colored background instead of showing an empty frame."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "badge",
      "name": "Badge",
      "href": "/components/badge",
      "url": "https://iconiqui.com/components/badge",
      "installPackage": "@iconiq/badge",
      "installCommand": "npx shadcn@latest add @iconiq/badge",
      "registryPath": "badge.json",
      "registryUrl": "https://iconiqui.com/r/badge.json",
      "summary": "Default export for a compact label pill with a permanent shimmer pass layered behind the content.",
      "apiSections": [
        {
          "id": "badge",
          "title": "Badge",
          "summary": "Default export for a compact label pill with a permanent shimmer pass layered behind the content.",
          "notes": [
            "The public API does not spread other span props, so data attributes or click handlers require a local wrapper or a component fork.",
            "Color overrides are applied through inline styles, which means they take priority over the default Tailwind utility classes."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Badge content rendered in the foreground layer so it always stays above the animated shimmer."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "\"\"",
              "required": false,
              "description": "Appended directly to the root span. Useful for size, radius, spacing, or border overrides."
            },
            {
              "name": "bgColor",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Inline backgroundColor override. If omitted, the component uses a dark neutral surface in light mode and a white surface in dark mode."
            },
            {
              "name": "textColor",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Inline text color override. If omitted, the badge picks the inverse of its default background palette."
            },
            {
              "name": "waveColor",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Color used for the middle stop of the animated gradient sweep. Defaults to the local CSS variable declared on the shimmer layer."
            }
          ]
        },
        {
          "id": "badge-visuals",
          "title": "Visual behavior",
          "summary": "Badge uses a quick mount animation and a continuously repeating shimmer sweep.",
          "notes": [
            "The root fades and scales from 0.95 to 1 on mount over 0.3 seconds.",
            "The shimmer travels from left to right over 2 seconds, waits 1.5 seconds, then repeats indefinitely."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "breadcrumbs",
      "name": "Breadcrumbs",
      "href": "/components/breadcrumbs",
      "url": "https://iconiqui.com/components/breadcrumbs",
      "installPackage": "@iconiq/breadcrumbs",
      "installCommand": "npx shadcn@latest add @iconiq/breadcrumbs",
      "registryPath": "breadcrumbs.json",
      "registryUrl": "https://iconiqui.com/r/breadcrumbs.json",
      "summary": "Each breadcrumb segment is described by a small object consumed by the Breadcrumbs component.",
      "apiSections": [
        {
          "id": "breadcrumb-item",
          "title": "BreadcrumbItem",
          "summary": "Each breadcrumb segment is described by a small object consumed by the Breadcrumbs component.",
          "notes": [],
          "fields": [
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Visible label and React key for the item. Labels should therefore be unique inside a single breadcrumb trail."
            },
            {
              "name": "href",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Link destination used by the rendered anchor. If it is omitted, the component falls back to '#'."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional icon shown before the label, typically a Lucide icon or any other inline React node."
            }
          ]
        },
        {
          "id": "breadcrumbs",
          "title": "Breadcrumbs",
          "summary": "Animated breadcrumb trail that maps over the items array and styles the last entry as the current location.",
          "notes": [
            "The last item still renders as a motion.a element, even if href is omitted. Its classes remove the interactive cursor but the fallback anchor target is still '#'.",
            "Separators only render after the first item and use the built-in ChevronRight icon from lucide-react."
          ],
          "fields": [
            {
              "name": "items",
              "type": "BreadcrumbItem[]",
              "defaultValue": "",
              "required": true,
              "description": "Ordered list of segments. Earlier items receive hover and tap motion, while the last item gets the shimmer and pulsing dot treatment."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root nav wrapper so you can place the trail inside your own header layout."
            }
          ]
        },
        {
          "id": "breadcrumbs-a11y",
          "title": "Accessibility and motion",
          "summary": "The component keeps semantic breadcrumb structure while layering Motion on top.",
          "notes": [
            "The root nav uses aria-label=\"breadcrumb\" and wraps items in an ordered list.",
            "AnimatePresence runs in popLayout mode so reordering or changing the trail keeps the transitions coherent.",
            "This implementation does not add aria-current to the final item, so add that yourself if you need stricter breadcrumb semantics."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "button",
      "name": "Button",
      "href": "/components/button",
      "url": "https://iconiqui.com/components/button",
      "installPackage": "@iconiq/button",
      "installCommand": "npx shadcn@latest add @iconiq/button",
      "registryPath": "button.json",
      "registryUrl": "https://iconiqui.com/r/button.json",
      "summary": "Ref-forwarding button built on motion.button plus a CVA recipe for size and variant styling.",
      "apiSections": [
        {
          "id": "button",
          "title": "Button",
          "summary": "Ref-forwarding button built on motion.button plus a CVA recipe for size and variant styling.",
          "notes": [
            "Standard button attributes such as onClick, aria-*, name, form, and data-* are forwarded to the underlying motion.button.",
            "The local pointer-down handler always calls your onPointerDown first, then decides whether to spawn a ripple.",
            "Reduced-motion users still get the button component, but the ripple effect is skipped."
          ],
          "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": "size",
              "type": "\"sm\" | \"md\" | \"lg\" | \"custom\"",
              "defaultValue": "md",
              "required": false,
              "description": "Controls height and padding. The custom size leaves sizing classes empty so the caller can drive layout entirely through className."
            },
            {
              "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": "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 is exported alongside the component so matching button classes can be reused on links or custom wrappers.",
          "notes": [
            "Variants ship with six visual states and four size tokens.",
            "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": []
        }
      ],
      "dependencies": [
        "motion",
        "class-variance-authority"
      ]
    },
    {
      "slug": "button-group",
      "name": "Button group",
      "href": "/components/button-group",
      "url": "https://iconiqui.com/components/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": "Standalone motion button with a light upward entrance, hover scale, and a small label nudge inside the content span.",
      "apiSections": [
        {
          "id": "button-group-button",
          "title": "Button",
          "summary": "Standalone motion button with a light upward entrance, hover scale, and a small label nudge inside the content span.",
          "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 animated inline span so the label can shift slightly on hover."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root button. Use it for local width, spacing, or surface overrides."
            }
          ]
        },
        {
          "id": "button-group-icon-button",
          "title": "IconButton",
          "summary": "Compact icon-only version of the same button surface, with a stronger hover scale and a rotating inner icon span.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Icon content rendered inside the motion span. SVG children inherit the built-in 1rem sizing utility."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the icon button root for size or surface overrides."
            }
          ]
        },
        {
          "id": "button-group-layout",
          "title": "ButtonGroup",
          "summary": "Simple flex wrapper for arranging several button surfaces in one row with shared staggered entrance motion.",
          "notes": [],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Buttons, icon buttons, or any other inline controls you want to keep in the same row."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer motion div. The base layout already applies a horizontal flex row with a small gap."
            }
          ]
        },
        {
          "id": "button-group-items",
          "title": "ButtonGroupItems",
          "summary": "Segmented button shell that turns each valid child element into an internal motion button with shared borders and equal visual rhythm.",
          "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."
          ],
          "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."
            }
          ]
        },
        {
          "id": "segmented-control",
          "title": "SegmentedControl",
          "summary": "String-based segmented selector with internal state support, hover wash, and a spring-driven selected indicator.",
          "notes": [],
          "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."
            }
          ]
        },
        {
          "id": "button-group-motion",
          "title": "Motion and interaction",
          "summary": "Each export shares the same spring-heavy motion language, but the interaction style changes slightly by surface.",
          "notes": [
            "Button and IconButton both animate in on mount, scale on hover and tap, and apply a muted background shift during hover.",
            "ButtonGroup only handles layout and entrance motion; the interactive behavior still comes from the child buttons inside it.",
            "SegmentedControl animates each option into place individually, then uses a shared layout indicator for the active segment and a lighter hover wash for inactive segments."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "calendar",
      "name": "Calendar",
      "href": "/components/calendar",
      "url": "https://iconiqui.com/components/calendar",
      "installPackage": "@iconiq/calendar",
      "installCommand": "npx shadcn@latest add @iconiq/calendar",
      "registryPath": "calendar.json",
      "registryUrl": "https://iconiqui.com/r/calendar.json",
      "summary": "Animated monthly calendar card that now supports both controlled and uncontrolled month and selection state.",
      "apiSections": [
        {
          "id": "calendar",
          "title": "Calendar",
          "summary": "Animated monthly calendar card that now supports both controlled and uncontrolled month and selection state.",
          "notes": [
            "Controlled mode: pass selected/month and respond to onSelect/onMonthChange.",
            "Uncontrolled mode: omit selected/month and optionally seed with defaultSelected/defaultMonth.",
            "When no defaults are provided, selected date and visible month both start from new 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 an interactive day in the current month."
            },
            {
              "name": "month",
              "type": "Date",
              "defaultValue": "",
              "required": false,
              "description": "Controlled visible month. Prev/next 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 to a previous or next month."
            },
            {
              "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."
            }
          ]
        },
        {
          "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 are dimmed and made non-interactive with pointer-events-none, which keeps context without allowing cross-month selection from the overflow cells.",
            "Weekday labels are hardcoded as Sun through Sat and displayed as single-letter headers, so localization or alternate week starts require editing the component source."
          ],
          "fields": []
        },
        {
          "id": "calendar-motion-a11y",
          "title": "Motion and interaction model",
          "summary": "Month transitions, selected-day changes, and the footer 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.",
            "The selected day highlight uses a shared layoutId of selected-day so the active surface glides between dates instead of remounting abruptly.",
            "This is still not a full calendar input primitive: there is no keyboard date navigation, no ARIA grid semantics, and no range or multi-select mode."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react",
        "date-fns"
      ]
    },
    {
      "slug": "carousels",
      "name": "Carousel",
      "href": "/components/carousels",
      "url": "https://iconiqui.com/components/carousels",
      "installPackage": "@iconiq/carousels",
      "installCommand": "npx shadcn@latest add @iconiq/carousels",
      "registryPath": "carousels.json",
      "registryUrl": "https://iconiqui.com/r/carousels.json",
      "summary": "Single exported testimonial carousel with internal pagination state, swipe gestures, animated slide transitions, and built-in arrow and dot controls.",
      "apiSections": [
        {
          "id": "carousel",
          "title": "Carousel",
          "summary": "Single exported testimonial carousel with internal pagination state, swipe gestures, animated slide transitions, and built-in arrow and dot controls.",
          "notes": [
            "The component does not expose a controlled index, change callback, or autoplay API. Navigation state is fully internal.",
            "Because the public surface only accepts testimonials, layout width, labels, and control styling require a local wrapper or a source edit if you want to change them."
          ],
          "fields": [
            {
              "name": "testimonials",
              "type": "Testimonial[]",
              "defaultValue": "",
              "required": false,
              "description": "Optional testimonial list shown by the carousel. When omitted, the component falls back to the sample items declared in the source file."
            }
          ]
        },
        {
          "id": "carousel-testimonial",
          "title": "Testimonial item",
          "summary": "Each item passed into the testimonials array follows a small typed shape used for the quote, author, and avatar row.",
          "notes": [
            "The active slide clamps the quote to three lines, so longer testimonials should still be edited to read cleanly inside the fixed-height card."
          ],
          "fields": [
            {
              "name": "quote",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Main testimonial copy rendered in the large italic text block inside the active slide."
            },
            {
              "name": "name",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Author name shown in the lower identity row beside the avatar or initials fallback."
            },
            {
              "name": "handle",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Secondary identity label rendered below the name, usually a short username or role marker."
            },
            {
              "name": "avatar",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional avatar image source. When omitted, the component shows the initials fallback chip instead."
            },
            {
              "name": "initials",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional fallback text rendered when no avatar string is provided. Leave it empty when you want the author row to render without any leading media."
            }
          ]
        },
        {
          "id": "carousel-interaction",
          "title": "Interaction and layout behavior",
          "summary": "The component couples motion and navigation into one fixed layout, so consumers get a ready-made interaction shell rather than a headless slider primitive.",
          "notes": [
            "The root width is capped at max-w-md and the slide stage uses a fixed 230px height, so very different aspect ratios require a source edit.",
            "Slide direction is used by AnimatePresence to decide whether the next card enters from the left or right."
          ],
          "fields": [
            {
              "name": "swipe threshold",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Dragging left or right past 80px changes slides. Smaller drags snap back to the current item."
            },
            {
              "name": "pagination dots",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Each testimonial maps to a dot button. The active dot stretches wider and clicking any dot jumps to that index."
            },
            {
              "name": "arrow controls",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "Previous and next buttons wrap around the array length instead of stopping at the edges."
            }
          ]
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "combobox",
      "name": "Combobox",
      "href": "/components/combobox",
      "url": "https://iconiqui.com/components/combobox",
      "installPackage": "@iconiq/combobox",
      "installCommand": "npx shadcn@latest add @iconiq/combobox",
      "registryPath": "combobox.json",
      "registryUrl": "https://iconiqui.com/r/combobox.json",
      "summary": "Each selectable row is described by a plain object and can optionally include a secondary description line.",
      "apiSections": [
        {
          "id": "combobox-option",
          "title": "ComboboxOption",
          "summary": "Each selectable row is described by a plain object and can optionally include a secondary description line.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable identifier used for the selected state and returned through onChange."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Primary text shown in the closed field and inside the dropdown row."
            },
            {
              "name": "description",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional helper copy rendered under the label inside the dropdown list."
            }
          ]
        },
        {
          "id": "combobox",
          "title": "Combobox",
          "summary": "Searchable single-select field that owns open state, search query, and active row internally, while the selected value stays parent-driven.",
          "notes": [
            "This is effectively controlled for selection. If the parent does not feed the next onChange result back into value, the checkmark and closed-field label do not update.",
            "Closing the popover resets the live query string, so reopening the field starts from the full option list again."
          ],
          "fields": [
            {
              "name": "options",
              "type": "ComboboxOption[]",
              "defaultValue": "",
              "required": true,
              "description": "Available rows rendered in display order and used as the filtering source."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Currently selected option value. The component derives the visible label entirely from this prop when the field is closed."
            },
            {
              "name": "onChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a row is selected and also when the clear action resets the field to an empty string."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "\"Select an option...\"",
              "required": false,
              "description": "Shown when no value is selected, and again while the field is open with an empty query."
            },
            {
              "name": "emptyMessage",
              "type": "string",
              "defaultValue": "\"No results found.\"",
              "required": false,
              "description": "Fallback copy rendered when filtering produces no matching options."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer relative wrapper so width or placement can be adjusted externally."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "false",
              "required": false,
              "description": "Disables the input, blocks opening, and applies a reduced-opacity presentation."
            },
            {
              "name": "clearable",
              "type": "boolean",
              "defaultValue": "true",
              "required": false,
              "description": "Controls whether the clear button appears once a value has been selected."
            }
          ]
        },
        {
          "id": "combobox-filtering",
          "title": "Filtering, keyboard, and layout behavior",
          "summary": "The dropdown is portaled to document.body, positioned from the field bounds, and supports a stronger keyboard model than the simpler select component.",
          "notes": [
            "Filtering is a case-insensitive substring match across label, value, and description.",
            "ArrowUp, ArrowDown, Home, End, Enter, Escape, and Tab are all handled directly on the input to drive the internal activeIndex and open state.",
            "The clear button uses tabIndex={-1}, so it is pointer-accessible but not keyboard reachable in this version.",
            "Because the list is rendered in a portal with fixed positioning, overflow-hidden ancestors do not clip it. Placement is recalculated from the trigger rect while it is open."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "context-menu",
      "name": "Context menu",
      "href": "/components/context-menu",
      "url": "https://iconiqui.com/components/context-menu",
      "installPackage": "@iconiq/context-menu",
      "installCommand": "npx shadcn@latest add @iconiq/context-menu",
      "registryPath": "context-menu.json",
      "registryUrl": "https://iconiqui.com/r/context-menu.json",
      "summary": "Stateful wrapper that listens for the native contextmenu event on a local surface and renders a fixed-position floating menu.",
      "apiSections": [
        {
          "id": "context-menu",
          "title": "ContextMenu",
          "summary": "Stateful wrapper that listens for the native contextmenu event on a local surface and renders a fixed-position floating menu.",
          "notes": [
            "Open state is fully internal. This implementation does not expose controlled open props, state callbacks, or an imperative API.",
            "The menu opens only from the native contextmenu event, then flips horizontally or vertically when the estimated panel would overflow the viewport.",
            "Closing is handled internally on outside mousedown, scroll, resize, and Escape. ArrowUp and ArrowDown move the highlighted row in local state, but DOM focus does not move into the menu."
          ],
          "fields": [
            {
              "name": "items",
              "type": "ContextMenuItem[]",
              "defaultValue": "",
              "required": true,
              "description": "Ordered list of menu rows. Each item defines its own label, optional icon and shortcut, click handler, and row state."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Content wrapped by the local context-click target. The component always renders a div around this content and attaches the right-click handler there."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the wrapper div that receives the native context menu event."
            },
            {
              "name": "menuClassName",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the floating motion.div for local surface styling overrides. The component still applies an inline width of 232px."
            }
          ]
        },
        {
          "id": "context-menu-item",
          "title": "ContextMenuItem",
          "summary": "Data shape used by the items prop to define each row in the menu.",
          "notes": [
            "Keyboard navigation skips disabled rows in both directions. If every row is disabled, the highlighted index stays unchanged."
          ],
          "fields": [
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Primary row copy rendered as the main action label."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional leading visual rendered inside the fixed 16px icon slot."
            },
            {
              "name": "shortcut",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional trailing helper text, typically a keyboard hint such as R or Cmd+D."
            },
            {
              "name": "onSelect",
              "type": "() => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the row is activated with a click or Enter on the currently highlighted item."
            },
            {
              "name": "destructive",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Switches the row into the destructive color treatment and changes the active highlight tint."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Dims the row and blocks pointer and Enter selection."
            },
            {
              "name": "separatorAfter",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Inserts a thin divider after the row unless it is already the last rendered item."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "drawer",
      "name": "Drawer",
      "href": "/components/drawer",
      "url": "https://iconiqui.com/components/drawer",
      "installPackage": "@iconiq/drawer",
      "installCommand": "npx shadcn@latest add @iconiq/drawer",
      "registryPath": "drawer.json",
      "registryUrl": "https://iconiqui.com/r/drawer.json",
      "summary": "Single exported overlay drawer controlled entirely from parent state, with side-based panel motion and built-in body scroll locking.",
      "apiSections": [
        {
          "id": "drawer",
          "title": "Drawer",
          "summary": "Single exported overlay drawer controlled entirely from parent state, with side-based panel motion and built-in body scroll locking.",
          "notes": [
            "This component does not forward arbitrary DOM props or refs to the overlay or panel. The public API is limited to the controlled props above.",
            "While open, the component sets document.body.style.overflow to hidden and restores it during cleanup.",
            "There is no focus trap, portal primitive, or aria dialog wiring here, so this version is closer to a visual application drawer than a full modal accessibility primitive."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": true,
              "description": "Controls whether the drawer and overlay render at all. The component is fully controlled and does not keep its own open state."
            },
            {
              "name": "onClose",
              "type": "() => void",
              "defaultValue": "",
              "required": true,
              "description": "Called when the overlay is clicked or when Escape is pressed while the drawer is open."
            },
            {
              "name": "side",
              "type": "\"left\" | \"right\" | \"top\" | \"bottom\"",
              "defaultValue": "\"right\"",
              "required": false,
              "description": "Chooses the panel edge, slide direction, and the matching border placement from the internal panelVariants map."
            },
            {
              "name": "title",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Primary heading rendered in the header row. When omitted, the heading node still renders but stays empty."
            },
            {
              "name": "description",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Secondary helper line rendered under the title when present."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Content rendered inside the scrolling body area below the header."
            }
          ]
        },
        {
          "id": "drawer-motion-layout",
          "title": "Motion, layout, and close behavior",
          "summary": "The drawer uses a spring-driven panel plus staggered header and body children, with a softer duration fallback when reduced motion is enabled.",
          "notes": [
            "Top and bottom drawers cap their height at 80vh, while left and right drawers cap their width at max-w-md and otherwise fill the viewport edge-to-edge.",
            "A decorative top shimmer is always rendered inside the panel. Remove or restyle it locally if you want a flatter surface."
          ],
          "fields": [
            {
              "name": "overlay",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "A fixed full-screen overlay is always rendered behind the panel and closes the drawer on click."
            },
            {
              "name": "close button",
              "type": "built-in",
              "defaultValue": "",
              "required": false,
              "description": "The header always includes a close button with the Lucide X icon wired to onClose."
            }
          ]
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "dialog",
      "name": "Dialog",
      "href": "/components/dialog",
      "url": "https://iconiqui.com/components/dialog",
      "installPackage": "@iconiq/dialog",
      "installCommand": "npx shadcn@latest add @iconiq/dialog",
      "registryPath": "dialog.json",
      "registryUrl": "https://iconiqui.com/r/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-close",
          "title": "DialogTrigger and DialogClose",
          "summary": "These exports are direct Radix aliases used to open or close the dialog from any custom element.",
          "notes": [
            "Because both exports come directly from Radix, they also accept 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 or close control without adding an extra wrapper element."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Interactive content rendered by the trigger or close primitive."
            }
          ]
        },
        {
          "id": "dialog-layout-helpers",
          "title": "DialogHeader and DialogFooter",
          "summary": "Layout helpers used to structure dialog content without changing dialog behavior.",
          "notes": [
            "Both 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 helper 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-text-helpers",
          "title": "DialogTitle and DialogDescription",
          "summary": "Semantic text helpers that forward to the matching Radix title and description primitives.",
          "notes": [
            "Both helpers forward refs to the underlying Radix primitives."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Text or inline markup rendered inside the title or description primitive."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged with the default title or description styles."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-dialog",
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "dropdown",
      "name": "Dropdown",
      "href": "/components/dropdown",
      "url": "https://iconiqui.com/components/dropdown",
      "installPackage": "@iconiq/dropdown",
      "installCommand": "npx shadcn@latest add @iconiq/dropdown",
      "registryPath": "dropdown.json",
      "registryUrl": "https://iconiqui.com/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."
          ],
          "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, and its spring animation is handled internally."
          ],
          "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 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-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": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "file-upload",
      "name": "File upload",
      "href": "/components/file-upload",
      "url": "https://iconiqui.com/components/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": "hover-card",
      "name": "Hover card",
      "href": "/components/hover-card",
      "url": "https://iconiqui.com/components/hover-card",
      "installPackage": "@iconiq/hover-card",
      "installCommand": "npx shadcn@latest add @iconiq/hover-card",
      "registryPath": "hover-card.json",
      "registryUrl": "https://iconiqui.com/r/hover-card.json",
      "summary": "Stateful wrapper that opens and closes a local callout from pointer and focus events with configurable delays.",
      "apiSections": [
        {
          "id": "hover-card",
          "title": "HoverCard",
          "summary": "Stateful wrapper that opens and closes a local callout from pointer and focus events with configurable delays.",
          "notes": [
            "Open state is internal only. This implementation does not expose a controlled open prop or state-change callback.",
            "The root renders a relative inline-block span and attaches the hover and focus handlers there, so the content stays anchored to that local wrapper.",
            "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 root span that anchors the trigger and positioned content."
            },
            {
              "name": "openDelay",
              "type": "number",
              "defaultValue": "80",
              "required": false,
              "description": "Delay in milliseconds before the card opens after pointer or focus entry."
            },
            {
              "name": "closeDelay",
              "type": "number",
              "defaultValue": "120",
              "required": false,
              "description": "Delay in milliseconds before the card closes after pointer or focus leaves the root."
            }
          ]
        },
        {
          "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 element. Pass type='button' yourself if you place it inside a form.",
            "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 that appears below the trigger with a spring entrance and blur 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 absolutely positioned relative to the root wrapper rather than portaled to document.body, so overflow-hidden ancestors can clip it.",
            "By default the content is centered below the trigger with mt-3 spacing and a fixed w-72 width."
          ],
          "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."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-slot",
        "motion"
      ]
    },
    {
      "slug": "input-group",
      "name": "Input group",
      "href": "/components/input-group",
      "url": "https://iconiqui.com/components/input-group",
      "installPackage": "@iconiq/input-group",
      "installCommand": "npx shadcn@latest add @iconiq/input-group",
      "registryPath": "input-group.json",
      "registryUrl": "https://iconiqui.com/r/input-group.json",
      "summary": "Floating-label input field with optional prefix and suffix slots, a center-out focus rule, and inline error messaging driven entirely by props.",
      "apiSections": [
        {
          "id": "inputgroups",
          "title": "Inputgroups",
          "summary": "Floating-label input field with optional prefix and suffix slots, a center-out focus rule, and inline error messaging driven entirely by props.",
          "notes": [
            "Standard native input props such as name, type, value, defaultValue, placeholder, autoComplete, disabled, onFocus, onBlur, and onChange are forwarded directly to the underlying input element.",
            "The outer field shell uses a mouse-down focus handoff, so clicking the label area or prefix icon focuses the input without stealing focus from the suffix button.",
            "Value presence is tracked from the real input value, which keeps the floating label aligned for both controlled and uncontrolled usage."
          ],
          "fields": [
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Field label rendered inside the shell until the input becomes focused or contains a value, then animated upward into its floating position."
            },
            {
              "name": "error",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional validation message rendered below the field. Passing a value also switches the label and underline to the destructive palette."
            },
            {
              "name": "prefixIcon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Leading visual placed before the input area. The slot is best suited to compact icons and inherits the same focus-aware color shift as the suffix."
            },
            {
              "name": "suffixIcon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional trailing visual rendered inside a button, which makes it useful for actions such as show-password toggles or clear controls."
            },
            {
              "name": "onSuffixClick",
              "type": "() => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when the suffix button is pressed. It only matters when suffixIcon is also present."
            },
            {
              "name": "id",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional input id. When omitted, the component creates one with useId and links the animated label automatically."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Applied to the native input element itself, not the outer shell. Use it for text sizing, placeholder, or input-level spacing overrides."
            }
          ]
        },
        {
          "id": "input-group",
          "title": "InputGroup",
          "summary": "Lightweight vertical wrapper for stacking multiple Inputgroups fields with consistent spacing.",
          "notes": [
            "All remaining div props are forwarded to the wrapper, so data attributes and layout helpers can be attached at the group level."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "One or more Inputgroups fields, or any other custom content you want to keep in the same vertical flow."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the wrapper div. The base layout already uses a full-width flex column with a 1.5rem gap."
            }
          ]
        },
        {
          "id": "input-group-motion",
          "title": "Motion and behavior",
          "summary": "The component keeps its motion treatment quiet and focused on form affordances rather than full-panel animation.",
          "notes": [
            "The label, prefix slot, and suffix slot all use spring transitions, so they respond to focus without introducing layout shift.",
            "The bottom accent line grows from the center outward only while the field is focused, then collapses away on blur.",
            "Error copy mounts and exits through AnimatePresence, which keeps the spacing stable while still giving feedback a small fade-and-rise transition."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "pagination",
      "name": "Pagination",
      "href": "/components/pagination",
      "url": "https://iconiqui.com/components/pagination",
      "installPackage": "@iconiq/pagination",
      "installCommand": "npx shadcn@latest add @iconiq/pagination",
      "registryPath": "pagination.json",
      "registryUrl": "https://iconiqui.com/r/pagination.json",
      "summary": "Pagination root that can either render the full paginator from total, page, and onChange props or act as the parent wrapper for the composed shadcn-style pieces.",
      "apiSections": [
        {
          "id": "pagination",
          "title": "Pagination",
          "summary": "Pagination root that can either render the full paginator from total, page, and onChange props or act as the parent wrapper for the composed shadcn-style pieces.",
          "notes": [
            "This keeps the same UI and motion treatment as the original single-component paginator, but now also exposes shadcn-style building blocks.",
            "Out-of-range page changes are ignored, so previous is inert on page 1 and next is inert on the final page."
          ],
          "fields": [
            {
              "name": "total",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Total number of pages available. When you use the built-in wrapper mode, the component renders the first page, last page, current page, and one sibling on either side, collapsing the rest into ellipsis markers."
            },
            {
              "name": "page",
              "type": "number",
              "defaultValue": "",
              "required": false,
              "description": "Controlled current page. When omitted, the root manages its own page state internally starting from page 1."
            },
            {
              "name": "onChange",
              "type": "(page: number) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever a valid next page is chosen from the numbered buttons or the previous and next controls. The composed primitives also use this through context when you do not provide custom button handlers."
            },
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional composed pagination structure. When omitted, the root renders the full paginator automatically using total, page, and onChange."
            }
          ]
        },
        {
          "id": "pagination-content",
          "title": "PaginationContent and PaginationItem",
          "summary": "The composed content wrapper keeps previous and next controls on the edges while the page links stay centered inside the same fixed-width rail.",
          "notes": [
            "PaginationContent preserves the same centered 280px page rail from the current design instead of switching to a looser layout.",
            "PaginationItem uses layout-aware motion so page entries keep the same fluid shifting behavior when the visible range changes."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Render PaginationPrevious, PaginationNext, PaginationLink, and PaginationEllipsis inside PaginationContent. Numeric and ellipsis entries can be wrapped with PaginationItem."
            }
          ]
        },
        {
          "id": "pagination-links",
          "title": "PaginationLink, PaginationPrevious, PaginationNext, and PaginationEllipsis",
          "summary": "These primitives expose the numbered buttons and edge controls individually while keeping the existing visual behavior intact.",
          "notes": [
            "Previous and next keep the same hover arrow nudge and current label treatment from the approved design.",
            "Ellipsis markers remain static separators and are not interactive."
          ],
          "fields": [
            {
              "name": "isActive",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Marks the current page on PaginationLink and keeps the underline anchored under the active number."
            },
            {
              "name": "text",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional label override for PaginationPrevious and PaginationNext. They default to Prev and Next."
            }
          ]
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "popover",
      "name": "Popover",
      "href": "/components/popover",
      "url": "https://iconiqui.com/components/popover",
      "installPackage": "@iconiq/popover",
      "installCommand": "npx shadcn@latest add @iconiq/popover",
      "registryPath": "popover.json",
      "registryUrl": "https://iconiqui.com/r/popover.json",
      "summary": "Standard shadcn-style export: `Popover` is `PopoverPrimitive.Root`, matching what the CLI installs into `components/ui/popover`.",
      "apiSections": [
        {
          "id": "popover-root",
          "title": "Popover",
          "summary": "Standard shadcn-style export: `Popover` is `PopoverPrimitive.Root`, matching what the CLI installs into `components/ui/popover`.",
          "notes": [
            "Any remaining root props continue to work because the export is the Radix primitive itself."
          ],
          "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 and PopoverAnchor",
          "summary": "These exports are direct aliases of the matching Radix primitives and are used to open the popover or redefine its positioning anchor.",
          "notes": [
            "Because both exports come directly from Radix, they also accept the remaining primitive props for event handling and accessibility wiring."
          ],
          "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 or layout content rendered by the trigger or 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 and uses the Radix transform-origin CSS variable so the motion scales from the resolved placement.",
            "Entry and exit animation are owned internally, so initial, animate, exit, and transition are not part of the public prop surface."
          ],
          "fields": [
            {
              "name": "open",
              "type": "boolean",
              "defaultValue": "",
              "required": true,
              "description": "Controls whether the animated portal branch renders at all. In practice this must mirror the root open state for entry and exit motion to run correctly."
            },
            {
              "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."
            }
          ]
        }
      ],
      "dependencies": [
        "@radix-ui/react-popover",
        "motion"
      ]
    },
    {
      "slug": "checkbox-group",
      "name": "Checkbox group",
      "href": "/components/checkbox-group",
      "url": "https://iconiqui.com/components/checkbox-group",
      "installPackage": "@iconiq/checkbox-group",
      "installCommand": "npx shadcn@latest add @iconiq/checkbox-group",
      "registryPath": "checkbox-group.json",
      "registryUrl": "https://iconiqui.com/r/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": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables the row button and blocks hover, active, and toggle behavior for that option."
            }
          ]
        },
        {
          "id": "checkbox-group",
          "title": "CheckboxGroup",
          "summary": "Animated multi-select list whose checked state is derived entirely from the value prop.",
          "notes": [
            "If you want the UI to update when a user clicks, you must feed the next array from onChange back into value. Without that parent state loop, the component stays visually unchanged.",
            "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 component does not keep internal selection state beyond this prop."
            },
            {
              "name": "onChange",
              "type": "(value: string[]) => void",
              "defaultValue": "",
              "required": false,
              "description": "Receives the next selected values array after a row is toggled."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root flex column wrapper."
            }
          ]
        },
        {
          "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": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "radiogroup",
      "name": "Radio group",
      "href": "/components/radiogroup",
      "url": "https://iconiqui.com/components/radiogroup",
      "installPackage": "@iconiq/radiogroup",
      "installCommand": "npx shadcn@latest add @iconiq/radiogroup",
      "registryPath": "radiogroup.json",
      "registryUrl": "https://iconiqui.com/r/radiogroup.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 that can run uncontrolled from local state or sync to a controlled value prop.",
          "notes": [
            "If options is empty, the uncontrolled initial state becomes undefined and no row is selected.",
            "Controlled updates are synced through an effect that watches the value prop."
          ],
          "fields": [
            {
              "name": "options",
              "type": "{ value: string; label: string; description?: string }[]",
              "defaultValue": "",
              "required": true,
              "description": "Available choices in display order."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled selected value. If omitted, the component starts from the first option's value and manages selection locally."
            },
            {
              "name": "onChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called whenever a user selects a row."
            },
            {
              "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 layers Motion over custom radio semantics rather than using native input[type=radio].",
          "notes": [
            "The active background uses a fixed layoutId of radio-active-bg. Multiple RadioGroup instances on the same screen can therefore share cross-layout animation unless you fork the implementation.",
            "The root sets role='radiogroup' and each row sets role='radio' plus aria-checked, but there is no arrow-key navigation or roving tabindex behavior."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "select",
      "name": "Select",
      "href": "/components/select",
      "url": "https://iconiqui.com/components/select",
      "installPackage": "@iconiq/select",
      "installCommand": "npx shadcn@latest add @iconiq/select",
      "registryPath": "select.json",
      "registryUrl": "https://iconiqui.com/r/select.json",
      "summary": "Each selectable row is described by a plain object and rendered inside a portaled menu.",
      "apiSections": [
        {
          "id": "select-option",
          "title": "Option shape",
          "summary": "Each selectable row is described by a plain object and rendered inside a portaled menu.",
          "notes": [],
          "fields": [
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Stable identifier used to determine the selected option and what onChange returns."
            },
            {
              "name": "label",
              "type": "string",
              "defaultValue": "",
              "required": true,
              "description": "Text shown in both the trigger and the dropdown row."
            },
            {
              "name": "icon",
              "type": "ReactNode",
              "defaultValue": "",
              "required": false,
              "description": "Optional leading visual shown only inside the dropdown row."
            }
          ]
        },
        {
          "id": "select",
          "title": "Select",
          "summary": "Animated single-select dropdown that manages open state internally but expects the selected value to come from the parent.",
          "notes": [
            "This implementation is effectively controlled for selection. If you call onChange without updating value, the visible selection and checkmark do not move.",
            "The public API still does not expose disabled or native form props."
          ],
          "fields": [
            {
              "name": "options",
              "type": "{ value: string; label: string; icon?: ReactNode }[]",
              "defaultValue": "",
              "required": true,
              "description": "Rows available in the dropdown menu."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Currently selected option value. The component derives its selected label entirely from this prop."
            },
            {
              "name": "onChange",
              "type": "(value: string) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a row is chosen. The menu closes immediately afterward."
            },
            {
              "name": "placeholder",
              "type": "string",
              "defaultValue": "Select an option…",
              "required": false,
              "description": "Fallback trigger text shown when no option matches the current value."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the outer wrapper so width and placement can be adjusted without editing the component source."
            }
          ]
        },
        {
          "id": "select-overlay",
          "title": "Overlay and interaction behavior",
          "summary": "The dropdown menu is portaled to document.body and continuously repositioned while open.",
          "notes": [
            "A mounted flag prevents createPortal from running during the initial server render.",
            "useLayoutEffect starts a requestAnimationFrame loop that keeps the menu aligned to the trigger while the viewport changes.",
            "Clicking outside the trigger and menu closes the dropdown. There is no keyboard list navigation or highlighted-option state in this version."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion",
        "lucide-react"
      ]
    },
    {
      "slug": "skeleton",
      "name": "Skeleton",
      "href": "/components/skeleton",
      "url": "https://iconiqui.com/components/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": "slider",
      "name": "Slider",
      "href": "/components/slider",
      "url": "https://iconiqui.com/components/slider",
      "installPackage": "@iconiq/slider",
      "installCommand": "npx shadcn@latest add @iconiq/slider",
      "registryPath": "slider.json",
      "registryUrl": "https://iconiqui.com/r/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 number is derived from the animated motion value, so the readout stays in sync with the spring animation rather than jumping immediately."
          ],
          "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 whenever pointer interaction computes a new clamped value."
            },
            {
              "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": "label",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Optional label shown on the left side of the header row above the track."
            }
          ]
        },
        {
          "id": "slider-interaction",
          "title": "Interaction model",
          "summary": "Slider is currently optimized for pointer interaction only.",
          "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.",
            "This version does not expose keyboard controls, role='slider', or aria-valuenow, so accessible form-heavy experiences should wrap or extend it."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "motion"
      ]
    },
    {
      "slug": "spinner",
      "name": "Spinner",
      "href": "/components/spinner",
      "url": "https://iconiqui.com/components/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": "switch",
      "name": "Switch",
      "href": "/components/switch",
      "url": "https://iconiqui.com/components/switch",
      "installPackage": "@iconiq/switch",
      "installCommand": "npx shadcn@latest add @iconiq/switch",
      "registryPath": "switch.json",
      "registryUrl": "https://iconiqui.com/r/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": [
        "@radix-ui/react-switch",
        "motion"
      ]
    },
    {
      "slug": "table",
      "name": "Table",
      "href": "/components/table",
      "url": "https://iconiqui.com/components/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.",
            "Semantic roles default to a div-based table structure (`table`, `rowgroup`, `row`, `columnheader`, and `cell`) so the installed primitive is more accessible without changing the visual layout."
          ],
          "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 custom layouts stay aligned."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root wrapper 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": "Top shell for the header area. It preserves the original top border before the first row.",
          "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": "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 row primitive 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 use the original spring-based row transitions."
            },
            {
              "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 keep the original muted hover wash. Defaults to false for header rows and true for body rows."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the row shell for spacing or color overrides."
            },
            {
              "name": "Motion div props",
              "type": "ComponentPropsWithoutRef<typeof motion.div>",
              "defaultValue": "",
              "required": false,
              "description": "Additional motion.div props such as layout, transition, whileHover, and exit can still be passed directly."
            }
          ]
        },
        {
          "id": "table-head",
          "title": "TableHead",
          "summary": "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."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the header cell wrapper."
            }
          ]
        },
        {
          "id": "table-cell",
          "title": "TableCell",
          "summary": "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 caption line 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 block 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": "Motion div props",
              "type": "ComponentPropsWithoutRef<typeof motion.div>",
              "defaultValue": "",
              "required": false,
              "description": "You can still override animate, initial, transition, or className when customizing the empty state."
            }
          ]
        },
        {
          "id": "table-sort-button",
          "title": "TableSortButton",
          "summary": "Optional header helper that preserves the original label-plus-chevron treatment 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 icon opacity and enables the active sort direction treatment."
            },
            {
              "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."
            },
            {
              "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": "tabs",
      "name": "Tabs",
      "href": "/components/tabs",
      "url": "https://iconiqui.com/components/tabs",
      "installPackage": "@iconiq/tabs",
      "installCommand": "npx shadcn@latest add @iconiq/tabs",
      "registryPath": "tabs.json",
      "registryUrl": "https://iconiqui.com/r/tabs.json",
      "summary": "Root wrapper for a clean tab interface with controlled or uncontrolled value handling from Base UI.",
      "apiSections": [
        {
          "id": "tabs",
          "title": "Tabs",
          "summary": "Root wrapper for a clean tab interface with controlled or uncontrolled value handling from Base UI.",
          "notes": [
            "The implementation stays intentionally small: it relies on Base UI for selection state, keyboard behavior, and panel wiring.",
            "Use local className overrides on TabsList or TabsTrigger when a specific screen needs a more opinionated visual treatment."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Compose TabsList, TabsTrigger, and TabsContent inside the root, following the familiar shadcn-style structure."
            },
            {
              "name": "defaultValue",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Initial active tab value for uncontrolled usage."
            },
            {
              "name": "value",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Controlled active tab value."
            },
            {
              "name": "onValueChange",
              "type": "(value: string, details: object) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called when a trigger changes the active tab through click or keyboard navigation."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the root wrapper around the list and content panels."
            }
          ]
        },
        {
          "id": "tabs-list",
          "title": "TabsList",
          "summary": "Inline trigger rail that provides the muted segmented background behind a set of tab triggers.",
          "notes": [
            "The default styles keep the list compact so it works well for docs toggles, install blocks, and simple settings surfaces."
          ],
          "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 clean active surface, quieter inactive state, and built-in accessibility wiring from Base UI.",
          "notes": [
            "Active styling uses the presence of Base UI's data-active attribute rather than a custom indicator layer.",
            "Focus, arrow-key navigation, and ARIA relationships come from the underlying tabs primitive."
          ],
          "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": "Single panel tied to a matching trigger value.",
          "notes": [
            "Hidden panels are managed by the underlying tabs primitive, so you keep the usual DOM and accessibility behavior without extra wrapper logic.",
            "Standard div attributes such as data-*, aria-*, id, style, and event handlers are forwarded to the panel element."
          ],
          "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 panel element."
            }
          ]
        }
      ],
      "dependencies": [
        "@base-ui/react"
      ]
    },
    {
      "slug": "toggle",
      "name": "Toggle",
      "href": "/components/toggle",
      "url": "https://iconiqui.com/components/toggle",
      "installPackage": "@iconiq/toggle",
      "installCommand": "npx shadcn@latest add @iconiq/toggle",
      "registryPath": "toggle.json",
      "registryUrl": "https://iconiqui.com/r/toggle.json",
      "summary": "Single pressed-state toggle built on Radix Toggle, with Motion-driven button, icon, and ripple feedback layered over shadcn-style size and variant classes.",
      "apiSections": [
        {
          "id": "toggle",
          "title": "Toggle",
          "summary": "Single pressed-state toggle built on Radix Toggle, with Motion-driven button, icon, and ripple feedback layered over shadcn-style size and variant classes.",
          "notes": [
            "Additional Radix toggle button props such as aria-label, name, value, and type are forwarded through the underlying Toggle.Root surface.",
            "The component renders Radix Root with asChild internally, then supplies its own motion.button as the child node."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Visible button content rendered inside the animated inner span. This can be plain text, icons, or both."
            },
            {
              "name": "variant",
              "type": "\"default\" | \"outline\"",
              "defaultValue": "default",
              "required": false,
              "description": "Visual treatment from the internal CVA config. Outline adds the input border and shadow-sm treatment."
            },
            {
              "name": "size",
              "type": "\"default\" | \"sm\" | \"lg\"",
              "defaultValue": "default",
              "required": false,
              "description": "Height and horizontal padding preset applied through the shared toggleVariants helper."
            },
            {
              "name": "pressed",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Controlled pressed state from Radix Toggle.Root. Use this when the parent should own the on/off state."
            },
            {
              "name": "defaultPressed",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Initial pressed state for uncontrolled usage."
            },
            {
              "name": "onPressedChange",
              "type": "(pressed: boolean) => void",
              "defaultValue": "",
              "required": false,
              "description": "Called after the component kicks off its local motion sequence, with the next pressed value from Radix."
            },
            {
              "name": "disabled",
              "type": "boolean",
              "defaultValue": "",
              "required": false,
              "description": "Disables the toggle and prevents the hover, tap, and pressed-state interaction flow."
            },
            {
              "name": "className",
              "type": "string",
              "defaultValue": "",
              "required": false,
              "description": "Merged onto the rendered motion button for local spacing or surface overrides."
            }
          ]
        },
        {
          "id": "toggle-motion",
          "title": "Motion and state behavior",
          "summary": "Every pressed change triggers a button squash, a center ripple, and a separate icon animation sequence.",
          "notes": [
            "The outer button uses useAnimationControls so the pressed sequence can run immediately whenever Radix reports a state change.",
            "The icon motion differs between on and off transitions, so enabling and disabling the toggle do not feel identical.",
            "Hover always applies a slight upward lift and tap applies an extra scale-down, independent of whether the toggle is currently pressed."
          ],
          "fields": []
        }
      ],
      "dependencies": [
        "@radix-ui/react-toggle",
        "class-variance-authority",
        "motion"
      ]
    },
    {
      "slug": "tooltip",
      "name": "Tooltip",
      "href": "/components/tooltip",
      "url": "https://iconiqui.com/components/tooltip",
      "installPackage": "@iconiq/tooltip",
      "installCommand": "npx shadcn@latest add @iconiq/tooltip",
      "registryPath": "tooltip.json",
      "registryUrl": "https://iconiqui.com/r/tooltip.json",
      "summary": "Animated tooltip with a canonical Tooltip export. It owns its own open state 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 and toggles in response to hover and focus events.",
          "notes": [
            "The trigger wrapper handles onMouseEnter, onMouseLeave, onFocus, and onBlur. No trigger props are forwarded directly to the child node.",
            "The timeout used for delayed open is cleared on leave and again on unmount."
          ],
          "fields": [
            {
              "name": "children",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Trigger content wrapped in a relative inline-flex container."
            },
            {
              "name": "content",
              "type": "ReactNode",
              "defaultValue": "",
              "required": true,
              "description": "Tooltip body rendered inside the animated bubble."
            },
            {
              "name": "side",
              "type": "\"top\" | \"bottom\" | \"left\" | \"right\"",
              "defaultValue": "top",
              "required": false,
              "description": "Controls which positioning class and directional motion offset are used."
            },
            {
              "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 absolutely positioned inside its local wrapper rather than portaled to the document body.",
          "notes": [
            "Because the bubble is not portaled, overflow-hidden ancestors can clip it and z-index stacking still depends on the surrounding layout.",
            "The bubble itself gets role='tooltip', but the trigger does not receive aria-describedby or an id link automatically.",
            "The arrow is a rotated square whose placement changes with the side prop."
          ],
          "fields": []
        }
      ],
      "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": "Dia Text component documentation.",
      "apiSections": [],
      "dependencies": []
    },
    {
      "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": "Shimmer Text component documentation.",
      "apiSections": [],
      "dependencies": []
    }
  ],
  "latestRelease": {
    "version": "v1.0.4",
    "date": "7 May 2026",
    "title": "GEO and AI discovery rollout",
    "summary": "Adds a full Generative Engine Optimization layer across the product, with AI-readable discovery routes, richer metadata, and structured component indexing.",
    "groups": [
      {
        "items": [
          "New AI discovery endpoints: /llms.txt, /llms-full.txt, and /ai-index.json.",
          "A machine-readable component catalog generated from the existing docs and API reference data."
        ],
        "label": "Added"
      },
      {
        "items": [
          "Site metadata, JSON-LD, sitemap, and robots coverage improved for AI crawlers and answer engines.",
          "Component documentation pages now expose stronger structured data for individual component understanding."
        ],
        "label": "Updated"
      },
      {
        "items": [
          "Discovery signals are now more consistent across the site instead of being split between isolated SEO surfaces."
        ],
        "label": "Fixed"
      }
    ]
  },
  "generatedAt": "2026-05-11T15:54:10.951Z"
}