Luke UI
GitHub repository

Combobox primitives

Lower-level parts for composing a searchable single-select combobox.

Use these primitives when ComboboxField does not fit your layout or loading UI. They expose the control, popover, listbox, and option parts used by ComboboxField. Start with ComboboxField when it fits.

Combobox primitives — Basic

Anatomy

ComboboxRoot owns the searchable single-select state. Put the control and popover inside it. Put the text input and trigger in ComboboxInputGroup. Put the listbox and its items in ComboboxPopover.

<ComboboxRoot defaultItems={countries} aria-label="Country">
	<ComboboxInputGroup>
		<ComboboxInput />
		<ComboboxTrigger aria-label="Toggle options" />
	</ComboboxInputGroup>
	<ComboboxPopover>
		<ComboboxListBox<{ id: string; label: string }>>
			{(item) => <ComboboxItem>{item.label}</ComboboxItem>}
		</ComboboxListBox>
	</ComboboxPopover>
</ComboboxRoot>

Control and options

ComboboxInput opens the menu when someone clicks it and supplies the editable combobox input. ComboboxTrigger toggles the option menu. ComboboxClearButton renders only when the root has a selection and clears both the selection and input value.

Use ComboboxItem for options. It adds a checkmark for the selected option. ComboboxSection groups related options and can render a heading. ComboboxListBox accepts static children or a render function with items. Its loadMoreItem slot appends content after the main collection.

Size

Set size on ComboboxRoot to give the control and option primitives a shared size. Individual ComboboxInputGroup, ComboboxInput, ComboboxClearButton, ComboboxTrigger, ComboboxItem, and ComboboxLoadMoreItem components can override that size when necessary. ComboboxInputGroup sizes a nested Icon the same way InputGroup does at the same control size.

Loading and empty results

Use ComboboxLoadMoreItem as the listbox's load-more sentinel. Use ComboboxEmptyState for custom empty content, including a loading message or spinner. ComboboxField supplies common loading and empty-state handling when its built-in composition is enough.

Tray presentation

ComboboxTray shows options in a full-screen tray. Pair it with ComboboxTrayTrigger to show the current selection and open the tray.

Combobox primitives — Tray

Inside the tray, ComboboxInput is the search field. ComboboxClearButton clears the search and the selection. ComboboxField chooses the tray or the popover for you.

ComboboxRoot defaults allowsEmptyCollection to true, so typing a filter that matches no options keeps the tray open for empty states and custom values.

While the tray is closed, ComboboxTrayTrigger keeps constraint validation and form submission working. Pass isRequired, validationBehavior, isDisabled, isReadOnly, form, and allowsCustomValue on the root.

Set isRequired so a field blocks submit until someone chooses a value, or enters custom text when allowsCustomValue is set. Set validationBehavior="aria" on the root to report validation through ARIA instead of the constraint API.

The field submits under the root's name. By default that value is the selected key. Set formValue="text", or set allowsCustomValue, to submit text instead — including a selected option's label, or custom text that has no key. The search field does not submit, so the field sends one value whether the tray is open or closed.

A read-only field still submits. So does a field with validationBehavior="aria". A disabled field submits nothing in text mode. In key mode a disabled field still submits the selected key.

Popover and accessibility

ComboboxPopover preserves the active Luke UI theme identity and explicit colour mode when it portals the listbox. It portals a desktop-style positioned popover and never becomes a tray. Use ComboboxTray for the tray presentation.

Give ComboboxRoot an accessible name with aria-label or a connected label. Keep the root/control/input/listbox structure so React Aria's combobox semantics and keyboard behaviour remain intact.

API

ComboboxRootProps

ComboboxRootProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxInputGroupProps

ComboboxInputGroupProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxInputProps

ComboboxInputProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxClearButtonProps

ComboboxClearButtonProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxTriggerProps

ComboboxTriggerProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxPopoverProps

ComboboxPopoverProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxTrayTriggerProps

ComboboxTrayTriggerProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxTrayProps

ComboboxListBoxProps

ComboboxListBoxProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxItemProps

ComboboxItemProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxLoadMoreItemProps

ComboboxLoadMoreItemProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxSectionProps

ComboboxSectionProps also accepts compatible DOM and ARIA attributes and event handlers for its rendered element.

Prop

Type

ComboboxEmptyStateProps