1451 lines
44 KiB
Markdown
1451 lines
44 KiB
Markdown
# Combobox
|
|
|
|
Combines a text input with a listbox, allowing users to filter a list of options to items matching a query.
|
|
|
|
## Import
|
|
|
|
```
|
|
Copyts
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
// or
|
|
import { Root, Label, ... } from "@kobalte/core/combobox";
|
|
// or (deprecated)
|
|
import { Combobox } from "@kobalte/core";
|
|
```
|
|
|
|
```
|
|
Copyts
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
// or
|
|
import { Root, Label, ... } from "@kobalte/core/combobox";
|
|
// or (deprecated)
|
|
import { Combobox } from "@kobalte/core";
|
|
```
|
|
|
|
## Features
|
|
|
|
- Exposed to assistive technology as a combobox using the [WAI ARIA Combobox](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/) design pattern.
|
|
- Support for single and multiple selection.
|
|
- Support for disabled options.
|
|
- Labeling support for accessibility.
|
|
- Support for description and error message help text linked to the button via ARIA.
|
|
- Tab stop focus management.
|
|
- Keyboard support for opening the listbox using the arrow keys, including automatically focusing the first or last item accordingly.
|
|
- Support for opening the list box when typing, on focus, or manually.
|
|
- Browser autofill integration via a hidden native `<select>` element.
|
|
- Custom localized announcements for option focusing, filtering, and selection using an ARIA live region to work around VoiceOver bugs.
|
|
- Supports items, and groups of items.
|
|
- Supports custom placeholder.
|
|
- Can be controlled or uncontrolled.
|
|
|
|
## Anatomy
|
|
|
|
The combobox consists of:
|
|
|
|
- **Combobox:** The root container for a combobox component.
|
|
- **Combobox.Label:** The label that gives the user information on the combobox.
|
|
- **Combobox.Description:** The description that gives the user more information on the combobox.
|
|
- **Combobox.ErrorMessage:** The error message that gives the user information about how to fix a validation error on the combobox.
|
|
- **Combobox.Control:** Contains the combobox input and trigger.
|
|
- **Combobox.Input:** The input used to filter the combobox options and reflects the selected value.
|
|
- **Combobox.Trigger:** The button that opens the combobox.
|
|
- **Combobox.Icon:** A small icon often displayed next to the input as a visual affordance for the fact it can be open.
|
|
- **Combobox.Portal:** Portals its children into the `body` when the combobox is open.
|
|
- **Combobox.Content:** Contains the content to be rendered when the combobox is open.
|
|
- **Combobox.Arrow:** An optional arrow element to render alongside the combobox content.
|
|
- **Combobox.Listbox:** Contains a list of items and allows a user to combobox one or more of them.
|
|
- **Combobox.Section:** Used to render the label of an option group. It won't be focusable using arrow keys.
|
|
- **Combobox.Item:** An item of the combobox.
|
|
- **Combobox.ItemLabel:** An accessible label to be announced for the item.
|
|
- **Combobox.ItemDescription:** An optional accessible description to be announced for the item.
|
|
- **Combobox.ItemIndicator:** The visual indicator rendered when the item is selected.
|
|
|
|
```
|
|
Copytsx
|
|
<Combobox>
|
|
<Combobox.Label />
|
|
<Combobox.Control>
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon />
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Description />
|
|
<Combobox.ErrorMessage />
|
|
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Arrow />
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
<Combobox>
|
|
<Combobox.Label />
|
|
<Combobox.Control>
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon />
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Description />
|
|
<Combobox.ErrorMessage />
|
|
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Arrow />
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
```
|
|
|
|
## Example
|
|
|
|
Sort
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
import "./style.css";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function App() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item} class="combobox__item">
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator class="combobox__item-indicator">
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control class="combobox__control" aria-label="Fruit">
|
|
<Combobox.Input class="combobox__input" />
|
|
<Combobox.Trigger class="combobox__trigger">
|
|
<Combobox.Icon class="combobox__icon">
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content class="combobox__content">
|
|
<Combobox.Listbox class="combobox__listbox" />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
import "./style.css";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function App() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item} class="combobox__item">
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator class="combobox__item-indicator">
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control class="combobox__control" aria-label="Fruit">
|
|
<Combobox.Input class="combobox__input" />
|
|
<Combobox.Trigger class="combobox__trigger">
|
|
<Combobox.Icon class="combobox__icon">
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content class="combobox__content">
|
|
<Combobox.Listbox class="combobox__listbox" />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Filtering options
|
|
|
|
The `defaultFilter` prop can be used to customize the way `Combobox` filter the list of options.
|
|
|
|
For convenience, we provide 3 built-in filtering mechanism based on substring matches with locale sensitive matching support. It automatically uses the current locale set by the application, either via the default browser language or via the `I18nProvider`.
|
|
|
|
- **startsWith**: Show options that starts with the input value.
|
|
- **endsWith**: Show options that ends with the input value.
|
|
- **contains**: Show options that contains the input value.
|
|
|
|
A custom filter function can also be passed to the `defaultFilter` prop, it receives _an option and the input value_ as parameters, and should return a `boolean`.
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function FilteringExample() {
|
|
return (
|
|
<Combobox options={ALL_OPTIONS} defaultFilter="startsWith">
|
|
//...rest of the component.
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function FilteringExample() {
|
|
return (
|
|
<Combobox options={ALL_OPTIONS} defaultFilter="startsWith">
|
|
//...rest of the component.
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Default value
|
|
|
|
An initial, uncontrolled value can be provided using the `defaultValue` prop, which accepts a value corresponding with the `options`.
|
|
|
|
Sort
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function DefaultValueExample() {
|
|
return (
|
|
<Combobox
|
|
defaultValue="Blueberry"
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function DefaultValueExample() {
|
|
return (
|
|
<Combobox
|
|
defaultValue="Blueberry"
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Controlled value
|
|
|
|
The `value` prop, which accepts a value corresponding with the `options` prop, can be used to make the value controlled. The `onChange` event is fired when the user selects an option, and receives the selected option.
|
|
|
|
Sort
|
|
|
|
Your favorite fruit is: Blueberry.
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function ControlledExample() {
|
|
const [value, setValue] = createSignal("Blueberry");
|
|
|
|
const onInputChange = (value: string) => {
|
|
// Remove selection when input is cleared.
|
|
if (value === "") {
|
|
setValue("");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
value={value()}
|
|
onChange={setValue}
|
|
onInputChange={onInputChange}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<p>Your favorite fruit is: {value()}.</p>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function ControlledExample() {
|
|
const [value, setValue] = createSignal("Blueberry");
|
|
|
|
const onInputChange = (value: string) => {
|
|
// Remove selection when input is cleared.
|
|
if (value === "") {
|
|
setValue("");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
value={value()}
|
|
onChange={setValue}
|
|
onInputChange={onInputChange}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<p>Your favorite fruit is: {value()}.</p>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Description
|
|
|
|
The `Combobox.Description` component can be used to associate additional help text with a combobox.
|
|
|
|
Sort
|
|
|
|
Choose the fruit you like the most.
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function DescriptionExample() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Description>Choose the fruit you like the most.</Combobox.Description>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function DescriptionExample() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Description>Choose the fruit you like the most.</Combobox.Description>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Error message
|
|
|
|
The `Combobox.ErrorMessage` component can be used to help the user fix a validation error. It should be combined with the `validationState` prop to semantically mark the combobox as invalid for assistive technologies.
|
|
|
|
By default, it will render only when the `validationState` prop is set to `invalid`, use the `forceMount` prop to always render the error message (ex: for usage with animation libraries).
|
|
|
|
Sort
|
|
|
|
Hmm, I prefer apples.
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function ErrorMessageExample() {
|
|
const [value, setValue] = createSignal("Grapes");
|
|
|
|
const onInputChange = (value: string) => {
|
|
// Remove selection when input is cleared.
|
|
if (value === "") {
|
|
setValue("");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
value={value()}
|
|
onChange={setValue}
|
|
onInputChange={onInputChange}
|
|
validationState={value() !== "Apple" ? "invalid" : "valid"}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.ErrorMessage>Hmm, I prefer apples.</Combobox.ErrorMessage>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function ErrorMessageExample() {
|
|
const [value, setValue] = createSignal("Grapes");
|
|
|
|
const onInputChange = (value: string) => {
|
|
// Remove selection when input is cleared.
|
|
if (value === "") {
|
|
setValue("");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
value={value()}
|
|
onChange={setValue}
|
|
onInputChange={onInputChange}
|
|
validationState={value() !== "Apple" ? "invalid" : "valid"}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.ErrorMessage>Hmm, I prefer apples.</Combobox.ErrorMessage>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
### HTML forms
|
|
|
|
The combobox `name` prop, paired with the `Combobox.HiddenSelect` component, can be used for integration with HTML forms.
|
|
|
|
AppleBananaBlueberryGrapesPineapple
|
|
|
|
Sort
|
|
|
|
ResetSubmit
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function HTMLFormExample() {
|
|
const onSubmit = (e: SubmitEvent) => {
|
|
// handle form submission.
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={onSubmit}>
|
|
<Combobox
|
|
name="fruit"
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.HiddenSelect />
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<div>
|
|
<button type="reset">Reset</button>
|
|
<button>Submit</button>
|
|
</div>
|
|
</form>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function HTMLFormExample() {
|
|
const onSubmit = (e: SubmitEvent) => {
|
|
// handle form submission.
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={onSubmit}>
|
|
<Combobox
|
|
name="fruit"
|
|
options={ALL_OPTIONS}
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.HiddenSelect />
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<div>
|
|
<button type="reset">Reset</button>
|
|
<button>Submit</button>
|
|
</div>
|
|
</form>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Using object as options
|
|
|
|
Objects can be used as options instead of plain strings. In this case you have to tell the combobox how it should work with the provided options. For this you **have to use** the following props:
|
|
|
|
- `optionValue`: The property name to use as the value of an option (submitted with `<form>`).
|
|
- `optionTextValue`: The property name to use as the text value of an option for **filtering** and keyboard navigation.
|
|
- `optionLabel`: The property name to use as the label of an option, displayed in the combobox input.
|
|
- `optionDisabled`: The property name to use as the disabled flag of an option.
|
|
|
|
Sort
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
interface Fruit {
|
|
value: string;
|
|
label: string;
|
|
disabled: boolean;
|
|
}
|
|
|
|
const ALL_OPTIONS: Fruit[] = [\
|
|
{ value: "apple", label: "Apple", disabled: false },\
|
|
{ value: "banana", label: "Banana", disabled: false },\
|
|
{ value: "blueberry", label: "Blueberry", disabled: false },\
|
|
{ value: "grapes", label: "Grapes", disabled: true },\
|
|
{ value: "pineapple", label: "Pineapple", disabled: false },\
|
|
];
|
|
|
|
function ObjectExample() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
optionValue="value"
|
|
optionTextValue="label"
|
|
optionLabel="label"
|
|
optionDisabled="disabled"
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue.label}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
interface Fruit {
|
|
value: string;
|
|
label: string;
|
|
disabled: boolean;
|
|
}
|
|
|
|
const ALL_OPTIONS: Fruit[] = [\
|
|
{ value: "apple", label: "Apple", disabled: false },\
|
|
{ value: "banana", label: "Banana", disabled: false },\
|
|
{ value: "blueberry", label: "Blueberry", disabled: false },\
|
|
{ value: "grapes", label: "Grapes", disabled: true },\
|
|
{ value: "pineapple", label: "Pineapple", disabled: false },\
|
|
];
|
|
|
|
function ObjectExample() {
|
|
return (
|
|
<Combobox
|
|
options={ALL_OPTIONS}
|
|
optionValue="value"
|
|
optionTextValue="label"
|
|
optionLabel="label"
|
|
optionDisabled="disabled"
|
|
placeholder="Search a fruit…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue.label}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Fruit">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Using option groups
|
|
|
|
When using option groups you have to tell the combobox how to distinguish an option from a group. For this you **have to use** the following props:
|
|
|
|
- `optionGroupChildren`: The property name that refers to the children options of an option group.
|
|
|
|
Additionally, the `sectionComponent` prop is used to display the option group label in the combobox.
|
|
|
|
Sort
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
interface Food {
|
|
value: string;
|
|
label: string;
|
|
disabled: boolean;
|
|
}
|
|
|
|
interface Category {
|
|
label: string;
|
|
options: Food[];
|
|
}
|
|
|
|
const ALL_OPTIONS: Category[] = [\
|
|
{\
|
|
label: "Fruits",\
|
|
options: [\
|
|
{ value: "apple", label: "Apple", disabled: false },\
|
|
{ value: "banana", label: "Banana", disabled: false },\
|
|
{ value: "blueberry", label: "Blueberry", disabled: false },\
|
|
{ value: "grapes", label: "Grapes", disabled: true },\
|
|
{ value: "pineapple", label: "Pineapple", disabled: false },\
|
|
],\
|
|
},\
|
|
{\
|
|
label: "Meat",\
|
|
options: [\
|
|
{ value: "beef", label: "Beef", disabled: false },\
|
|
{ value: "chicken", label: "Chicken", disabled: false },\
|
|
{ value: "lamb", label: "Lamb", disabled: false },\
|
|
{ value: "pork", label: "Pork", disabled: false },\
|
|
],\
|
|
},\
|
|
];
|
|
|
|
export function OptionGroupExample() {
|
|
return (
|
|
<Combobox<Food, Category>
|
|
options={ALL_OPTIONS}
|
|
optionValue="value"
|
|
optionTextValue="label"
|
|
optionLabel="label"
|
|
optionDisabled="disabled"
|
|
optionGroupChildren="options"
|
|
placeholder="Search a food…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue.label}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
sectionComponent={props => (
|
|
<Combobox.Section>{props.section.rawValue.label}</Combobox.Section>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Food">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
|
|
interface Food {
|
|
value: string;
|
|
label: string;
|
|
disabled: boolean;
|
|
}
|
|
|
|
interface Category {
|
|
label: string;
|
|
options: Food[];
|
|
}
|
|
|
|
const ALL_OPTIONS: Category[] = [\
|
|
{\
|
|
label: "Fruits",\
|
|
options: [\
|
|
{ value: "apple", label: "Apple", disabled: false },\
|
|
{ value: "banana", label: "Banana", disabled: false },\
|
|
{ value: "blueberry", label: "Blueberry", disabled: false },\
|
|
{ value: "grapes", label: "Grapes", disabled: true },\
|
|
{ value: "pineapple", label: "Pineapple", disabled: false },\
|
|
],\
|
|
},\
|
|
{\
|
|
label: "Meat",\
|
|
options: [\
|
|
{ value: "beef", label: "Beef", disabled: false },\
|
|
{ value: "chicken", label: "Chicken", disabled: false },\
|
|
{ value: "lamb", label: "Lamb", disabled: false },\
|
|
{ value: "pork", label: "Pork", disabled: false },\
|
|
],\
|
|
},\
|
|
];
|
|
|
|
export function OptionGroupExample() {
|
|
return (
|
|
<Combobox<Food, Category>
|
|
options={ALL_OPTIONS}
|
|
optionValue="value"
|
|
optionTextValue="label"
|
|
optionLabel="label"
|
|
optionDisabled="disabled"
|
|
optionGroupChildren="options"
|
|
placeholder="Search a food…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue.label}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
sectionComponent={props => (
|
|
<Combobox.Section>{props.section.rawValue.label}</Combobox.Section>
|
|
)}
|
|
>
|
|
<Combobox.Control aria-label="Food">
|
|
<Combobox.Input />
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
);
|
|
}
|
|
```
|
|
|
|
Notice the usage of generics on `Combobox` for proper TypeScript support.
|
|
|
|
### Multiple selection
|
|
|
|
The `multiple` prop can be used to create a combobox that allow multi-selection. In this case the value provided to `value`, `defaultValue` and `onChange` props is of type `Array<T>`.
|
|
|
|
In this case `Combobox.Input` can't display the values, instead the `Combobox.Control` children _render prop_ expose an array of selected options, and two method for removing an option from the selection and clear the selection.
|
|
|
|
BlueberryCrossGrapesCross
|
|
|
|
CrossSort
|
|
|
|
Your favorite fruits are: Blueberry, Grapes.
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function MultipleSelectionExample() {
|
|
const [values, setValues] = createSignal(["Blueberry", "Grapes"]);
|
|
|
|
return (
|
|
<>
|
|
<Combobox<string>
|
|
multiple
|
|
options={ALL_OPTIONS}
|
|
value={values()}
|
|
onChange={setValues}
|
|
placeholder="Search some fruits…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control<string> aria-label="Fruits">
|
|
{state => (
|
|
<>
|
|
<div>
|
|
<For each={state.selectedOptions()}>
|
|
{option => (
|
|
<span onPointerDown={e => e.stopPropagation()}>
|
|
{option}
|
|
<button onClick={() => state.remove(option)}>
|
|
<CrossIcon />
|
|
</button>
|
|
</span>
|
|
)}
|
|
</For>
|
|
<Combobox.Input />
|
|
</div>
|
|
<button onPointerDown={e => e.stopPropagation()} onClick={state.clear}>
|
|
<CrossIcon />
|
|
</button>
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</>
|
|
)}
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<p>Your favorite fruits are: {values().join(", ")}.</p>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Combobox } from "@kobalte/core/combobox";
|
|
import { CaretSortIcon, CheckIcon } from "some-icon-library";
|
|
import { createSignal } from "solid-js";
|
|
|
|
const ALL_OPTIONS = ["Apple", "Banana", "Blueberry", "Grapes", "Pineapple"];
|
|
|
|
function MultipleSelectionExample() {
|
|
const [values, setValues] = createSignal(["Blueberry", "Grapes"]);
|
|
|
|
return (
|
|
<>
|
|
<Combobox<string>
|
|
multiple
|
|
options={ALL_OPTIONS}
|
|
value={values()}
|
|
onChange={setValues}
|
|
placeholder="Search some fruits…"
|
|
itemComponent={props => (
|
|
<Combobox.Item item={props.item}>
|
|
<Combobox.ItemLabel>{props.item.rawValue}</Combobox.ItemLabel>
|
|
<Combobox.ItemIndicator>
|
|
<CheckIcon />
|
|
</Combobox.ItemIndicator>
|
|
</Combobox.Item>
|
|
)}
|
|
>
|
|
<Combobox.Control<string> aria-label="Fruits">
|
|
{state => (
|
|
<>
|
|
<div>
|
|
<For each={state.selectedOptions()}>
|
|
{option => (
|
|
<span onPointerDown={e => e.stopPropagation()}>
|
|
{option}
|
|
<button onClick={() => state.remove(option)}>
|
|
<CrossIcon />
|
|
</button>
|
|
</span>
|
|
)}
|
|
</For>
|
|
<Combobox.Input />
|
|
</div>
|
|
<button onPointerDown={e => e.stopPropagation()} onClick={state.clear}>
|
|
<CrossIcon />
|
|
</button>
|
|
<Combobox.Trigger>
|
|
<Combobox.Icon>
|
|
<CaretSortIcon />
|
|
</Combobox.Icon>
|
|
</Combobox.Trigger>
|
|
</>
|
|
)}
|
|
</Combobox.Control>
|
|
<Combobox.Portal>
|
|
<Combobox.Content>
|
|
<Combobox.Listbox />
|
|
</Combobox.Content>
|
|
</Combobox.Portal>
|
|
</Combobox>
|
|
<p>Your favorite fruits are: {values().join(", ")}.</p>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Origin-aware animations
|
|
|
|
We expose a CSS custom property `--kb-combobox-content-transform-origin` which can be used to animate the content from its computed origin.
|
|
|
|
```
|
|
Copycss
|
|
/* style.css */
|
|
.combobox__content {
|
|
transform-origin: var(--kb-combobox-content-transform-origin);
|
|
animation: contentHide 250ms ease-in forwards;
|
|
}
|
|
|
|
.combobox__content[data-expanded] {
|
|
animation: contentShow 250ms ease-out;
|
|
}
|
|
|
|
@keyframes contentShow {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes contentHide {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(-8px);
|
|
}
|
|
}
|
|
```
|
|
|
|
```
|
|
Copycss
|
|
/* style.css */
|
|
.combobox__content {
|
|
transform-origin: var(--kb-combobox-content-transform-origin);
|
|
animation: contentHide 250ms ease-in forwards;
|
|
}
|
|
|
|
.combobox__content[data-expanded] {
|
|
animation: contentShow 250ms ease-out;
|
|
}
|
|
|
|
@keyframes contentShow {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(-8px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
@keyframes contentHide {
|
|
from {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
to {
|
|
opacity: 0;
|
|
transform: translateY(-8px);
|
|
}
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Combobox
|
|
|
|
`Combobox` is equivalent to the `Root` import from `@kobalte/core/combobox` (and deprecated `Combobox.Root`).
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| defaultFilter | `"startsWith" | "endsWith" | "contains" | ((option: Option, inputValue: string) => boolean)`<br> The filter function used to determine if an option should be included in the combo box list. |
|
|
| options | `Array<T | U>`<br> An array of options to display as the available options. |
|
|
| optionValue | `keyof T | ((option: T) => string | number)`<br> Property name or getter function to use as the value of an option. This is the value that will be submitted when the combobox is part of a `<form>`. |
|
|
| optionTextValue | `keyof T | ((option: T) => string)`<br> Property name or getter function to use as the text value of an option for typeahead purpose. |
|
|
| optionLabel | `keyof T | ((option: T) => string)`<br> Property name or getter function to use as the label of an option. This is the string representation of the option to display in the `Combobox.Input`. |
|
|
| optionDisabled | `keyof T | ((option: T) => boolean)`<br> Property name or getter function to use as the disabled flag of an option. |
|
|
| optionGroupChildren | `keyof U`<br> Property name that refers to the children options of an option group. |
|
|
| itemComponent | `Component<ComboboxItemComponentProps<T>>`<br> When NOT virtualized, the component to render as an item in the `Combobox.Listbox`. |
|
|
| sectionComponent | `Component<ComboboxSectionComponentProps<U>>`<br> When NOT virtualized, the component to render as a section in the `Combobox.Listbox`. |
|
|
| multiple | `boolean`<br> Whether the combobox allows multi-selection. |
|
|
| placeholder | `JSX.Element`<br> The content that will be rendered when no value or defaultValue is set. |
|
|
| value | `T | Array<T>`<br> The controlled value of the combobox. |
|
|
| defaultValue | `T | Array<T>`<br> The value of the combobox when initially rendered. Useful when you do not need to control the value. |
|
|
| onChange | `(value: T | Array<T>) => void`<br> Event handler called when the value changes. |
|
|
| open | `boolean`<br> The controlled open state of the combobox. |
|
|
| defaultOpen | `boolean`<br> The default open state when initially rendered. Useful when you do not need to control the open state. |
|
|
| onOpenChange | `(open: boolean, triggerMode?: ComboboxTriggerMode) => void`<br> Event handler called when the open state of the combobox changes. Returns the new open state and the action that caused the opening of the menu. |
|
|
| onInputChange | `(value: string) => void`<br> Handler that is called when the combobox input value changes. |
|
|
| triggerMode | `ComboboxTriggerMode`<br> The interaction required to display the combobox menu, it can be one of the following: <br> \- **input**: open the combobox menu when the user is typing. <br> \- **focus**: open the combobox menu when the input is focused. <br> \- **manual**: open the combobox menu when pressing arrow down/up while focus is on the input or clicking on the trigger. |
|
|
| removeOnBackspace | `boolean`<br> When `multiple` is true, whether the last selected option should be removed when the user press the Backspace key and the input is empty. |
|
|
| allowDuplicateSelectionEvents | `boolean`<br> Whether `onChange` should fire even if the new value is the same as the last. |
|
|
| disallowEmptySelection | `boolean`<br> Whether the combobox allows empty selection or not. |
|
|
| allowsEmptyCollection | `boolean`<br> Whether the combobox allows the menu to be open when the collection is empty. |
|
|
| closeOnSelection | `boolean`<br> Whether the combobox closes after selection. |
|
|
| selectionBehavior | `'toggle' | 'replace'`<br> How selection should behave in the combobox. |
|
|
| virtualized | `boolean`<br> Whether the combobox uses virtual scrolling. |
|
|
| modal | `boolean`<br> Whether the combobox should be the only visible content for screen readers, when set to `true`: <br> \- interaction with outside elements will be disabled. <br> \- scroll will be locked. <br> \- focus will be locked inside the combobox content. <br> \- elements outside the combobox content will not be visible for screen readers. |
|
|
| preventScroll | `boolean`<br> Whether the scroll should be locked even if the combobox is not modal. |
|
|
| forceMount | `boolean`<br> Used to force mounting the combobox (portal, positioner and content) when more control is needed. Useful when controlling animation with SolidJS animation libraries. |
|
|
| name | `string`<br> The name of the combobox. Submitted with its owning form as part of a name/value pair. |
|
|
| validationState | `'valid' | 'invalid'`<br> Whether the combobox should display its "valid" or "invalid" visual styling. |
|
|
| required | `boolean`<br> Whether the user must select an item before the owning form can be submitted. |
|
|
| disabled | `boolean`<br> Whether the combobox is disabled. |
|
|
| readOnly | `boolean`<br> Whether the combobox items can be selected but not changed by the user. |
|
|
| autoComplete | `string`<br> Describes the type of autocomplete functionality the input should provide if any. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#htmlattrdefautocomplete) |
|
|
| translations | [`ComboboxIntlTranslations`](https://github.com/kobaltedev/kobalte/blob/main/packages/core/src/combobox/combobox.intl.ts)<br> Localization strings. |
|
|
| noResetInputOnBlur | `boolean`<br> Prevents input reset on combobox blur when content is displayed. |
|
|
|
|
`Combobox` also accepts the following props to customize the placement of the `Combobox.Content`.
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| placement | `Placement`<br> The placement of the combobox content. |
|
|
| gutter | `number`<br> The distance between the combobox content and the trigger element. |
|
|
| shift | `number`<br> The skidding of the combobox content along the trigger element. |
|
|
| flip | `boolean | string`<br> Controls the behavior of the combobox content when it overflows the viewport: <br> \- If a `boolean`, specifies whether the combobox content should flip to the opposite side when it overflows.<br> \- If a `string`, indicates the preferred fallback placements when it overflows.<br>The placements must be spaced-delimited, e.g. "top left". |
|
|
| slide | `boolean`<br> Whether the combobox content should slide when it overflows. |
|
|
| overlap | `boolean`<br> Whether the combobox content can overlap the trigger element when it overflows. |
|
|
| sameWidth | `boolean`<br> Whether the combobox content should have the same width as the trigger element. This will be exposed to CSS as `--kb-popper-anchor-width`. |
|
|
| fitViewport | `boolean`<br> Whether the combobox content should fit the viewport. If this is set to true, the combobox content will have `maxWidth` and `maxHeight` set to the viewport size. This will be exposed to CSS as `--kb-popper-available-width` and `--kb-popper-available-height`. |
|
|
| hideWhenDetached | `boolean`<br> Whether to hide the combobox content when the trigger element becomes occluded. |
|
|
| detachedPadding | `number`<br> The minimum padding in order to consider the trigger element occluded. |
|
|
| arrowPadding | `number`<br> The minimum padding between the arrow and the combobox content corner. |
|
|
| overflowPadding | `number`<br> The minimum padding between the combobox content and the viewport edge. This will be exposed to CSS as `--kb-popper-overflow-padding`. |
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-valid | Present when the combobox is valid according to the validation rules. |
|
|
| data-invalid | Present when the combobox is invalid according to the validation rules. |
|
|
| data-required | Present when the user must select an item before the owning form can be submitted. |
|
|
| data-disabled | Present when the combobox is disabled. |
|
|
| data-readonly | Present when the combobox is read only. |
|
|
|
|
`Combobox.Label`, `Combobox.Control`, `Combobox.Input`, `Combobox.Trigger`, `Combobox.Description` and `Combobox.ErrorMesssage` shares the same data-attributes.
|
|
|
|
### Combobox.Control
|
|
|
|
| Render Prop | Description |
|
|
| --- | --- |
|
|
| selectedOptions | `Accessor<T[]>`<br> An array of selected options. |
|
|
| remove | `(option: T) => void`<br> A function to remove an option from the selection. |
|
|
| clear | `() => void`<br> A function to clear the selection. |
|
|
|
|
### Combobox.Trigger
|
|
|
|
`Combobox.Trigger` consists of [Button](https://kobalte.dev/docs/core/components/button).
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-expanded | Present when the combobox is open. |
|
|
| data-closed | Present when the combobox is close. |
|
|
|
|
### Combobox.Icon
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-expanded | Present when the combobox is open. |
|
|
| data-closed | Present when the combobox is close. |
|
|
|
|
### Combobox.ErrorMessage
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| forceMount | `boolean`<br> Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries. |
|
|
|
|
### Combobox.Content
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-expanded | Present when the combobox is open. |
|
|
| data-closed | Present when the combobox is close. |
|
|
|
|
### Combobox.Arrow
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| size | `number`<br> The size of the arrow. |
|
|
|
|
### Combobox.Listbox
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| scrollRef | `Accessor<HTMLElement | undefined>`<br> The ref attached to the scrollable element, used to provide automatic scrolling on item focus. If not provided, defaults to the listbox. |
|
|
| scrollToItem | `(key: string) => void`<br> When virtualized, the Virtualizer function used to scroll to the item of the given key. |
|
|
| children | `(items: Accessor<Collection<CollectionNode<T | U>>>) => JSX.Element`<br> When virtualized, a map function that receives an _items_ signal representing all items and sections. |
|
|
|
|
### Combobox.Item
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| item | `CollectionNode`<br> The collection node to render. |
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-disabled | Present when the item is disabled. |
|
|
| data-selected | Present when the item is selected. |
|
|
| data-highlighted | Present when the item is highlighted. |
|
|
|
|
`Combobox.ItemLabel`, `Combobox.ItemDescription` and `Combobox.ItemIndicator` shares the same data-attributes.
|
|
|
|
### Combobox.ItemIndicator
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| forceMount | `boolean`<br> Used to force mounting when more control is needed. Useful when controlling animation with SolidJS animation libraries. |
|
|
|
|
## Rendered elements
|
|
|
|
| Component | Default rendered element |
|
|
| --- | --- |
|
|
| `Combobox` | `div` |
|
|
| `Combobox.Label` | `span` |
|
|
| `Combobox.Description` | `div` |
|
|
| `Combobox.ErrorMessage` | `div` |
|
|
| `Combobox.Control` | `div` |
|
|
| `Combobox.Input` | `input` |
|
|
| `Combobox.Trigger` | `button` |
|
|
| `Combobox.Icon` | `span` |
|
|
| `Combobox.Portal` | `Portal` |
|
|
| `Combobox.Content` | `div` |
|
|
| `Combobox.Arrow` | `div` |
|
|
| `Combobox.Listbox` | `ul` |
|
|
| `Combobox.Section` | `li` |
|
|
| `Combobox.Item` | `li` |
|
|
| `Combobox.ItemLabel` | `div` |
|
|
| `Combobox.ItemDescription` | `div` |
|
|
| `Combobox.ItemIndicator` | `div` |
|
|
|
|
## Accessibility
|
|
|
|
### Keyboard Interactions
|
|
|
|
| Key | Description |
|
|
| --- | --- |
|
|
| `Enter` | When focus is virtualy on an item, selects the focused item. |
|
|
| `ArrowDown` | When focus is on the input, opens the combobox and virtual focuses the first or selected item. <br> When focus is virtualy on an item, moves virtual focus to the next item. |
|
|
| `ArrowUp` | When focus is on the input, opens the combebox and virtual focuses the last or selected item. <br> When focus is virtualy on an item, moves virtual focus to the previous item. |
|
|
| `Alt` \+ `ArrowDown` | When focus is on the input, opens the combobox. |
|
|
| `Alt` \+ `ArrowUp` | When focus is on the input, closes the combobox. |
|
|
| `Home` | When focus is on the input, moves virtual focus to first item. |
|
|
| `End` | When focus is on the input, moves virtual focus to last item. |
|
|
| `Esc` | When the combobox is open, closes the combobox. <br> When the combobox is closed, clear the input and selection unless `noResetInputOnBlur` is set to `true`. |
|
|
|
|
Previous[←Color Wheel](https://kobalte.dev/docs/core/components/color-wheel)Next[Context Menu→](https://kobalte.dev/docs/core/components/context-menu) |