Using Context Menus
The easiest way to configure a context menu is to provide the
getCellContextMenuItems
callback function and use it to return the menu items you want to show in the context menu.const getCellContextMenuItems = ({ column, value }) => { if (column.id === 'currency') { return [ { label: `Convert ${value}`, key: 'currency-convert', }, ]; } if (column.id === 'age') { return null; } return [ { label: `Welcome ${value}`, key: 'hi', }, ]; }; <DataSource<Developer> data={data} primaryKey="id"> <InfiniteTable<Developer> getCellContextMenuItems={getCellContextMenuItems} columns={columns} /> </DataSource>;
COPY
Right-click any cell in the table to see the custom context menu.
View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers100') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { stack: { field: 'stack', header: 'Stack', }, firstName: { field: 'firstName', header: 'Name', }, age: { field: 'age', header: 'Age', }, hobby: { field: 'hobby', header: 'Hobby', }, preferredLanguage: { header: 'Language', field: 'preferredLanguage', }, }; export default function App() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columns={columns} getCellContextMenuItems={({ data, column }) => { return [ { key: 'hello', label: `Hello, ${data?.lastName} ${data?.firstName}`, onClick: () => { alert(`Hello, ${data?.lastName} ${data?.firstName}`); }, }, { key: 'col', label: `Current clicked column: ${column.header}`, }, { key: 'learn', label: `Learn`, menu: { items: [ { key: 'backend', label: 'Backend', onClick: () => { alert( `Learn Backend, ${data?.lastName} ${data?.firstName}`, ); }, }, { key: 'frontend', label: 'Frontend', onClick: () => { alert( `Learn Frontend, ${data?.lastName} ${data?.firstName}`, ); }, }, ], }, }, ]; }} /> </DataSource> </>
The
getCellContextMenuItems
function can return one of the following:null
- no custom context menu will be displayed, the default context menu will be shown (default event behavior not prevented)[]
- an empty array - no custom context menu will be displayed, but the default context menu is not shown - the default event behavior is preventedArray<MenuItem>
- an array of menu items to be displayed in the context menu - eachMenuItem
should have:- a unique
key
property, - a
label
property with the value to display in the menu cell - it's calledlabel
because this is the name of the default column in the context menu - an optional
onClick
callback function to handle the click event on the menu item.
- a unique
In addition, if you need to configure the context menu to have other columns rather than the default column (named
label
), you can do so by returning an object with columns
and items
:const getCellContextMenuItems = () => { return { columns: [{ name: 'label' }, { name: 'lcon' }], items: [ { label: 'Welcome', icon: '👋', key: 'hi', onAction: () => { // do something }, hideMenuOnAction: true, }, { label: 'Convert', icon: '🔁', key: 'convert', }, ], }; };
COPY
Right-click any cell in the table to see a context menu with multiple columns (
icon
, label
and description
).View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers100') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { stack: { field: 'stack', header: 'Stack', }, firstName: { field: 'firstName', header: 'Name', }, age: { field: 'age', header: 'Age', }, hobby: { field: 'hobby', header: 'Hobby', }, preferredLanguage: { header: 'Language', field: 'preferredLanguage', }, }; export default function App() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columns={columns} columnDefaultEditable getCellContextMenuItems={({ data, column }) => { const columns = [ { name: 'icon' }, { name: 'label' }, { name: 'description' }, ]; return { columns, items: [ { key: 'hello', icon: '👋', label: `Hello, ${data?.lastName} ${data?.firstName}`, description: `This is a description for ${data?.lastName}`, onClick: () => { alert(`Hello, ${data?.lastName} ${data?.firstName}`); }, }, { key: 'col', icon: '🙌', label: `Column: ${column.header}`, description: `Current clicked column: ${column.header}`, }, { key: 'learn', icon: '📚', label: `Learn`, description: `Learn more about ${data?.preferredLanguage}`, menu: { columns, items: [ { key: 'backend', label: 'Backend', icon: '👨💻', description: 'In the Backend', onClick: () => { alert( `Learn Backend, ${data?.lastName} ${data?.firstName}`, ); }, }, { key: 'frontend', label: 'Frontend', icon: '👨💻', description: 'In the Frontend', onClick: () => { alert( `Learn Frontend, ${data?.lastName} ${data?.firstName}`, ); }, }, ], }, }, ], }; }} /> </DataSource> </>
Context Menus for the Table Body#
You might want to show a context menu for the table body, when the user right-clicks outside of any existing cell.
For this, you can use the
getContextMenuItems
prop.This function has almost the same signature as
getCellContextMenuItems
, with the following differences in the object passed as first parameter:- all cell-related properties (
column
,data
,value
, etc) can beundefined
- it contains an
event
property with the original event object for the right-click event
Right-click outside cells in the table to see a context menu for the table body.
View Mode
Fork Forkimport { InfiniteTable, DataSource, InfiniteTablePropColumns, } from '@infinite-table/infinite-react'; import * as React from 'react'; type Developer = { id: number; firstName: string; lastName: string; country: string; city: string; currency: string; preferredLanguage: string; stack: string; canDesign: 'yes' | 'no'; hobby: string; salary: number; age: number; }; const dataSource = () => { return fetch('https://infinite-table.com/.netlify/functions/json-server' + '/developers100') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { firstName: { field: 'firstName', header: 'Name', defaultWidth: 120, }, age: { field: 'age', header: 'Age', defaultWidth: 100, }, preferredLanguage: { header: 'Language', defaultWidth: 120, field: 'preferredLanguage', }, }; export default function App() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columns={columns} getContextMenuItems={({ data, column }) => { if (!data) return [ { key: 'add', label: 'Add Item', onClick: () => { alert('Add Item'); }, }, ]; return [ { key: 'hello', label: `Hello, ${data?.lastName} ${data?.firstName}`, onClick: () => { alert(`Hello, ${data?.lastName} ${data?.firstName}`); }, }, { key: 'col', label: `Current clicked column: ${column?.header}`, }, { key: 'learn', label: `Learn`, menu: { items: [ { key: 'backend', label: 'Backend', onClick: () => { alert( `Learn Backend, ${data?.lastName} ${data?.firstName}`, ); }, }, { key: 'frontend', label: 'Frontend', onClick: () => { alert( `Learn Frontend, ${data?.lastName} ${data?.firstName}`, ); }, }, ], }, }, ]; }} /> </DataSource> </>
Hiding the Context Menu#
To hide the context menu when you click a menu item, you can use the
hideMenuOnAction
property on the menu item.Alternatively, you can use the object passed in as a parameter to the
item.onAction
callback function to hide the menu:const getCellContextMenuItems = () => { return { items: [ { label: 'Hello', key: 'hi', onAction: ({ key, hideMenu }) => { // do something console.log('Hello'); // hide the menu hideMenu(); }, }, ], }; };
COPY
The third option is to use the
hideContextMenu
function in the API.