{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "item-select",
  "title": "Select item",
  "description": "Styled item: the Select set. 5 decorative item variations (CheckItem, RadioItem, ToggleItem, MultiItem, HighlightItem) on the ai2 token system, driven by CSS token transitions and sized sm to xl. Part of the free styled layer.",
  "dependencies": [
    "lucide-react@^1.23.0"
  ],
  "registryDependencies": [
    "@ai2/tokens"
  ],
  "files": [
    {
      "path": "registry/ai2/styled/item-select.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* Item select family: 5 list rows carrying a REAL working selection state. Nothing is faked - every variant holds its own React state, the state changes on click and by keyboard, and the selected appearance comes from that state. The controls get an accessible label and the ids are produced with React.useId() (deterministic, SSR safe). Colour comes ONLY from tokens; alpha via color-mix. No animation. Every export renders without props too. */\n\nexport type StyledSize = \"sm\" | \"md\" | \"lg\" | \"xl\"\n\nconst box: Record<StyledSize, string> = {\n  sm: \"gap-2.5 rounded-lg p-2 text-sm\",\n  md: \"gap-3 rounded-lg p-3 text-sm\",\n  lg: \"gap-3.5 rounded-xl p-4 text-base\",\n  xl: \"gap-4 rounded-xl p-5 text-base\",\n}\n\nconst base =\n  \"flex w-full items-center [&_svg]:shrink-0 [&_i]:not-italic [&_i]:leading-none\"\n\nconst titleCls = \"truncate font-medium text-foreground\"\nconst descCls = \"truncate text-muted-foreground text-[0.85em]\"\n\n/* Satir kabugu: secili degilken notr, secili iken brand kenarligi + hafif tint. */\nconst rowShell =\n  \"cursor-pointer select-none border border-border bg-card text-card-foreground transition-colors duration-(--motion-fast) ease-(--motion-ease) hover:bg-accent has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50\"\n\nconst rowOn =\n  \"border-[color-mix(in_oklab,var(--color-brand)_45%,transparent)] bg-[color-mix(in_oklab,var(--color-brand)_8%,transparent)] hover:bg-[color-mix(in_oklab,var(--color-brand)_12%,transparent)]\"\n\n/* Controls under 24px carry an invisible hit area. */\nconst controlHit = \"relative after:absolute after:-inset-1.5\"\n\ntype Props = {\n  className?: string\n  size?: StyledSize\n}\n\nfunction Body({\n  title,\n  description,\n}: {\n  title: React.ReactNode\n  description?: React.ReactNode\n}) {\n  return (\n    <span className=\"flex min-w-0 flex-1 flex-col\">\n      <span className={titleCls}>{title}</span>\n      {description ? <span className={descCls}>{description}</span> : null}\n    </span>\n  )\n}\n\n/* Check: one row plus a real checkbox. The whole row is the label, clicking it checks. */\nexport function CheckItem({ className, size = \"md\" }: Props) {\n  const id = React.useId()\n  const [checked, setChecked] = React.useState(false)\n\n  return (\n    <label\n      htmlFor={id}\n      data-slot=\"styled-item\"\n      data-state={checked ? \"checked\" : \"unchecked\"}\n      className={cn(base, box[size], rowShell, checked && rowOn, className)}\n    >\n      <input\n        id={id}\n        type=\"checkbox\"\n        checked={checked}\n        onChange={(e) => setChecked(e.target.checked)}\n        className={cn(\n          \"size-4 shrink-0 accent-brand outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n          controlHit\n        )}\n      />\n      <Body title=\"Email notifications\" description=\"Send a digest every morning\" />\n    </label>\n  )\n}\n\nconst radioOptions = [\n  { value: \"starter\", title: \"Starter\", description: \"Up to 3 projects\" },\n  { value: \"pro\", title: \"Pro\", description: \"Unlimited projects\" },\n  { value: \"team\", title: \"Team\", description: \"Shared workspaces and roles\" },\n]\n\n/* Radio: a real 3-row radio group - only one can be selected at a time. */\nexport function RadioItem({ className, size = \"md\" }: Props) {\n  const name = React.useId()\n  const [value, setValue] = React.useState(\"pro\")\n\n  return (\n    <div\n      role=\"radiogroup\"\n      aria-label=\"Plan\"\n      className={cn(\"flex w-full flex-col gap-2\", className)}\n    >\n      {radioOptions.map((opt) => {\n        const on = value === opt.value\n        return (\n          <label\n            key={opt.value}\n            data-slot=\"styled-item\"\n            data-state={on ? \"checked\" : \"unchecked\"}\n            className={cn(base, box[size], rowShell, on && rowOn)}\n          >\n            <input\n              type=\"radio\"\n              name={name}\n              value={opt.value}\n              checked={on}\n              onChange={() => setValue(opt.value)}\n              className={cn(\n                \"size-4 shrink-0 accent-brand outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n                controlHit\n              )}\n            />\n            <Body title={opt.title} description={opt.description} />\n          </label>\n        )\n      })}\n    </div>\n  )\n}\n\n/* Toggle: one row plus a real switch (role=\"switch\", aria-checked, Space/Enter). */\nexport function ToggleItem({ className, size = \"md\" }: Props) {\n  const labelId = React.useId()\n  const [on, setOn] = React.useState(true)\n\n  return (\n    <div\n      data-slot=\"styled-item\"\n      data-state={on ? \"checked\" : \"unchecked\"}\n      className={cn(base, box[size], \"border border-border bg-card text-card-foreground\", className)}\n    >\n      <Body title={<span id={labelId}>Two-factor authentication</span>} description=\"Ask for a code on every new device\" />\n      <button\n        type=\"button\"\n        role=\"switch\"\n        aria-checked={on}\n        aria-labelledby={labelId}\n        onClick={() => setOn((v) => !v)}\n        className={cn(\n          \"inline-flex h-5 w-9 shrink-0 items-center rounded-full border border-transparent px-0.5 outline-none transition-colors duration-(--motion-fast) ease-(--motion-ease) focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n          on ? \"bg-brand\" : \"bg-[color-mix(in_oklab,var(--color-foreground)_18%,transparent)]\",\n          controlHit\n        )}\n      >\n        <span\n          aria-hidden=\"true\"\n          className={cn(\n            \"size-4 rounded-full bg-background shadow-sm transition-transform duration-(--motion-fast) ease-(--motion-ease)\",\n            on ? \"translate-x-4\" : \"translate-x-0\"\n          )}\n        />\n      </button>\n    </div>\n  )\n}\n\nconst multiOptions = [\n  { value: \"design\", title: \"Design\", description: \"Figma files and tokens\" },\n  { value: \"engineering\", title: \"Engineering\", description: \"Repos and pipelines\" },\n  { value: \"support\", title: \"Support\", description: \"Inbox and macros\" },\n]\n\n/* Multi: multiple selection - 3 rows with a live count of what is selected. */\nexport function MultiItem({ className, size = \"md\" }: Props) {\n  const group = React.useId()\n  const [selected, setSelected] = React.useState<string[]>([\"design\"])\n\n  const toggle = (value: string) =>\n    setSelected((prev) =>\n      prev.includes(value) ? prev.filter((v) => v !== value) : [...prev, value]\n    )\n\n  return (\n    <div\n      role=\"group\"\n      aria-label=\"Workspaces\"\n      className={cn(\"flex w-full flex-col gap-2\", className)}\n    >\n      {multiOptions.map((opt) => {\n        const id = `${group}-${opt.value}`\n        const on = selected.includes(opt.value)\n        return (\n          <label\n            key={opt.value}\n            htmlFor={id}\n            data-slot=\"styled-item\"\n            data-state={on ? \"checked\" : \"unchecked\"}\n            className={cn(base, box[size], rowShell, on && rowOn)}\n          >\n            <input\n              id={id}\n              type=\"checkbox\"\n              checked={on}\n              onChange={() => toggle(opt.value)}\n              className={cn(\n                \"size-4 shrink-0 accent-brand outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n                controlHit\n              )}\n            />\n            <Body title={opt.title} description={opt.description} />\n            {on ? (\n              <span className=\"inline-flex h-5 shrink-0 items-center rounded-md bg-brand px-2 text-xs font-medium text-brand-foreground\">\n                Added\n              </span>\n            ) : null}\n          </label>\n        )\n      })}\n      <span className=\"px-1 text-xs text-muted-foreground\">\n        {selected.length} of {multiOptions.length} selected\n      </span>\n    </div>\n  )\n}\n\n/* Highlight: no control - the row itself is a toggle. While selected it gets a brand\n   surface + a trailing checkmark. The state is announced with aria-pressed. */\nexport function HighlightItem({ className, size = \"md\" }: Props) {\n  const [on, setOn] = React.useState(false)\n\n  return (\n    <button\n      type=\"button\"\n      aria-pressed={on}\n      onClick={() => setOn((v) => !v)}\n      data-slot=\"styled-item\"\n      data-state={on ? \"checked\" : \"unchecked\"}\n      className={cn(\n        base,\n        box[size],\n        \"cursor-pointer border border-border bg-card text-left text-card-foreground outline-none transition-colors duration-(--motion-fast) ease-(--motion-ease) hover:bg-accent focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n        on &&\n          \"border-[color-mix(in_oklab,var(--color-brand)_45%,transparent)] bg-[color-mix(in_oklab,var(--color-brand)_10%,transparent)]\",\n        className\n      )}\n    >\n      <Body title=\"Dark interface\" description=\"Follow the system appearance\" />\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          \"inline-flex size-5 shrink-0 items-center justify-center rounded-full transition-colors duration-(--motion-fast) ease-(--motion-ease) [&_svg]:size-3.5\",\n          on ? \"bg-brand text-brand-foreground\" : \"bg-transparent text-transparent\"\n        )}\n      >\n        <Check />\n      </span>\n    </button>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/ui/item-select.tsx"
    }
  ],
  "categories": [
    "styled",
    "item"
  ],
  "type": "registry:component"
}