# Context Menu
URL: https://pro.rv-grid.com/api/context-menu/
Source: src/content/docs/api/context-menu.md
## Module Extensions

### `HTMLRevoGridElement` (Extended from `global`)

```ts
interface HTMLRevoGridElement {
  /**
       * Context menu configuration for row and body-cell targets.
       */
      rowContextMenu?: ContextMenuConfig;
  /**
       * Context menu configuration for column-header targets.
       */
      columnContextMenu?: ContextMenuConfig;
  /**
       * Legacy/shared context menu configuration. Used as a fallback when target-specific
       * row/column configs are not provided.
       */
      contextMenu?: ContextMenuConfig;
  /** Kebab-case alias for framework/native custom element bindings. */
      'row-context-menu'?: ContextMenuConfig;
  /** Kebab-case alias for framework/native custom element bindings. */
      'column-context-menu'?: ContextMenuConfig;
  /** Kebab-case alias for framework/native custom element bindings. */
      'context-menu'?: ContextMenuConfig
}
```

---

### `AdditionalData` (Extended from `@revolist/revogrid`)

```ts
interface AdditionalData {
  /**
       * The context menu configuration for row and body-cell targets.
       *
       * @example
       * ```typescript
       * grid.additionalData = {
       *   rowContextMenu: { items: [{ name: 'Edit', action: () => console.log('Edit action') }] },
       * };
       * ```
       *
       * Prefer the direct `grid.rowContextMenu` property when the framework wrapper supports it.
       */
      rowContextMenu?: ContextMenuConfig;
  /**
       * The context menu configuration for column-header targets.
       *
       * @example
       * ```typescript
       * grid.additionalData = {
       *   columnContextMenu: { items: [{ name: 'Autosize', action: () => console.log('Autosize') }] },
       * };
       * ```
       *
       * Prefer the direct `grid.columnContextMenu` property when the framework wrapper supports it.
       */
      columnContextMenu?: ContextMenuConfig
}
```

## Plugin API

### `ContextMenuPlugin`

Adds configurable context menus to RevoGrid.

The plugin supports separate `rowContextMenu` and `columnContextMenu`
configurations while keeping `contextMenu` as a legacy fallback. Column menus
receive the current column, virtual column index, and column section, so a
single `columnContextMenu` can resolve different menu items for regular,
left-pinned, right-pinned, or specific columns.

**Example:**
```typescript
* ```typescript
 * import { ContextMenuPlugin } from '@revolist/revogrid-pro'
 *
 * const grid = document.createElement('revo-grid');
 * grid.plugins = [ContextMenuPlugin];
 * grid.rowContextMenu = { items: [{ name: 'Delete row' }] };
 * grid.columnContextMenu = {
 *   items: [{ name: 'Autosize column' }],
 *   resolve(context) {
 *     if (context.target === 'column' && context.columnType === 'colPinStart') {
 *       return { items: [{ name: 'Unpin left column' }] };
 *     }
 *   },
 * };
 * ```
```

#### Dependencies

- **Event integration** `RowHeaderPlugin`: Integrates with RowHeaderPlugin row menu events when present.

```ts
class ContextMenuPlugin {
  /**
     * Applies defaults to a partial context menu config.
     *
     * @param config - User-provided menu config.
     * @param targetSelectors - Default selectors for the target-specific config.
     */
  getConfig(config: Partial<ContextMenuConfig> =;

  /**
     * Hides the context menu popup without clearing the active config.
     */
  close();

  /**
     * Opens the context menu for a DOM target.
     *
     * If `menuTarget` is provided, that target config is used directly. Otherwise
     * the plugin inspects the DOM target and chooses the column menu before the row
     * menu. The selected config is passed through `resolve` before rendering.
     *
     * @param target - Element that should anchor or identify the menu target.
     * @param event - Pointer event used for positioning and resolver context.
     * @param menuTarget - Optional explicit target used by row-header menu events.
     */
  async open(target: EventTarget | null, event?: MouseEvent, menuTarget?: ContextMenuTarget);

  clearSubscriptions();
}
```

---

### `ContextMenuTarget`

Supported high-level targets for the context menu.

`row` covers body cells and row-menu buttons. `column` covers column header
cells, including pinned column sections.

```ts
/**
 * Supported high-level targets for the context menu.
 *
 * `row` covers body cells and row-menu buttons. `column` covers column header
 * cells, including pinned column sections.
 */
export type ContextMenuTarget = 'row' | 'column';
```

---

### `ContextMenuOpenContextBase`

Shared context passed to dynamic menu resolvers and menu item actions.

```ts
/**
 * Shared context passed to dynamic menu resolvers and menu item actions.
 */
export type ContextMenuOpenContextBase = {
  /** The active menu target type. */
  target: ContextMenuTarget;
  /** Element that caused the menu to open. */
  triggerElement: HTMLElement;
  /** Mouse event that opened the menu, when opened from pointer interaction. */
  triggerEvent?: MouseEvent;
  /** Grid element that owns the plugin instance. */
  revogrid: HTMLRevoGridElement;
  /** Core plugin providers for data, dimensions, selection, columns, viewport, and plugins. */
  providers: PluginProviders;
};
```

---

### `ContextMenuColumnGroup`

```ts
export type ContextMenuColumnGroup = {
  /** Display label rendered by the grouped header. */
  name: string;
  /** Source child columns covered by this grouped header. */
  children: (ColumnGrouping | ColumnRegular)[];
  /** Physical indexes covered by this column group. */
  indexes: number[];
  /** Grouping row depth in the header. */
  depth?: number;
};
```

---

### `ColumnContextMenuOpenContext` (Extended from `index.ts`)

Context available when a menu opens from a column header target.

```ts
/**
 * Context available when a menu opens from a column header target.
 */
export type ColumnContextMenuOpenContext = ContextMenuOpenContextBase & {
  target: 'column';
  /** Column model resolved from the header section and virtual column index. */
  column?: ColumnRegular;
  /** Column group model resolved when opening from a grouped header cell. */
  columnGroup?: ContextMenuColumnGroup;
  /** Physical column indexes covered by this menu target when it is a grouped header cell. */
  columnIndexes?: number[];
  /** Grouping row depth when opening from a grouped header cell. */
  columnGroupDepth?: number;
  /** Virtual column index inside the current column section. */
  columnIndex?: number;
  /** Column section that opened the menu: regular, left-pinned, or right-pinned. */
  columnType?: DimensionCols;
};
```

---

### `RowContextMenuOpenContext` (Extended from `index.ts`)

Context available when a menu opens from a row/body target.

```ts
/**
 * Context available when a menu opens from a row/body target.
 */
export type RowContextMenuOpenContext = ContextMenuOpenContextBase & {
  target: 'row';
};
```

---

### `ContextMenuOpenContext`

Union of all target-specific open contexts.

```ts
/**
 * Union of all target-specific open contexts.
 */
export type ContextMenuOpenContext = ColumnContextMenuOpenContext | RowContextMenuOpenContext;
```

---

### `ContextMenuConfigResolver`

Dynamic menu resolver.

Return `undefined` to keep the base config, return a partial config to override
settings/items for this invocation, or return `null` to suppress the menu.

**Example:**
```typescript
* ```ts
 * const columnContextMenu = {
 *   items: defaultItems,
 *   resolve(context) {
 *     if (context.target === 'column' && context.columnType === 'colPinStart') {
 *       return { items: pinnedColumnItems };
 *     }
 *   },
 * };
 * ```
```

```ts
/**
 * Dynamic menu resolver.
 *
 * Return `undefined` to keep the base config, return a partial config to override
 * settings/items for this invocation, or return `null` to suppress the menu.
 *
 * @example
 * ```ts
 * const columnContextMenu = {
 *   items: defaultItems,
 *   resolve(context) {
 *     if (context.target === 'column' && context.columnType === 'colPinStart') {
 *       return { items: pinnedColumnItems };
 *     }
 *   },
 * };
 * ```
 */
export type ContextMenuConfigResolver = (
  context: ContextMenuOpenContext,
) => Partial<ContextMenuConfig> | null | undefined;
```

---

### `ContextMenuActionContext`

Context passed as the fifth argument to `ContextMenuItem.action`.

```ts
/**
 * Context passed as the fifth argument to `ContextMenuItem.action`.
 */
export type ContextMenuActionContext = {
  /** Grid element that owns the plugin instance. */
  revogrid: HTMLRevoGridElement,
  /** Core plugin providers for data, dimensions, selection, columns, viewport, and plugins. */
  providers: PluginProviders,
  /** Context captured when this menu was opened. */
  menu?: ContextMenuOpenContext,
};
```

---

### `ContextMenuItem`

Single menu item definition.

```ts
/**
 * Single menu item definition.
 */
export type ContextMenuItem = {
  /** Text or dynamic text rendered inside the item. */
  name: string | ((focused?: Cell | null, range?: RangeArea | null) => string);
  /** CSS class added to the `<li>` item. */
  class?: string;
  /** Icon rendered before the item name. Accepts CSS classes or inline SVG markup. */
  icon?: string;
  /** CSS class added to the `<li>` item, optionally calculated from selection state. */
  rowClass?: string | ((item: ContextMenuItem, focused?: Cell | null, range?: RangeArea | null) => string);
  /** Hide the item statically or from current selection state. */
  hidden?: boolean | ((item: ContextMenuItem, focused?: Cell | null, range?: RangeArea | null) => boolean);
  /** Disable the item statically or from current selection state while keeping it visible. */
  disabled?: boolean | ((item: ContextMenuItem, focused?: Cell | null, range?: RangeArea | null) => boolean);
  /** Called when the item is selected. */
  action?: (event: MouseEvent, focused?: Cell | null, range?: RangeArea | null, close?: () => void, context?: ContextMenuActionContext) => void;
  /** Keep the popup open after this item action runs. */
  keepOpen?: boolean;
  /** Custom item renderer. */
  template?: (h: HyperFunc<VNode>, item: ContextMenuItem, focused?: Cell | null, range?: RangeArea | null, close?: () => void) => any;
};
```

---

### `ContextMenuConfig`

Context menu configuration.

Use `rowContextMenu` for row/body targets and `columnContextMenu` for header
targets. `resolve` can refine either menu at open time for column sections,
individual columns, or any other target-specific condition.

```ts
/**
 * Context menu configuration.
 *
 * Use `rowContextMenu` for row/body targets and `columnContextMenu` for header
 * targets. `resolve` can refine either menu at open time for column sections,
 * individual columns, or any other target-specific condition.
 */
export type ContextMenuConfig = {
  /** Items rendered in the popup. */
  items: ContextMenuItem[];
  /** Open the menu on the native `contextmenu` event. Defaults to `true`. */
  rightClick?: boolean;
  /** Open the menu on left click. Defaults to `false`. */
  leftClick?: boolean;
  /** CSS selectors that can trigger this menu. */
  targetSelectors?: string[];
  /** Position the popup relative to the target element instead of pointer coordinates. */
  anchorToTarget?: boolean;
  /**
   * Resolves a menu override for the current target before the menu opens.
   * Return `null` to suppress the menu for that target, `undefined` to use the base config,
   * or a partial config to override items/settings for this invocation.
   */
  resolve?: ContextMenuConfigResolver;
};
```

---

### `renderMenuItemIcon`

```ts
export function renderMenuItemIcon(icon?: string);
```

---

### `contextPopUp`

Extra VNode renderer registered by `ContextMenuPlugin`.

It reads the plugin instance state (`config`, `activeContext`, selection, and
close handler) and renders the current popup items. Menu item actions receive
the latest `activeContext`, which lets column menu actions know the exact
pinned section and column that opened the menu.

```ts
export function contextPopUp(this:;
```

---

### `POP_EL`

Registered extra VNode name for the context-menu popup.

The plugin uses this value to replace any previous popup renderer when the
plugin is re-created, preventing duplicate popup nodes.

```ts
POP_EL: string;
```
