Files
2025-10-16 21:45:52 -07:00

17 lines
2.8 KiB
JSON

{
"name": "combobox",
"description": "Autocomplete combobox with search",
"dependencies": [
"@radix-ui/react-popover"
],
"registryDependencies": [
"command"
],
"files": [
{
"name": "combobox.tsx",
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check, ChevronsUpDown } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/registry/default/ui/button\"\nimport {\n Command,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from \"@/registry/default/ui/command\"\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"@/registry/default/ui/popover\"\n\nexport interface ComboboxOption {\n value: string\n label: string\n}\n\nexport interface ComboboxProps {\n options: ComboboxOption[]\n value?: string\n onChange?: (value: string) => void\n placeholder?: string\n emptyText?: string\n}\n\nexport function Combobox({\n options,\n value,\n onChange,\n placeholder = \"Select option...\",\n emptyText = \"No option found.\",\n}: ComboboxProps) {\n const [open, setOpen] = React.useState(false)\n const [searchValue, setSearchValue] = React.useState(\"\")\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button\n variant=\"outline\"\n role=\"combobox\"\n aria-expanded={open}\n className=\"w-full justify-between\"\n >\n {value\n ? options.find((option) => option.value === value)?.label\n : placeholder}\n <ChevronsUpDown className=\"ml-2 h-4 w-4 shrink-0 opacity-50\" />\n </Button>\n </PopoverTrigger>\n <PopoverContent className=\"w-full p-0\">\n <Command>\n <CommandInput\n placeholder=\"Search...\"\n value={searchValue}\n onValueChange={setSearchValue}\n />\n <CommandList>\n <CommandEmpty>{emptyText}</CommandEmpty>\n <CommandGroup>\n {options.map((option) => (\n <CommandItem\n key={option.value}\n value={option.value}\n onSelect={(currentValue) => {\n onChange?.(currentValue === value ? \"\" : currentValue)\n setOpen(false)\n }}\n >\n <Check\n className={cn(\n \"mr-2 h-4 w-4\",\n value === option.value ? \"opacity-100\" : \"opacity-0\"\n )}\n />\n {option.label}\n </CommandItem>\n ))}\n </CommandGroup>\n </CommandList>\n </Command>\n </PopoverContent>\n </Popover>\n )\n}\n"
}
],
"type": "components:ui"
}