- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Code Block
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Dialog
- Direction
- Drawer
- Dropdown Menu
- Empty
- Field
- Form
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Pagination
- Popover
- Progress
- Questionnaire
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toast
- Toggle
- Toggle Group
- Tooltip
- Trace
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxDemo() {
return (
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Installation#
pnpm dlx shadcn@latest add https://ui.ikramhasan.com/r/combobox.json
Usage#
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ExampleCombobox() {
return (
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Object items#
Use itemToStringValue when your items are objects.
import * as React from "react"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
type Framework = {
label: string
value: string
}
const frameworks: Framework[] = [
{ label: "Next.js", value: "next" },
{ label: "SvelteKit", value: "sveltekit" },
{ label: "Nuxt", value: "nuxt" },
]
export function ExampleComboboxCustomItems() {
return (
<Combobox
items={frameworks}
itemToStringValue={(framework) => framework.label}
>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(framework) => (
<ComboboxItem key={framework.value} value={framework}>
{framework.label}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Multiple selection#
Use multiple with chips for multi-select behavior.
import * as React from "react"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxValue,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ExampleComboboxMultiple() {
const [value, setValue] = React.useState<string[]>([])
return (
<Combobox
items={frameworks}
multiple
value={value}
onValueChange={setValue}
>
<ComboboxChips>
<ComboboxValue>
{value.map((item) => (
<ComboboxChip key={item}>{item}</ComboboxChip>
))}
</ComboboxValue>
<ComboboxChipsInput placeholder="Add framework" />
</ComboboxChips>
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Composition#
Simple#
A single-line input and a flat list (see Basic).
Combobox
├── ComboboxInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxItem
└── ComboboxItemWith chips#
Multi-select with multiple, chips, and a chips input (see Multiple).
Combobox
├── ComboboxChips
│ ├── ComboboxValue
│ │ └── ComboboxChip
│ └── ComboboxChipsInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxItem
└── ComboboxItemWith groups and collection#
Nested items per group using ComboboxCollection inside each ComboboxGroup, with a separator between groups (see Groups).
Combobox
├── ComboboxInput
└── ComboboxContent
├── ComboboxEmpty
└── ComboboxList
├── ComboboxGroup
│ ├── ComboboxLabel
│ └── ComboboxCollection
│ ├── ComboboxItem
│ └── ComboboxItem
├── ComboboxSeparator
└── ComboboxGroup
├── ComboboxLabel
└── ComboboxCollection
├── ComboboxItem
└── ComboboxItemExamples#
Basic#
A combobox with a list of frameworks.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxBasic() {
return (
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Multiple#
Multiple selection with multiple and ComboboxChips.
"use client"
import * as React from "react"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxItem,
ComboboxList,
ComboboxValue,
useComboboxAnchor,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxMultiple() {
const anchor = useComboboxAnchor()
return (
<Combobox
multiple
autoHighlight
items={frameworks}
defaultValue={[frameworks[0], frameworks[1]]}
>
<ComboboxChips ref={anchor} className="w-full max-w-xs">
<ComboboxValue>
{(values) => (
<React.Fragment>
{values.map((value: string) => (
<ComboboxChip key={value}>{value}</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Add framework" />
</React.Fragment>
)}
</ComboboxValue>
</ComboboxChips>
<ComboboxContent anchor={anchor}>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Multiple without remove buttons#
Set showRemove={false} on ComboboxChip to hide its remove button. Backspace still removes the last chip.
"use client"
import * as React from "react"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxItem,
ComboboxList,
ComboboxValue,
useComboboxAnchor,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxMultipleNoRemove() {
const anchor = useComboboxAnchor()
return (
<Combobox
multiple
autoHighlight
items={frameworks}
defaultValue={[frameworks[0], frameworks[1]]}
>
<ComboboxChips ref={anchor} className="w-full max-w-xs">
<ComboboxValue>
{(values) => (
<React.Fragment>
{values.map((value: string) => (
<ComboboxChip key={value} showRemove={false}>
{value}
</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Add framework" />
</React.Fragment>
)}
</ComboboxValue>
</ComboboxChips>
<ComboboxContent anchor={anchor}>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Clear Button#
Use the showClear prop to show a clear button.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxClearDemo() {
return (
<Combobox items={frameworks} defaultValue={frameworks[0]}>
<ComboboxInput placeholder="Select a framework" showClear />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Groups#
Use ComboboxGroup and ComboboxSeparator to group items.
"use client"
import {
Combobox,
ComboboxCollection,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxLabel,
ComboboxList,
ComboboxSeparator,
} from "@/components/ui/combobox"
const timezones = [
{
value: "Americas",
items: [
"(GMT-5) New York",
"(GMT-6) Chicago",
"(GMT-7) Denver",
"(GMT-8) Los Angeles",
"(GMT-3) São Paulo",
],
},
{
value: "Europe",
items: [
"(GMT+0) London",
"(GMT+1) Paris",
"(GMT+1) Berlin",
"(GMT+2) Athens",
"(GMT+3) Istanbul",
],
},
{
value: "Asia/Pacific",
items: [
"(GMT+4) Dubai",
"(GMT+5:30) Mumbai",
"(GMT+6) Dhaka",
"(GMT+8) Singapore",
"(GMT+9) Tokyo",
"(GMT+10) Sydney",
],
},
]
export function ComboboxGroups() {
return (
<Combobox items={timezones}>
<ComboboxInput placeholder="Select a timezone" />
<ComboboxContent>
<ComboboxEmpty>No timezones found.</ComboboxEmpty>
<ComboboxList>
{(group) => (
<ComboboxGroup key={group.value} items={group.items}>
<ComboboxLabel>{group.value}</ComboboxLabel>
<ComboboxCollection>
{(item: string) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxCollection>
<ComboboxSeparator />
</ComboboxGroup>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Custom Items#
You can render a custom component inside ComboboxItem.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
import {
Item,
ItemContent,
ItemDescription,
ItemTitle,
} from "@/components/ui/item"
type Repository = {
name: string
description: string
}
const repositories: Repository[] = [
{ name: "web", description: "Marketing site and docs" },
{ name: "api", description: "Public REST and webhooks" },
{ name: "dashboard", description: "Customer dashboard" },
{ name: "mobile", description: "iOS and Android apps" },
{ name: "infra", description: "Terraform and CI" },
]
export function ComboboxCustom() {
return (
<Combobox
items={repositories}
itemToStringValue={(repository: Repository) => repository.name}
>
<ComboboxInput placeholder="Search repositories..." />
<ComboboxContent>
<ComboboxEmpty>No repositories found.</ComboboxEmpty>
<ComboboxList>
{(repository: Repository) => (
<ComboboxItem key={repository.name} value={repository}>
<Item size="xs" className="p-0">
<ItemContent>
<ItemTitle className="whitespace-nowrap">
{repository.name}
</ItemTitle>
<ItemDescription>{repository.description}</ItemDescription>
</ItemContent>
</Item>
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Invalid#
Use the aria-invalid prop to mark the combobox invalid.
The framework your app is built with.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
import {
Field,
FieldDescription,
FieldError,
FieldLabel,
} from "@/components/ui/field"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxInvalid() {
return (
<Field data-invalid className="max-w-xs">
<FieldLabel htmlFor="combobox-framework-invalid">Framework</FieldLabel>
<Combobox items={frameworks}>
<ComboboxInput
id="combobox-framework-invalid"
placeholder="Select a framework"
aria-invalid
/>
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
<FieldDescription>The framework your app is built with.</FieldDescription>
<FieldError errors={[{ message: "Select a framework." }]} />
</Field>
)
}"use client"
import * as React from "react"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxItem,
ComboboxList,
ComboboxValue,
useComboboxAnchor,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxMultipleInvalid() {
const anchor = useComboboxAnchor()
return (
<Combobox
multiple
autoHighlight
items={frameworks}
defaultValue={[frameworks[0], frameworks[1]]}
>
<ComboboxChips ref={anchor} className="w-full max-w-xs">
<ComboboxValue>
{(values) => (
<React.Fragment>
{values.map((value: string) => (
<ComboboxChip key={value}>{value}</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Add framework" aria-invalid />
</React.Fragment>
)}
</ComboboxValue>
</ComboboxChips>
<ComboboxContent anchor={anchor}>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Disabled#
Use the disabled prop to disable the combobox.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxDisabled() {
return (
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" disabled />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}"use client"
import * as React from "react"
import {
Combobox,
ComboboxChip,
ComboboxChips,
ComboboxChipsInput,
ComboboxContent,
ComboboxEmpty,
ComboboxItem,
ComboboxList,
ComboboxValue,
useComboboxAnchor,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxMultipleDisabled() {
const anchor = useComboboxAnchor()
return (
<Combobox
multiple
autoHighlight
items={frameworks}
defaultValue={[frameworks[0], frameworks[1]]}
disabled
>
<ComboboxChips ref={anchor} className="w-full max-w-xs">
<ComboboxValue>
{(values) => (
<React.Fragment>
{values.map((value: string) => (
<ComboboxChip key={value}>{value}</ComboboxChip>
))}
<ComboboxChipsInput placeholder="Add framework" disabled />
</React.Fragment>
)}
</ComboboxValue>
</ComboboxChips>
<ComboboxContent anchor={anchor}>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Disabled Items#
Set disabled on a ComboboxItem to skip it during keyboard navigation.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
const unavailable = ["Nuxt.js", "Remix"]
export function ComboboxDisabledItems() {
return (
<Combobox items={frameworks}>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem
key={item}
value={item}
disabled={unavailable.includes(item)}
>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Auto Highlight#
Use the autoHighlight prop to highlight the first item as you filter.
"use client"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/combobox"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
export function ComboboxAutoHighlight() {
return (
<Combobox items={frameworks} autoHighlight>
<ComboboxInput placeholder="Select a framework" />
<ComboboxContent>
<ComboboxEmpty>No items found.</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Popup#
Trigger the combobox from a button with the render prop, and move the ComboboxInput inside the ComboboxContent.
"use client"
import { Button } from "@/components/ui/button"
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
ComboboxTrigger,
ComboboxValue,
} from "@/components/ui/combobox"
type Region = {
value: string
label: string
}
const regions: Region[] = [
{ value: "", label: "Select region" },
{ value: "us-east-1", label: "US East (N. Virginia)" },
{ value: "us-west-2", label: "US West (Oregon)" },
{ value: "eu-west-1", label: "Europe (Ireland)" },
{ value: "eu-central-1", label: "Europe (Frankfurt)" },
{ value: "ap-south-1", label: "Asia Pacific (Mumbai)" },
{ value: "ap-northeast-1", label: "Asia Pacific (Tokyo)" },
{ value: "sa-east-1", label: "South America (São Paulo)" },
]
export function ComboboxPopup() {
return (
<Combobox items={regions.slice(1)} defaultValue={regions[0]}>
<ComboboxTrigger
render={
<Button
variant="secondary"
className="w-64 justify-between font-normal"
/>
}
>
<ComboboxValue />
</ComboboxTrigger>
<ComboboxContent>
<ComboboxInput showTrigger={false} placeholder="Search" />
<ComboboxEmpty>No regions found.</ComboboxEmpty>
<ComboboxList>
{(region: Region) => (
<ComboboxItem key={region.value} value={region}>
{region.label}
</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}Input Group#
Add an addon by placing an InputGroupAddon inside the ComboboxInput.
"use client"
import { GlobeIcon } from "lucide-react"
import {
Combobox,
ComboboxCollection,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxLabel,
ComboboxList,
} from "@/components/ui/combobox"
import { InputGroupAddon } from "@/components/ui/input-group"
const timezones = [
{
value: "Americas",
items: [
"(GMT-5) New York",
"(GMT-6) Chicago",
"(GMT-7) Denver",
"(GMT-8) Los Angeles",
"(GMT-3) São Paulo",
],
},
{
value: "Europe",
items: [
"(GMT+0) London",
"(GMT+1) Paris",
"(GMT+1) Berlin",
"(GMT+2) Athens",
"(GMT+3) Istanbul",
],
},
{
value: "Asia/Pacific",
items: [
"(GMT+4) Dubai",
"(GMT+5:30) Mumbai",
"(GMT+6) Dhaka",
"(GMT+8) Singapore",
"(GMT+9) Tokyo",
"(GMT+10) Sydney",
],
},
]
export function ComboboxInputGroup() {
return (
<Combobox items={timezones}>
<ComboboxInput placeholder="Select a timezone">
<InputGroupAddon>
<GlobeIcon />
</InputGroupAddon>
</ComboboxInput>
<ComboboxContent className="w-60">
<ComboboxEmpty>No timezones found.</ComboboxEmpty>
<ComboboxList>
{(group) => (
<ComboboxGroup key={group.value} items={group.items}>
<ComboboxLabel>{group.value}</ComboboxLabel>
<ComboboxCollection>
{(item: string) => (
<ComboboxItem key={item} value={item}>
{item}
</ComboboxItem>
)}
</ComboboxCollection>
</ComboboxGroup>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
)
}API Reference#
ComboboxInput#
The field. It accepts all Base UI Combobox Input props.
| Prop | Type | Default |
|---|---|---|
showTrigger | boolean | true |
showClear | boolean | false |
disabled | boolean | false |
ComboboxContent#
The popup. It accepts all Base UI Combobox Popup props, plus these positioner props.
| Prop | Type | Default |
|---|---|---|
side | "top" | "right" | "bottom" | "left" | "bottom" |
sideOffset | number | 6 |
align | "start" | "center" | "end" | "start" |
alignOffset | number | 0 |
anchor | RefObject<HTMLElement> | - |
ComboboxChip#
A selected value in a ComboboxChips field. It accepts all Base UI Combobox Chip props.
| Prop | Type | Default |
|---|---|---|
showRemove | boolean | true |
useComboboxAnchor#
Returns a ref for ComboboxChips. Pass it to ComboboxContent's anchor so the popup spans the whole chips field.
See the Base UI Combobox documentation for the rest.
On This Page
InstallationUsageObject itemsMultiple selectionCompositionSimpleWith chipsWith groups and collectionExamplesBasicMultipleMultiple without remove buttonsClear ButtonGroupsCustom ItemsInvalidDisabledDisabled ItemsAuto HighlightPopupInput GroupAPI ReferenceComboboxInputComboboxContentComboboxChipuseComboboxAnchor