GitHub

Dropdown Menu

Click-toggled menu. The trigger is slotted and items are set via the items property. Selecting emits a menu-action event; outside-click and Esc close it.

Stable wc import '@esa/ecology/esa-dropdown-menu';

Preview

Items are set in a script: el.items = [{ label: "Edit", action: "edit" }, …].

<esa-dropdown-menu id="dd-start" position="below-start">
  <button>Actions ▾</button>
</esa-dropdown-menu>

Positions

<esa-dropdown-menu position="below-start"></esa-dropdown-menu>
<esa-dropdown-menu position="below-end"></esa-dropdown-menu>

API

PropTypeDefaultDescription
items EsaMenuItem[] [] Menu items, set as a property. Each: { label, icon?, action?, disabled?, divider?, variant? }.
position 'below-start' | 'below-end' | 'above-start' | 'above-end' 'below-start' Corner the panel anchors to.
width 'auto' | 'trigger' 'auto' 'trigger' matches the panel min-width to the trigger.
open boolean false Reflected open state.

Methods

PropTypeDefaultDescription
close() method Closes the menu programmatically.

Events

EventTypeDefaultDescription
menu-action CustomEvent<string> Fired when a non-disabled item with an action is selected; detail is the item's action string.

Accessibility

  • The panel is role="menu" and each item is role="menuitem"; dividers are role="separator".
  • Disabled items set the native disabled attribute and are skipped on activation.
  • Escape and any outside click close the menu.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--dropdown-menu-bg component #fcfcfc via --color-surface-elevated--color-gray-1
--dropdown-menu-border-color component #cecece via --color-border--color-gray-7
--dropdown-menu-item-color component #202020 via --color-text-primary--color-gray-12
--dropdown-menu-max-width component 280px
--dropdown-menu-min-width component 160px
--dropdown-menu-radius component 0.5rem via --radius-200
--focus-ring-color component #65ba74 via --color-border-focus--color-grass-8
--focus-ring-width component 2px
--color-border-light semantic #d9d9d9 via --color-gray-6
--color-danger semantic #e5484d via --color-red-9
--color-danger-subtle semantic #fff7f7 via --color-red-2
--color-surface-sunken semantic #f0f0f0 via --color-gray-3
--font-sans semantic 'DM Sans', sans-serif
--type-size-200 semantic clamp(0.75rem, 0.66rem + 0.44vw, 0.9375rem)
--radius-100 primitive 0.25rem
--radius-full primitive 9999px
--shadow-300 primitive 0 6px 24px -6px rgba(0, 0, 0, 0.07)
--spacing-100 primitive 0.25rem
--spacing-200 primitive 0.5rem
--spacing-300 primitive 0.75rem
--z-dropdown primitive 50