Settings row for a list too long to read: pressing it opens a width-matched list with a search field, the keyboard walking the results while focus stays in the field. Options carry groups, descriptions, swatches and search keywords, and `multiple` turns the row into a counted multi-select.
The import and the props worth knowing about, in one place.
import { InspectorCombobox } from "@/components/beste/component/inspector-combobox";
const pages = [
{ value: "home", label: "Home", group: "Pages" },
{ value: "pricing", label: "Pricing", group: "Pages" },
{ value: "docs", label: "Documentation", group: "Pages", keywords: ["help", "guide"] },
{ value: "cart", label: "Cart", group: "Shop" },
];
<InspectorCombobox label="Link to" options={pages} defaultValue="pricing" />
// Controlled. The argument is a string here and an array under `multiple`, so
// narrow it at the call site, which is what knows which it asked for.
<InspectorCombobox
label="Link to"
options={pages}
value={page}
onValueChange={(next) => setPage(next as string)}
onOpenChange={(open) => console.log("list open:", open)}
searchable // on by default past eight options
searchPlaceholder="Find a page"
placeholder="Choose a page" // shown while nothing is selected
emptyMessage="No page matches"
clearable // adds a "Clear Link to" button at the foot
tone="outline" // "muted" (default) | "outline" | "ghost"
size="sm" // "sm" | "default" | "lg"
/>
// Several at once: the row counts them, and the list stays open between presses
<InspectorCombobox
label="Categories"
multiple
max={3}
options={["Editorial", "Commerce", "Marketing", "Docs"]}
value={categories}
onValueChange={(next) => setCategories(next as string[])}
/>
// Options can carry a mark and a second line
<InspectorCombobox
label="Theme"
options={[
{ value: "sand", label: "Sand", swatch: "#d6cbb8", description: "Warm neutral" },
{ value: "slate", label: "Slate", swatch: "#64748b", description: "Cool neutral" },
]}
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Down / Up | Move through the results without leaving the search field |
|---|---|
| Home / End | Jump to the first or last result |
| Enter | Choose the active result |
| Escape | Close the list, leaving the value alone |
| Typing | Filters on the label, the value, the description and any keywords |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
label* | string | — | Label rendered on the left, inside the row. |
icon | LucideIcon | — | Optional leading icon shown before the label. |
options | (string | InspectorComboboxOption)[] | — | The options on offer. |
value | string | string[] | — | Controlled selection: a string, or an array of them with `multiple`. Pair it with `onValueChange`. |
defaultValue | string | string[] | — | Initial selection in uncontrolled mode. |
onValueChange | (value: ComboboxValue) => void | — | Fires on every selection. The argument is a string, or an array of them when `multiple` is set — narrow it at the call site, which knows which it asked for. |
onOpenChange | (open: boolean) => void | — | Fires when the list opens or closes. |
multiple | boolean | — | Choose several. The row then counts them and the list keeps itself open. |
max | number | — | Ceiling on how many may be chosen at once, with `multiple`. |
searchable | boolean | — | Show the search field. Defaults to on once there are more than eight options, which is the point at which reading the list stops being faster than typing. |
searchPlaceholder | string | — | Ghost text for the search field. |
placeholder | string | — | Shown in the row while nothing is selected. |
emptyMessage | string | — | Message shown when nothing matches the search. |
clearable | boolean | — | Offer a clear button at the foot of the list once something is selected. |
disabled | boolean | — | Block interaction and dim the row. |
tone | "muted" | "outline" | "ghost" | "muted" | Surface treatment: filled (default), hairline outline, or bare until hover. |
size | "sm" | "default" | "lg" | "default" | Row height preset. |
className | string | — | |
aria-label | string | — | Accessible name. Falls back to `label`. |