Menu
Overlay action menu for commands such as edit, copy, archive, and delete.
Menu composes a panel, trigger directive, menu items, headers, and separators.
import {
KuiButton,
KuiMenu,
KuiMenuFor,
KuiMenuHeader,
KuiMenuItem,
KuiSeparator,
} from '@kikita-labs/ui';Use menu for actions, not value selection. Use Select or Dropdown for picking values.
<div class="basic-menu-example">
<button kuiButton type="button" [kuiMenuFor]="actionsMenu">Actions</button>
<kui-menu #actionsMenu ariaLabel="Project actions">
<button type="button" kuiMenuItem>
<span class="kui-menu-item__label">Edit</span>
</button>
<button type="button" kuiMenuItem>
<span class="kui-menu-item__label">Copy</span>
</button>
<hr kuiSeparator spacing="xs" />
<button type="button" kuiMenuItem appearance="destructive">
<span class="kui-menu-item__label">Delete</span>
</button>
</kui-menu>
</div>Headers, icons, shortcuts, disabled states, and destructive actions are projected item content.
<div class="menu-content-example">
<button kuiButton type="button" shape="outline" [kuiMenuFor]="rowMenu">Row actions</button>
<kui-menu #rowMenu ariaLabel="Row actions" menuAlign="end" minWidth="220px">
<div kuiMenuHeader>Project</div>
<button type="button" kuiMenuItem>
<span class="kui-menu-item__icon" aria-hidden="true">E</span>
<span class="kui-menu-item__label">Rename</span>
<span class="kui-menu-item__shortcut">F2</span>
</button>
<button type="button" kuiMenuItem>
<span class="kui-menu-item__icon" aria-hidden="true">C</span>
<span class="kui-menu-item__label">Copy link</span>
<span class="kui-menu-item__shortcut">Ctrl C</span>
</button>
<hr kuiSeparator spacing="xs" />
<button type="button" kuiMenuItem disabled>
<span class="kui-menu-item__label">Archive</span>
</button>
</kui-menu>
</div>Set defaults.menu once for the application or for a subtree. Each option resolves as local input > defaults.menu.<option> > built-in default.
import { provideKikitaUi } from '@kikita-labs/ui';
export const appConfig: ApplicationConfig = {
providers: [
provideKikitaUi({
defaults: {
menu: {
/* options below */
},
},
}),
],
};| Name | Type | Default | Description |
|---|---|---|---|
| placement | 'top' | 'bottom' | 'left' | 'right' | — | Preferred side of the anchor. The overlay flips to the opposite side when it does not fit. |
| offset | number | — | Gap in px between the anchor and the overlay panel. |
| menuAlign | 'start' | 'end' | — | Alignment along the trigger edge. |
| minWidth | string | null | — | Minimum panel width as a CSS length. |
Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-menu-item-shortcut-font-size | CSS custom property | --kui-text-xs-size | Item shortcut font size |
Every text the component owns (accessible names, visible words, announcements) is a typed message with an English default. Override it for the application with provideKikitaUi({ messages }), or for a subtree with provideKuiMessages.
| Name | Type | Default | Description |
|---|---|---|---|
| label | string | — | Accessible name of the menu when ariaLabel is not set. Default Actions. |
Inputs verified against @kikita-labs/ui v2.0.0 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| ariaLabel | string | undefined | undefined | Accessible name for the menu panel. Falls back to the menu.label message (Actions). |
| placement | 'top' | 'bottom' | 'left' | 'right' | undefined | undefined | Preferred side of the trigger the menu opens on. Falls back to defaults.menu.placement, then bottom. Auto-flips to the opposite side to fit the viewport. |
| menuAlign | 'start' | 'end' | undefined | undefined | Alignment along the trigger edge (defaults.menu.menuAlign, then start). For top/bottom placement, start is left-aligned and end is right-aligned. For left/right placement, start is top-aligned and end is bottom-aligned. |
| offset | number | undefined | undefined | Pixel gap between the trigger and the menu panel. Falls back to defaults.menu.offset, then 4. A static numeric string is coerced. |
| minWidth | string | null | undefined | undefined | Optional minimum inline size, applied to the visible panel as well as its overlay pane. Falls back to defaults.menu.minWidth, then none. |
| [kuiMenuFor] | KuiMenu | undefined | - | Wires a native trigger to a menu instance and manages trigger ARIA state. |
| kuiMenuHeader | - | - | Marks a non-interactive group heading inside the menu panel. Renders with role="presentation". |
| kuiSeparator | - | - | Native hr[kuiSeparator] divider between menu item groups. See the Separator page for spacing and appearance inputs. |
| kuiMenuItem.appearance | 'neutral' | 'destructive' | 'neutral' | Visual treatment for an action item. Use destructive for dangerous actions. |
| kuiMenuItem.disabled | boolean | false | Prevents activation and applies disabled/aria-disabled semantics. Disabled items are skipped by keyboard navigation. |
| isOpen | WritableSignal<boolean> | false | Whether the menu is currently open. Read it from a template reference. |
| KuiMenuOptions | interface | - | Shape of defaults.menu: placement, offset, menuAlign and minWidth. |
Menu owns keyboard navigation while keeping triggers and items native.
Consumer-visible changes of @kikita-labs/ui 2.0 for Menu.