Combobox

Autocomplete input and command palette with a list of suggestions.

Usage

HTML + Javascript

This component requires Javascript.

Combobox uses the same Alpine.js code and markup as the Select component, the only difference being the search box at the top of the listbox.

You can set up a few additional options on the <div data-popover> element:

  • data-side can be set to top, bottom, left, or right to change the side of the popover.
  • data-align can be set to start, center, or end to change the alignment of the popover.
  • data-empty to set up the message when the search is empty.

You can include the Javascript code provided below, load it as an individual file or use the CLI. Some Alpine.js properties are also required on certain elements (e.g. x-bind, x-data, @click).

<div class="popover" x-data="select('', '')" @click.away="open = false">
  <button type="button" aria-haspopup="listbox" aria-expanded="false" x-bind="$trigger" class="btn-outline justify-between font-normal w-[200px]">
    <div x-html="selectedLabel" class="flex items-center gap-x-2"></div>

    <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevrons-up-down-icon lucide-chevrons-up-down text-muted-foreground opacity-50 shrink-0">
      <path d="m7 15 5 5 5-5" />
      <path d="m7 9 5-5 5 5" />
    </svg>
  </button>
  <div data-popover aria-hidden="true" x-bind="$content">
    <header>
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search-icon lucide-search">
        <circle cx="11" cy="11" r="8" />
        <path d="m21 21-4.3-4.3" />
      </svg>
      <input type="text" value="" placeholder="Search framework..." autocomplete="off" autocorrect="off" spellcheck="false" aria-autocomplete="list" role="combobox" aria-expanded="true" aria-controls="-content" aria-labelledby="-trigger" x-model="query" x-bind="$filter" />
    </header>

    <div role="listbox" aria-orientation="vertical" data-empty="No framework found.">
      <div role="option" data-value="Next.js">Next.js</div>

      <div role="option" data-value="SvelteKit">SvelteKit</div>

      <div role="option" data-value="Nuxt.js">Nuxt.js</div>

      <div role="option" data-value="Remix">Remix</div>

      <div role="option" data-value="Astro">Astro</div>
    </div>
  </div>
</div>

Jinja and Nunjucks

You can use the select() Nunjucks or Jinja macro for this component. If you use one of the macros, make sure to set is_combobox to True (or true for Nunjucks).

{% call select(
  listbox_attrs={"data-empty": "No framework found."},
  is_combobox=true
) %}
  <div role="option" data-value="nextjs">Next.js</div>
  <div role="option" data-value="sveltekit">SvelteKit</div>
  <div role="option" data-value="nuxtjs">Nuxt.js</div>
  <div role="option" data-value="remix">Remix</div>
  <div role="option" data-value="astro">Astro</div>
{% endcall %}

Examples

Scrollable

Top side