Dropdown Menu

The <nys-dropdownmenu> and <nys-dropdownmenuitem> components are a list of actions or options that appears when a user interacts with a trigger, and disappears after a selection or clicking away.

Copy Code
<nys-button id="my-trigger-id" label="Dropdown Trigger"></nys-button>
<nys-dropdownmenu id="my-dropdownmenu" for="my-trigger-id">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Repositories & Github Pages" href="/repos"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Organizations" href="/organizations"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>

Options

Connecting to a Trigger

The <nys-dropdownmenu> anchors itself to a trigger element provided by the user, such as a button or avatar, by matching its for attribute to the trigger's id.

Copy Code
<nys-button id="my-trigger-id" label="Open Menu"></nys-button>
<nys-dropdownmenu for="my-trigger-id">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>

Position

Use the position prop to control where the dropdown menu appears relative to its trigger. Supported positions are:

  • bottom-start
  • bottom-end (default auto position)
  • top-start
  • top-end

Note: If the preferred position does not fit within the viewport, the component will automatically find the best alternative.

Copy Code
<nys-button id="trigger-bottom-start" label="trigger"></nys-button>
<nys-dropdownmenu for="trigger-bottom-start" position="bottom-start">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Settings" href="/settings"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>
<nys-dropdownmenu for="trigger-bottom-end" position="top-end">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Settings" href="/settings"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>

In Global Header

A common use case is pairing <nys-dropdownmenu> with <nys-globalheader> for user profile navigation.

Copy Code
<nys-globalheader appName="User Registration Form" agencyName="Office of Information Technology Services">
    <nys-button id="my-user-actions" slot="user-actions" label="Log out" prefixIcon="slotted">
        <nys-avatar slot="prefix-icon" ariaLabel="User avatar" initials="NY"></nys-avatar>
    </nys-button>
</nys-globalheader>
<nys-dropdownmenu id="dropdownmenu1" for="my-user-actions" position="bottom-end">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Repositories & Github Pages" href="/repos"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Organizations" href="/organizations" disabled></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>

With Icons

Use the prefixIcon property on <nys-dropdownmenuitem> to add an icon before the label.

Copy Code
<nys-button id="trigger-icons" label="Open Menu"></nys-button>
<nys-dropdownmenu for="trigger-icons">
    <nys-dropdownmenuitem label="Action 1" prefixIcon="lock_filled"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 2" prefixIcon="social_youtube"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 3" prefixIcon="visibility" disabled></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 4" prefixIcon="sms"></nys-dropdownmenuitem>
</nys-dropdownmenu>

Disabled Items

Use the disabled attribute on individual <nys-dropdownmenuitem> elements to prevent interaction.

Copy Code
<nys-button id="trigger-disabled" label="Open Menu"></nys-button>
<nys-dropdownmenu for="trigger-disabled">
    <nys-dropdownmenuitem label="Profile" href="/profile"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Organizations" href="/organizations" disabled></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Sign out" href="/logout"></nys-dropdownmenuitem>
</nys-dropdownmenu>

Actions (no href)

Omit the href property to render items as <button> elements for action-based menus instead of navigation links. Use the nys-click dispatch event to call for specific functions to execute actions

Copy Code
<nys-button id="trigger-actions" label="Open Menu"></nys-button>
<nys-dropdownmenu for="trigger-actions">
    <nys-dropdownmenuitem label="Action 1"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 2"></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 3" disabled></nys-dropdownmenuitem>
    <nys-dropdownmenuitem label="Action 4"></nys-dropdownmenuitem>
</nys-dropdownmenu>

Usage

When to use this component

  • To display a list of actions or links under a single trigger.
  • To provide the user with a way to easily switch context or perform actions within the application. They’re used for navigation or commands, where an action is initiated based on the selection.
  • User profile access, giving users the option to log in, an icon or username in the header can act as a dropdown trigger.
  • Dropdown menus are typically used when you have 5-15 items to choose from.

When to consider something else

  • When you need users to select a value from a list for form input. Consider the <nys-select> component instead.
  • When users need to filter or search through many options for form input. Consider the <nys-combobox> component instead.
  • When the menu is not intended for navigation links or action menus.
  • When the action is always visible and frequently used. Consider a standalone button or <nys-button> instead.

Do

  • Keep to 3-7 actions when possible
  • Order actions by frequency or importance
  • Separate destructive actions with a divider
  • Use clear labels (e.g., “Profile”, “Account Settings”, “Sign out”)
  • Avoid vague labels like “Manage” or “Options”

Don't

  • Don't use for form inputs or selectable values — use <nys-select> instead
  • Don't use without a label or accessible description on the trigger
  • Don't nest dropdown menus inside other dropdown menus

Accessibility

The <nys-dropdownmenu> component includes the following accessibility-focused features:

  • The trigger element automatically receives aria-haspopup="menu" and aria-expanded attributes
  • The menu uses role="menu" and each item uses role="menuitem" for proper screen reader support
  • Supports full keyboard interaction: Enter/Space to open, Escape to close, ArrowUp/ArrowDown to navigate items, and Tab to close when leaving the last item
  • Focus is automatically moved to the first menu item when the dropdown opens, and returned to the trigger on close

Properties

<nys-dropdownmenu>

Property Type
id String
for String
showDropdown boolean
position "bottom-start" , "bottom-end" , "top-start" , "top-end"

<nys-dropdownmenuitem>

Property Type
id String
label String
href String
disabled boolean
target String (default "_self")
prefixIcon String
divider String

Style Overrides

There are no existing CSS variables for this component. Explore existing options, or propose a new one with a Component Proposal.


Events

The <nys-dropdownmenuitem> component emits one custom Javascript events:

  1. nys-click – Emitted when a dropdown menu item is clicked.

Event details

The nys-click event includes a detail object with the following properties:

  • id (string): The id of the clicked item.
  • label (string): The label of the clicked item.
  • href (string): The href of the clicked item. Only present if href was provided.

You can listen to these events using JavaScript:

Copy Code
// Select the dropdownmenu component
const dropdownmenu = document.querySelector("nys-dropdownmenu");
// Listen for the 'nys-click' event
dropdownmenu.addEventListener('nys-click', (event) => {
    const { id, label, href } = event.detail;
    if (href) {
        console.log(`Link item clicked (${id}): ${label} with href = ${href}`);
    } else {
        console.log(`Action item clicked (${id}): ${label}`);
    }
});

Suggest a New Component

Do you have an idea for a new NYS Design System web component? Look through the existing proposals in our GitHub discussions board to see if someone already proposed something similar. If not, feel free to submit one.