Combobox
Search a longer list without losing keyboard selection or a clear current value.
import { … } from "@fungi.computer/caps/components/combobox";Inline search
import { useState } from "react";import { Combobox } from "@fungi.computer/caps/components/combobox";
type Mushroom = { id: string; name: string };
const mushrooms: Mushroom[] = [ { id: "chanterelle", name: "Chanterelle" }, { id: "morel", name: "Morel" }, { id: "lions-mane", name: "Lion's mane" },];
export default function InlineSearch() { const [value, setValue] = useState<string | null>("morel"); return ( <Combobox aria-label="Find a mushroom" getKey={(item) => item.id} getLabel={(item) => item.name} items={mushrooms} onValueChange={setValue} placeholder="Search mushrooms…" value={value} /> );}Trigger popup
import { useState } from "react";import { Combobox, ComboboxTrigger,} from "@fungi.computer/caps/components/combobox";
type Spot = { id: string; name: string; biome: string };
const spots: Spot[] = [ { id: "oak-hollow", name: "Oak hollow", biome: "Deciduous" }, { id: "mossy-ridge", name: "Mossy ridge", biome: "Conifer" }, { id: "creek-bend", name: "Creek bend", biome: "Riparian" },];
export default function TriggerPopup() { const [value, setValue] = useState<string | null>("mossy-ridge"); const current = spots.find((spot) => spot.id === value); return ( <Combobox aria-label="Choose a foraging spot" defaultOpen getKey={(item) => item.id} getLabel={(item) => item.name} groupBy={(item) => item.biome} items={spots} onValueChange={setValue} trigger={ <ComboboxTrigger>{current?.name ?? "Choose a spot"}</ComboboxTrigger> } value={value} /> );}Multiple selection
import { useState } from "react";import { Combobox } from "@fungi.computer/caps/components/combobox";
type Tag = { id: string; name: string };
const tags: Tag[] = [ { id: "edible", name: "Edible" }, { id: "medicinal", name: "Medicinal" }, { id: "toxic", name: "Toxic" }, { id: "unknown", name: "Unknown" },];
export default function MultipleSelection() { const [value, setValue] = useState<string[]>(["edible"]); return ( <div className="flex w-full max-w-sm flex-col gap-2"> <Combobox aria-label="Tag this mushroom" getKey={(item) => item.id} getLabel={(item) => item.name} items={tags} multiple onValueChange={setValue} value={value} /> <p className="text-xs text-base-content"> {value.length ? value.join(", ") : "No tags yet"} </p> </div> );}Props
ComboboxProps
| Prop | Type | Description |
|---|---|---|
T | |
T
ComboboxBaseProps
| Prop | Type | Description |
|---|---|---|
activeTone? | "neutral" | | Color intent for the locally active option. |
container? | BasePopover.Portal.Props["container"] | Native portal destination. Use an unclipped themed container for nested themes. |
contentClassName? | string | |
emptyMessage? | ReactNode | |
getKey() | (item) => string | Returns the stable identity used to track and compare items. |
getLabel() | (item) => string | Returns the text shown for an item in the trigger and the list. |
getSearchText()? | (item) => string | Returns the text matched against caller input; defaults to the item's label. |
groupBy()? | (item) => string | Returns the heading an item is grouped under in the list. |
id? | string | Identifies the popup trigger or inline input for native label association. |
inputProps? | Omit<React.InputHTMLAttributes<HTMLInputElement>, "defaultValue" | "value"> | |
inputRef? | React.Ref<HTMLInputElement> | |
rootRef? | React.Ref<HTMLDivElement> | Receives the selection control's root div. |
isDisabled()? | (item) => boolean | Returns whether an item is unselectable. |
items | readonly T[] | |
placeholder? | string | |
renderItem()? | (item, active, state) => ReactNode | Renders one item's content; defaults to its label. |
activeTone?"neutral" |"primary" Color intent for the locally active option.
container?BasePopover.Portal.Props["container"]Native portal destination. Use an unclipped themed container for nested themes.
contentClassName?stringemptyMessage?ReactNodegetKey()(item) => stringReturns the stable identity used to track and compare items.
getLabel()(item) => stringReturns the text shown for an item in the trigger and the list.
getSearchText()?(item) => stringReturns the text matched against caller input; defaults to the item's label.
groupBy()?(item) => stringReturns the heading an item is grouped under in the list.
id?stringIdentifies the popup trigger or inline input for native label association.
inputProps?Omit<React.InputHTMLAttributes<HTMLInputElement>, "defaultValue" | "value">inputRef?React.Ref<HTMLInputElement>rootRef?React.Ref<HTMLDivElement>Receives the selection control's root div.
isDisabled()?(item) => booleanReturns whether an item is unselectable.
itemsreadonly T[]placeholder?stringrenderItem()?(item, active, state) => ReactNodeRenders one item's content; defaults to its label.
ComboboxBaseProps
| Prop | Type | Description |
|---|---|---|
T | |
T
ComboboxPopupProps
| Prop | Type | Description |
|---|---|---|
defaultOpen? | boolean | |
onOpenChange()? | (open) => void | Called after the popup's open state changes. |
open? | never | |
trigger | ReactElement<ButtonHTMLAttributes<HTMLButtonElement>> | |
triggerRef? | React.Ref<HTMLButtonElement> |
defaultOpen?booleanonOpenChange()?(open) => voidCalled after the popup's open state changes.
open?nevertriggerReactElement<ButtonHTMLAttributes<HTMLButtonElement>>triggerRef?React.Ref<HTMLButtonElement>
ComboboxPopupProps
| Prop | Type | Description |
|---|---|---|
defaultOpen? | never | |
onOpenChange()? | (open) => void | Called after the popup's open state changes. |
open | boolean | |
trigger | ReactElement<ButtonHTMLAttributes<HTMLButtonElement>> | |
triggerRef? | React.Ref<HTMLButtonElement> |
defaultOpen?neveronOpenChange()?(open) => voidCalled after the popup's open state changes.
openbooleantriggerReactElement<ButtonHTMLAttributes<HTMLButtonElement>>triggerRef?React.Ref<HTMLButtonElement>
ComboboxValueProps
| Prop | Type | Description |
|---|---|---|
T | |
T
ComboboxValueProps
| Prop | Type | Description |
|---|---|---|
multiple | true | |
value | readonly string[] | |
defaultValue? | never | |
onValueChange()? | (value, items) => void | Called with the newly selected keys and items. |
multipletruevaluereadonly string[]defaultValue?neveronValueChange()?(value, items) => voidCalled with the newly selected keys and items.
Full types: API reference.