{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "model-picker",
  "title": "Model picker",
  "description": "Lets people choose which AI model answers — a quiet name-and-chevron trigger in the composer that opens a list with Auto first, a line on what each model is good for, and a check on the current one.",
  "registryDependencies": [
    "button",
    "dropdown-menu",
    "https://www.quilldesignsystem.com/r/icon.json",
    "https://www.quilldesignsystem.com/r/tone-badge.json"
  ],
  "files": [
    {
      "path": "registry/lib/model-picker.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { Button } from '@/components/ui/button'\nimport {\n  DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuRadioGroup,\n  DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Icon } from '@/components/ui/icon'\nimport { ToneBadge } from '@/components/ui/tone-badge'\nimport { cn } from '@/lib/utils'\n\nexport type ModelOption = {\n  value: string\n  label: string\n  /** One line on what it is good for. */\n  description?: string\n  /** A short tag such as \"New\". */\n  badge?: string\n}\n\nexport const AUTO_MODEL: ModelOption = { value: 'auto', label: 'Auto', description: 'Picks the right model for each message' }\n\n/** Lets people choose which AI model answers — a quiet name-and-chevron trigger in the composer that opens a list with Auto first, a line on what each model is good for, and a check on the current one. */\nexport function ModelPicker({\n  models, value, onValueChange, auto = AUTO_MODEL, label = 'Model', className,\n}: {\n  models: ModelOption[]\n  value: string\n  onValueChange: (value: string) => void\n  /** The first option; false leaves it out. */\n  auto?: ModelOption | false\n  label?: string\n  className?: string\n}) {\n  const all = auto ? [auto, ...models] : models\n  // Nothing to choose from: draw nothing rather than an empty trigger.\n  if (!all.length) return null\n  // A value the list no longer has (a retired model) shows the first option, never an empty trigger.\n  const current = all.find((m) => m.value === value) ?? all[0]\n  const row = (m: ModelOption) => (\n    // items-start keeps the check on the name row's line, not centred on the name plus description.\n    <DropdownMenuRadioItem key={m.value} value={m.value} className=\"items-start py-1.5\">\n      <span className=\"grid\">\n        {/* Fixed line height on the row so the badge and the check share the name's centre line. */}\n        <span className=\"flex h-5 items-center gap-1.5\">\n          <span data-model-name>{m.label}</span>\n          {m.badge ? <ToneBadge tone=\"moss\" size=\"sm\">{m.badge}</ToneBadge> : null}\n        </span>\n        {m.description ? <span className=\"text-xs text-muted-foreground\">{m.description}</span> : null}\n      </span>\n    </DropdownMenuRadioItem>\n  )\n  return (\n    <DropdownMenu>\n      <DropdownMenuTrigger\n        render={\n          <Button type=\"button\" variant=\"ghost\" size=\"sm\" className={cn('rounded-full text-ink-soft', className)} aria-label={`${label}: ${current.label}`}>\n            {current.label}\n            <Icon name=\"keyboard_arrow_down\" />\n          </Button>\n        }\n      />\n      <DropdownMenuContent align=\"end\" className=\"w-panel\">\n        {/* Base UI: a GroupLabel must live inside a Group or RadioGroup. */}\n        <DropdownMenuRadioGroup value={current.value} onValueChange={(v) => onValueChange(String(v))}>\n          {auto ? row(auto) : null}\n          {auto && models.length ? <DropdownMenuSeparator /> : null}\n          {auto && models.length ? <DropdownMenuLabel>Choose</DropdownMenuLabel> : null}\n          {models.map(row)}\n        </DropdownMenuRadioGroup>\n      </DropdownMenuContent>\n    </DropdownMenu>\n  )\n}\n",
      "type": "registry:ui",
      "target": "components/ui/model-picker.tsx"
    }
  ],
  "docs": "Lets people choose which AI model answers — a quiet name-and-chevron trigger in the composer that opens a list with Auto first, a line on what each model is good for, and a check on the current one. Do: Give every model a one-line description of what it is good for (\"Fast answers, fewer credits\"). Don't: List bare model names — people cannot choose between names they do not know. Do: Offer Auto first so people who do not care never have to choose. Don't: Make people pick a model before their first message. Use select when the choice is an ordinary form setting, not an AI model. Use radio-group when the model is chosen once on a settings page; show the same options as radios.",
  "type": "registry:ui"
}