Menu
SvMenu: a dropdown / actions menu with submenus, separators, icons and keyboard shortcuts. Portalled + animated, full keyboard (arrows, Enter, Escape, ArrowRight/Left).
A live, editable Svelte 5 component example from the SvGrid gallery (Layout). Read the SvGrid UI component docs for the full API.
What this example shows
SvMenu - a dropdown / actions menu with submenus, separators, icons and keyboard shortcuts. Portalled + animated; full keyboard (arrows, Enter, Escape, ArrowRight/Left for submenus).
Imports, features and API used
Imports: @svgrid/grid
Source code (326-menu.svelte)
<script lang="ts">
/**
* SvMenu - a dropdown / actions menu with submenus, separators, icons and
* keyboard shortcuts. Portalled + animated; full keyboard (arrows, Enter,
* Escape, ArrowRight/Left for submenus).
*/
import { SvMenu, SvButton } from '@svgrid/grid'
import type { MenuItem } from '@svgrid/grid'
let last = $state('')
const items: MenuItem[] = [
{ label: 'New file', shortcut: 'Ctrl+N', onSelect: () => (last = 'New file') },
{ label: 'Open...', shortcut: 'Ctrl+O', onSelect: () => (last = 'Open') },
{ separator: true },
{
label: 'Share',
children: [
{ label: 'Copy link', onSelect: () => (last = 'Copy link') },
{ label: 'Email', onSelect: () => (last = 'Email') },
{ separator: true },
{ label: 'Export as PDF', onSelect: () => (last = 'Export PDF') },
],
},
{ label: 'Rename', shortcut: 'F2', onSelect: () => (last = 'Rename') },
{ separator: true },
{ label: 'Delete', shortcut: 'Del', onSelect: () => (last = 'Delete') },
{ label: 'Archived (disabled)', disabled: true },
]
</script>
<div class="wrap">
<header>
<h2>Menu</h2>
<p>A dropdown menu with submenus, separators, shortcuts and full keyboard. Arrow to navigate, Enter to pick, ArrowRight opens a submenu.</p>
</header>
<div class="row">
<SvMenu {items}>
{#snippet anchor()}<SvButton variant="primary">File actions ▾</SvButton>{/snippet}
</SvMenu>
<SvMenu {items} ariaLabel="Row actions">
{#snippet anchor()}<SvButton variant="outline">⋯</SvButton>{/snippet}
</SvMenu>
<span class="last">{last ? `Chose: ${last}` : 'Nothing chosen yet'}</span>
</div>
</div>
<style>
.wrap { padding: 20px; max-width: 620px; display: flex; flex-direction: column; gap: 18px; }
header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; line-height: 1.5; }
.row { display: flex; align-items: center; gap: 14px; }
.last { font-size: 13px; color: var(--sg-muted, #64748b); }
</style>Related documentation
Related articles
- A Right-Click Context Menu for Your Svelte Data Grid - Build a right-click context menu that wires row actions, handles multi-row selection, and stays out of the way of SvGrid's own event handling.
- A Custom Column Header Menu in SvGrid - Build a per-column header menu for sort, hide, pin, and custom actions using header snippets and your own dropdown component.
- Avoiding Layout Thrash in Custom Grid Cells - Layout thrash from interleaved DOM reads and writes is the most common cause of scroll jank in grids with custom cells - here is how to find it and design your way out of it.
More Layout examples
- Account & security settings console - A real SaaS settings surface composed from the UI kit: SvMenubar app bar, promise + Undo-action toasts on save, SvPopconfirm on destructive rows, SvHoverCard teammate previews, and frame input adornments (leading icons, prefix affixes, masked API key). Profile / Team / Security tabs over SvCard + SvStat.
- Invoice builder - An adornment-heavy money form: currency prefixes, % suffixes, masked tax IDs (frame adornments), line items with SvPopconfirm delete + Undo action toasts, live SvStat totals, an SvHoverCard tax hint, and a promise toast on Send. Pure UI-kit composition.
- Operations KPI dashboard - A KPI console: SvStat + SvSparkline tiles, an SvGauge SLA dial, SvHoverCard drill-down previews per service, an SvMenubar toolbar (View / Range / Actions) and a promise toast on Refresh. Pure UI-kit composition, no grid dependency.
- Form: rich field types - SvForm reaching the whole input suite from one schema - phone, country, mask, combobox, radio, slider, tags, datetime and file - plus per-field help text, a readonly field, column span, and a promise toast on submit.
- Form: cascading fields - SvForm dependent selects - a child list derives from the parent value via a function `options`, and `dependsOn` clears the child when the parent changes so a stale selection never lingers. Country -> State -> City.