Actions
Context Menu
A menu of actions for one area of the page, opened by right-click, Shift+F10 or a More actions button.
| Class name | Type | Description |
|---|---|---|
context-menuplf:context-menu | Component | Wraps the surface and the menu |
menuplf:menu | Component | The list of items, with context-menu-content |
context-menu-triggerplf:context-menu-trigger | Part | The surface that opens the menu |
context-menu-contentplf:context-menu-content | Part | The floating panel |
menu-shortcutplf:menu-shortcut | Part | A key hint; binds no key |
menu-itemplf:menu-item | Part | A button or link item |
menu-titleplf:menu-title | Part | A label above items |
menu-separatorplf:menu-separator | Part | A divider between items |
menu-iconplf:menu-icon | Part | An SVG icon before the text; an icon class there doesn't need it |
menu-textplf:menu-text | Part | An item's text |
menu-item-errorplf:menu-item-error | Color | A destructive item |
Default
Keep the More actions button: touch screens have no right-click.
<div class="context-menu card" data-plf-context-menu data-plf-align="start">
<div class="context-menu-trigger card-body flex flex-col gap-4" aria-describedby="context-menu-default-help">
<div>
<h3 class="card-title">Workspace preview</h3>
<p class="card-description" id="context-menu-default-help">A scoped area with a compact action menu. Selected text keeps the browser's menu.</p>
</div>
<div class="flex flex-wrap items-center gap-4">
<button class="btn btn-outline btn-sm" data-plf-context-menu-button hidden>
<span class="icon icon-dots"></span>
<span>More actions</span>
</button>
</div>
</div>
<div class="context-menu-content menu" aria-label="Workspace preview actions" hidden>
<div class="menu-title">Workspace preview</div>
<button class="menu-item">
<span class="icon icon-folder-open"></span>
<span class="menu-text">Open</span>
<span class="menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="menu-item" disabled>
<span class="icon icon-pencil"></span>
<span class="menu-text">Rename</span>
</button>
<button class="menu-item">
<span class="icon icon-copy"></span>
<span class="menu-text">Duplicate</span>
</button>
<hr class="menu-separator">
<button class="menu-item menu-item-error">
<span class="icon icon-trash"></span>
<span class="menu-text">Delete</span>
</button>
</div>
</div><div class="plf:context-menu plf:card" data-plf-context-menu data-plf-align="start">
<div class="plf:context-menu-trigger plf:card-body plf:flex plf:flex-col plf:gap-4" aria-describedby="context-menu-default-help">
<div>
<h3 class="plf:card-title">Workspace preview</h3>
<p class="plf:card-description" id="context-menu-default-help">A scoped area with a compact action menu. Selected text keeps the browser's menu.</p>
</div>
<div class="plf:flex plf:flex-wrap plf:items-center plf:gap-4">
<button class="plf:btn plf:btn-outline plf:btn-sm" data-plf-context-menu-button hidden>
<span class="plf:icon plf:icon-dots"></span>
<span>More actions</span>
</button>
</div>
</div>
<div class="plf:context-menu-content plf:menu" aria-label="Workspace preview actions" hidden>
<div class="plf:menu-title">Workspace preview</div>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-folder-open"></span>
<span class="plf:menu-text">Open</span>
<span class="plf:menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="plf:menu-item" disabled>
<span class="plf:icon plf:icon-pencil"></span>
<span class="plf:menu-text">Rename</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-copy"></span>
<span class="plf:menu-text">Duplicate</span>
</button>
<hr class="plf:menu-separator">
<button class="plf:menu-item plf:menu-item-error">
<span class="plf:icon plf:icon-trash"></span>
<span class="plf:menu-text">Delete</span>
</button>
</div>
</div>import { buttonClass, CardDescription, CardTitle, ContextMenu, ContextMenuButton, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuText, ContextMenuTitle, ContextMenuTrigger, Icon } from '@pelatform/react';
export function Example() {
return (
<ContextMenu className="card" align="start">
<ContextMenuTrigger className="card-body flex flex-col gap-4" aria-describedby="context-menu-default-help">
<div>
<CardTitle>Workspace preview</CardTitle>
<CardDescription id="context-menu-default-help">A scoped area with a compact action menu. Selected text keeps the browser's menu.</CardDescription>
</div>
<div className="flex flex-wrap items-center gap-4">
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm' })}>
<Icon name="dots" />
<span>More actions</span>
</ContextMenuButton>
</div>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Workspace preview actions">
<ContextMenuTitle>Workspace preview</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}import { buttonClass, CardDescription, CardTitle, ContextMenu, ContextMenuButton, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuText, ContextMenuTitle, ContextMenuTrigger, Icon } from '@pelatform/react/prefixed';
export function Example() {
return (
<ContextMenu className="plf:card" align="start">
<ContextMenuTrigger className="plf:card-body plf:flex plf:flex-col plf:gap-4" aria-describedby="context-menu-default-help">
<div>
<CardTitle>Workspace preview</CardTitle>
<CardDescription id="context-menu-default-help">A scoped area with a compact action menu. Selected text keeps the browser's menu.</CardDescription>
</div>
<div className="plf:flex plf:flex-wrap plf:items-center plf:gap-4">
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm' })}>
<Icon name="dots" />
<span>More actions</span>
</ContextMenuButton>
</div>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Workspace preview actions">
<ContextMenuTitle>Workspace preview</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
);
}In a list
Each row’s icon-only button needs an aria-label that names the row.
<ul class="item-group" role="list" aria-label="Project files">
<li class="context-menu" data-plf-context-menu data-plf-align="end">
<div class="context-menu-trigger item item-outline">
<span class="item-media">
<span class="icon icon-file-text"></span>
</span>
<div class="item-content">
<h3 class="item-title"><a href="#">Design notes</a></h3>
<p class="item-description">Document · Updated today</p>
</div>
<div class="item-actions">
<button class="btn btn-outline btn-sm btn-square" data-plf-context-menu-button aria-label="More actions for Design notes" hidden>
<span class="icon icon-dots"></span>
</button>
</div>
</div>
<div class="context-menu-content menu" aria-label="Design notes actions" hidden>
<div class="menu-title">Design notes</div>
<button class="menu-item">
<span class="icon icon-folder-open"></span>
<span class="menu-text">Open</span>
<span class="menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="menu-item">
<span class="icon icon-pencil"></span>
<span class="menu-text">Rename</span>
</button>
<button class="menu-item">
<span class="icon icon-copy"></span>
<span class="menu-text">Duplicate</span>
</button>
<hr class="menu-separator">
<button class="menu-item menu-item-error">
<span class="icon icon-trash"></span>
<span class="menu-text">Delete</span>
</button>
</div>
</li>
<li class="context-menu" data-plf-context-menu data-plf-align="end">
<div class="context-menu-trigger item item-outline">
<span class="item-media">
<span class="icon icon-file-text"></span>
</span>
<div class="item-content">
<h3 class="item-title"><a href="#">Budget report</a></h3>
<p class="item-description">Spreadsheet · Updated yesterday</p>
</div>
<div class="item-actions">
<button class="btn btn-outline btn-sm btn-square" data-plf-context-menu-button aria-label="More actions for Budget report" hidden>
<span class="icon icon-dots"></span>
</button>
</div>
</div>
<div class="context-menu-content menu" aria-label="Budget report actions" hidden>
<div class="menu-title">Budget report</div>
<button class="menu-item">
<span class="icon icon-folder-open"></span>
<span class="menu-text">Open</span>
<span class="menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="menu-item">
<span class="icon icon-pencil"></span>
<span class="menu-text">Rename</span>
</button>
<button class="menu-item">
<span class="icon icon-copy"></span>
<span class="menu-text">Duplicate</span>
</button>
<hr class="menu-separator">
<button class="menu-item menu-item-error">
<span class="icon icon-trash"></span>
<span class="menu-text">Delete</span>
</button>
</div>
</li>
<li class="context-menu" data-plf-context-menu data-plf-align="end">
<div class="context-menu-trigger item item-outline">
<span class="item-media">
<span class="icon icon-file-text"></span>
</span>
<div class="item-content">
<h3 class="item-title"><a href="#">Project archive</a></h3>
<p class="item-description">Folder · Rename unavailable</p>
</div>
<div class="item-actions">
<button class="btn btn-outline btn-sm btn-square" data-plf-context-menu-button aria-label="More actions for Project archive" hidden>
<span class="icon icon-dots"></span>
</button>
</div>
</div>
<div class="context-menu-content menu" aria-label="Project archive actions" hidden>
<div class="menu-title">Project archive</div>
<button class="menu-item">
<span class="icon icon-folder-open"></span>
<span class="menu-text">Open</span>
<span class="menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="menu-item" disabled>
<span class="icon icon-pencil"></span>
<span class="menu-text">Rename</span>
</button>
<button class="menu-item">
<span class="icon icon-copy"></span>
<span class="menu-text">Duplicate</span>
</button>
<hr class="menu-separator">
<button class="menu-item menu-item-error">
<span class="icon icon-trash"></span>
<span class="menu-text">Delete</span>
</button>
</div>
</li>
</ul><ul class="plf:item-group" role="list" aria-label="Project files">
<li class="plf:context-menu" data-plf-context-menu data-plf-align="end">
<div class="plf:context-menu-trigger plf:item plf:item-outline">
<span class="plf:item-media">
<span class="plf:icon plf:icon-file-text"></span>
</span>
<div class="plf:item-content">
<h3 class="plf:item-title"><a href="#">Design notes</a></h3>
<p class="plf:item-description">Document · Updated today</p>
</div>
<div class="plf:item-actions">
<button class="plf:btn plf:btn-outline plf:btn-sm plf:btn-square" data-plf-context-menu-button aria-label="More actions for Design notes" hidden>
<span class="plf:icon plf:icon-dots"></span>
</button>
</div>
</div>
<div class="plf:context-menu-content plf:menu" aria-label="Design notes actions" hidden>
<div class="plf:menu-title">Design notes</div>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-folder-open"></span>
<span class="plf:menu-text">Open</span>
<span class="plf:menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-pencil"></span>
<span class="plf:menu-text">Rename</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-copy"></span>
<span class="plf:menu-text">Duplicate</span>
</button>
<hr class="plf:menu-separator">
<button class="plf:menu-item plf:menu-item-error">
<span class="plf:icon plf:icon-trash"></span>
<span class="plf:menu-text">Delete</span>
</button>
</div>
</li>
<li class="plf:context-menu" data-plf-context-menu data-plf-align="end">
<div class="plf:context-menu-trigger plf:item plf:item-outline">
<span class="plf:item-media">
<span class="plf:icon plf:icon-file-text"></span>
</span>
<div class="plf:item-content">
<h3 class="plf:item-title"><a href="#">Budget report</a></h3>
<p class="plf:item-description">Spreadsheet · Updated yesterday</p>
</div>
<div class="plf:item-actions">
<button class="plf:btn plf:btn-outline plf:btn-sm plf:btn-square" data-plf-context-menu-button aria-label="More actions for Budget report" hidden>
<span class="plf:icon plf:icon-dots"></span>
</button>
</div>
</div>
<div class="plf:context-menu-content plf:menu" aria-label="Budget report actions" hidden>
<div class="plf:menu-title">Budget report</div>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-folder-open"></span>
<span class="plf:menu-text">Open</span>
<span class="plf:menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-pencil"></span>
<span class="plf:menu-text">Rename</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-copy"></span>
<span class="plf:menu-text">Duplicate</span>
</button>
<hr class="plf:menu-separator">
<button class="plf:menu-item plf:menu-item-error">
<span class="plf:icon plf:icon-trash"></span>
<span class="plf:menu-text">Delete</span>
</button>
</div>
</li>
<li class="plf:context-menu" data-plf-context-menu data-plf-align="end">
<div class="plf:context-menu-trigger plf:item plf:item-outline">
<span class="plf:item-media">
<span class="plf:icon plf:icon-file-text"></span>
</span>
<div class="plf:item-content">
<h3 class="plf:item-title"><a href="#">Project archive</a></h3>
<p class="plf:item-description">Folder · Rename unavailable</p>
</div>
<div class="plf:item-actions">
<button class="plf:btn plf:btn-outline plf:btn-sm plf:btn-square" data-plf-context-menu-button aria-label="More actions for Project archive" hidden>
<span class="plf:icon plf:icon-dots"></span>
</button>
</div>
</div>
<div class="plf:context-menu-content plf:menu" aria-label="Project archive actions" hidden>
<div class="plf:menu-title">Project archive</div>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-folder-open"></span>
<span class="plf:menu-text">Open</span>
<span class="plf:menu-shortcut" aria-hidden="true">Enter</span>
</button>
<button class="plf:menu-item" disabled>
<span class="plf:icon plf:icon-pencil"></span>
<span class="plf:menu-text">Rename</span>
</button>
<button class="plf:menu-item">
<span class="plf:icon plf:icon-copy"></span>
<span class="plf:menu-text">Duplicate</span>
</button>
<hr class="plf:menu-separator">
<button class="plf:menu-item plf:menu-item-error">
<span class="plf:icon plf:icon-trash"></span>
<span class="plf:menu-text">Delete</span>
</button>
</div>
</li>
</ul>import { buttonClass, ContextMenu, ContextMenuButton, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuText, ContextMenuTitle, ContextMenuTrigger, Icon, ItemActions, itemClass, ItemContent, ItemDescription, ItemGroup } from '@pelatform/react';
export function Example() {
return (
<ItemGroup aria-label="Project files">
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="item-title"><a href="#">Design notes</a></h3>
<ItemDescription>Document · Updated today</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Design notes">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Design notes actions">
<ContextMenuTitle>Design notes</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="item-title"><a href="#">Budget report</a></h3>
<ItemDescription>Spreadsheet · Updated yesterday</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Budget report">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Budget report actions">
<ContextMenuTitle>Budget report</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="item-title"><a href="#">Project archive</a></h3>
<ItemDescription>Folder · Rename unavailable</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Project archive">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Project archive actions">
<ContextMenuTitle>Project archive</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
</ItemGroup>
);
}import { buttonClass, ContextMenu, ContextMenuButton, ContextMenuContent, ContextMenuItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuText, ContextMenuTitle, ContextMenuTrigger, Icon, ItemActions, itemClass, ItemContent, ItemDescription, ItemGroup } from '@pelatform/react/prefixed';
export function Example() {
return (
<ItemGroup aria-label="Project files">
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="plf:item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="plf:item-title"><a href="#">Design notes</a></h3>
<ItemDescription>Document · Updated today</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Design notes">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Design notes actions">
<ContextMenuTitle>Design notes</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="plf:item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="plf:item-title"><a href="#">Budget report</a></h3>
<ItemDescription>Spreadsheet · Updated yesterday</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Budget report">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Budget report actions">
<ContextMenuTitle>Budget report</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
<li>
<ContextMenu align="end">
<ContextMenuTrigger className={itemClass({ variant: 'outline' })}>
<span className="plf:item-media">
<Icon name="file-text" />
</span>
<ItemContent>
<h3 className="plf:item-title"><a href="#">Project archive</a></h3>
<ItemDescription>Folder · Rename unavailable</ItemDescription>
</ItemContent>
<ItemActions>
<ContextMenuButton className={buttonClass({ variant: 'outline', size: 'sm', shape: 'square' })} aria-label="More actions for Project archive">
<Icon name="dots" />
</ContextMenuButton>
</ItemActions>
</ContextMenuTrigger>
<ContextMenuContent aria-label="Project archive actions">
<ContextMenuTitle>Project archive</ContextMenuTitle>
<ContextMenuItem>
<Icon name="folder-open" />
<ContextMenuText>Open</ContextMenuText>
<ContextMenuShortcut>Enter</ContextMenuShortcut>
</ContextMenuItem>
<ContextMenuItem disabled>
<Icon name="pencil" />
<ContextMenuText>Rename</ContextMenuText>
</ContextMenuItem>
<ContextMenuItem>
<Icon name="copy" />
<ContextMenuText>Duplicate</ContextMenuText>
</ContextMenuItem>
<ContextMenuSeparator />
<ContextMenuItem color="error">
<Icon name="trash" />
<ContextMenuText>Delete</ContextMenuText>
</ContextMenuItem>
</ContextMenuContent>
</ContextMenu>
</li>
</ItemGroup>
);
}JavaScript
Context Menu needs JavaScript. The Full script (pelatform-ui.min.js) starts every component on page load, with no code of your own; with ESM imports, call init() yourself, as in Installation. For markup you add later, see Dynamic content.
<link rel="stylesheet" href="pelatform-ui.min.css">
<link rel="stylesheet" href="icons/icons.min.css">
<script src="pelatform-ui.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.min.css">
<link rel="stylesheet" href="components/button.min.css">
<link rel="stylesheet" href="components/card.min.css">
<link rel="stylesheet" href="components/dropdown-menu.min.css">
<link rel="stylesheet" href="components/item.min.css">
<link rel="stylesheet" href="components/context-menu.min.css">
<link rel="stylesheet" href="icons/icons.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/context-menu.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script><link rel="stylesheet" href="pelatform-ui.prefixed.min.css">
<link rel="stylesheet" href="icons/icons.prefixed.min.css">
<script src="pelatform-ui.min.js" defer></script><link rel="stylesheet" href="core/pelatform-ui-core.prefixed.min.css">
<link rel="stylesheet" href="components/button.prefixed.min.css">
<link rel="stylesheet" href="components/card.prefixed.min.css">
<link rel="stylesheet" href="components/dropdown-menu.prefixed.min.css">
<link rel="stylesheet" href="components/item.prefixed.min.css">
<link rel="stylesheet" href="components/context-menu.prefixed.min.css">
<link rel="stylesheet" href="icons/icons.prefixed.min.css">
<script src="core/pelatform-ui-core.min.js" defer></script>
<script src="components/context-menu.min.js" defer></script>
<script>document.addEventListener('DOMContentLoaded', () => PLF.init());</script>| Attribute | Purpose |
|---|---|
data-plf-context-menu |
Marks the wrapper |
data-plf-context-menu-trigger |
Optional: marks the surface, otherwise the wrapper’s direct child without hidden: a div, section, article or li. It gets role="group", and its first heading names it unless it has aria-label or aria-labelledby |
data-plf-context-menu-button |
The More actions <button>, with text or aria-label; authored hidden, shown by the script |
data-plf-context-menu-content |
Optional: marks the panel, otherwise the wrapper’s direct child with hidden. The surface’s first heading names it unless it has aria-label or aria-labelledby. Its direct <button> and <a href> children are the items, and it holds no other controls |
data-plf-context-menu-separator |
Optional: gives another element the separator role; an <hr class="menu-separator"> needs none |
data-plf-label |
On an item, the text typeahead matches |
data-plf-placement |
On the wrapper: top, bottom (default), left or right, for keyboard and button opening |
data-plf-align |
On the wrapper: start, center (default) or end |
disabled, aria-disabled="true" |
An item or the More actions button that cannot be used |
| Method | Behavior |
|---|---|
PLF. |
Returns the instance, creating it for valid markup |
PLF. |
Returns the instance or null |
instance. |
Opens, at an optional viewport point {x, y}. Returns false when already open, unavailable or canceled |
instance. |
Closes; reason is api (the default), trigger, keyboard or pointer. Returns false when already closed or canceled |
instance. |
Returns {open, position}; position is {x, y} or null |
instance. |
Closes without events and removes listeners and added attributes |
| Event | When |
|---|---|
plf: |
Before opening; cancelable |
plf: |
After opening |
plf: |
Before closing; cancelable |
plf: |
After closing |
Each event’s detail:
| Property | Value |
|---|---|
instance |
The Context Menu instance |
reason |
api, trigger, keyboard or pointer |
trigger |
The surface, the button or the chosen item, or null |
target |
The surface |
position |
The viewport point it opened at, {x, y}, or null |
| Key | Action |
|---|---|
| Shift+F10, ContextMenu | On the surface or the button, opens the menu |
| Enter, Space | On the button, toggles the menu; on an item, activates it |
| Down Arrow, Up Arrow | On the button, open at the first or last item; in the menu, move to the next or previous item |
| Home, End | Move to the first or last item |
| Letters | Move to the next item that starts with the typed text |
| Escape | Closes the menu and returns focus |
| Tab, Shift+Tab | Close the menu and move to the next or previous control |
React
ContextMenu from @pelatform/react renders this menu: it keeps its own state, or the application sets it with open, and each part is a component of its own.
| Prop | Values | Default |
|---|---|---|
placement |
top, right, bottom or left, for keyboard and button opening |
bottom |
align |
start, center or end |
center |
open |
true while the menu is open, beside the More actions button, which the application changes in onOpenChange |
Its own state |
defaultOpen |
true starts open when the application does not set open |
false |
onOpenChange |
(open, reason), called when the menu opens or closes: pointer (a right-click, a press outside or scrolling), trigger (the More actions button or a chosen item), keyboard, or api (another Context Menu opening); keep open to stay as it is |
None |
The parts:
| Part | Element |
|---|---|
ContextMenuTrigger |
A div with context-menu-trigger, the surface: a group its first heading names, which a right-click, Shift+F10 or the Menu key opens the menu from |
ContextMenuButton |
The More actions button; buttonClass gives it a look |
ContextMenuContent |
A div with context-menu-content menu, the menu |
ContextMenuItem |
A button with menu-item, or a link with href; color="error" marks a destructive item, and onSelect runs when it is chosen, then the menu closes unless it calls event. |
ContextMenuTitle |
A div with menu-title |
ContextMenuSeparator |
An hr with menu-separator |
ContextMenuText |
A span with menu-text |
ContextMenuShortcut |
A span with menu-shortcut, hidden from assistive technologies |
The other props are the element’s own, className and ref included.
| Variable | Default |
|---|---|
--plf-context-menu-width |
14rem, capped to the viewport |
--plf-context-menu-bg, --plf-context-menu-color |
Elevated surface and text |
--plf-context-menu-border |
--plf-color-border-subtle; also the separator color |
--plf-context-menu-radius |
Large radius (8px) |
--plf-context-menu-item-hover-bg |
--plf-color-surface-muted; --plf-color-danger-subtle on destructive items |