Menus

DSMenu is the popover surface; DSKebabMenu pairs it with the canonical ··· overflow trigger. Replaces UDropdownMenu for in-app surfaces — resume cards, application rows, settings lines.

DSMenu surface

The bare surface, rendered open with no trigger. This is what DSKebabMenu shows under the hood. Drop it behind any custom trigger when the kebab pattern doesn't fit.

Kebab — simple items

Three plain text items. The most common shape: a per-item action menu on a card or list row.

Untitled resume — Senior Designer

Kebab — leading icons

Each item carries a DSIcon leading glyph. Icons inherit the muted ink tone so the labels stay primary.

Frontend engineer · Acme

Kebab — destructive item

The destructive flag retones the row in --ds-status-error. Use for irreversible actions (delete, remove).

Resume · Published

Kebab — mixed states

Disabled items render greyed and uninteractive; destructive items still pick up the error tone. Combine freely.

Resume · Draft

Alignment — start vs. end

Default is end-aligned (menu hangs from the right edge of the trigger). Pass align='start' when the trigger sits on the left of its row.

align="start"
align="end" (default)

Trigger sizes

size='sm' (default, 1.875rem) for in-row use; size='md' (2.25rem) for headers and toolbars.

size="sm"
size="md"

DSDropdownMenu — avatar trigger

Wraps any slot-provided trigger (avatar pill, labeled button, icon button). The two-dimensional items array becomes grouped sections separated by hairlines. Use type='label' for a non-interactive section header — matches the avatar menu in AppTopNav.

DSDropdownMenu — labeled-button trigger

A flat items list works too — drop the same primitive behind a labeled 'Menu' button to mirror the desktop nav dropdown. Items with `to` render as NuxtLinks; items with `href` render as anchors; items with neither render as buttons that fire onSelect / @select.