AG Grid React Component wrapper for integrating the high-performance data grid into React applications
—
React components for customizing column headers and header groups with full interaction support, including sorting, resizing, and menu triggers.
Custom React components for rendering column headers with interaction handling.
/**
* Props provided to custom header components
* @template TData - Type of row data objects
* @template TContext - Type of grid context
*/
interface CustomHeaderProps<TData = any, TContext = any>
extends IHeaderParams<TData, TContext> {}Usage Examples:
import React, { useState } from 'react';
import { CustomHeaderProps } from 'ag-grid-react';
// Simple custom header with icon
const IconHeaderComponent: React.FC<CustomHeaderProps> = (props) => {
const [sortOrder, setSortOrder] = useState<'asc' | 'desc' | null>(null);
const onSortChanged = () => {
const currentSort = props.column.getSort();
setSortOrder(currentSort);
};
React.useEffect(() => {
props.column.addEventListener('sortChanged', onSortChanged);
return () => {
props.column.removeEventListener('sortChanged', onSortChanged);
};
}, [props.column]);
const handleSort = () => {
props.progressSort(true); // Enable multi-sort with Ctrl
};
const getSortIcon = () => {
if (sortOrder === 'asc') return '↑';
if (sortOrder === 'desc') return '↓';
return '';
};
return (
<div
style={{
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
height: '100%'
}}
onClick={handleSort}
>
<span>{props.displayName}</span>
<span style={{ marginLeft: '5px' }}>{getSortIcon()}</span>
</div>
);
};
// Interactive header with custom menu
const InteractiveHeaderComponent: React.FC<CustomHeaderProps> = (props) => {
const [showMenu, setShowMenu] = useState(false);
const handleMenuClick = (event: React.MouseEvent) => {
event.stopPropagation();
setShowMenu(!showMenu);
// Trigger column menu
props.showColumnMenu(event.target as HTMLElement);
};
return (
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<span>{props.displayName}</span>
<button
onClick={handleMenuClick}
style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}
>
⋮
</button>
</div>
);
};
// Usage in column definitions
const columnDefs = [
{
field: 'name',
headerComponent: IconHeaderComponent,
sortable: true
},
{
field: 'email',
headerComponent: InteractiveHeaderComponent,
menuTabs: ['generalMenuTab', 'filterMenuTab']
}
];Custom React components for rendering column group headers with expand/collapse functionality.
/**
* Props provided to custom header group components
* @template TData - Type of row data objects
* @template TContext - Type of grid context
*/
interface CustomHeaderGroupProps<TData = any, TContext = any>
extends IHeaderGroupParams<TData, TContext> {}Usage Example:
import React, { useState, useEffect } from 'react';
import { CustomHeaderGroupProps } from 'ag-grid-react';
const CustomHeaderGroupComponent: React.FC<CustomHeaderGroupProps> = (props) => {
const [expanded, setExpanded] = useState(true);
useEffect(() => {
const updateExpandedState = () => {
const isExpanded = props.columnGroup.isExpanded();
setExpanded(isExpanded);
};
props.columnGroup.addEventListener('expandedChanged', updateExpandedState);
updateExpandedState(); // Initial state
return () => {
props.columnGroup.removeEventListener('expandedChanged', updateExpandedState);
};
}, [props.columnGroup]);
const handleToggle = () => {
const newExpandedState = !expanded;
props.setExpanded(newExpandedState);
};
return (
<div
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '100%',
cursor: 'pointer',
backgroundColor: '#f0f0f0',
fontWeight: 'bold'
}}
onClick={handleToggle}
>
<span>{expanded ? '−' : '+'}</span>
<span style={{ marginLeft: '5px' }}>{props.displayName}</span>
</div>
);
};
// Usage in column definitions
const columnDefs = [
{
headerName: 'User Information',
headerGroupComponent: CustomHeaderGroupComponent,
children: [
{ field: 'firstName', headerName: 'First Name' },
{ field: 'lastName', headerName: 'Last Name' },
{ field: 'email', headerName: 'Email' }
]
}
];Custom React components for rendering inner header content (used internally by AG Grid).
/**
* Props provided to custom inner header components
* @template TData - Type of row data objects
* @template TContext - Type of grid context
*/
interface CustomInnerHeaderProps<TData = any, TContext = any>
extends IHeaderParams<TData, TContext> {}
/**
* Props provided to custom inner header group components
* @template TData - Type of row data objects
* @template TContext - Type of grid context
*/
interface CustomInnerHeaderGroupProps<TData = any, TContext = any>
extends IHeaderGroupParams<TData, TContext> {}Custom React components for rendering header tooltips.
/**
* Props provided to custom tooltip components
* @template TData - Type of row data objects
* @template TValue - Type of cell value
* @template TContext - Type of grid context
*/
interface CustomTooltipProps<TData = any, TValue = any, TContext = any>
extends ITooltipParams<TData, TValue, TContext> {}Usage Example:
import React from 'react';
import { CustomTooltipProps } from 'ag-grid-react';
const CustomTooltipComponent: React.FC<CustomTooltipProps> = (props) => {
return (
<div
style={{
backgroundColor: '#333',
color: 'white',
padding: '10px',
borderRadius: '4px',
boxShadow: '0 2px 10px rgba(0,0,0,0.2)',
maxWidth: '200px'
}}
>
<div style={{ fontWeight: 'bold', marginBottom: '5px' }}>
{props.colDef?.headerName || props.colDef?.field}
</div>
<div style={{ fontSize: '12px' }}>
{props.value || 'No data'}
</div>
{props.rowIndex !== undefined && (
<div style={{ fontSize: '10px', marginTop: '5px', opacity: 0.8 }}>
Row: {props.rowIndex + 1}
</div>
)}
</div>
);
};
// Usage in column definition
const columnDefs = [
{
field: 'description',
headerName: 'Description',
headerTooltip: 'Detailed description of the item',
tooltipComponent: CustomTooltipComponent
}
];Complex header components with multiple interactions:
import React, { useState, useEffect, useRef } from 'react';
import { CustomHeaderProps } from 'ag-grid-react';
const AdvancedHeaderComponent: React.FC<CustomHeaderProps> = (props) => {
const [sortState, setSortState] = useState<string | null>(null);
const [filterActive, setFilterActive] = useState(false);
const menuRef = useRef<HTMLDivElement>(null);
useEffect(() => {
// Monitor sort changes
const onSortChanged = () => {
setSortState(props.column.getSort());
};
// Monitor filter changes
const onFilterChanged = () => {
setFilterActive(props.column.isFilterActive());
};
props.column.addEventListener('sortChanged', onSortChanged);
props.column.addEventListener('filterChanged', onFilterChanged);
// Initial state
onSortChanged();
onFilterChanged();
return () => {
props.column.removeEventListener('sortChanged', onSortChanged);
props.column.removeEventListener('filterChanged', onFilterChanged);
};
}, [props.column]);
const handleSort = (direction: 'asc' | 'desc' | null) => {
props.column.setSort(direction);
};
const handleFilter = () => {
props.showColumnMenu(menuRef.current!);
};
const getSortIcon = () => {
switch (sortState) {
case 'asc': return '↑';
case 'desc': return '↓';
default: return '↕';
}
};
return (
<div
ref={menuRef}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
height: '100%',
padding: '0 8px'
}}
>
<span
style={{
fontWeight: sortState ? 'bold' : 'normal',
color: filterActive ? '#1976d2' : 'inherit'
}}
>
{props.displayName}
</span>
<div style={{ display: 'flex', gap: '4px' }}>
<button
onClick={() => handleSort(sortState === 'asc' ? 'desc' : 'asc')}
style={{
border: 'none',
background: 'transparent',
cursor: 'pointer',
color: sortState ? '#1976d2' : '#666'
}}
>
{getSortIcon()}
</button>
<button
onClick={handleFilter}
style={{
border: 'none',
background: 'transparent',
cursor: 'pointer',
color: filterActive ? '#1976d2' : '#666'
}}
>
🔍
</button>
</div>
</div>
);
};Install with Tessl CLI
npx tessl i tessl/npm-ag-grid-react