{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "type": "registry:ui",
  "title": "Select",
  "description": "Select built on Base UI with seam overlay-depth entrance.",
  "dependencies": [
    "@base-ui/react",
    "motion",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://seamui.dev/r/utils.json",
    "https://seamui.dev/r/motion.json",
    "https://seamui.dev/r/haptics.json"
  ],
  "files": [
    {
      "path": "registry/seam/ui/select.tsx",
      "content": "\"use client\"\n\nimport type * as React from \"react\"\nimport { Select as BaseSelect } from \"@base-ui/react/select\"\nimport { Check, ChevronDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { condense } from \"@/lib/motion\"\nimport { useHaptics } from \"@/lib/haptics\"\n\nfunction Select({\n  onValueChange,\n  ...props\n}: React.ComponentProps<typeof BaseSelect.Root>) {\n  // Committing a selection is a state change — fire the seam tick (§3b), the\n  // same feedback RadioGroup gives for the same pick-one semantic.\n  const { trigger } = useHaptics()\n  return (\n    <BaseSelect.Root\n      onValueChange={(\n        ...args: Parameters<NonNullable<typeof onValueChange>>\n      ) => {\n        trigger(\"tick\")\n        onValueChange?.(...args)\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction SelectValue(props: React.ComponentProps<typeof BaseSelect.Value>) {\n  return <BaseSelect.Value data-slot=\"select-value\" {...props} />\n}\n\nfunction SelectTrigger({\n  className,\n  children,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<typeof BaseSelect.Trigger> & {\n  /**\n   * default — recessed muted pill (inline-editable value in a toolbar well).\n   * ghost   — naked text + chevron for inline dropdowns.\n   */\n  variant?: \"default\" | \"ghost\"\n}) {\n  return (\n    <BaseSelect.Trigger\n      data-slot=\"select-trigger\"\n      className={cn(\n        \"flex h-10 items-center justify-between gap-2 rounded-md squircle text-sm outline-none\",\n        // default — a debossed entry well, styled to match Input/OTP/etc: a\n        // hairline border carving it into the surface (seamui design language).\n        variant === \"default\" &&\n          \"w-full border border-border/60 bg-muted shadow-well px-3.5 py-2 hover:bg-muted/80\",\n        variant === \"ghost\" &&\n          \"w-fit bg-transparent px-2 py-2 hover:text-foreground\",\n        // Focus/open lifts the border to the ring colour, like the other wells.\n        \"focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:border-ring\",\n        \"data-[popup-open]:ring-2 data-[popup-open]:ring-ring/50 data-[popup-open]:border-ring\",\n        \"data-[invalid]:border-destructive data-[invalid]:ring-2 data-[invalid]:ring-destructive/30\",\n        \"disabled:pointer-events-none disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <BaseSelect.Icon className=\"text-muted-foreground\">\n        <ChevronDown className=\"size-4\" />\n      </BaseSelect.Icon>\n    </BaseSelect.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  sideOffset = 6,\n  ...props\n}: React.ComponentProps<typeof BaseSelect.Popup> & { sideOffset?: number }) {\n  return (\n    <BaseSelect.Portal>\n      {/* alignItemWithTrigger={false}: drop the list *below* the trigger like a\n          combobox/dropdown, instead of Base UI's default native-style behavior\n          that overlays the selected item on top of the trigger. */}\n      <BaseSelect.Positioner\n        sideOffset={sideOffset}\n        align=\"start\"\n        alignItemWithTrigger={false}\n        className=\"z-50\"\n      >\n        <BaseSelect.Popup\n          data-slot=\"select-content\"\n          className={cn(\n            // A debossed tray (muted well) that floats up — the chosen option\n            // rises out of it as an embossed key (seam well/key language, §1),\n            // the same shape as the toggle group, just vertical.\n            \"bg-muted text-foreground z-50 max-h-[min(24rem,var(--available-height))] min-w-[var(--anchor-width)] overflow-y-auto rounded-lg squircle border border-border/60 p-1.5 shadow-overlay outline-none\",\n            condense.surface,\n            className\n          )}\n          {...props}\n        >\n          {children}\n        </BaseSelect.Popup>\n      </BaseSelect.Positioner>\n    </BaseSelect.Portal>\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof BaseSelect.Item>) {\n  return (\n    <BaseSelect.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"relative flex cursor-default select-none items-center gap-2 rounded-md squircle py-1.5 pl-2.5 pr-8 text-sm outline-none\",\n        // Transient keyboard/pointer cursor. On the near-white tray a fill alone\n        // is <1.2:1, so pair it with a solid hairline that clears WCAG 1.4.11\n        // non-text contrast — a light warm-gray in light (3.4:1, kept soft) and\n        // muted-foreground in dark (6.2:1) — so the active state is perceivable\n        // by colour, not just the shadow.\n        \"data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground data-[highlighted]:ring-1 data-[highlighted]:ring-inset data-[highlighted]:ring-ring-hairline\",\n        // The chosen value is an embossed key raised out of the tray. bg-secondary\n        // (not card) reads raised in BOTH themes — white on the light well, lighter\n        // than the well in dark — and the same hairline delineates it at 3:1. The\n        // compound keeps the key embossed even when it's the cursor (on open Base\n        // UI highlights the selected item).\n        \"data-[selected]:bg-secondary data-[selected]:text-secondary-foreground data-[selected]:shadow-resting data-[selected]:font-medium data-[selected]:ring-1 data-[selected]:ring-inset data-[selected]:ring-ring-hairline\",\n        \"data-[selected]:data-[highlighted]:bg-secondary data-[selected]:data-[highlighted]:text-secondary-foreground\",\n        \"data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n        className\n      )}\n      {...props}\n    >\n      <BaseSelect.ItemText>{children}</BaseSelect.ItemText>\n      <BaseSelect.ItemIndicator className=\"absolute right-2 flex items-center\">\n        <Check className=\"size-4\" />\n      </BaseSelect.ItemIndicator>\n    </BaseSelect.Item>\n  )\n}\n\nfunction SelectGroup(props: React.ComponentProps<typeof BaseSelect.Group>) {\n  return <BaseSelect.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseSelect.GroupLabel>) {\n  return (\n    <BaseSelect.GroupLabel\n      data-slot=\"select-label\"\n      className={cn(\n        \"px-2 py-1.5 text-xs font-medium text-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof BaseSelect.Separator>) {\n  return (\n    <BaseSelect.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border -mx-1 my-1 h-px\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Select,\n  SelectTrigger,\n  SelectValue,\n  SelectContent,\n  SelectItem,\n  SelectGroup,\n  SelectLabel,\n  SelectSeparator,\n}\n",
      "type": "registry:ui",
      "target": "components/ui/select.tsx"
    }
  ]
}