{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "glass-combobox",
  "title": "Glass Combobox",
  "author": "Alex Chih (https://alexchih.com)",
  "description": "Searchable select composed from the command palette inside a popover.",
  "dependencies": [
    "cmdk",
    "lucide-react"
  ],
  "registryDependencies": [
    "https://washiveil.alexchih.com/r/theme.json",
    "https://washiveil.alexchih.com/r/glass-popover.json",
    "https://washiveil.alexchih.com/r/glass-command.json"
  ],
  "files": [
    {
      "path": "registry/washiveil/ui/glass-combobox.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { Check, ChevronsUpDown } from 'lucide-react'\n\nimport { cn } from '@/lib/utils'\nimport { GlassPopover, GlassPopoverContent, GlassPopoverTrigger } from './glass-popover'\nimport {\n  GlassCommand,\n  GlassCommandEmpty,\n  GlassCommandGroup,\n  GlassCommandInput,\n  GlassCommandItem,\n  GlassCommandList,\n} from './glass-command'\n\nexport interface GlassComboboxProps {\n  options: { value: string; label: string }[]\n  value?: string\n  onValueChange?: (value: string) => void\n  placeholder?: string\n  emptyText?: string\n  className?: string\n  /** Accessible name for the combobox trigger. Falls back to `placeholder`. */\n  ariaLabel?: string\n}\n\nfunction GlassCombobox({\n  options,\n  value: controlledValue,\n  onValueChange,\n  placeholder = 'Select...',\n  emptyText = 'No results found.',\n  className,\n  ariaLabel,\n}: GlassComboboxProps) {\n  const [open, setOpen] = React.useState(false)\n  const [internalValue, setInternalValue] = React.useState('')\n\n  const value = controlledValue !== undefined ? controlledValue : internalValue\n\n  const selectedLabel = options.find((opt) => opt.value === value)?.label\n\n  function handleSelect(currentValue: string) {\n    const newValue = currentValue === value ? '' : currentValue\n    if (controlledValue === undefined) {\n      setInternalValue(newValue)\n    }\n    onValueChange?.(newValue)\n    setOpen(false)\n  }\n\n  return (\n    <GlassPopover open={open} onOpenChange={setOpen}>\n      <GlassPopoverTrigger asChild>\n        <button\n          role=\"combobox\"\n          aria-expanded={open}\n          aria-label={ariaLabel ?? placeholder}\n          className={cn(\n            'flex h-10 w-full items-center justify-between rounded-xl border border-border bg-glass px-3.5 py-2.5 text-sm backdrop-blur-md transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50',\n            className,\n          )}\n        >\n          <span className={cn(!selectedLabel && 'text-muted-foreground')}>{selectedLabel ?? placeholder}</span>\n          <ChevronsUpDown className=\"size-4 shrink-0 text-faint\" />\n        </button>\n      </GlassPopoverTrigger>\n      <GlassPopoverContent className=\"w-(--radix-popover-trigger-width) p-0\">\n        <GlassCommand>\n          <GlassCommandInput placeholder={placeholder} />\n          <GlassCommandList>\n            <GlassCommandEmpty>{emptyText}</GlassCommandEmpty>\n            <GlassCommandGroup>\n              {options.map((option) => (\n                <GlassCommandItem key={option.value} value={option.value} onSelect={handleSelect}>\n                  <Check className={cn('size-4 shrink-0', value === option.value ? 'opacity-100' : 'opacity-0')} />\n                  {option.label}\n                </GlassCommandItem>\n              ))}\n            </GlassCommandGroup>\n          </GlassCommandList>\n        </GlassCommand>\n      </GlassPopoverContent>\n    </GlassPopover>\n  )\n}\n\nexport { GlassCombobox }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}