` element.
### `ComboboxItem` options
| Property | Type | Description |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `label` | `string` | The text displayed for this option in the dropdown, and used to filter options as the user types. |
| `value` | `string` | The underlying value submitted with form data and passed to `onValueChange`. Must be unique. |
## Examples
### Basic usage
Render a `Combobox` by supplying an array of `options`. Each `option` can either be a `ComboboxItem`, or a plain string. Use `ComboboxItem` objects when the value associated with each item differs from the text you want to display:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function ObjectOptionsCombobox() {
return (
);
}
```
When the displayed text is the same as the value of the item, a string option is a convenient shorthand:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function StringOptionsCombobox() {
return (
);
}
```
Both shapes can be mixed in the same `options` array. Options are filtered against their `label` as the user types, and selecting an option fills the input with that option's `label` while reporting its `value`.
### Uncontrolled vs controlled
Render a `Combobox` in an uncontrolled fashion to let it keep track of its own selection. Pass `defaultValue` if you need an option to be selected initially:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function UncontrolledCombobox() {
return (
);
}
```
If you need to control which option is selected, use the `value` and `onValueChange` props. `value` is the `value` of the selected option, and is `null` when nothing is selected. Clearing the selection with the clear button calls `onValueChange` with `null`:
```tsx demo
import { useState } from "react";
import { Button } from "@tenstorrent/vesper/button";
import { Combobox } from "@tenstorrent/vesper/combobox";
import { Typography } from "@tenstorrent/vesper/typography";
const FRUITS = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Cherry", value: "cherry" },
];
export default function ControlledCombobox() {
const [fruit, setFruit] = useState
("apple");
return (
Selected value: {fruit ?? "null"}
);
}
```
### Controlling the input's text
The text typed into the input is tracked separately from the selected value. Use `defaultInputValue` to seed the input's text, or `inputValue` and `onInputValueChange` to control it:
```tsx demo
import { useState } from "react";
import { Combobox } from "@tenstorrent/vesper/combobox";
import { Typography } from "@tenstorrent/vesper/typography";
export default function ControlledInputValueCombobox() {
const [query, setQuery] = useState("");
return (
Input value: {query || "empty"}
);
}
```
Controlling the input's text is most useful when the options themselves depend on what the user typed, eg. when they are fetched from a server:
```tsx
import { useEffect, useState } from "react";
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function AsyncCombobox() {
const [query, setQuery] = useState("");
const [options, setOptions] = useState([]);
useEffect(() => {
const controller = new AbortController();
fetch(`/api/repositories?q=${encodeURIComponent(query)}`, {
signal: controller.signal,
})
.then((response) => response.json())
.then((repositories: string[]) => setOptions(repositories))
.catch(() => {});
return () => controller.abort();
}, [query]);
return (
);
}
```
> [!NOTE]
>
> Options are always filtered against the text in the input. When you supply options that have already been filtered by a server, make sure the results have labels that match against what the user typed.
### Different sizes
The `Combobox` component can be rendered at `sm`, `md`, or `lg` size, defaulting to `md`. Size affects the height, padding, and text styles of the input, as well as the size of its icons.
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
const COUNTRIES = ["Canada", "Japan", "Norway"];
export default function ComboboxSizes() {
return (
);
}
```
### Variants
The `Combobox` component can be rendered in one of four variants: `default`, `warning`, `success`, or `error`. The variant determines the colour scheme of the input.
#### Default variant
A `Combobox` renders with the `default` variant when no `variant` prop is specified.
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function DefaultCombobox() {
return (
);
}
```
#### Warning variant
Use the `warning` variant to flag a selection that needs attention, but that doesn't prevent the form from being submitted:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function WarningCombobox() {
return (
);
}
```
#### Success variant
The `success` variant is best suited for confirming that a selection has been validated as expected:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function SuccessCombobox() {
return (
);
}
```
#### Error variant
The `error` variant highlights a missing or invalid selection that must be corrected before the form can be submitted:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function ErrorCombobox() {
return (
);
}
```
### Customising the empty state
When no option matches the text in the input, the dropdown renders a short empty state message. Use `emptyStateText` to tailor it to the data being searched:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function ComboboxWithCustomEmptyState() {
return (
);
}
```
### Disabled and read-only
Pass `disabled` to prevent all interaction with the input and its dropdown:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function DisabledCombobox() {
return (
);
}
```
Pass `readOnly` when the value should be visible and submitted with the form, but not editable:
```tsx demo
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function ReadOnlyCombobox() {
return (
);
}
```
### Controlling the dropdown
The dropdown opens when the input or the caret is clicked, and as the user types. You can open it initially with `defaultOpen`, or control it entirely with `open` and `onOpenChange`:
```tsx demo
import { useState } from "react";
import { Button } from "@tenstorrent/vesper/button";
import { Combobox } from "@tenstorrent/vesper/combobox";
export default function ControlledDropdownCombobox() {
const [open, setOpen] = useState(false);
return (
);
}
```
### Usage in forms
`Combobox` renders a form control, so passing a `name` includes the selected value in form submissions, and `required` participates in native form validation:
```tsx demo
import { useState } from "react";
import { Button } from "@tenstorrent/vesper/button";
import { Combobox } from "@tenstorrent/vesper/combobox";
import { Typography } from "@tenstorrent/vesper/typography";
const FRUITS = [
{ label: "Apple", value: "apple" },
{ label: "Banana", value: "banana" },
{ label: "Cherry", value: "cherry" },
];
export default function FormComboboxDemo() {
const [submitted, setSubmitted] = useState(null);
return (
);
}
```
The value submitted is the `value` of the selected option, not the text displayed in the input. The form above submits `fruit=apple` when "Apple" is selected.
Use the `form` prop to associate the field with a `