Zazz Design Framework
Components

Combobox

An input combined with a predefined list, filtering options like a select.

A <ui-combobox> looks like a select and filters like an autocomplete, but never submits free text. The form value lives in an authored hidden input (data-slot="combobox-value"), synced whenever the selection changes. Options match against their visible label and carry their machine value in data-value. Selected options get aria-selected and the shared option checkmark.

The visible input carries a display value, not the filter. Committing writes the option label into the input and clears the query. Reopening by clicking the control or chevron shows the full list with the committed row checked, matching Select. Opening selects that label so the first keystroke replaces it. Focus alone does not open the panel, keeping keyboard tab navigation quiet. On blur, stray text reverts to the committed label, and cleared text clears the selection.

Omit the popover attribute on the panel for the inline variant: the list renders in flow and stays open without a floating surface, chevron, or dismissal. Filtering, highlighting, and committing work identically. This variant fits inside surfaces that already float, such as a Menubar help menu.

Without JavaScript this control remains inert. When a no-JS fallback is required, use Select instead.

Default

Loading components…

Multiselect

Add data-variant="multiselect" to select a set of values. Committing toggles a row instead of replacing the selection, and the panel stays open to allow multiple picks. Each selected value renders as a removable tag inside the control while the input continues filtering beside them. Pressing Backspace on an empty input removes the last tag, and the control wraps onto extra rows as tags accumulate.

A tag's markup is HTML, not script. Author a <template data-slot="combobox-tag-template"> and the combobox clones it once per selected value, filling in the label (combobox-tag-label), the value, and the remove button's accessible name (combobox-tag-remove). Changing the badge variant, adding an icon, or swapping the component requires no script changes. Omitting the template uses the default muted badge.

Options with aria-selected="true" are the single source of truth. Tags and hidden inputs derive from them in DOM order. The form submits repeated name pairs like <select multiple>: the authored hidden input carries the first value, and stamped siblings carry the rest. Because tags are stamped by script, server-rendered selections stay invisible without JavaScript (though values still submit). Where server-rendered initial state matters, use <ui-multiselect> instead.

Loading components…

API

AttributeTargetValues
data-variantRootmultiselect: select a set, shown as removable tags
data-label-removeRootTag remove-button label (default: Remove {label})
data-slot<template> in the rootcombobox-tag-template: tag blueprint (optional)
data-value[data-slot="combobox-item"]Submitted value (label is the match text)
data-keywords[data-slot="combobox-item"]Space-separated extra match targets
aria-selected[data-slot="combobox-item"]true seeds the selection from markup
data-sortRootscore: rank by match (default: DOM order)
data-min-lengthRootCharacters before typing opens the panel
name / value[data-slot="combobox-value"]The hidden input the form submits
data-side / data-align[data-slot="combobox-panel"]Placement (popover matrix)

On this page