# MultiCombobox

```tsx
import { MultiCombobox, useMultiCombobox } from '@tangible/ui';
```

Interactive docs and examples: [MultiCombobox in Storybook](https://storybook-tangible-ui.pages.dev/?path=/docs/forms-multicombobox--docs).

## MultiCombobox props

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `aria-describedby?` | `string` | | ID(s) of element(s) that describe this combobox (helper text, error). Forwarded to the input — Field.Control injects this. |
| `aria-invalid?` | `"false" \| "true" \| boolean` | | Invalid state, forwarded to the input. Field.Control injects this. |
| `aria-label?` | `string` | | Accessible name for the combobox. |
| `aria-labelledby?` | `string` | | ID of element that labels this combobox. |
| `aria-required?` | `"false" \| "true" \| boolean` | | Required state, forwarded to the input. Field.Control injects this. |
| `clearable?` | `boolean` | `true` | Whether to show the clear-all button when values are present. |
| `defaultOpen?` | `boolean` | `false` | Default open state for uncontrolled usage. |
| `defaultValue?` | `MultiComboboxValue` | | Default values for uncontrolled usage. |
| `disabled?` | `boolean` | `false` | Whether the combobox is disabled. |
| `filterMode?` | `"always" \| "when-searching"` | `'always'` | Controls filtering behavior. |
| `id?` | `string` | | Optional input ID override, applied to the inner `<input>`. Useful for Field integration via htmlFor — Field.Control injects this. |
| `inputClassName?` | `string` | | Class name applied directly to the `<input>` element. Use for utilities like `tui-input-reset` that must target the input itself. |
| `inputValue?` | `string` | | Controlled input value for search/filter. |
| `labels?` | `MultiComboboxLabels` | | Override default English strings for i18n. |
| `max?` | `number` | | Maximum number of selections allowed. When reached, unselected options become disabled. |
| `onInputChange?` | `(value: string) => void` | | Callback when input value changes (typing, clear). |
| `onMaxReached?` | `() => void` | | Callback when max selections is reached. |
| `onOpenChange?` | `(open: boolean) => void` | | Callback when open state changes. |
| `onQueryChange?` | `(query: string) => void` | | Callback when the effective query changes. |
| `onValueChange?` | `(value: MultiComboboxValue) => void` | | Callback when selection changes. |
| `open?` | `boolean` | | Controlled open state. |
| `openOnFocus?` | `boolean` | `true` | Whether to open the listbox when the input receives focus. |
| `overflow?` | `"trim" \| "wrap"` | `'trim'` | How selected chips behave when they exceed the control width. 'trim' (default): the control stays a single line (fixed height); chips flow horizontally and clip toward the inline-start, keeping the typing area in view. Preserves row alignment in multi-column form layouts. 'wrap': chips wrap onto new lines and the control grows vertically. Opt in for standalone or spacious placements. |
| `placeholder?` | `string` | `''` | Placeholder text for the input. Shown only when no values are selected. |
| `size?` | `"lg" \| "md" \| "sm"` | `'md'` | Control size. |
| `value?` | `MultiComboboxValue` | | Controlled selected values. |

### MultiCombobox.Content

Also exported as `MultiComboboxContent`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `className?` | `string` | | |

### MultiCombobox.Option

Also exported as `MultiComboboxOption`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children` | `React.ReactNode` | | |
| `value` | `OptionValue` | | The value for this option. Required and must be unique. Can be string or number. |
| `className?` | `string` | | |
| `disabled?` | `boolean` | `false` | Whether this option is disabled. |
| `textValue?` | `string` | | Text value used for the chip label when selected. Required when children is not a string. If children is a string, defaults to that. |

### MultiCombobox.Group

Also exported as `MultiComboboxGroup`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children?` | `ReactNode` | | |
| `className?` | `string` | | |

### MultiCombobox.Label

Also exported as `MultiComboboxLabel`.

| Prop | Type | Default | Description |
| - | - | - | - |
| `children?` | `ReactNode` | | |
| `className?` | `string` | | |

## Hooks

### useMultiCombobox

```ts
useMultiCombobox(): MultiComboboxActionsContextValue & MultiComboboxStateContextValue
```

Returns:

| Member | Type | Description |
| - | - | - |
| `disabled` | `boolean` | |
| `placeholder` | `string` | |
| `openOnFocus` | `boolean` | |
| `max` | `number \| undefined` | |
| `inputId` | `string` | |
| `listboxId` | `string` | |
| `ariaLabel?` | `string` | |
| `ariaLabelledBy?` | `string` | |
| `setOpen` | `(open: boolean) => void` | |
| `setInputValue` | `(value: string) => void` | |
| `toggleOption` | `(value: OptionValue, textValue: string) => void` | |
| `registerOption` | `(option: RegisteredOption) => void` | |
| `unregisterOption` | `(value: OptionValue) => void` | |
| `refs` | `{ reference: React.RefObject<ReferenceType \| null>; floating: React.RefObject<HTMLElement \| null>; setReference: (node: ReferenceType \| null) => void; setFloating: (node: HTMLElement \| null) => void; }` | |
| `inputRef` | `RefObject<HTMLInputElement \| null>` | |
| `listRef` | `MutableRefObject<(HTMLElement \| null)[]>` | |
| `getReferenceProps` | `(userProps?: React.HTMLProps<Element>) => Record<string, unknown>` | |
| `getFloatingProps` | `(userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>` | |
| `getItemProps` | `(userProps?: React.HTMLProps<HTMLElement>) => Record<string, unknown>` | |
| `open` | `boolean` | |
| `value` | `MultiComboboxValue` | |
| `inputValue` | `string` | |
| `maxReached` | `boolean` | |
| `isSelected` | `(value: OptionValue) => boolean` | |
| `query` | `string` | |
| `activeIndex` | `number` | |
| `activeOptionId` | `string \| undefined` | |
| `orderedOptions` | `RegisteredOption[]` | |
| `floatingStyles` | `CSSProperties` | |
| `floatingContext` | `FloatingContext` | |

`RegisteredOption` (the `option` of `registerOption`):

| Member | Type | Description |
| - | - | - |
| `value` | `OptionValue` | |
| `ref` | `RefObject<HTMLElement \| null>` | |
| `disabled` | `boolean` | |
| `textValue` | `string` | |

## Examples

Stories: Basic, Initial Values, Max (3), Sizes, Overflow: trim, Async, With Field, Disabled ([interactive page](https://storybook-tangible-ui.pages.dev/?path=/docs/forms-multicombobox--docs)).

## Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.

- `--tui-multicombobox-min-width`
- `--tui-multicombobox-control-bg`
- `--tui-multicombobox-control-fg`
- `--tui-multicombobox-control-border`
- `--tui-multicombobox-control-border-hover`
- `--tui-multicombobox-control-border-focus`
- `--tui-multicombobox-control-radius`
- `--tui-multicombobox-content-bg`
- `--tui-multicombobox-content-fg`
- `--tui-multicombobox-content-border`
- `--tui-multicombobox-content-shadow`
- `--tui-multicombobox-content-radius`
- `--tui-multicombobox-option-radius`
- `--tui-multicombobox-option-bg-hover`
- `--tui-multicombobox-option-bg-selected`
- `--tui-multicombobox-option-fg-hover`
- `--tui-multicombobox-option-fg-selected`
- `--tui-multicombobox-option-bg-selected-hover`
- `--tui-multicombobox-option-check`
- `--tui-multicombobox-option-gap`

---

Interactive version: https://storybook-tangible-ui.pages.dev/?path=/docs/forms-multicombobox--docs
