--- layout: layouts/page.njk title: Select description: Displays a list of options for the user to pick from—triggered by a button. toc: - label: Usage id: usage children: - label: HTML id: usage-html - 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 select 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: Disabled id: example-disabled - label: With icon id: example-with-icon --- {% from "macros/code_preview.njk" import code_preview %} {% from "macros/code_block.njk" import code_block %} {% from "select.njk" import select %} {% set code_native %}{% endset %} {{ code_preview("select-native", code_native) }} {% set code_html %} {{ select( trigger_attrs={"class": "w-[180px]"}, is_combobox=true, items=[ { type: "group", label: "Fruits", items: [ { type: "item", value: "apple", label: "Apple", attrs: {"data-force": "true"} }, { type: "item", value: "banana", label: "Banana", attrs: {"data-keywords": "bread"} }, { type: "item", value: "blueberry", label: "Blueberry" }, { type: "item", value: "pineapple", label: "Grapes" }, { type: "item", value: "pineapple", label: "Pineapple" } ] } ] ) }} {% endset %} {% set code_script %} {% endset %} {{ code_preview("select", code_script | prettyHtml ~ code_html | prettyHtml) }}

Usage

HTML

If you use a <select> element, just add the select class to it or have a parent with the form class (read more about form).

{{ code_block(code_native) }}

HTML + JavaScript

Step 1: Include the JavaScript files

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:

{% set code_script %} {% endset %} {{ code_block(code_script | prettyHtml, "html") }}
Components with JavaScript {% lucide "arrow-right" %} Use the CLI {% lucide "arrow-right" %} select.js {% lucide "arrow-right" %}

Step 2: Add your select HTML

{{ code_block(code_html | prettyHtml, "html") }}

HTML structure

<div class="select">
Wraps around the entire component.
<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 }">
As with the Popover component, you can set up the side and alignment of the popover using the data-side and data-align attributes.
<div role="listbox">
The listbox containing the options. Should have the following attributes:
  • 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 }">
Option that can be selected.Should have a unique id if you use the aria-activedescendant attribute on the trigger.
<hr role="separator"> Optional
Separator between groups/options.
<div role="group"> Optional
Group of options, can have a aria-labelledby attribute to link to a heading.
<span role="heading">
Group heading, must have an id attribute if you use the aria-labelledby attribute on the group.
<input type="hidden" name="{ NAME }" value="{ VALUE }"> Optional
The hidden input that holds the value of the field (if needed).

JavaScript events

basecoat:initialized
Once the component is fully initialized, it dispatches a custom (non-bubbling) basecoat:initialized event on itself.
basecoat:popover
When the popover opens, the component dispatches a custom (non-bubbling) basecoat:popover event on document. Other popover components (Combobox, Dropdown Menu, Popover and Select) listen for this to close any open popovers.
change
When the selected value changes, the component dispatches a custom (bubbling) change event on itself, with the selected value in event.detail (e.g. { detail: { value: "something" }}).

JavaScript methods

selectByValue

You 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):

{% set code_script %}{% endset %} {{ code_block(code_script | prettyHtml, "html") }}

Jinja and Nunjucks

You can use the select() Nunjucks or Jinja macro for this component.

Use Nunjucks or Jinja macros {% lucide "arrow-right" %} Jinja macro {% lucide "arrow-right" %} Nunjucks macro {% lucide "arrow-right" %}
{% set raw_code %}{% raw %}{{ select( items=[ { type: "group", label: "Fruits", items: [ { type: "item", value: "apple", label: "Apple" }, { type: "item", value: "banana", label: "Banana" }, { type: "item", value: "blueberry", label: "Blueberry" }, { type: "item", value: "grapes", label: "Grapes" }, { type: "item", value: "pineapple", label: "Pineapple" } ] } ] ) }}{% endraw %}{% endset %} {{ code_block(raw_code, "jinja") }}

Examples

Scrollable

{% set code %} {% call select( listbox_attrs={"class": "scrollbar overflow-y-auto max-h-64"} ) %} {% for i in range(0, 99) %}
0 %}data-value="item-{{ i }}"{% endif %}>Item {{ i }}
{% endfor %} {% endcall %} {% endset %} {{ code_preview("select-scrollable", code | prettyHtml) }}

Disabled

{% set code %} {% call select( trigger_attrs={"disabled": "disabled"} ) %}
Disabled
{% endcall %} {% endset %} {{ code_preview("select-disabled", code | prettyHtml) }}

With icon

{% set code %} {% call select( id="select-with-icons", trigger_attrs={'class': 'w-[180px]'} ) %}
{% lucide "chart-bar", {"class": "text-muted-foreground"} %} Bar
{% lucide "chart-line", {"class": "text-muted-foreground"} %} Line
{% lucide "chart-pie", {"class": "text-muted-foreground"} %} Pie
{% endcall %} {% endset %} {{ code_preview("select-scrollable", code | prettyHtml) }}