Searchable input for filtering and choosing from a list.
npx shadcn@latest add @iconiq/b-combobox"use client";
import { useState } from "react";
import {
Combobox,
ComboboxContent,
ComboboxEmpty,
ComboboxInput,
ComboboxItem,
ComboboxList,
} from "@/components/ui/b-combobox";
type RouteOption = {
value: string;
label: string;
description: string;
};
const options: RouteOption[] = [
{
value: "scout",
label: "Scout pass",
description: "First scan before the sprint opens up",
},
{
value: "transit",
label: "Transit window",
description: "Tighter route through the midfield line",
},
{
value: "deep",
label: "Deep field",
description: "Longer view with less traffic around it",
},
{
value: "late-run",
label: "Late run",
description: "Arrive second and attack the gap late",
},
];
export function ComboboxPreview() {
const [value, setValue] = useState<RouteOption | null>(options[1]);
return (
<div className="w-full max-w-sm">
<Combobox
itemToStringLabel={(item) => item.label}
itemToStringValue={(item) => item.value}
items={options}
onValueChange={setValue}
value={value}
>
<ComboboxInput label="Pick a route" placeholder="Search routes..." />
<ComboboxContent>
<ComboboxList>
{(option: RouteOption, index: number) => (
<ComboboxItem
description={option.description}
index={index}
key={option.value}
value={option}
>
{option.label}
</ComboboxItem>
)}
</ComboboxList>
<ComboboxEmpty>No route matches that query.</ComboboxEmpty>
</ComboboxContent>
</Combobox>
</div>
);
}itemsOptional item collection used by Base UI for filtering and render-function lists.
Type readonly Item[]
valueControlled selected value. Use an array when multiple is true.
Type Item | Item[] | null
defaultValueInitial selected value for uncontrolled usage.
Type Item | Item[] | null
onValueChangeCalled when an item is selected, a chip is removed, or the clear action resets the selection.
Type (value, eventDetails) => void
multipleAllows selecting multiple items. Pair with ComboboxChips, ComboboxChip, and ComboboxChipsInput.
Type boolean·Default false
itemToStringLabelMaps object values to the label shown in the input and used for text filtering.
Type (item: Item) => string
itemToStringValueMaps object values to the hidden form value.
Type (item: Item) => string
isItemEqualToValueCustom equality check for object values. Defaults to Object.is.
Type (item, value) => boolean
inputValueControlled search text. Leave uncontrolled for Base UI to manage query state.
Type string
onInputValueChangeCalled when the typed query changes.
Type (inputValue, eventDetails) => void
autoHighlightAutomatically highlights the first matching item while filtering.
Type boolean·Default false
openControlled popup state. Pair with onOpenChange.
Type boolean
onOpenChangeCalled when the popup opens or closes.
Type (open, eventDetails) => void
openOnInputClickWhen true, clicking the input shell opens the popup. Otherwise only focus is moved.
Type boolean·Default false
onItemHighlightedCalled when the highlighted item changes from keyboard or pointer navigation.
Type (value, eventDetails) => void
labelOptional label rendered above the input shell with an associated htmlFor.
Type ReactNode
placeholderShown when no item is selected and the input is empty.
Type string
showClearControls whether ComboboxClear is rendered in the input.
Type boolean·Default true
showTriggerControls whether the rotating trigger icon is rendered in the input.
Type boolean·Default true
sizeControls the input shell height.
Type "sm" | "default"·Default "default"
classNameMerged onto the wrapper when label is set, otherwise onto the input shell.
Type string
disabledDisables the input, clear button, and trigger while applying reduced-opacity presentation.
Type boolean·Default false
aria-invalidWhen true, applies destructive border and ring styling to the input shell.
Type boolean
disabledPrevents clearing while disabled.
Type boolean·Default false
classNameMerged onto the clear button.
Type string
disabledPrevents toggling while disabled.
Type boolean·Default false
classNameMerged onto the trigger button.
Type string
childrenStatus message content. Keep the root mounted and update children instead of conditionally rendering the component.
Type ReactNode
classNameMerged onto the status container.
Type string
sidePreferred side for the popup.
Type "top" | "right" | "bottom" | "left" | "inline-start" | "inline-end"·Default "bottom"
alignPopup alignment relative to the input anchor.
Type "start" | "center" | "end"·Default "start"
sideOffsetGap between the input shell and dropdown.
Type number·Default 4
classNameMerged onto the animated popup panel.
Type string
childrenRender explicit children or a render function when using the root items prop.
Type ReactNode | ((item, index) => ReactNode)
classNameMerged with the default list spacing and scroll classes.
Type string
valueStable value used by Base UI for selection.
Type Item
childrenPrimary item label content.
Type ReactNode
descriptionOptional secondary line rendered below the item label, matching the prior option description UI.
Type ReactNode
classNameMerged with the default row layout and motion classes.
Type string
Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.
Dependencies: @base-ui/react, motion, lucide-react.
This page documents the Base UI install only, because Radix UI does not ship a dedicated combobox primitive.
Install into components/ui/b-combobox.tsx so imports match the usage examples.
The generated registry file is /r/b-combobox.json.
Contact
Additionally, if you find any bug or issue, feel free to raise an issue.