Dropdown Menu

Displays a menu to the user — such as a set of actions or functions — triggered by a button.

Usage

HTML + JavaScript

Step 1: Include the JavaScript files

Include the dropdown-menu.js file. It is recommended to also include the CSS anchor positioning polyfill to support older browsers. Add this to the <head> of your page:

<script src="https://cdn.jsdelivr.net/npm/basecoat-css@beta/dist/js/dropdown-menu.min.js" defer></script>
<script type="module">
  if (!("anchorName" in document.documentElement.style)) {
    import("https://cdn.jsdelivr.net/npm/basecoat-css@beta/dist/js/css-anchor-positioning.min.js");
  }
</script>

Step 2: Add your dropdown menu HTML

<div class="dropdown-menu">
  <button type="button" id="demo-dropdown-menu-trigger" popovertarget="demo-dropdown-menu" aria-haspopup="menu" aria-controls="demo-dropdown-menu-menu" aria-expanded="false" class="btn-outline">Open</button>
  <div popover class="popover p-1 min-w-56" id="demo-dropdown-menu">
    <nav role="menu" id="demo-dropdown-menu-menu" aria-labelledby="demo-dropdown-menu-trigger">
      <div role="group" aria-labelledby="account-options">
        <span id="account-options" role="heading">My Account</span>
        <button type="button" role="menuitem">
          Profile
          <span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
        </button>
        <button type="button" role="menuitem">
          Billing
          <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘B</span>
        </button>
        <button type="button" role="menuitem">
          Settings
          <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘S</span>
        </button>
        <button type="button" role="menuitem">
          Keyboard shortcuts
          <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘K</span>
        </button>
      </div>
      <hr role="separator" />
      <button type="button" role="menuitem">GitHub</button>
      <button type="button" role="menuitem">Support</button>
      <button type="button" role="menuitem" disabled>API</button>
      <hr role="separator" />
      <button type="button" role="menuitem">
        Logout
        <span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
      </button>
    </nav>
  </div>
</div>

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.

Jinja and Nunjucks

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

{% call dropdown_menu(
  id="dropdown-menu",
  trigger="Open",
  trigger_attrs={"class": "btn-outline"},
  content_attrs={"class": "min-w-56"},
  register_on=["alpine:init", "htmx:afterSwap"]
) %}
<div role="group" aria-labelledby="account-options">
  <span id="account-options" role="heading">My Account</span>
  <button type="button" role="menuitem">
    Profile
    <span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
  </button>
  <button type="button" role="menuitem">
    Billing
    <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘B</span>
  </button>
  <button type="button" role="menuitem">
    Settings
    <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘S</span>
  </button>
  <button type="button" role="menuitem">
    Keyboard shortcuts
    <span class="text-muted-foreground ml-auto text-xs tracking-widest">⌘K</span>
  </button>
</div>
<hr role="separator">
<button type="button" role="menuitem">
  GitHub
</button>
<button type="button" role="menuitem">
  Support
</button>
<button type="button" role="menuitem" disabled>
  API
</button>
<hr role="separator">
<button type="button" role="menuitem">
  Logout
  <span class="text-muted-foreground ml-auto text-xs tracking-widest">⇧⌘P</span>
</button>
{% endcall %}

Examples

Checkboxes

Radio Group