--- 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: 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" }, { type: "item", value: "banana", label: "Banana" }, { 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).

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: "pineapple", 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) %}
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( 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) }}