---
product: "AG Grid"
title: "Menu Item Component"
description: "Menu Item Components allow you to customise the menu items shown in the and . Use these when the provided menu items do not meet your requirements."
enterprise: true
framework: react
version: "36.2.0"
related:
    - title: "Tool Panels"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/tool-panel/"
    - title: "Quick Access Toolbar"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/toolbar/"
    - title: "Column Menu"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-menu/"
    - title: "Column Chooser"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-chooser/"
    - title: "Context Menu"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/context-menu/"
    - title: "Status Bar"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/status-bar/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Menu Item Component

Menu Item Components allow you to customise the menu items shown in the [Column Menu](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-menu/) and [Context Menu](https://www.ag-grid.com/archive/36.2.0/react-data-grid/context-menu/). Use these when the provided menu items do not meet your requirements.

The following example demonstrates a custom menu item component in both the column menu and context menu. Clicking on the buttons in the custom menu items will log to the developer console.

#### Custom Menu Item Component

```tsx
'use client';
import { useFetchJson } from './useFetchJson';
import React, { StrictMode, useCallback, useMemo, useState } from "react";
import { createRoot } from "react-dom/client";

import type {
  ColDef,
  GetContextMenuItemsParams,
  GetMainMenuItemsParams,
} from "ag-grid-community";
import {
  ClientSideRowModelModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  CellSelectionModule,
  ClipboardModule,
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { AgGridProvider, AgGridReact } from "ag-grid-react";

import type { IOlympicData } from "./interfaces";
import MenuItem from "./menuItem";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  ColumnMenuModule,

  ContextMenuModule,
  ExcelExportModule,
  CellSelectionModule,
  ClipboardModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete" },
    { field: "country" },
    { field: "sport" },
    { field: "year" },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const getMainMenuItems = useCallback((params: GetMainMenuItemsParams) => {
    return [
      ...params.defaultItems,
      "separator",
      {
        name: "Click Alert Button and Close Menu",
        menuItem: MenuItem,
        menuItemParams: {
          buttonValue: "Alert",
        },
      },
      {
        name: "Click Alert Button and Keep Menu Open",
        suppressCloseOnSelect: true,
        menuItem: MenuItem,
        menuItemParams: {
          buttonValue: "Alert",
        },
      },
    ];
  }, []);

  const getContextMenuItems = useCallback(
    (params: GetContextMenuItemsParams) => {
      return [
        ...(params.defaultItems || []),
        "separator",
        {
          name: "Click Alert Button and Close Menu",
          menuItem: MenuItem,
          menuItemParams: {
            buttonValue: "Alert",
          },
        },
        {
          name: "Click Alert Button and Keep Menu Open",
          suppressCloseOnSelect: true,
          menuItem: MenuItem,
          menuItemParams: {
            buttonValue: "Alert",
          },
        },
      ];
    },
    [],
  );

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            getMainMenuItems={getMainMenuItems}
            getContextMenuItems={getContextMenuItems}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Custom Menu Item Component](https://www.ag-grid.com/archive/36.2.0/examples/component-menu-item/custom-menu-item/reactFunctionalTs/)

```jsx
export default ({ name, icon, shortcut, subMenu }) => {
    useGridMenuItem(() => {
        configureDefaults: () => true;
    });
    return (
        <div>
            <span className="ag-menu-option-part ag-menu-option-icon">{icon}</span>
            <span className="ag-menu-option-part ag-menu-option-text">{name}</span>
            <span className="ag-menu-option-part ag-menu-option-shortcut">{shortcut}</span>
            <span className="ag-menu-option-part ag-menu-option-popup-pointer">{subMenu ? '>': ''}</span>
        </div>
    );
};
```

> **Note**
>
> In previous versions of the grid, custom components were declared in an imperative way. See [Migrating to Use reactiveCustomComponents](https://www.ag-grid.com/archive/36.2.0/react-data-grid/upgrading-to-ag-grid-31-1/#migrating-custom-components-to-use-reactivecustomcomponents-option) for details on how to migrate to the current format.

To enable the default menu item behaviour, pass the callback `configureDefaults` to the `useGridMenuItem` hook and return `true` (see [Providing Custom Behaviour](https://www.ag-grid.com/archive/36.2.0/react-data-grid/component-menu-item/#providing-custom-behaviour)).

## Custom Menu Item Parameters

### Menu Item Props

The following props are passed to the custom menu item components (`CustomMenuItemProps` interface).

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `active` | `boolean` |  |  |  |
| `expanded` | `boolean` |  |  |  |
| `onActiveChange` | `Function` |  |  |  |
| `level` | `number` |  |  |  |
| `isAnotherSubMenuOpen` | `Function` |  |  |  |
| `openSubMenu` | `Function` |  |  |  |
| `closeSubMenu` | `Function` |  |  |  |
| `closeMenu` | `Function` |  |  |  |
| `updateTooltip` | `Function` |  |  |  |
| `subMenu` | `(MenuItemDef \| string)[]` |  |  |  |
| `subMenuRole` | `'menu' \| 'listbox' \| 'tree' \| 'grid' \| 'dialog'` |  |  |  |
| `menuItem` | `any` |  |  |  |
| `menuItemParams` | `any` |  |  |  |
| `name` | `string` |  |  |  |
| `disabled` | `boolean` |  |  |  |
| `shortcut` | `string` |  |  |  |
| `action` | `Function` |  |  |  |
| `checked` | `boolean` |  |  |  |
| `icon` | `Element \| string` |  |  |  |
| `cssClasses` | `string[]` |  |  |  |
| `tooltip` | `string` |  |  |  |
| `suppressCloseOnSelect` | `boolean` |  |  |  |
| `api` | `GridApi` |  |  |  |
| `context` | `TContext` |  |  |  |

### Menu Item Callbacks

The following callbacks can be passed to the `useGridMenuItem` hook (`CustomMenuItemCallbacks` interface). All the callbacks are optional, and the hook only needs to be used if callbacks are provided.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `select` | `Function` |  |  |  |
| `configureDefaults` | `Function` |  |  |  |

## Default Styling

In order for the menu to size dynamically, the default styling is provided via `display: table`. This means that if custom menu item components are used alongside grid-provided menu items, then they must adhere to a certain structure, or the grid styles must be overridden.

The default structure consists of a parent element with `display: table-row`, and four children with `display: table-cell`. This can be seen in the example above. If using `configureDefaults` and not suppressing root styling, the grid will automatically add the correct styling to the parent element.

This format can be overridden by [Styling the Menu](https://www.ag-grid.com/archive/36.2.0/react-data-grid/theming-popups/), notably `ag-menu-list`, `ag-menu-option`, `ag-menu-option-part`, `ag-menu-separator` and `ag-menu-separator-part`. This is demonstrated in the [Providing Custom Behaviour](https://www.ag-grid.com/archive/36.2.0/react-data-grid/component-menu-item/#providing-custom-behaviour) example below.

## Providing Custom Behaviour

As described above, the easiest way to configure the behaviour of a custom menu item is returning `true` from `configureDefaults`.

If this is not done, then the custom menu item will need to implement all of the required behaviour itself.

It is also possible to disable certain parts of the behaviour by returning an object of type `IMenuConfigParams` from `configureDefaults`:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressTooltip` | `boolean` |  |  |  |
| `suppressClick` | `boolean` |  |  |  |
| `suppressMouseDown` | `boolean` |  |  |  |
| `suppressMouseOver` | `boolean` |  |  |  |
| `suppressKeyboardSelect` | `boolean` |  |  |  |
| `suppressTabIndex` | `boolean` |  |  |  |
| `suppressAria` | `boolean` |  |  |  |
| `suppressRootStyles` | `boolean` |  |  |  |
| `suppressFocus` | `boolean` |  |  |  |

The following example demonstrates providing custom behaviour (in the column menu only) by including a filter as a menu item. To allow for a full-width custom menu item alongside grid-provided ones, the default menu styling is overridden (see [Default Styling](https://www.ag-grid.com/archive/36.2.0/react-data-grid/component-menu-item/#default-styling)).

#### Menu Item Component Without Defaults

```tsx
'use client';
import { useFetchJson } from './useFetchJson';
import React, { StrictMode, useCallback, useMemo, useState } from "react";
import { createRoot } from "react-dom/client";

import type { ColDef, GetMainMenuItems } from "ag-grid-community";
import {
  ClientSideRowModelModule,
  NumberFilterModule,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  CellSelectionModule,
  ClipboardModule,
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
} from "ag-grid-enterprise";
import { AgGridProvider, AgGridReact } from "ag-grid-react";

import type { IOlympicData } from "./interfaces";
import MenuItem from "./menuItem";
import "./style.css";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  TextFilterModule,
  NumberFilterModule,
  ClientSideRowModelModule,
  ColumnMenuModule,
  ContextMenuModule,
  ExcelExportModule,
  CellSelectionModule,
  ClipboardModule,
];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete" },
    { field: "country" },
    { field: "sport" },
    { field: "year" },
    { field: "gold" },
    { field: "silver" },
    { field: "bronze" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      filter: true,
      suppressHeaderFilterButton: true,
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const getMainMenuItems = useCallback<GetMainMenuItems>((params) => {
    return [
      ...params.defaultItems.filter((item) => item !== "columnFilter"),
      "separator",
      {
        name: "Filter",
        menuItem: MenuItem,
        menuItemParams: {
          column: params.column,
        },
      },
    ];
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            getMainMenuItems={getMainMenuItems}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Menu Item Component Without Defaults](https://www.ag-grid.com/archive/36.2.0/examples/component-menu-item/menu-item-without-defaults/reactFunctionalTs/)

Note this shows a column filter in the custom menu item as an example for how complex items can be added. It is not meant to be used as a complete solution.
