Skip to content

Combobox

An autocomplete text input with a filtered list. Options are authored as item parts with data-value; stimulus-zag builds the collection from them and filters it client-side as you type (case-insensitive label match), hiding non-matches.

html
<div data-controller="zag-combobox" data-part="root" class="relative max-w-xs">
  <label data-part="label" class="mb-1 block text-sm font-medium">Search a fruit</label>
  <div
    data-part="control"
    class="border-input bg-popover focus-within:ring-ring/50 flex items-center rounded-lg border focus-within:ring-2"
  >
    <input
      data-part="input"
      placeholder="Type to filter…"
      class="w-full rounded-l-lg px-3 py-2 text-sm focus:outline-none"
    />
    <button data-part="trigger" class="text-muted-foreground px-2" aria-label="Toggle">▾</button>
  </div>
  <div data-part="positioner">
    <ul
      data-part="content"
      hidden
      class="border-border bg-popover z-50 max-h-60 w-[var(--reference-width)] overflow-auto rounded-lg border p-1 shadow-lg focus:outline-none"
    >
      <li
        data-part="item"
        data-value="apple"
        class="data-[highlighted]:bg-primary data-[highlighted]:text-primary-foreground cursor-pointer rounded-md px-3 py-2 text-sm"
      >
        <span data-part="item-text">Apple</span>
      </li>
      <li
        data-part="item"
        data-value="banana"
        class="data-[highlighted]:bg-primary data-[highlighted]:text-primary-foreground cursor-pointer rounded-md px-3 py-2 text-sm"
      >
        <span data-part="item-text">Banana</span>
      </li>
      <li
        data-part="item"
        data-value="cherry"
        class="data-[highlighted]:bg-primary data-[highlighted]:text-primary-foreground cursor-pointer rounded-md px-3 py-2 text-sm"
      >
        <span data-part="item-text">Cherry</span>
      </li>
      <li
        data-part="item"
        data-value="grape"
        class="data-[highlighted]:bg-primary data-[highlighted]:text-primary-foreground cursor-pointer rounded-md px-3 py-2 text-sm"
      >
        <span data-part="item-text">Grape</span>
      </li>
      <li
        data-part="item"
        data-value="mango"
        class="data-[highlighted]:bg-primary data-[highlighted]:text-primary-foreground cursor-pointer rounded-md px-3 py-2 text-sm"
      >
        <span data-part="item-text">Mango</span>
      </li>
    </ul>
  </div>
</div>

Parts

root, label, control, input, trigger, clear-trigger, positioner, content, list, item, item-text, item-indicator.

Values

AttributeTypeDefaultDescription
data-zag-combobox-value-valueArray[]Selected value(s) by default (JSON).
data-zag-combobox-multiple-valueBooleanfalseAllow multiple selections.
data-zag-combobox-name-valueString""name for form submission.
data-zag-combobox-placeholder-valueString""Input placeholder.
data-zag-combobox-input-behavior-valueString"none""none", "autohighlight", "autocomplete".
data-zag-combobox-open-on-click-valueBooleantrueOpen the list when the input is clicked.
data-zag-combobox-allow-custom-value-valueBooleanfalseAccept values not in the list.
data-zag-combobox-loop-focus-valueBooleanfalseWrap keyboard focus.
data-zag-combobox-disabled-valueBooleanfalseDisable the combobox.
data-zag-combobox-required-valueBooleanfalseMark required.
data-zag-combobox-invalid-valueBooleanfalseMark invalid.
data-zag-combobox-read-only-valueBooleanfalseRead-only.

Events

Emits zag-combobox:change ({ value, items }), zag-combobox:input ({ inputValue }), and zag-combobox:open-change.

Programmatic control

value (getter), inputValue (getter), setValue(string[]), setInputValue(text), clear(), open(), close(), isOpen.