A powerful input component featuring autocomplete and a built-in command palette for instant suggestions.
lucide-react1'use client'
2
3import * as React from 'react'
4
5import { Combobox } from '@/components/ui/combobox'
6
7const frameworks = [
8 { value: 'next', label: 'Next.js' },
9 { value: 'sveltekit', label: 'SvelteKit' },
10 { value: 'nuxt', label: 'Nuxt.js' },
11 { value: 'remix', label: 'Remix' },
12 { value: 'astro', label: 'Astro' },
13]
14
15export function ComboboxPopoverExample() {
16 return <Combobox options={frameworks} placeholder="Select framework..." />
17}
18Install the following dependencies:
1'use client'
2
3import * as React from 'react'
4
5import { Combobox } from '@/components/ui/combobox'
6
7const statuses = [
8 { value: 'backlog', label: 'Backlog' },
9 { value: 'todo', label: 'Todo' },
10 { value: 'inprogress', label: 'In Progress' },
11 { value: 'done', label: 'Done' },
12 { value: 'canceled', label: 'Canceled' },
13]
14
15export function ComboboxDialogExample() {
16 return (
17 <Combobox
18 options={statuses}
19 placeholder="Select status..."
20 variant="dialog"
21 />
22 )
23}
241'use client'
2
3import * as React from 'react'
4
5import { Combobox } from '@/components/ui/combobox'
6
7const statuses = [
8 { value: 'backlog', label: 'Backlog' },
9 { value: 'todo', label: 'Todo' },
10 { value: 'inprogress', label: 'In Progress' },
11 { value: 'done', label: 'Done' },
12 { value: 'canceled', label: 'Canceled' },
13]
14
15export function ComboboxDrawerExample() {
16 const isDesktop = useMediaQuery('(min-width: 768px)')
17
18 return (
19 <Combobox
20 options={statuses}
21 placeholder="Select status..."
22 variant={isDesktop ? 'popover' : 'drawer'}
23 />
24 )
25}
26
27function useMediaQuery(query: string) {
28 const [matches, setMatches] = React.useState(false)
29
30 React.useEffect(() => {
31 const media = window.matchMedia(query)
32 const listener = () => setMatches(media.matches)
33 setMatches(media.matches)
34
35 media.addEventListener('change', listener)
36 return () => media.removeEventListener('change', listener)
37 }, [query])
38
39 return matches
40}
41Current project status
1'use client'
2
3import * as React from 'react'
4import { SlidersHorizontal } from 'lucide-react'
5
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 {
16 DropdownMenu,
17 DropdownMenuContent,
18 DropdownMenuGroup,
19 DropdownMenuItem,
20 DropdownMenuLabel,
21 DropdownMenuSeparator,
22 DropdownMenuSub,
23 DropdownMenuSubContent,
24 DropdownMenuSubTrigger,
25 DropdownMenuTrigger,
26} from '@/components/ui/dropdown-menu'
27
28const statuses = [
29 'Backlog',
30 'In Progress',
31 'Review',
32 'Completed',
33 'Blocked',
34 'On Hold',
35]
36
37export function ComboboxProjectStatus() {
38 const [status, setStatus] = React.useState('Backlog')
39 const [open, setOpen] = React.useState(false)
40
41 return (
42 <div className="border-border flex w-full min-w-[480px] flex-col gap-4 rounded-lg border bg-gray-100 px-4 py-2 sm:flex-row sm:items-center sm:justify-between">
43 <div className="flex items-center gap-2">
44 <span className="text-primary rounded-lg bg-gray-400 px-2 py-1 text-xs font-medium">
45 {status}
46 </span>
47 <p className="text-gray text-sm">Current project status</p>
48 </div>
49
50 <DropdownMenu open={open} onOpenChange={setOpen}>
51 <DropdownMenuTrigger asChild>
52 <Button variant="ghost" size="sm">
53 <SlidersHorizontal />
54 </Button>
55 </DropdownMenuTrigger>
56
57 <DropdownMenuContent align="end" className="w-[220px] p-0">
58 <DropdownMenuLabel>Project Actions</DropdownMenuLabel>
59 <DropdownMenuGroup>
60 <DropdownMenuItem>Assign team member</DropdownMenuItem>
61 <DropdownMenuItem>Set due date</DropdownMenuItem>
62 <DropdownMenuSeparator />
63
64 <DropdownMenuSub>
65 <DropdownMenuSubTrigger>
66 Change Status
67 </DropdownMenuSubTrigger>
68 <DropdownMenuSubContent className="p-0">
69 <Command>
70 <CommandInput
71 placeholder="Search status..."
72 autoFocus
73 className="h-9"
74 />
75 <CommandList>
76 <CommandEmpty>
77 No status found.
78 </CommandEmpty>
79 <CommandGroup>
80 {statuses.map((item) => (
81 <CommandItem
82 key={item}
83 value={item}
84 onSelect={() => {
85 setStatus(item)
86 setOpen(false)
87 }}
88 >
89 {item}
90 </CommandItem>
91 ))}
92 </CommandGroup>
93 </CommandList>
94 </Command>
95 </DropdownMenuSubContent>
96 </DropdownMenuSub>
97
98 <DropdownMenuSeparator />
99 <DropdownMenuItem className="text-red-600">
100 Remove Project
101 </DropdownMenuItem>
102 </DropdownMenuGroup>
103 </DropdownMenuContent>
104 </DropdownMenu>
105 </div>
106 )
107}
108| Prop | Type | Default |
|---|---|---|
| options | { value: string; label: string; }[] | [] |
| placeholder | string | "Select an option..." |
| emptyMessage | string | "No results found." |
| defaultValue | string | "" |
| onChange | (value: string) => void | - |
| variant | popover,dialog,drawer | popover |
| triggerClassName | string | "" |