--- layout: layouts/page.njk title: Dropdown Menu description: Displays a menu to the user — such as a set of actions or functions — triggered by a button. 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 dropdown menu HTML" id: usage-html-js-2 - label: HTML structure id: usage-html-js-3 - label: JavaScript events id: usage-html-js-4 - label: Jinja and Nunjucks id: usage-macro - label: Examples id: examples children: - label: Checkboxes id: example-checkboxes - label: Radio Group id: example-radio-group --- {% from "macros/code_block.njk" import code_block %} {% from "macros/code_preview.njk" import code_preview %} {% from "dropdown-menu.njk" import dropdown_menu %} {% set code_html %} {% call dropdown_menu( id="demo-dropdown-menu", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
My Account
Profile ⇧⌘P
Billing ⌘B
Settings ⌘S
Keyboard shortcuts ⌘K

GitHub
Support
API

Logout ⇧⌘P
{% endcall %} {% endset %} {{ code_preview("dropdown-menu", code_html | prettyHtml) }}

Usage

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" %} dropdown-menu.js {% lucide "arrow-right" %}

Step 2: Add your dropdown menu HTML

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

HTML structure

<div class="dropdown-menu">
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="menu": indicates that the button opens a menu.
  • aria-controls="{ MENU_ID }": points to the menu's id.
  • aria-expanded="false": tracks the popover's state.
<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="menu">
The menu containing the options. Should have the following attributes:
  • id="{ MENU_ID }": refered to by the aria-controls attribute of the trigger.
  • aria-labelledby="{ BUTTON_ID }": linked to by the button's id attribute.
<button role="menuitem">
Menu item.
<button role="menuitemcheckbox">
Menu item with a checkbox.
<button role="menuitemradio">
Menu item with a radio button.
<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.

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.

Jinja and Nunjucks

You can use the dropdown_menu() 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 %}{% call dropdown_menu( id="dropdown-menu", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
My Account
Profile ⇧⌘P
Billing ⌘B
Settings ⌘S
Keyboard shortcuts ⌘K

GitHub
Support
API

Logout ⇧⌘P
{% endcall %}{% endraw %}{% endset%} {{ code_block(raw_code, "jinja") }}

Examples

Checkboxes

{% set code %}{% call dropdown_menu( id="dropdown-menu-checkboxes", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
Account Options
{% lucide "user" %} Profile ⇧⌘P
{% lucide "credit-card" %} Billing ⌘B
{% lucide "settings" %} Settings ⌘S

Appearance
{% lucide "check", { "class": "invisible group-aria-checked:visible", "aria-hidden": "true", "focusable": "false" } %} Status Bar ⇧⌘P
{% lucide "check", { "class": "invisible group-aria-checked:visible", "aria-hidden": "true", "focusable": "false" } %} Activity Bar ⌘B
{% lucide "check", { "class": "invisible group-aria-checked:visible", "aria-hidden": "true", "focusable": "false" } %} Panel ⌘S

{% lucide "log-out" %} Logout ⇧⌘P
{% endcall %} {% endset %} {{ code_preview("dropdown-menu-checkboxes", code | prettyHtml) }}

Radio Group

{% set code %}{% call dropdown_menu( id="dropdown-menu-radio-group", trigger="Open", trigger_attrs={"class": "btn-outline"}, popover_attrs={"class": "min-w-56"} ) %}
Panel Position
Status Bar ⇧⌘P
Activity Bar ⌘B
Panel ⌘S
{% endcall %} {% endset %} {{ code_preview("dropdown-menu", code | prettyHtml) }}