Combobox
View as MarkdownAn input with a popup list for searching and selecting values from a collection.
Features
Permalink to heading "Features"- Searchable list with keyboard navigation
- Single and multiple selection
- Disabled items and item groups
- Works with the Field component for forms and validation
- Submits the
valueof the selected items throughhiddenInput, the visible input shows their labels emptyplaceholder for a search without matches- Locale-aware filtering in the default entry file, replaceable per instance through
onInputValueChange - Async, server-rendered search results via
ui:template dialogpopup type moves the input into the popup, behind a focusable trigger
hiddenInput submits the value of the selected items. Place it once anywhere inside combobox.root and it renders one visually hidden input per selected value, or a single empty one while nothing is selected. ui:combobox.root includes it for you. A Field focuses the combobox through that input when it is the first invalid field of a submitted form, and the input hands the focus on to the visible one.
Place the options inside list, which carries the listbox semantics and scrolling. content wraps it and is announced as a dialog with the dialog popup type. The styled ui:combobox.content combines positioner and content in one part, so you nest ui:combobox.list in it yourself.
combobox.empty is a placeholder for a collection with nothing to show, because no item matches the search text or an async search is still waiting for results. Place it next to combobox.list inside content. It shows and hides itself.
<primitives:combobox.root>
<primitives:combobox.label />
<primitives:combobox.control>
<primitives:combobox.input />
<primitives:combobox.clearTrigger />
<primitives:combobox.trigger />
</primitives:combobox.control>
<primitives:combobox.positioner>
<primitives:combobox.content>
<primitives:combobox.empty />
<primitives:combobox.list>
<primitives:combobox.item>
<primitives:combobox.itemText />
<primitives:combobox.itemIndicator />
</primitives:combobox.item>
<primitives:combobox.itemGroup>
<primitives:combobox.itemGroupLabel />
</primitives:combobox.itemGroup>
</primitives:combobox.list>
</primitives:combobox.content>
</primitives:combobox.positioner>
<primitives:combobox.hiddenInput />
</primitives:combobox.root>
Installation
Permalink to heading "Installation"typo3 ui:add combobox
Please copy the files manually from GitHub into your project.
Read more about installing Components and Primitives.
Examples
Permalink to heading "Examples"Default value
Permalink to heading "Default value"Pass defaultValue to preselect an item. The demo opens with Nigeria in the input, rendered on the server.
Disabled items
Permalink to heading "Disabled items"Set disabled: true on an item of the collection to make it unselectable. Oracle Database and Microsoft SQL Server are disabled in the demo.
With item groups
Permalink to heading "With item groups"Set groupByKey on ui:listCollection to group the items, here by their category. Type in the demo and groups without a match disappear.
With form field
Permalink to heading "With form field"Wrap the combobox in ui:field.root to share label, name, required and invalid state. The demo is a required country field.
Multiple selection
Permalink to heading "Multiple selection"Set multiple="{true}" to select several values. The demo lists the selected cities above the input.
Change the filter
Permalink to heading "Change the filter"Pass your own onInputValueChange in a custom entry file to change how items match, here by the start of the label with startsWith. Type "b" in the demo and the list shrinks to the cities starting with B.
Async search
Permalink to heading "Async search"Fetch matching items from a server-side search endpoint as people type. Type a city in the demo to see the results come in.
Write the item markup once inside a ui:template block and pass the endpoint as searchUrl. The entry file queries it, clones the template for every result and rebuilds the collection. combobox.item, combobox.itemText and combobox.itemIndicator detect the template on their own, so they take no value. collection is optional when no items are known up front.
combobox.empty shows whenever no item is rendered: before the first query, while a request runs, after an error and for a query without matches. Its content is yours to update, here a spinner and a status text. They are slot content, so their ui:ref takes context: 'combobox', as in {ui:ref(name: 'statusSpinner', context: 'combobox')}.
The demo sends the query with extbase.post(), fetches with AsyncList and delays the spinner with a DelayedIndicator to avoid flicker on fast responses.
Async search with groups
Permalink to heading "Async search with groups"Group the results the endpoint returns, here by country. Write a second ui:template for the group (combobox.itemGroup with combobox.itemGroupLabel), clone it once per group, append the cloned items to the group and the group to combobox.list. Pass the group key as the value of its Template so the groups stay apart.
Move the input into the popup
Permalink to heading "Move the input into the popup"Set popupType="{f:constant(name: 'Jramke\FluidPrimitives\Enum\PopupType::Dialog')}" for a popover-style picker: a trigger opens the popup and the input sits at the top of the content, above the list. content is announced as a dialog, and the trigger is focusable (its own focusable prop overrides that). With the input in the popup, the trigger shows the selection itself, here through a valueText element the entry file keeps in sync with api.valueAsString. Open the picker in the demo and type to filter.
Localization
Permalink to heading "Localization"The labels of the trigger and the clear button ship in the language file and follow the site language. Pass translations to override them for one combobox.
<f:variable
name="comboboxTranslations"
value="{
triggerLabel: '{f:translate(key: \'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:combobox.trigger\')}',
clearTriggerLabel: '{f:translate(key: \'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:combobox.clear\')}'
}"
/>
<ui:combobox.root translations="{comboboxTranslations}"> ... </ui:combobox.root>
API Reference
Permalink to heading "API Reference"The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.
combobox.root
Permalink to heading "combobox.root"Provides shared combobox state and wraps all related parts. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
collection | Domain\Dto\ListCollectionThe item collection. | Yes | - |
name | stringThe `name` attribute of the underlying select. Inherited from a surrounding field when available. | No | - |
form | stringThe associate form of the underlying select. | No | - |
disabled | booleanWhether the select is disabled. Inherited from a surrounding field when available. | No | - |
invalid | booleanWhether the select is invalid. Inherited from a surrounding field when available. | No | - |
readOnly | booleanWhether the select is read-only. Inherited from a surrounding field when available. | No | - |
required | booleanWhether the select is required. Inherited from a surrounding field when available. | No | - |
placeholder | stringThe placeholder text of the combobox's input. | No | - |
defaultOpen | booleanThe initial open state of the combobox when rendered. Use when you don't need to control the open state of the combobox. | No | false |
defaultValue | mixedThe initial value of the combobox's selected items when rendered. Use when you don't need to control the value of the combobox's selected items. | No | - |
defaultInputValue | stringThe initial value of the combobox's input when rendered. Use when you don't need to control the value of the combobox's input. | No | - |
defaultHighlightedValue | stringThe initial highlighted value of the combobox when rendered. Use when you don't need to control the highlighted value of the combobox. | No | - |
openOnClick | booleanWhether to open the combobox popup on initial click on the input. | No | false |
openOnKeyPress | booleanWhether to open the combobox on arrow key press. | No | true |
openOnChange | booleanWhether to show the combobox when the input value changes. | No | true |
closeOnSelect | booleanWhether to close the combobox when an item is selected. Defaults to `true` or if multiple enabled `false`. | No | - |
loopFocus | booleanWhether to loop focus within the combobox. | No | true |
multiple | booleanWhether to allow multiple selection. **Good to know:** When `multiple` is `true`, the `selectionBehavior` is automatically set to `clear`. It is recommended to render the selected items in a separate container. | No | - |
allowCustomValue | booleanWhether to allow typing custom values in the input. | No | false |
alwaysSubmitOnEnter | booleanWhether to always submit on Enter key press, even if popup is open. Useful for single-field autocomplete forms where Enter should submit the form. | No | false |
inputBehavior | Enum\ComboboxInputBehaviorDefines the auto-completion behavior of the combobox. - `autohighlight`: The first focused item is highlighted as the user types - `autocomplete`: Navigating the listbox with the arrow keys selects the item and the input is updated. | No | None |
selectionBehavior | Enum\ComboboxSelectionBehaviorThe behavior of the combobox input when an item is selected - `replace`: The selected item string is set as the input value - `clear`: The input value is cleared - `preserve`: The input value is preserved. Defaults to `replace` or if multiple enabled `clear` | No | - |
popupType | Enum\PopupTypeThe kind of popup the combobox's content is: `listbox` for a regular combobox, `dialog` when it holds other interactive content. | No | Listbox |
autoFocus | booleanWhether to autofocus the input on mount. | No | - |
positioning | arrayThe positioning options to dynamically position the menu. | No | {
"placement": "bottom",
"sameWidth": true
} |
translations | arrayLocalized combobox labels. Use `f:translate` for per-template localization overrides when needed. | No | - |
searchUrl | stringEndpoint queried for async search results (e.g. built with f:uri.action in the consuming template). The consumer's own controller/entry.ts owns the request/response shape. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
rootId | stringThe root ID of the component, used for hydration and identification. | No | - |
ids | arrayThe IDs of of the component parts for composition. | No | [] |
autoMount | booleanWhether the client initializes the component on its own. Set it to false to mount it yourself with `mount()` | No | true |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-root | <uid> |
data-invalid | Present when invalid |
data-readonly | Present when read-only |
combobox.label
Permalink to heading "combobox.label"Labels the combobox. Renders a <label> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-label | <uid> |
data-readonly | Present when read-only |
data-disabled | Present when disabled |
data-invalid | Present when invalid |
data-required | Present when required |
data-focus | Present when focused |
combobox.control
Permalink to heading "combobox.control"Groups the input and its trigger/clear buttons. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-control | <uid> |
data-state | "open" | "closed" |
data-focus | Present when focused |
data-disabled | Present when disabled |
data-invalid | Present when invalid |
combobox.input
Permalink to heading "combobox.input"The text input used to search and select from the collection. Renders an <input> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-input | <uid> |
data-invalid | Present when invalid |
data-autofocus | |
data-state | "open" | "closed" |
combobox.clearTrigger
Permalink to heading "combobox.clearTrigger"Clears the current input value and selection. Renders a <button> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-clear-trigger | <uid> |
data-invalid | Present when invalid |
combobox.trigger
Permalink to heading "combobox.trigger"Opens and closes the combobox listbox. Not focusable unless focusable is set, or popupType is dialog. Renders a <button> element.
| Name | Description | Required | Default |
|---|---|---|---|
focusable | booleanWhether the trigger can receive focus. By default only the trigger of a combobox with `popupType` `dialog` can - otherwise the input is the focus target and the trigger stays out of the tab order. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-trigger | <uid> |
data-state | "open" | "closed" |
data-invalid | Present when invalid |
data-focusable | |
data-readonly | Present when read-only |
data-disabled | Present when disabled |
combobox.positioner
Permalink to heading "combobox.positioner"Positions the floating combobox content. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-positioner | <uid> |
data-nested | Present when the positioner is nested within another {{widget}} |
data-has-nested | Present when the positioner has nested {{widget}}s |
combobox.content
Permalink to heading "combobox.content"The popup surface, positioned by positioner. Holds the list and empty and, with popupTypedialog, the input too. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-content | <uid> |
data-state | "open" | "closed" |
data-placement | The placement of the content |
data-side | The side of the trigger that the content is positioned on |
data-empty | Present when the content is empty |
data-nested | listbox |
data-has-nested | listbox |
combobox.list
Permalink to heading "combobox.list"The listbox inside content that holds the options - it scrolls and carries role="listbox". Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-list | <uid> |
data-empty | Present when the content is empty |
combobox.empty
Permalink to heading "combobox.empty"Displays a placeholder for when no items match the current search. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
combobox.item
Permalink to heading "combobox.item"Represents a selectable option. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
item | mixedThe collection item for this combobox option. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-item | <uid> |
data-highlighted | Present when highlighted |
data-state | "checked" | "unchecked" |
data-disabled | Present when disabled |
data-value | The value of the item |
combobox.itemText
Permalink to heading "combobox.itemText"Displays the text content of an option. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-item-text | <uid> |
data-state | "checked" | "unchecked" |
data-disabled | Present when disabled |
data-highlighted | Present when highlighted |
combobox.itemIndicator
Permalink to heading "combobox.itemIndicator"Displays the selected-state indicator for an option. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-item-indicator | <uid> |
data-state | "checked" | "unchecked" |
combobox.itemGroup
Permalink to heading "combobox.itemGroup"Groups related options together. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
value | stringThe value identifier of the item group. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Rendered data attributes
| Attribute | Description |
|---|---|
data-combobox-item-group | <uid> |
data-empty | Present when the content is empty |
combobox.itemGroupLabel
Permalink to heading "combobox.itemGroupLabel"Labels a group of related options. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
combobox.hiddenInput
Permalink to heading "combobox.hiddenInput"Provides the real, submittable value(s) for the selected item(s), since the visible input only ever holds label text. Renders one <input> element per selected value, or one empty <input> while nothing is selected.
| Name | Description | Required | Default |
|---|---|---|---|
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
Machine JavaScript API
Permalink to heading "Machine JavaScript API"| Name | Type | Description |
|---|---|---|
focused | boolean | Whether the combobox is focused |
open | boolean | Whether the combobox is open |
inputValue | string | The value of the combobox input |
highlightedValue | string | null | The value of the highlighted item |
highlightedItem | V | null | The highlighted item |
setHighlightValue | (value: string) => void | The value of the combobox input |
clearHighlightValue | VoidFunction | Function to clear the highlighted value |
syncSelectedItems | VoidFunction | Function to sync the selected items with the value. Useful when `value` is updated from async sources. |
selectedItems | V[] | The selected items |
hasSelectedItems | boolean | Whether there's a selected item |
value | string[] | The selected item keys |
valueAsString | string | The string representation of the selected items |
selectValue | (value: string) => void | Function to select a value |
setValue | (value: string[]) => void | Function to set the value of the combobox |
clearValue | (value?: string) => void | Function to clear the value of the combobox |
focus | VoidFunction | Function to focus on the combobox input |
setInputValue | (value: string, reason?: InputValueChangeReason) => void | Function to set the input value of the combobox |
getItemState | (props: ItemProps) => ItemState | Returns the state of a combobox item |
setOpen | (open: boolean, reason?: OpenChangeReason) => void | Function to open or close the combobox |
collection | ListCollection<V> | Function to toggle the combobox |
reposition | (options?: Partial<PositioningOptions>) => void | Function to set the positioning options |
multiple | boolean | Whether the combobox allows multiple selections |
disabled | boolean | Whether the combobox is disabled |
getRootState | () => RootState | Returns the state of the root |
getContentState | () => ContentState | Returns the state of the content |
getTriggerState | (props?: TriggerProps) => TriggerState | Returns the state of the trigger |
Accessibility
Permalink to heading "Accessibility"| Key | Description |
|---|---|
ArrowDown | When the combobox is closed, opens the listbox and highlights to the first option. When the combobox is open, moves focus to the next option. |
ArrowUp | When the combobox is closed, opens the listbox and highlights to the last option. When the combobox is open, moves focus to the previous option. |
Home | When the combobox is open, moves focus to the first option. |
End | When the combobox is open, moves focus to the last option. |
Escape | Closes the listbox. |
Enter | Selects the highlighted option and closes the combobox. |
Esc | Closes the combobox |