ComboBox

A ComboBox puts a text input, a popover, and a listbox together in one accessible selection pattern. It permits one selection or more than one selection. You can control its state, or you can let the component control it. The keyboard operates all of it, and the component has a pending state for asynchronous data.

Anatomy

ComboBox.Root holds the open state, the input text, the selection, and the filter. You assemble the other parts inside it as you want. ComboBox.Clear and ComboBox.Trigger are optional, and they never take the focus from the input.

<script>
	import { ComboBox } from '@human-kit/ui';
</script>

<ComboBox.Root>
	<ComboBox.Input />
	<ComboBox.Clear />
	<ComboBox.Trigger />
	<ComboBox.Popover>
		<ComboBox.List>
			<ComboBox.Item id="1">Option 1</ComboBox.Item>
		</ComboBox.List>
	</ComboBox.Popover>
</ComboBox.Root>

Tags for more than one selection

Set selectionMode="multiple", and show the selected values with ComboBox.Tags, ComboBox.Tag, and ComboBox.TagRemove. The popover stays open after each selection. If the input is empty, the Backspace key removes the last tag.

Open modes

The trigger prop controls when the popover opens. With "focus", the popover opens when the input gets the focus. With "input", the popover opens when the user starts to type. With "press", the popover opens only when the user pushes ComboBox.Trigger. Change the mode below, then open the field again to see the difference.

Pending state

Set pending on ComboBox.Root to show the state of an asynchronous request. The root gets data-pending, and the trigger button and the clear button stop their operation. The input stays editable, thus the user can change the query.

Usage guidelines

  • Put all of the parts in ComboBox.Root.
  • Use the controlled props (value, inputValue, and open) only when your own code must hold the state.
  • Use pending on ComboBox.Root to show the state of an asynchronous request on the root. The other parts stay under your control.
  • In new code, use ComboBox.Trigger. ComboBox.Button is still available, but only for compatibility.
  • Use ComboBox.Clear when you want a control that removes the input text and the selected value together.
  • In the multiple mode, use ComboBox.Tags, ComboBox.Tag, and ComboBox.TagRemove to show the selected values.
  • Select trigger="focus", trigger="input", or trigger="press" for the open behavior that you want.
  • On a server, give the root a stable id. Thus the ARIA ids stay the same.

Accessibility

  • ComboBox.Input has role="combobox" with aria-autocomplete="list", aria-haspopup="listbox", and aria-expanded. Its aria-controls attribute points at the list.
  • The DOM focus stays in the input. The arrow keys move a virtual focus through the options with aria-activedescendant.
  • The list has role="listbox". Each option has role="option" with aria-selected.
  • The Enter key selects the option with the virtual focus. The Escape key closes the popover. When the user types, the component filters the list.
  • If there is no label that the user sees, give ComboBox.Root or ComboBox.Input an aria-label or an aria-labelledby attribute.

API reference

Root

The container with the state. It holds the open state, the input text, the selection, the filter, and the keyboard operation.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-combobox Identifies the combobox root element.
data-disabled Present when the combobox is disabled.
data-focus-visible Present while the focus must be visible (keyboard modality).
data-focus-within Present while focus is inside the combobox.
data-focused Present while the combobox has focus.
data-pending Present while the combobox is in a pending (busy) state.
data-readonly Present when the combobox is readonly.

Input

A text input with role="combobox". It keeps the text, the active descendant, and the keyboard operation correct with the root.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-form-type Tells a password manager that the field is not a credential. The manager then ignores the field.
data-lpignore Tells LastPass not to put its autofill overlay on the field. That overlay would cover the listbox.

Trigger

An optional button that opens and closes the popover. It does not take the focus from the input.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-open Present while the popover is open.

Button

A second name for ComboBox.Trigger, for compatibility. In new code, use ComboBox.Trigger.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Clear

An optional button that removes the input text and the selection. It does not take the focus from the input. It is disabled when there is nothing to remove.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Popover

The container of the options, which floats against the input group. It uses Popover.Root and Popover.Content in the non-modal mode.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

List

The listbox of the options. ComboBox.Root holds the selection state and the selection mode. This part also accepts ListBox.Root props, for example class and emptyPlaceholder.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Item

An option that the user can select. It has the combobox filter, the virtual focus, and the registration. It needs a unique id. For an item that does an action and does not select, use onAction.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

ItemIndicator

The selection mark in a ComboBox.Item. The default is a check mark icon.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-state "checked" while the item is selected, "unchecked" otherwise.

Status

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Tags

The container that makes a tag for each selected value, in the multiple mode. It has an optional mode that keeps the tags on one line.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Tag

One tag, for one selected value, in the multiple selection mode.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-disabled Present when the combobox is disabled.
data-focused Present while the tag is focused.
data-tag-id The selected item id represented by the tag.

TagRemove

The button that removes its tag from the selection.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.