Skip to content

Dropdown <l-dropdown>

Dropdowns are used to present a list of actions or options in a floating menu anchored to a trigger button. Commonly used for overflow menus, contextual actions, and navigation.

HTML tag<l-dropdown>
Native
Progressive
Plain
Shadow-DOM
Shadow-DOM Custom Element

Options

Basic

Click the trigger to open the menu. Click outside or press Escape to close.

Edit Duplicate Archive
Code
html
<l-dropdown>
  <button
    slot="trigger"
    class="l-button"
  >
    Options
  </button>
  <l-dropdown-item value="edit">Edit</l-dropdown-item>
  <l-dropdown-item value="duplicate">Duplicate</l-dropdown-item>
  <l-dropdown-item value="archive">Archive</l-dropdown-item>
</l-dropdown>

Disabled items

Add disabled to individual items to prevent selection.

Edit Duplicate Archive Delete
Code
html
<l-dropdown>
  <button
    slot="trigger"
    class="l-button"
  >
    Actions
  </button>
  <l-dropdown-item value="edit">Edit</l-dropdown-item>
  <l-dropdown-item value="duplicate">Duplicate</l-dropdown-item>
  <l-dropdown-item disabled>Archive</l-dropdown-item>
  <l-dropdown-item value="delete">Delete</l-dropdown-item>
</l-dropdown>

Checkbox items

Set type="checkbox" for toggleable items. The dropdown stays open when checking items.

Name Email Phone Address
Code
html
<l-dropdown>
  <button
    slot="trigger"
    class="l-button"
  >
    View columns
  </button>
  <l-dropdown-item
    type="checkbox"
    checked
    >Name</l-dropdown-item
  >
  <l-dropdown-item
    type="checkbox"
    checked
    >Email</l-dropdown-item
  >
  <l-dropdown-item type="checkbox">Phone</l-dropdown-item>
  <l-dropdown-item type="checkbox">Address</l-dropdown-item>
</l-dropdown>

Section labels

Add <l-dropdown-label> to caption a group of items. It is non-interactive — keyboard navigation and typeahead skip it. Use <l-divider> between sections.

Layout Compact Comfortable Columns Name Email Phone
Code
html
<l-dropdown>
  <button
    slot="trigger"
    class="l-button"
  >
    View options
  </button>

  <l-dropdown-label>Layout</l-dropdown-label>
  <l-dropdown-item
    type="checkbox"
    checked
    >Compact</l-dropdown-item
  >
  <l-dropdown-item type="checkbox">Comfortable</l-dropdown-item>

  <l-divider></l-divider>

  <l-dropdown-label>Columns</l-dropdown-label>
  <l-dropdown-item
    type="checkbox"
    checked
    >Name</l-dropdown-item
  >
  <l-dropdown-item
    type="checkbox"
    checked
    >Email</l-dropdown-item
  >
  <l-dropdown-item type="checkbox">Phone</l-dropdown-item>
</l-dropdown>

Nest <l-dropdown-item slot="submenu"> elements inside an item to create a submenu — at any depth. A parent item shows a chevron, opens on hover, click, Enter or ArrowRight, and closes with ArrowLeft or Escape. Selecting a nested item fires the same select event on the dropdown and closes the whole menu (checkbox items keep it open). Use <hr slot="submenu"> for separators inside a submenu.

Documents PDF Word Document Spreadsheets Excel Formats Excel (.xlsx) CSV (.csv) OpenDocument (.ods)
Options Compress files Include metadata
Code
html
<l-dropdown>
  <button
    slot="trigger"
    class="l-button"
  >
    Export
  </button>

  <l-dropdown-item>
    Documents
    <l-dropdown-item
      slot="submenu"
      value="pdf"
      >PDF</l-dropdown-item
    >
    <l-dropdown-item
      slot="submenu"
      value="docx"
      >Word Document</l-dropdown-item
    >
  </l-dropdown-item>

  <l-dropdown-item>
    Spreadsheets
    <l-dropdown-item slot="submenu">
      Excel Formats
      <l-dropdown-item
        slot="submenu"
        value="xlsx"
        >Excel (.xlsx)</l-dropdown-item
      >
      <l-dropdown-item
        slot="submenu"
        value="csv"
        >CSV (.csv)</l-dropdown-item
      >
    </l-dropdown-item>
    <l-dropdown-item
      slot="submenu"
      value="ods"
      >OpenDocument (.ods)</l-dropdown-item
    >
  </l-dropdown-item>

  <hr />

  <l-dropdown-item>
    Options
    <l-dropdown-item
      slot="submenu"
      type="checkbox"
      value="compress"
      >Compress files</l-dropdown-item
    >
    <l-dropdown-item
      slot="submenu"
      type="checkbox"
      checked
      value="metadata"
      >Include metadata</l-dropdown-item
    >
  </l-dropdown-item>
</l-dropdown>

Placement

Set placement to control position. Default is bottom-start.

Option 1 Option 2 Option 3 Option 1 Option 2 Option 3 Option 1 Option 2 Option 3
Code
html
<div class="flex gap-4">
  <l-dropdown placement="bottom-start">
    <button
      slot="trigger"
      class="l-button"
    >
      Bottom start
    </button>
    <l-dropdown-item>Option 1</l-dropdown-item>
    <l-dropdown-item>Option 2</l-dropdown-item>
    <l-dropdown-item>Option 3</l-dropdown-item>
  </l-dropdown>

  <l-dropdown placement="bottom-end">
    <button
      slot="trigger"
      class="l-button"
    >
      Bottom end
    </button>
    <l-dropdown-item>Option 1</l-dropdown-item>
    <l-dropdown-item>Option 2</l-dropdown-item>
    <l-dropdown-item>Option 3</l-dropdown-item>
  </l-dropdown>

  <l-dropdown placement="top-start">
    <button
      slot="trigger"
      class="l-button"
    >
      Top start
    </button>
    <l-dropdown-item>Option 1</l-dropdown-item>
    <l-dropdown-item>Option 2</l-dropdown-item>
    <l-dropdown-item>Option 3</l-dropdown-item>
  </l-dropdown>
</div>

Min width

Set min-width="trigger" to floor the panel at the trigger's width — useful for select-like triggers (a date-range or filter button). The panel still grows with its content and stays matched if the trigger resizes while open.

This month This quarter This year
Code
html
<l-dropdown min-width="trigger">
  <button
    slot="trigger"
    class="l-button"
  >
    1 Jan 2026 – 2 Jun 2026
    <l-icon name="lucide:chevron-down"></l-icon>
  </button>
  <l-dropdown-item value="month">This month</l-dropdown-item>
  <l-dropdown-item value="quarter">This quarter</l-dropdown-item>
  <l-dropdown-item value="year">This year</l-dropdown-item>
</l-dropdown>

Disabled

Add disabled to prevent opening.

Edit Duplicate
Code
html
<l-dropdown disabled>
  <button
    slot="trigger"
    class="l-button"
    disabled
  >
    Options
  </button>
  <l-dropdown-item value="edit">Edit</l-dropdown-item>
  <l-dropdown-item value="duplicate">Duplicate</l-dropdown-item>
</l-dropdown>

Examples

Account menu

Use the header slot for a profile row, the prefix slot on each <l-dropdown-item> for a leading icon, and <l-divider> between groups for section breaks — <l-dropdown> tightens slotted <l-divider> spacing automatically.

jane.cooper@acme.com Super admin
Manage profile Preferences Get help Sign out
v1.2.3 Documentation
Code
html
<l-dropdown>
  <l-avatar
    slot="trigger"
    interactive
    name="Jane Cooper"
    aria-label="Account"
    style="--appearance: circle; --color: var(--color-purple-200)"
  ></l-avatar>

  <div
    slot="header"
    class="flex items-center gap-3 px-2 py-2"
  >
    <l-avatar
      name="Jane Cooper"
      style="--appearance: circle; --color: var(--color-purple-200)"
    ></l-avatar>
    <div class="flex flex-col">
      <span class="text-sm font-medium text-primary">jane.cooper@acme.com</span>
      <span class="text-xs text-secondary">Super admin</span>
    </div>
  </div>

  <l-divider></l-divider>

  <l-dropdown-item value="profile">
    <iconify-icon
      slot="prefix"
      icon="lucide:user-round-cog"
    ></iconify-icon>
    Manage profile
  </l-dropdown-item>
  <l-dropdown-item value="preferences">
    <iconify-icon
      slot="prefix"
      icon="lucide:settings"
    ></iconify-icon>
    Preferences
  </l-dropdown-item>
  <l-dropdown-item value="help">
    <iconify-icon
      slot="prefix"
      icon="lucide:life-buoy"
    ></iconify-icon>
    Get help
  </l-dropdown-item>

  <l-divider></l-divider>

  <l-dropdown-item value="signout">
    <iconify-icon
      slot="prefix"
      icon="lucide:log-out"
    ></iconify-icon>
    Sign out
  </l-dropdown-item>

  <l-divider></l-divider>

  <div
    slot="footer"
    class="flex items-center justify-between gap-2 px-2 py-1.5 text-xs text-secondary"
  >
    <span>v1.2.3</span>
    <a
      class="hover:underline"
      href="#"
      >Documentation</a
    >
  </div>
</l-dropdown>

Accessibility

Criteria

Role

Trigger is a menu button (aria-haspopup="menu"); panel has role="menu", items have role="menuitem" or role="menuitemcheckbox"

WCAG4.1.2
RGAA7.1
Accessible name

Each role="menu" panel is named — the root menu after its trigger, every submenu after its parent item

WCAG4.1.2
RGAA7.1
Expanded state

Trigger receives aria-expanded reflecting open state

WCAG4.1.2
Checked state

Checkbox items use aria-checked to communicate toggle state

WCAG4.1.2
Submenu state

Items with a submenu expose aria-haspopup="menu", aria-controls, and reflect aria-expanded

WCAG4.1.2
Disabled state

Disabled items use aria-disabled, remaining in the DOM for discoverability

WCAG4.1.2
Focus management

Focus moves into menu on open and returns to trigger on close; Tab closes the menu

WCAG2.4.3
RGAA10.7
Focus visible

The focused item shows a focus ring distinct from the hover state

WCAG2.4.7
RGAA10.7
Motion

Respects prefers-reduced-motion

WCAG2.3.3

Keyboard interactions

Enter
Opens menu and focuses first item; selects the focused item; or opens the focused item's submenu
Space
Opens menu and focuses first item; selects the focused item; or opens the focused item's submenu
ArrowDown
Opens menu and focuses first item; or moves focus to the next item of the current level (wraps)
ArrowUp
Opens menu and focuses last item; or moves focus to the previous item of the current level (wraps)
ArrowRight
Opens the focused item's submenu and focuses its first item
ArrowLeft
Closes the current submenu and returns focus to its parent item
Home
Moves focus to the first item of the current level
End
Moves focus to the last item of the current level
Escape
Closes the current submenu; at the root level, closes the menu and returns focus to the trigger
Tab
Closes menu and moves focus to the next focusable element

API reference

Importing

js
import 'luxen-ui/dropdown';
import 'luxen-ui/dropdown-item';
import 'luxen-ui/dropdown-label';

Attributes & Properties

openbooleandefault:falseProperty
Whether the dropdown is open.
placementPlacementdefault:'bottom-start'Property
Preferred placement of the panel.
distancenumberdefault:4Property
Distance in pixels from the trigger.
disabledbooleandefault:falseProperty
Disables the dropdown trigger.
min-width'trigger' | undefinedProperty
Floor the panel's width at the trigger's width. Set to trigger so the panel is never narrower than the trigger; it still grows with its content. Useful for select-like triggers (a date-range or filter button) where the panel should line up with the control. Re-applies if the trigger resizes while open.

Methods

show()Method
hide()Method
toggle()Method

Events

showcancelableEvent
Fired before the dropdown opens. Cancelable.
after-showEvent
Fired after the open animation completes.
hidecancelableEvent
Fired before the dropdown closes. Cancelable.
after-hideEvent
Fired after the close animation completes.
selectEvent
Fired when an item is selected, including items nested in submenus. Bubbles. Properties: item: DropdownItem.

Slots

triggerSlot
The element that triggers the dropdown.
headerSlot
Optional content rendered above the menu items (e.g. a user profile row). Use an <l-divider> (or <hr>) after it to separate from items.
(default)Slot
Menu content (l-dropdown-item elements). Drop an <l-divider> (or <hr>) between items to render a section separator, or an <l-dropdown-label> to caption a group of items. Nest items with slot="submenu" inside an item to create a submenu.
footerSlot
Optional content rendered below the menu items (e.g. a version label or shortcut row). Use an <l-divider> (or <hr>) before it to separate from items.

CSS custom properties

--backgroundCustom property
Panel background color.
--border-radiusdefault:8pxCustom property
Panel border radius.
--paddingdefault:0.25remCustom property
Panel inner padding. Slotted <l-divider> elements bleed by this amount on each side to span the panel edges.
--shadowCustom property
Panel box shadow.
--show-durationdefault:150Custom property
Show animation duration in ms.
--hide-durationdefault:150Custom property
Hide animation duration in ms.
valuestringProperty
The value associated with this item.
disabledbooleandefault:falseProperty
Disables the item.
type'normal' | 'checkbox'default:'normal'Property
The type of item: normal or checkbox.
checkedbooleandefault:falseProperty
Whether the checkbox item is checked.
submenu-openbooleandefault:falseProperty
Whether this item's submenu is open. Managed by the parent l-dropdown.
hasSubmenubooleanProperty
Whether this item has nested slot="submenu" items.
(default)Slot
Label text.
prefixSlot
Leading content (e.g. icon).
suffixSlot
Trailing content.
submenuSlot
Nested l-dropdown-item elements rendered in a submenu panel anchored to this item. Drop an <hr> between them for a separator.
(default)Slot
Label text.
--colordefault:var(--l-color-text-tertiary)Custom property
Text color.