Column header context menu configuration.
The header menu provides column-level actions accessible via a dropdown in the column header. Configure sorting, pinning, hiding, auto-sizing, and custom actions.
interface GridHeaderMenuConfig {
hidden?: boolean;
showSort?: boolean;
showPin?: boolean;
showHide?: boolean;
showAutoSize?: boolean;
showReset?: boolean;
customItems?: ReactNode;
}<ActiveGrid
columns={columns}
data={data}
headerMenu={{
showSort: true,
showPin: true,
showHide: true,
showAutoSize: true,
}}
{...}
/>booleanfalseheaderMenu={{
hidden: true, // No menu icon in headers
}}booleantrueheaderMenu={{
showSort: true,
}}Options shown:
booleantrueheaderMenu={{
showPin: true,
}}Options shown:
booleantruebooleantruebooleantrueResets:
ReactNodeOverride header menu per column:
Different menu configurations per column:
Clicking "Sort Ascending" or "Sort Descending" triggers sorting:
Clicking "Pin Left" or "Pin Right" pins the column:
Clicking "Hide Column" hides the column:
Clicking "Auto-size Column" optimizes width:
Clicking "Reset Column" resets to defaults:
Header menu is accessible via:
Menu inherits theme styling automatically. Customize via CSS:
Header menus include:
The menu is triggered by clicking the three-dot icon (⋮) in the column header.
headerMenu={{
showHide: true,
}}headerMenu={{
showAutoSize: true,
}}headerMenu={{
showReset: true,
}}headerMenu={{
customItems: (
<>
<DropdownMenuItem onClick={handleCustomAction}>
Custom Action
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
),
}}<ActiveGrid
columns={columns}
data={data}
headerMenu={{
showSort: true,
showPin: true,
showHide: true,
showAutoSize: true,
showReset: true,
customItems: (
<>
<DropdownMenuItem onClick={handleFreeze}>
<Snowflake className="mr-2 h-4 w-4" />
Freeze Column
</DropdownMenuItem>
<DropdownMenuSeparator />
</>
),
}}
{...}
/>{
accessorKey: 'actions',
header: 'Actions',
meta: {
headerMenu: {
showSort: false,
showPin: false,
showHide: false,
},
},
}headerMenu={{
showSort: true,
showPin: false,
showHide: false,
showAutoSize: false,
showReset: false,
}}headerMenu={{
showSort: true,
showPin: true,
showHide: true,
showAutoSize: true,
showReset: true,
}}headerMenu={{
showSort: true,
showPin: true,
showHide: true,
showAutoSize: false, // No auto-size
showReset: false, // No reset
}}headerMenu={{
customItems: (
<DropdownMenuItem onClick={handleExport}>
<Download className="mr-2 h-4 w-4" />
Export Column
</DropdownMenuItem>
),
}}headerMenu={{
customItems: (
<>
<DropdownMenuItem onClick={handleCopy}>
<Copy className="mr-2 h-4 w-4" />
Copy Column Data
</DropdownMenuItem>
<DropdownMenuItem onClick={handleFilter}>
<Filter className="mr-2 h-4 w-4" />
Advanced Filter
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={handleAnalyze}>
<BarChart className="mr-2 h-4 w-4" />
Analyze Column
</DropdownMenuItem>
</>
),
}}function HeaderMenuWithContext({ column }) {
return (
<>
<DropdownMenuItem
onClick={() => {
const data = column.getFilteredRows().map(row => row.getValue(column.id));
console.log('Column data:', data);
}}
>
<Info className="mr-2 h-4 w-4" />
Show Stats
</DropdownMenuItem>
</>
);
}
<ActiveGrid
headerMenu={{
customItems: <HeaderMenuWithContext />,
}}
{...}
/>const columns: GridColumnDef<User>[] = [
{
accessorKey: 'name',
header: 'Name',
meta: {
headerMenu: {
showSort: true,
showPin: true,
showHide: false, // Always visible
},
},
},
{
accessorKey: 'email',
header: 'Email',
meta: {
headerMenu: {
showSort: true,
showPin: true,
customItems: (
<DropdownMenuItem onClick={handleEmailAll}>
<Mail className="mr-2 h-4 w-4" />
Email All
</DropdownMenuItem>
),
},
},
},
{
accessorKey: 'actions',
header: 'Actions',
meta: {
headerMenu: {
hidden: true, // No menu for actions column
},
},
},
];// User clicks "Sort Ascending" on Name column
// → table.setSorting([{ id: 'name', desc: false }])// User clicks "Pin Left" on Status column
// → column.pin('left')// User clicks "Hide Column"
// → column.toggleVisibility(false)// User clicks "Auto-size Column"
// → calculateAutoSize(table, column)
// → column.setSize(optimalWidth)// User clicks "Reset Column"
// → column.setSize(column.columnDef.size)
// → column.clearSorting()
// → column.pin(false)import {
Copy,
Download,
BarChart,
Filter,
Snowflake,
} from 'lucide-react';
function UsersTable() {
const handleCopyColumn = (column: Column<User>) => {
const values = column.getFacetedRowModel().rows
.map(row => row.getValue(column.id));
navigator.clipboard.writeText(values.join('\n'));
toast.success('Column copied to clipboard');
};
const handleExportColumn = (column: Column<User>) => {
const data = column.getFacetedRowModel().rows
.map(row => ({ [column.id]: row.getValue(column.id) }));
exportToCSV(data, `${column.id}.csv`);
};
const handleShowStats = (column: Column<User>) => {
const values = column.getFacetedRowModel().rows
.map(row => row.getValue(column.id)) as number[];
const sum = values.reduce((a, b) => a + b, 0);
const avg = sum / values.length;
toast.info(`Average: ${avg.toFixed(2)}`);
};
return (
<ActiveGrid
columns={columns}
data={users}
headerMenu={{
showSort: true,
showPin: true,
showHide: true,
showAutoSize: true,
showReset: true,
customItems: (column) => (
<>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => handleCopyColumn(column)}>
<Copy className="mr-2 h-4 w-4" />
Copy Column
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExportColumn(column)}>
<Download className="mr-2 h-4 w-4" />
Export Column
</DropdownMenuItem>
{column.columnDef.meta?.filterType === 'number' && (
<DropdownMenuItem onClick={() => handleShowStats(column)}>
<BarChart className="mr-2 h-4 w-4" />
Show Statistics
</DropdownMenuItem>
)}
</>
),
}}
/>
);
}.dropdown-menu-content {
/* Custom menu styling */
}
.dropdown-menu-item {
/* Custom item styling */
}{
id: 'select',
header: 'Select',
meta: {
headerMenu: {
hidden: true, // No menu for selection column
},
},
}import { GridHeaderMenuConfig } from '@workspace/active-grid';
const headerMenuConfig: GridHeaderMenuConfig = {
showSort: true,
showPin: true,
showHide: true,
showAutoSize: true,
customItems: <CustomMenuItems />,
};
<ActiveGrid
headerMenu={headerMenuConfig}
{...}
/>