A kebab menu that collapses secondary toolbar actions behind one trigger. Items self-register, so a menu whose entries are all permission-gated renders nothing at all.
DefaultHover openNo items
No action yet
<ToolbarMenu> <ToolbarMenuItem onclick={importCsv}>Import CSV</ToolbarMenuItem> <ToolbarMenuItem onclick={download}>Download CSV</ToolbarMenuItem></ToolbarMenu>Installation
pnpm add @chanrg/4uiImport the stylesheet once, at the root of your app:
import '@chanrg/4ui/styles.css';Usage
import { ToolbarMenu } from '@chanrg/4ui';<ToolbarMenu> <ToolbarMenuItem onclick={importCsv}>Import CSV</ToolbarMenuItem> <ToolbarMenuItem onclick={download}>Download CSV</ToolbarMenuItem></ToolbarMenu>Composition
Use the following composition to build a toolbar menu:
ToolbarMenu
└── ToolbarMenuItem
├── icon (snippet)
└── childrenGated items
Items self-register, so a menu whose entries are all permission-gated renders no trigger at all.
Every item is gated away, so no trigger renders at all
<!-- Every item is permission-gated away, so no trigger renders at all. --><ToolbarMenu> {#if canImport}<ToolbarMenuItem onclick={importCsv}>Import CSV</ToolbarMenuItem>{/if}</ToolbarMenu>API reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | 'Actions' | Names both the trigger and the panel. |
children | Snippet | — | ToolbarMenuItem rows. |
item.icon / disabled / title | Snippet / boolean / string | — | Per-item leading glyph, gating, and a tooltip explaining why it is gated. |
item.onclick | (event) => void | — | Activation closes the menu without stealing focus from a modal it opens. |
CSS variables
| Variable | Description |
|---|---|
--4ui-surface | Primary component surface. |
--4ui-text | Primary foreground color. |
--4ui-border | Default control and panel border. |
Accessibility
- Arrow keys, Home and End roam the live menu items and Tab wraps inside the panel.
- Escape closes and returns focus to the trigger.
- The panel stays mounted while hidden, so an item that opened a dialog keeps its state.