{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "title": "Select",
  "description": "A select component.",
  "dependencies": [
    "class-variance-authority",
    "@hugeicons/react",
    "@hugeicons/core-free-icons"
  ],
  "registryDependencies": [
    "@cubby-ui/scroll-area",
    "@cubby-ui/popup-search",
    "@cubby-ui/elevated"
  ],
  "files": [
    {
      "path": "registry/default/select/select.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport { Select as BaseSelect } from \"@base-ui/react/select\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport {\n  CheckIcon,\n  ChevronDownIcon,\n  ChevronUpIcon,\n  UnfoldMoreIcon,\n} from \"@hugeicons/core-free-icons\";\n\nimport { cn } from \"@/lib/utils\";\nimport { POPUP_ITEM } from \"@/registry/default/lib/popup-search\";\nimport {\n  elevatedSurface,\n  type SurfaceLevel,\n} from \"@/registry/default/lib/elevated\";\nimport {\n  ScrollArea,\n  type ScrollAreaProps,\n} from \"@/registry/default/scroll-area/scroll-area\";\n\nconst Select = BaseSelect.Root;\n\nfunction SelectGroup({ ...props }: BaseSelect.Group.Props) {\n  return <BaseSelect.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectBackdrop({ ...props }: BaseSelect.Backdrop.Props) {\n  return <BaseSelect.Backdrop data-slot=\"select-backdrop\" {...props} />;\n}\n\nfunction SelectPortal({ ...props }: BaseSelect.Portal.Props) {\n  return <BaseSelect.Portal data-slot=\"select-portal\" {...props} />;\n}\n\nfunction SelectValue({ className, ...props }: BaseSelect.Value.Props) {\n  return (\n    <BaseSelect.Value\n      data-slot=\"select-value\"\n      className={className}\n      {...props}\n    />\n  );\n}\n\nconst selectTriggerVariants = cva(\n  [\n    // Layout — w-fit by default since selects size to their value, not full-width\n    \"group/select-trigger relative inline-flex w-fit items-center justify-between gap-2.5 rounded-lg border bg-clip-padding\",\n    // Focus ring\n    \"focus-visible:outline-ring/50 ease-out-expo outline-0 outline-offset-0 outline-transparent transition-[outline-width,outline-offset,outline-color] duration-100 outline-solid focus-visible:outline-2 focus-visible:outline-offset-2\",\n    // Invalid state\n    \"aria-invalid:outline-destructive/50 aria-invalid:outline-2 aria-invalid:outline-offset-2 aria-invalid:outline-solid\",\n    // Text + placeholder + icon\n    \"text-base font-normal whitespace-nowrap sm:not-pointer-coarse:text-sm\",\n    \"data-placeholder:text-muted-foreground\",\n    \"[&_svg:not([class*='text-'])]:text-muted-foreground\",\n    \"*:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 *:data-[slot=select-value]:overflow-hidden\",\n    \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n    // Disabled\n    \"data-disabled:pointer-events-none data-disabled:opacity-60\",\n    // Interaction\n    \"cursor-pointer select-none\",\n  ],\n  {\n    variants: {\n      variant: {\n        // Opaque bg for page-level or non-elevated substrates. --outline-hover\n        // is a deliberate -5% darken of --card/--input for a sharp hover delta.\n        default:\n          \"bg-input hover:bg-(--outline-hover) data-popup-open:bg-(--outline-hover)\",\n        // Translucent overlay for Cards, Dialogs, etc. --surface-hover (alpha\n        // overlay) preserves translucency on any substrate depth.\n        elevated:\n          \"bg-input-elevated hover:bg-surface-hover data-popup-open:bg-surface-hover\",\n        // Chromeless — mirrors the button's ghost variant for use in toolbars\n        // and inline next to ghost buttons. Chevron follows the text on hover.\n        ghost:\n          \"border-transparent bg-transparent text-muted-foreground hover:bg-surface-hover hover:text-foreground data-popup-open:bg-surface-hover data-popup-open:text-foreground group-hover/select-trigger:[&_svg:not([class*='text-'])]:text-foreground\",\n      },\n      size: {\n        default: \"h-10 px-3.5 pr-2.5 py-2 sm:not-pointer-coarse:h-9\",\n        // Compact trigger. Note: tighter than the Button sm size (px-3), so\n        // ghost triggers in toolbars pair best with icon-size ghost buttons,\n        // which carry no horizontal padding.\n        sm: \"h-9 px-3 pr-2 py-1.5 sm:not-pointer-coarse:h-8\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  },\n);\n\ntype SelectTriggerProps = BaseSelect.Trigger.Props &\n  VariantProps<typeof selectTriggerVariants> & {\n    hideChevronRotation?: boolean;\n  };\n\nfunction SelectTrigger({\n  className,\n  children,\n  size,\n  variant,\n  hideChevronRotation = false,\n  ...props\n}: SelectTriggerProps) {\n  return (\n    <BaseSelect.Trigger\n      data-slot=\"select-trigger\"\n      className={cn(selectTriggerVariants({ size, variant }), className)}\n      {...props}\n    >\n      {children}\n      <BaseSelect.Icon>\n        <HugeiconsIcon strokeWidth={2} icon={UnfoldMoreIcon} />\n      </BaseSelect.Icon>\n    </BaseSelect.Trigger>\n  );\n}\n\ninterface SelectContentProps\n  extends\n    Omit<BaseSelect.Positioner.Props, \"render\">,\n    Pick<\n      ScrollAreaProps,\n      | \"fadeEdges\"\n      | \"scrollbarGutter\"\n      | \"persistScrollbar\"\n      | \"hideScrollbar\"\n      | \"nativeScroll\"\n    > {\n  className?: string;\n  size?: \"default\" | \"sm\";\n  /** Surface elevation level for the popup bg (1-8). Bump when nesting inside a Dialog or other elevated container. Defaults to 3. */\n  level?: SurfaceLevel;\n  /** Shadow weight (1-8). Pinned to 3 by default so the dropdown reads the same regardless of nesting depth. */\n  shadowLevel?: SurfaceLevel;\n}\n\nfunction SelectContent({\n  className,\n  sideOffset = 4,\n  alignItemWithTrigger = false,\n  nativeScroll = false,\n  fadeEdges = true,\n  scrollbarGutter = false,\n  persistScrollbar,\n  hideScrollbar,\n  size,\n  level = 3,\n  shadowLevel = 3,\n  children,\n  ...props\n}: SelectContentProps) {\n  return (\n    <SelectPortal>\n      <SelectBackdrop />\n      <BaseSelect.Positioner\n        data-slot=\"select-positioner\"\n        sideOffset={sideOffset}\n        alignItemWithTrigger={alignItemWithTrigger}\n        className=\"z-50 select-none\"\n        {...props}\n      >\n        <BaseSelect.Popup\n          data-slot=\"select-content\"\n          data-size={size}\n          data-level={level}\n          className={cn(\n            // Combobox-style popup\n            \"text-popover-foreground relative flex flex-col overflow-clip rounded-xl\",\n            // Surface elevation — bg tracks `level`, shadow weight tracks `shadowLevel` (defaults to `level`)\n            elevatedSurface(level, shadowLevel),\n            // Size constraints\n            \"max-w-(--available-width)\",\n            \"min-w-(--anchor-width)\",\n            // when data side does not equal none\n            \"not-data-[side=none]:max-h-(--available-height)\",\n            // Animation (disabled for alignItemWithTrigger via data-[side=none] to prevent Firefox jiggle)\n            \"ease-out-expo origin-(--transform-origin) transition-[transform,scale,opacity] duration-100 data-[side=none]:duration-50\",\n            \"data-ending-style:scale-97 data-ending-style:opacity-0 data-starting-style:scale-97 data-starting-style:opacity-0\",\n          )}\n        >\n          {alignItemWithTrigger && (\n            <BaseSelect.ScrollUpArrow\n              data-slot=\"select-scroll-up-arrow\"\n              className=\"top-0 z-1 flex w-full cursor-default items-center justify-center rounded-t-xl bg-linear-to-b from-(--popup-surface,var(--popover)) from-50% to-transparent py-0.5\"\n            >\n              <HugeiconsIcon\n                className=\"size-4\"\n                strokeWidth={2}\n                icon={ChevronUpIcon}\n              />\n            </BaseSelect.ScrollUpArrow>\n          )}\n          <ScrollArea\n            fadeEdges={fadeEdges}\n            scrollbarGutter={scrollbarGutter}\n            persistScrollbar={persistScrollbar}\n            hideScrollbar={hideScrollbar}\n            nativeScroll={nativeScroll}\n            className={cn(\"max-h-80 in-data-[side=none]:max-h-full\", className)}\n            // With alignItemWithTrigger (data-side=\"none\") Base UI makes the\n            // List the scroller via an inline `max-height: 100%`, which only\n            // resolves against a definite parent height — pin the content\n            // wrapper to the viewport so the List clips and scrolls itself.\n            // Withheld under nativeScroll, which has no content wrapper to pin\n            // and warns about the prop it cannot honour.\n            contentClassName={\n              nativeScroll ? undefined : \"in-data-[side=none]:h-full\"\n            }\n          >\n            <BaseSelect.List\n              data-slot=\"select-list\"\n              className={cn(\"rounded-xl\")}\n            >\n              {children}\n            </BaseSelect.List>\n          </ScrollArea>\n          {alignItemWithTrigger && (\n            <BaseSelect.ScrollDownArrow\n              data-slot=\"select-scroll-down-arrow\"\n              className=\"bottom-0 z-1 flex w-full cursor-default items-center justify-center rounded-b-xl bg-linear-to-t from-(--popup-surface,var(--popover)) from-50% to-transparent py-0.5\"\n            >\n              <HugeiconsIcon\n                className=\"size-4\"\n                strokeWidth={2}\n                icon={ChevronDownIcon}\n              />\n            </BaseSelect.ScrollDownArrow>\n          )}\n        </BaseSelect.Popup>\n      </BaseSelect.Positioner>\n    </SelectPortal>\n  );\n}\n\nfunction SelectItem({ className, children, ...props }: BaseSelect.Item.Props) {\n  return (\n    <BaseSelect.Item\n      data-slot=\"select-item\"\n      className={cn(\n        // Combobox-style item with grid layout\n        POPUP_ITEM,\n        \"relative grid cursor-default grid-cols-[1fr_1rem] items-center gap-2 outline-none select-none in-data-[side=none]:min-w-[calc(var(--anchor-width))]\",\n        // Over the trigger (alignItemWithTrigger), rows take its height, text\n        // size and inset plus 1px, so the popup covers the trigger's edge.\n        \"in-data-[side=none]:min-h-(--anchor-height) in-data-[side=none]:px-3 in-data-[side=none]:py-0 in-data-[side=none]:pointer-coarse:py-0 [[data-side=none]_[data-size=sm]_&]:px-2.5\",\n        \"in-data-[side=none]:text-base in-data-[side=none]:sm:not-pointer-coarse:text-sm\",\n        // Spacing from list edges\n        \"mx-1 first:mt-1 last:mb-1\",\n        // Hover and highlight states — uses --surface-hover overlay so the\n        // delta is the same regardless of the popup's surface level.\n        \"data-highlighted:text-accent-foreground data-highlighted:bg-surface-hover\",\n        // Icon and text styling\n        \"[&_svg:not([class*='text-'])]:text-muted-foreground\",\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        // Disabled state\n        \"data-disabled:pointer-events-none data-disabled:opacity-60\",\n        className,\n      )}\n      {...props}\n    >\n      <BaseSelect.ItemText className=\"break-all\">\n        {children}\n      </BaseSelect.ItemText>\n      <BaseSelect.ItemIndicator>\n        <HugeiconsIcon strokeWidth={2} icon={CheckIcon} />\n      </BaseSelect.ItemIndicator>\n    </BaseSelect.Item>\n  );\n}\n\nfunction SelectGroupLabel({\n  className,\n  ...props\n}: BaseSelect.GroupLabel.Props) {\n  return (\n    <BaseSelect.GroupLabel\n      data-slot=\"select-group-label\"\n      className={cn(\n        \"text-muted-foreground bg-(--popup-surface,var(--popover)) px-3.5 py-1.5 pt-2.5 text-xs font-semibold\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction SelectSeparator({ className, ...props }: BaseSelect.Separator.Props) {\n  return (\n    <BaseSelect.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"bg-border mx-1 my-1 h-px min-h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction SelectLabel({ className, ...props }: BaseSelect.Label.Props) {\n  return (\n    <BaseSelect.Label\n      data-slot=\"select-label\"\n      className={cn(\n        \"text-foreground text-sm leading-5 font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-60 peer-disabled:cursor-not-allowed peer-disabled:opacity-60\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction SelectList({ className, ...props }: BaseSelect.List.Props) {\n  return (\n    <BaseSelect.List\n      data-slot=\"select-list\"\n      className={cn(\"\", className)}\n      {...props}\n    />\n  );\n}\n\nexport {\n  Select,\n  SelectTrigger,\n  selectTriggerVariants,\n  SelectContent,\n  SelectItem,\n  SelectValue,\n  SelectGroup,\n  SelectGroupLabel,\n  SelectSeparator,\n  SelectBackdrop,\n  SelectLabel,\n  SelectList,\n};\n",
      "type": "registry:ui",
      "target": "components/ui/cubby-ui/select.tsx"
    }
  ],
  "type": "registry:ui"
}