--- layout: layouts/page.njk title: Combobox description: Autocomplete input and command palette with a list of suggestions. toc: - label: Usage id: usage children: - label: HTML + JavaScript id: usage-html-js children: - label: "Step 1: Include the JavaScript files" id: usage-html-js-1 - label: "Step 2: Add your combobox HTML" id: usage-html-js-2 - label: HTML structure id: usage-html-js-3 - label: JavaScript events id: usage-html-js-4 - label: JavaScript methods id: usage-html-js-5 - label: Jinja and Nunjucks id: usage-macro - label: Examples id: examples children: - label: Scrollable id: example-scrollable - label: Top side id: example-top --- {% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} {% from "select.njk" import select %} {% set options_frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"] %} {% set code_html %} {% call select( trigger_attrs={"class": "w-[200px]"}, listbox_attrs={"data-empty": "No framework found."}, is_combobox=true, search_placeholder="Search framework..." ) %} {% for framework in options_frameworks %}
You can either include the JavaScript file for all the components, or just the one for this component by adding this to the <head> of your page:
Combobox uses the same markup and JavaScript as the Select component, the only difference being the search box at the top of the listbox:
<div class="select"><button type="button" popovertarget="{ POPOVER_ID }">The trigger to open the popover, can also have the following attributes:
id="{BUTTON_ID}": linked to by the aria-labelledby attribute of the listbox.aria-haspopup="listbox": indicates that the button opens a listbox.aria-controls="{ LISTBOX_ID }": points to the listbox's id.aria-expanded="false": tracks the popover's state.aria-activedescendant="{ OPTION_ID }": points to the active option's id.<div popover class="popover" id="{ POPOVER_ID }">data-side and data-align attributes.
<header><div role="listbox">id="{ LISTBOX_ID }": refered to by the aria-controls attribute of the trigger.aria-labelledby="{ BUTTON_ID }": linked to by the button's id attribute.<div role="option" data-value="{ VALUE }">aria-activedescendant attribute on the trigger. Optional attributes:
data-filter: custom text used for filtering (if different from displayed content, e.g., data-filter="united states")data-keywords: additional keywords for enhanced filtering (e.g., data-keywords="bread fruit")data-force: forces the option to always display, regardless of filter (e.g., data-force)aria-disabled="true": marks option as disabled (excluded from selection and keyboard navigation)<hr role="separator"> Optional<div role="group"> Optionalaria-labelledby attribute to link to a heading.<span role="heading">id attribute if you use the aria-labelledby attribute on the group.<input type="hidden" name="{ NAME }" value="{ VALUE }"> Optionalbasecoat:initializedbasecoat:initialized event on itself.basecoat:popoverbasecoat:popover event on document. Other popover components (Combobox, Dropdown Menu, Popover and Select) listen for this to close any open popovers.changechange event on itself, with the selected value in event.detail (e.g. {detail: {value: "something"}}).selectByValueYou can call this method on the component after it is initialized to select an option by value (i.e. the option with the matching data-value attribute):
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).