Rime

Menu

An action menu from a button: groups, headings, separators, icons, links and danger items, in a frosted popover.

Menu lists actions (not choices; that is Select). Items can be links (rendered as Next Links) or callbacks, carry an icon and a description, and be marked danger or disabled. It shares Select's popover family.

Installation

npx shadcn@latest add KezLahd/rime/menu

Also installs: base, icon.

Usage

import { Menu } from "@/components/ui";

<Menu label="Actions" items={[{ id: "edit", label: "Edit", onSelect: edit }, { id: "sep", separator: true }, { id: "void", label: "Void invoice", tone: "danger", onSelect: confirm }]} />

Examples

Open

inline renders the menu open under its trigger, in place.

Default

API

Generated from the component's TypeScript types and JSDoc (scripts/gen-ui-registry.mjs), so it always matches the source.

Menu

Menu props
PropTypeDefaultDescription
labelRequiredReactNodeTrigger content. A chevron is appended unless iconOnly or hideChevron.
aria-labelstringAccessible name when the trigger content is not descriptive (an avatar, an icon).
itemsRequiredReadonlyArray<MenuEntry>
headerReactNodeTinted block at the top of the menu: name and ID number, say.
align"start" | "end""end"
iconOnlybooleanIcon-only trigger (a "more" ellipsis): a square ghost button, no chevron. Give it an aria-label.
hideChevronbooleanDrops the chevron from a custom trigger that signals the menu another way.
disabledboolean
triggerClassNamestring
classNamestring
inlinebooleanfalseRender the menu open, in place, under its trigger: no portal, no focus move, no outside-click listener. For docs and thumbnails.

Theme tokens

Per-component tokens are undeclared by default, so the default shown is the fallback the CSS uses. Set one at :root (or in theme.css) to restyle every instance. Live values are read from this page, so they follow the Rime Studio.

Menu per-component tokens
TokenDefaultLive value
--chip-radiusvar(--r-sm)…
--popover-item-active-bglinear-gradient(to right, rgba(var(--rgb-brand), 0.14), rgba(var(--rgb-brand-deep), 0.07))…
--popover-item-press-bglinear-gradient(to right, rgba(var(--rgb-brand), 0.2), rgba(var(--rgb-brand-deep), 0.1))…
--popover-item-radiusvar(--r-xs)…
--popover-padcalc(6px * var(--density))…
--popover-radiusvar(--r-lg)…
--recess-fill-disabledrgba(var(--rgb-white), 0.3)…

System tokens it reads

Menu system tokens
TokenDefaultLive value
--blur-recesstokens.css…
--border-wtokens.css…
--brand-gradient-washtokens.css…
--danger-inktokens.css…
--densitytokens.css…
--durtokens.css…
--dur-fasttokens.css…
--easetokens.css…
--ease-outtokens.css…
--focus-halotokens.css…
--focus-ringtokens.css…
--font-bodytokens.css…
--ink-bodytokens.css…
--ink-brandtokens.css…
--ink-disabledtokens.css…
--ink-headingtokens.css…
--ink-mutedtokens.css…
--ink-secondarytokens.css…
--line-softtokens.css…
--popover-blurtokens.css…
--popover-bordertokens.css…
--popover-shadowtokens.css…
--popover-surfacetokens.css…
--r-lgtokens.css…
--r-smtokens.css…
--r-xstokens.css…
--recess-filltokens.css…
--recess-fill-hovertokens.css…
--rgb-brandtokens.css…
--rgb-brand-deeptokens.css…
--rgb-contacttokens.css…
--rgb-dangertokens.css…
--rgb-whitetokens.css…
--shadow-recesstokens.css…
--text-captiontokens.css…
--text-microtokens.css…
--text-smalltokens.css…
--tracking-labeltokens.css…
--wash-activetokens.css…
--wash-subtletokens.css…
--z-popovertokens.css…

Accessibility

  • role="menu" with roving focus: arrows, Home, End, typeahead; Esc and Tab close and return focus to the trigger.

Do and don't

Do

  • Put destructive items last, after a separator.

Don't

  • Don't hide the only way to do something important in a menu.

For AI agents

This page as markdown, rendered from the same registry entry. Point an agent at it (or add .md to this page's URL), or at /llms.txt for the index.

Open menu.md