Column Menus
All columns in the Infinite Table have a default menu, which can be customized or hidden altogether.
Customise the menu items#
To customize the column menu (for all columns, or for a specific column), use the
getColumnMenuItems prop. This function is called with an array of menu items (which are the default items) and it should the final array of menu items - so you can return the default items as is, or you can adjust the default items to fit your needs. Customizing-column-menu
function getColumnMenuItems(items, { column }) {
if (column.id === 'firstName') {
// you can adjust the default items for a specific column
items.splice(0, 0, {
key: 'firstName',
label: 'First name menu item',
onClick: () => {
console.log('Hey there!');
},
});
}
// or for all columns
items.push({
key: 'hello',
label: 'Hello World',
onClick: () => {
alert('Hello World from column ' + column.id);
},
});
return items;
} COPY
getColumnMenuItems can return an empty array, in which case, the column menu will not be shown - however, people will still be able to click the menu icon to trigger the column context menu.If you want to dynamically decide whether a column should show a menu or not, you can use the
columns.renderMenuIcon prop.In this example, the currency and preferredLanguage columns have a custom icon for triggering the column context menu.
In addition, the
preferredLanguage column has a custom header that shows a button for triggering the column 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' + '/developers1k') .then((r) => r.json()) .then((data: Developer[]) => data); }; const columns: InfiniteTablePropColumns<Developer> = { currency: { field: 'currency', // custom menu icon renderMenuIcon: () => <div>🌎</div>, }, preferredLanguage: { field: 'preferredLanguage', defaultWidth: 350, header: ({ columnApi, renderLocation }) => { // if we're inside the column menu with all columns, return only the col name if (renderLocation === 'column-menu') { return 'Preferred Language'; } // but for the real column header // return this custom content return ( <> Preferred Language{' '} <button // we need to stop propagation so we don't trigger a sort when this button is clicked onPointerDown={(e) => e.stopPropagation()} onMouseDown={(e) => { // again, stop propagation so the menu is not closed automatically // so we can control it in the line below e.stopPropagation(); columnApi.toggleContextMenu(e.target); }} style={{ border: '1px solid magenta', margin: 2 }} > Toggle menu </button> </> ); }, // custom menu icon renderMenuIcon: () => <div>🌎</div>, }, salary: { field: 'salary', // hide the menu icon renderMenuIcon: false, }, country: { field: 'country', }, id: { field: 'id', defaultWidth: 80, renderMenuIcon: false }, firstName: { field: 'firstName', }, }; export default function ColumnContextMenuItems() { return ( <> <DataSource<Developer> primaryKey="id" data={dataSource}> <InfiniteTable<Developer> columnHeaderHeight={70} columns={columns} getColumnMenuItems={(items, { column }) => { if (column.id === 'firstName') { // you can adjust the default items for a specific column items.splice(0, 0, { key: 'firstName', label: 'First name menu item', onAction: () => { console.log('Hey there!'); }, }); } items.push( { key: 'hello', label: 'Hello World', onAction: () => { alert('Hello World from column ' + column.id); }, }, { key: 'translate', label: 'Translate', menu: { items: [ { key: 'translateToEnglish', label: 'English', onAction: () => { console.log('Translate to English'); }, }, { key: 'translateToFrench', label: 'French', onAction: () => { console.log('Translate to French'); }, }, ], }, }, ); return items; }} /> </DataSource> </>
As you can see in the demo above, you can use
getColumnMenuItems to return the default items (received as the first parameter to the function), or another totally different array. We chose to pass the default items to the function, so you can use them as a starting point and adjust them to your needs.Each item in the array you return from
getColumnMenuItems should have a key and a label property. Additionally, you can specify an onAction function, which will be called when the user clicks the menu item.It's also possible to create items with submenus. For this, specify a
menu property in the item, with an items array. Each item in the items array should have a key and a label property, as you would expect. Menu_items_with_submenus
function getColumnMenuItems(items, { column }) { const items = [ { key: 'translate', label: 'Translate', menu: { items: [ { key: 'translateToEnglish', label: 'English', onAction: () => { console.log('Translate to English'); }, }, { key: 'translateToFrench', label: 'French', onAction: () => { console.log('Translate to French'); }, }, ], }, }, ]; return items; }
COPY
Custom menu icon#
To customize the menu icon, use the
columns.renderMenuIcon prop. This prop can be a boolean or a function that returns a ReactNode. custom-menu-icon
const columns = {
name: {
field: 'firstName',
renderMenuIcon: () => <div>🌎</div>,
},
salary: {
field: 'salary',
renderMenuIcon: false,
},
}; COPY
For a custom menu icon 🌠 you don't have to hook up the
mousedown/click in order to show or hide the menu - all this is done for you - just render your custom ReactNode and you're good to go.