ContextMenuPlugin
Since v0.1.1
Context Menu Plugin for tbw-grid
Adds a customizable right-click menu to grid cells. Build anything from simple copy/paste actions to complex nested menus with conditional visibility, icons, and keyboard shortcuts.
Installation
Section titled “Installation”import { ContextMenuPlugin } from '@toolbox-web/grid/plugins/context-menu';Menu Item Structure
Section titled “Menu Item Structure”| Property | Type | Description |
|---|---|---|
id | string | Unique item identifier |
name | string | Display label |
icon | string | Icon class or HTML |
shortcut | string | Keyboard shortcut hint |
action | (params) => void | Click handler |
disabled | boolean | (params) => boolean | Disable condition |
visible | boolean | (params) => boolean | Visibility condition |
items | MenuItem[] | Submenu items |
separator | boolean | Create a divider line |
Menu Context (params)
Section titled “Menu Context (params)”| Property | Type | Description |
|---|---|---|
rowIndex | number | Clicked row index |
colIndex | number | Clicked column index |
field | string | Column field name |
value | any | Cell value |
row | any | Full row data |
column | ColumnConfig | Column configuration |
CSS Custom Properties
Section titled “CSS Custom Properties”| Property | Default | Description |
|---|---|---|
--tbw-context-menu-bg | var(--tbw-color-panel-bg) | Menu background |
--tbw-context-menu-fg | var(--tbw-color-fg) | Menu text color |
--tbw-context-menu-hover | var(--tbw-color-row-hover) | Item hover background |
| Option | Type | Description |
|---|---|---|
items? | ContextMenuItem[] | (params: ContextMenuParams) => ContextMenuItem[] | Menu items - static array or function returning items |
Examples
Section titled “Examples”Basic Context Menu
Section titled “Basic Context Menu”import '@toolbox-web/grid';import { ContextMenuPlugin } from '@toolbox-web/grid/plugins/context-menu';
grid.gridConfig = { plugins: [ new ContextMenuPlugin({ items: [ { id: 'copy', name: 'Copy', shortcut: 'Ctrl+C', action: (ctx) => navigator.clipboard.writeText(ctx.value) }, { separator: true, id: 'sep1', name: '' }, { id: 'delete', name: 'Delete', action: (ctx) => removeRow(ctx.rowIndex) }, ], }), ],};Conditional Menu Items
Section titled “Conditional Menu Items”new ContextMenuPlugin({ items: [ { id: 'edit', name: 'Edit', visible: (ctx) => ctx.column.editable === true }, { id: 'delete', name: 'Delete', disabled: (ctx) => ctx.row.locked === true }, ],})Touch input and the long-press priority order
Section titled “Touch input and the long-press priority order”The menu is opened by a native contextmenu event, which browsers already
synthesise from a right-click, a trackpad two-finger tap and a touch
long-press. There is therefore no long-press polyfill here — but a long-press
is an overloaded gesture, so the grid resolves it in a fixed order:
| Target | Long-press opens | Condition |
|---|---|---|
| Header cell | Column header menu | When the header-menu plugin is registered (#270, not yet built) |
| Row | Touch selection mode | When SelectionPlugin runs in mode: 'row' |
| Cell | Cell range painting | When SelectionPlugin runs in mode: 'cell' or 'range' |
| Row / cell | This menu | Otherwise |
The mechanism is deliberately passive. event-delegation.ts promotes a
coarse long-press after 400 ms and offers it to the plugins; if one claims
it, the grid suppresses the browser’s own contextmenu for a short window so
a menu does not pop on top of the gesture that was just consumed. If nothing
claims it, no suppression happens and this plugin opens exactly as it does
for a right-click.
When selection mode has consumed the long-press, these items remain reachable
through the More… button in SelectionPlugin’s selection toolbar, so
touch users never lose right-click parity.
See Also
Section titled “See Also”ContextMenuConfigfor configuration optionsContextMenuItemfor menu item structureContextMenuParamsfor action callback parameters
Extends BaseGridPlugin
Inherited methods like
attach(),detach(),afterRender(), etc. are documented in the base class.
Methods
Section titled “Methods”showMenu()
Section titled “showMenu()”Programmatically show the context menu at the specified position.
Use this to open the menu from custom UI elements or keyboard shortcuts
without requiring a native contextmenu event.
showMenu(x: number, y: number, params: Partial<ContextMenuParams>): voidParameters
Section titled “Parameters”| Name | Type | Description |
|---|---|---|
x | number | Viewport X coordinate (pixels) |
y | number | Viewport Y coordinate (pixels) |
params | Partial<ContextMenuParams> | Partial context menu parameters — unspecified fields receive sensible defaults |
Example
Section titled “Example”const menu = grid.getPluginByName('context-menu');// Open menu at a button's position with row contextconst rect = button.getBoundingClientRect();menu.showMenu(rect.left, rect.bottom, { row: selectedRow, rowIndex: 3, column: columns[0],});hideMenu()
Section titled “hideMenu()”Hide the context menu if it is currently open.
Safe to call even when the menu is already closed.
hideMenu(): voidisMenuOpen()
Section titled “isMenuOpen()”Check if the context menu is currently open.
isMenuOpen(): booleanReturns
Section titled “Returns”boolean - true when the menu is visible