npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gospore/dropdown-menu

v1.0.132

Published

A headless, fully keyboard accessible menu primitive used throughout the Design System. The package exports the following building blocks:

Readme

@gospore/dropdown-menu

A headless, fully keyboard accessible menu primitive used throughout the Design System. The package exports the following building blocks:

  • DropdownMenu – trigger + portal that positions content with Popper.js, teleports into the nearest Theme portal host (falling back to <body>), and traps focus when open.
  • DropdownItem – basic option row that closes the menu when activated.
  • DropdownSubmenu – nested menu row that opens a side-positioned submenu and coordinates close/focus behavior with its parent menu.
  • DropdownItemCheckbox / DropdownItemRadio – stateful options that sync with checkbox or radio data structures.
  • DropdownItemGroup – wraps related options, adds optional headings, and filters items when used inside Select.

Provide your own trigger slot to replace the default button, or keep text="…" for a ready-made trigger rendered with the Button component. Set menuWidth when the popup should use a fixed width. Numbers are converted to pixels; strings can use CSS units or design tokens. Use fitContainer when the popup should instead match the trigger width.

Slots & events

Use listAriaLabel to give the popup surface its own accessible name. When omitted, the popup continues to be labelled by the trigger. This is especially useful with listRole="dialog".

  • trigger(slotProps) – custom trigger; receives toggleOpen, selected, and DOM ids to wire up ARIA attributes manually.
  • default slot – the menu content (usually a stack of item/group components).
  • Emits update:open (for v-model) and focusout when focus leaves both the trigger and the portal.

DropdownMenu exposes updatePosition() and closeDropdownMenu() via ref for advanced integrations.

Large menus are positioned and height-constrained before they become visible, so the panel does not flash at the viewport-sized fallback height on open. The popup then uses a short 150ms fade and small surface translate on open, reverses the same transition on close, and disables that motion under prefers-reduced-motion.

Items use short, property-scoped transitions for hover and selection colors, focus-ring shadows, and the submenu's disabled opacity. Theme changes may briefly interpolate those properties; their settled light and dark states retain the documented contrast.

DropdownItem

A lightweight anchor that forwards attrs, closes its parent menu on click, and supports arrow-key activation inside Select.

Emits click and keydown so hosting components can react without reaching into the DOM.

DropdownSubmenu

Use DropdownSubmenu inside a DropdownMenu or DropdownItemGroup when one row should reveal another menu level. The default trigger uses role="menuitem", aria-haspopup="menu", aria-expanded, and a right-chevron indicator.

<DropdownMenu text="Actions">
    <DropdownItemGroup>
        <DropdownItem @click="rename">Rename</DropdownItem>
        <DropdownSubmenu label="Move to">
            <DropdownItem @click="moveToInbox">Inbox</DropdownItem>
            <DropdownItem @click="moveToArchive">Archive</DropdownItem>
        </DropdownSubmenu>
    </DropdownItemGroup>
</DropdownMenu>

Nested menus can also be rendered recursively from data. Render items with children as DropdownSubmenu and leaf items as DropdownItem; the parent menu still coordinates focus, side placement, and close-on-select behavior for the whole tree.

DropdownSubmenu supports v-model:open, id, label, disabled, position (default right-start), flip, preventOverflow, openDelay, closeDelay, and closeOnSelect. closeOnSelect defaults to root, so activating a child item closes the whole dropdown tree. Set it to submenu to close only the nested panel, or false to leave menus open after activation.

Provide a trigger slot for custom submenu rows. It receives triggerID, dropdownMenuID, selected, disabled, open, close, toggleOpen, and triggerProps so custom markup can preserve the built-in ARIA and event behavior.

DropdownItemGroup

Wrap options in a titled section and optionally filter children. Select leverages it to keep the menu height in sync.

Direct dropdown-item children may be rendered normally or through Vue <template> fragments; filter, focus, and item-role handling is applied consistently after fragments are flattened. Wrapper components are kept intact and are responsible for forwarding any filtering state to the items they render. Keep Select options as direct dropdown-item children so its keyboard index matches the filtered rows; wrapper components are intended for regular DropdownMenu content such as recursively rendered submenus.

The component exposes closeDropdownMenu() and updatePosition() helpers to keep Popper aligned.

A titled group exposes the title as its accessible group name. The visible heading is hidden from the accessibility tree so menu and listbox ownership contains only valid item roles.

Checkbox & radio items

DropdownItemCheckbox accepts either a boolean or an array v-model, toggles the entry, and automatically updates DropdownMenu’s Popper position when a wrapped Select re-renders.

DropdownItemRadio mirrors radio-button behavior: v-model:checked receives the currently selected value, and activating an option closes the menu (unless used with puppetMode). Both variants accept disabled, filter, filterValue, focused, and inputFocused props just like DropdownItem.

Accessibility

  • The popup surface renders inside a portal with role="menu" by default, role="listbox" when listRole="listbox", or role="dialog" for composed popup controls. The default trigger wires aria-haspopup, aria-controls, and aria-expanded.
  • A listbox surface makes nested plain, checkbox, and radio dropdown items expose role="option" and aria-selected, including items rendered through wrapper components.
  • Focus is trapped inside the menu while open (unless puppetMode is enabled) via focus-trap, and ESC closes the menu + returns focus to the trigger. Open submenu panels are added to the root focus trap so teleported nested panels remain keyboard-contained.
  • Nested menus open with click, Enter, Space, or ArrowRight; ArrowLeft closes the active submenu and restores focus to its trigger.
  • Scroll indicators fade in/out so users notice additional content while the panel keeps a constrained height.

Skeletons

This package also exports DropdownItemGroupSkeleton, DropdownItemSkeleton for async loading states. Import the owning package CSS plus @gospore/skeleton/skeleton.css so the shared skeleton primitive styles and tokens are available. Skeletons are decorative by default; put aria-busy, role="status", or loading copy on the surrounding region when assistive technology needs an explicit loading announcement.