Skip to content

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.

import { ContextMenuPlugin } from '@toolbox-web/grid/plugins/context-menu';
PropertyTypeDescription
idstringUnique item identifier
namestringDisplay label
iconstringIcon class or HTML
shortcutstringKeyboard shortcut hint
action(params) => voidClick handler
disabledboolean | (params) => booleanDisable condition
visibleboolean | (params) => booleanVisibility condition
itemsMenuItem[]Submenu items
separatorbooleanCreate a divider line
PropertyTypeDescription
rowIndexnumberClicked row index
colIndexnumberClicked column index
fieldstringColumn field name
valueanyCell value
rowanyFull row data
columnColumnConfigColumn configuration
PropertyDefaultDescription
--tbw-context-menu-bgvar(--tbw-color-panel-bg)Menu background
--tbw-context-menu-fgvar(--tbw-color-fg)Menu text color
--tbw-context-menu-hovervar(--tbw-color-row-hover)Item hover background
OptionTypeDescription
items?ContextMenuItem[] | (params: ContextMenuParams) => ContextMenuItem[]Menu items - static array or function returning items
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) },
],
}),
],
};
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:

TargetLong-press opensCondition
Header cellColumn header menuWhen the header-menu plugin is registered (#270, not yet built)
RowTouch selection modeWhen SelectionPlugin runs in mode: 'row'
CellCell range paintingWhen SelectionPlugin runs in mode: 'cell' or 'range'
Row / cellThis menuOtherwise

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.

Extends BaseGridPlugin

Inherited methods like attach(), detach(), afterRender(), etc. are documented in the base class.

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>): void
NameTypeDescription
xnumberViewport X coordinate (pixels)
ynumberViewport Y coordinate (pixels)
paramsPartial<ContextMenuParams>Partial context menu parameters — unspecified fields receive sensible defaults
const menu = grid.getPluginByName('context-menu');
// Open menu at a button's position with row context
const rect = button.getBoundingClientRect();
menu.showMenu(rect.left, rect.bottom, {
row: selectedRow,
rowIndex: 3,
column: columns[0],
});

Hide the context menu if it is currently open.

Safe to call even when the menu is already closed.

hideMenu(): void

Check if the context menu is currently open.

isMenuOpen(): boolean

boolean - true when the menu is visible


AI assistants: For complete API documentation, implementation guides, and code examples for this library, see https://toolboxjs.com/llms-full.txt