{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "title": "Select",
  "description": "Native-feeling select menu built on Base UI Select.",
  "dependencies": [
    "@base-ui/react@^1.8.0",
    "lucide-react@^1.48.0"
  ],
  "files": [
    {
      "path": "registry/rapid/ui/select/select.tsx",
      "content": "'use client'\n\nimport { Select as SelectPrimitive } from '@base-ui/react/select'\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'\nimport * as React from 'react'\nimport { cn } from '@/lib/utils'\n\ntype SelectReadOnlyContextValue = {\n\treadOnly: boolean\n\tsetTriggerReadOnly: (readOnly: boolean) => void\n}\n\nconst SelectReadOnlyContext = React.createContext<SelectReadOnlyContextValue>({\n\treadOnly: false,\n\tsetTriggerReadOnly: () => {},\n})\n\n/**\n * `readOnly` shows the value but keeps the list closed (pointer, keyboard and label clicks) and blocks changes.\n * Unlike `disabled`, the trigger stays focusable. It can be set here or on `SelectTrigger`.\n */\nfunction Select<Value, Multiple extends boolean | undefined = false>({\n\treadOnly: readOnlyProp = false,\n\tonOpenChange,\n\t...props\n}: SelectPrimitive.Root.Props<Value, Multiple>) {\n\tconst [triggerReadOnly, setTriggerReadOnly] = React.useState(false)\n\tconst readOnly = readOnlyProp || triggerReadOnly\n\tconst contextValue = React.useMemo(() => ({ readOnly, setTriggerReadOnly }), [readOnly])\n\n\treturn (\n\t\t<SelectReadOnlyContext.Provider value={contextValue}>\n\t\t\t<SelectPrimitive.Root<Value, Multiple>\n\t\t\t\treadOnly={readOnly}\n\t\t\t\tonOpenChange={(open, eventDetails) => {\n\t\t\t\t\t// While read-only, keep the list closed however it is asked to open\n\t\t\t\t\tif (readOnly && open) {\n\t\t\t\t\t\teventDetails.cancel()\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t\tonOpenChange?.(open, eventDetails)\n\t\t\t\t}}\n\t\t\t\t{...props}\n\t\t\t/>\n\t\t</SelectReadOnlyContext.Provider>\n\t)\n}\n\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\n\treturn <SelectPrimitive.Group data-slot=\"select-group\" className={cn('scroll-my-1 p-1', className)} {...props} />\n}\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n\treturn <SelectPrimitive.Value data-slot=\"select-value\" className={cn('flex flex-1 text-left', className)} {...props} />\n}\n\nfunction SelectTrigger({\n\tclassName,\n\tsize = 'default',\n\treadOnly: readOnlyProp,\n\tchildren,\n\t...props\n}: SelectPrimitive.Trigger.Props & {\n\tsize?: 'sm' | 'default'\n\t/** Shows the value but prevents opening the list. Unlike `disabled`, the trigger stays focusable. */\n\treadOnly?: boolean\n}) {\n\tconst { readOnly: rootReadOnly, setTriggerReadOnly } = React.useContext(SelectReadOnlyContext)\n\tconst readOnly = readOnlyProp || rootReadOnly\n\n\tReact.useLayoutEffect(() => {\n\t\tsetTriggerReadOnly(!!readOnlyProp)\n\t\treturn () => setTriggerReadOnly(false)\n\t}, [readOnlyProp, setTriggerReadOnly])\n\n\treturn (\n\t\t<SelectPrimitive.Trigger\n\t\t\tdata-slot=\"select-trigger\"\n\t\t\tdata-size={size}\n\t\t\tdata-read-only={readOnly || undefined}\n\t\t\t// Base UI's trigger is a combobox, which allows aria-readonly\n\t\t\taria-readonly={readOnly || undefined}\n\t\t\tclassName={cn(\n\t\t\t\t\"flex w-full items-center justify-between gap-1.5 rounded-lg border border-input bg-background py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none hover:border-primary/90 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-read-only:cursor-default data-read-only:border-dashed data-read-only:border-input data-read-only:bg-muted/50 data-read-only:text-foreground data-read-only:hover:border-input data-read-only:hover:bg-muted/50 data-[size=default]:h-10 data-[size=sm]:h-8 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t\t<SelectPrimitive.Icon render={<ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />} />\n\t\t</SelectPrimitive.Trigger>\n\t)\n}\n\nfunction SelectContent({\n\tclassName,\n\tchildren,\n\tside = 'bottom',\n\tsideOffset = 4,\n\talign = 'center',\n\talignOffset = 0,\n\talignItemWithTrigger = true,\n\t...props\n}: SelectPrimitive.Popup.Props &\n\tPick<SelectPrimitive.Positioner.Props, 'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'>) {\n\treturn (\n\t\t<SelectPrimitive.Portal>\n\t\t\t<SelectPrimitive.Positioner\n\t\t\t\tside={side}\n\t\t\t\tsideOffset={sideOffset}\n\t\t\t\talign={align}\n\t\t\t\talignOffset={alignOffset}\n\t\t\t\talignItemWithTrigger={alignItemWithTrigger}\n\t\t\t\tclassName=\"isolate z-50\"\n\t\t\t>\n\t\t\t\t<SelectPrimitive.Popup\n\t\t\t\t\tdata-slot=\"select-content\"\n\t\t\t\t\tdata-align-trigger={alignItemWithTrigger}\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-border duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\t{...props}\n\t\t\t\t>\n\t\t\t\t\t<SelectScrollUpButton />\n\t\t\t\t\t<SelectPrimitive.List>{children}</SelectPrimitive.List>\n\t\t\t\t\t<SelectScrollDownButton />\n\t\t\t\t</SelectPrimitive.Popup>\n\t\t\t</SelectPrimitive.Positioner>\n\t\t</SelectPrimitive.Portal>\n\t)\n}\n\nfunction SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {\n\treturn (\n\t\t<SelectPrimitive.GroupLabel data-slot=\"select-label\" className={cn('px-1.5 py-1 text-xs', className)} {...props} />\n\t)\n}\n\nfunction SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {\n\treturn (\n\t\t<SelectPrimitive.Item\n\t\t\tdata-slot=\"select-item\"\n\t\t\tclassName={cn(\n\t\t\t\t\"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\n\t\t\t\t{children}\n\t\t\t</SelectPrimitive.ItemText>\n\t\t\t<SelectPrimitive.ItemIndicator\n\t\t\t\trender={<span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />}\n\t\t\t>\n\t\t\t\t<CheckIcon className=\"pointer-events-none\" />\n\t\t\t</SelectPrimitive.ItemIndicator>\n\t\t</SelectPrimitive.Item>\n\t)\n}\n\nfunction SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {\n\treturn (\n\t\t<SelectPrimitive.Separator\n\t\t\tdata-slot=\"select-separator\"\n\t\t\tclassName={cn('pointer-events-none -mx-1 my-1 h-px bg-muted', className)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\n\nfunction SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\n\treturn (\n\t\t<SelectPrimitive.ScrollUpArrow\n\t\t\tdata-slot=\"select-scroll-up-button\"\n\t\t\tclassName={cn(\n\t\t\t\t\"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ChevronUpIcon aria-hidden=\"true\" />\n\t\t</SelectPrimitive.ScrollUpArrow>\n\t)\n}\n\nfunction SelectScrollDownButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\n\treturn (\n\t\t<SelectPrimitive.ScrollDownArrow\n\t\t\tdata-slot=\"select-scroll-down-button\"\n\t\t\tclassName={cn(\n\t\t\t\t\"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t<ChevronDownIcon aria-hidden=\"true\" />\n\t\t</SelectPrimitive.ScrollDownArrow>\n\t)\n}\n\nexport {\n\tSelect,\n\tSelectContent,\n\tSelectGroup,\n\tSelectItem,\n\tSelectLabel,\n\tSelectScrollDownButton,\n\tSelectScrollUpButton,\n\tSelectSeparator,\n\tSelectTrigger,\n\tSelectValue,\n}\n",
      "type": "registry:ui",
      "target": "components/ui/select.tsx"
    }
  ],
  "type": "registry:ui"
}