Combobox
glasswave/comboboxFreeComponent
Searchable select pattern using Popover + Command.
Live preview
live · rendered by the registry
Rendered by glasswave on their own page — this is the component running, not a screenshot of it.Install it
npx shadcn@latest add https://glasswave.denizisik.com/r/combobox.jsonSource
1"use client";23import { Check, ChevronsUpDown } from "lucide-react";4import { useState } from "react";5import { cn } from "@/lib/utils";6import { Button } from "@/components/ui/button";7import {8 Command,9 CommandEmpty,10 CommandGroup,11 CommandInput,12 CommandItem,13 CommandList,14} from "@/components/ui/command";15import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";1617export type ComboboxOption = {18 value: string;19 label: string;20 keywords?: string[];21};2223export interface ComboboxProps {24 options: ComboboxOption[];25 value?: string | null;26 onValueChange?: (value: string | null) => void;27 placeholder?: string;28 searchPlaceholder?: string;29 emptyText?: string;30 className?: string;31 disabled?: boolean;32}3334export function Combobox({35 options,36 value,37 onValueChange,38 placeholder = "Select…",39 searchPlaceholder = "Search…",40 emptyText = "No results found.",41 className,42 disabled,43}: ComboboxProps) {44 const [open, setOpen] = useState(false);45 const selected = options.find((o) => o.value === value);4647 return (48 <Popover open={open} onOpenChange={setOpen}>49 <PopoverTrigger asChild>50 <Button51 type="button"52 variant="glass"53 role="combobox"54 aria-expanded={open}55 disabled={disabled}56 className={cn("min-w-[220px] justify-between font-normal", className)}57 >58 <span className="truncate">{selected?.label ?? placeholder}</span>59 <ChevronsUpDown className="size-4 shrink-0 opacity-50" aria-hidden />60 </Button>61 </PopoverTrigger>62 <PopoverContent63 className="w-[var(--radix-popover-trigger-width)] min-w-[220px] p-0"64 align="start"65 >66 <Command>67 <CommandInput placeholder={searchPlaceholder} />68 <CommandList>69 <CommandEmpty>{emptyText}</CommandEmpty>70 <CommandGroup>71 {options.map((opt) => (72 <CommandItem73 key={opt.value}74 value={opt.label}75 keywords={opt.keywords ?? [opt.label, opt.value]}76 onSelect={() => {77 onValueChange?.(opt.value === value ? null : opt.value);78 setOpen(false);79 }}80 >81 <Check82 className={cn(83 "size-4 shrink-0",84 value === opt.value ? "opacity-100" : "opacity-0",85 )}86// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from glasswave
All 60 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | glasswave | Components | Free | 2 deps | |
| Alertalert | glasswave | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | glasswave | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | glasswave | Components | Free | 1 dep | |
| Avataravatar | glasswave | Components | Free | 1 dep | |
| Badgebadge | glasswave | Components | Free | 1 dep | |
| Breadcrumbbreadcrumb | glasswave | Components | Free | 2 deps | |
| Buttonbutton | glasswave | Components | Free | 2 deps |
