React component integration for cell rendering, editing, and custom cell behavior with type-safe props and lifecycle management.
Custom React components for rendering cell content with full access to cell data and grid context.
/**
* Props provided to custom cell renderer components
* @template TData - Type of row data objects
* @template TValue - Type of cell value
* @template TContext - Type of grid context
*/
interface CustomCellRendererProps<TData = any, TValue = any, TContext = any>
extends ICellRendererParams<TData, TValue, TContext> {}Usage Examples:
import React from 'react';
import { CustomCellRendererProps } from 'ag-grid-react';
// Simple cell renderer with styled content
const StatusCellRenderer: React.FC<CustomCellRendererProps> = (props) => {
const status = props.value;
const className = status === 'active' ? 'status-active' : 'status-inactive';
return (
<span className={className}>
{status?.toUpperCase()}
</span>
);
};
// Complex cell renderer with interaction
const ActionCellRenderer: React.FC<CustomCellRendererProps> = (props) => {
const handleEdit = () => {
console.log('Edit row:', props.data);
};
const handleDelete = () => {
props.api.applyTransaction({ remove: [props.data] });
};
return (
<div>
<button onClick={handleEdit}>Edit</button>
<button onClick={handleDelete}>Delete</button>
</div>
);
};
// Usage in column definition
const columnDefs = [
{
field: 'status',
cellRenderer: StatusCellRenderer
},
{
field: 'actions',
cellRenderer: ActionCellRenderer,
width: 150
}
];Custom React components for editing cell values with controlled input and validation.
/**
* Props provided to custom cell editor components
* @template TData - Type of row data objects
* @template TValue - Type of cell value
* @template TContext - Type of grid context
*/
interface CustomCellEditorProps<TData = any, TValue = any, TContext = any>
extends ICellEditorParams<TData, TValue, TContext> {
/** The value in the cell when editing started */
initialValue: TValue | null | undefined;
/** The current value for the editor */
value: TValue | null | undefined;
/** Callback that should be called every time the value in the editor changes */
onValueChange: (value: TValue | null | undefined) => void;
}Usage Examples:
import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
import { CustomCellEditorProps, useGridCellEditor } from 'ag-grid-react';
// Simple text editor
const TextCellEditor = forwardRef<any, CustomCellEditorProps>((props, ref) => {
const [value, setValue] = useState(props.initialValue || '');
const inputRef = useRef<HTMLInputElement>(null);
useImperativeHandle(ref, () => ({
getValue: () => value,
isCancelBeforeStart: () => false,
isCancelAfterEnd: () => false
}));
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
inputRef.current.select();
}
}, []);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const newValue = e.target.value;
setValue(newValue);
props.onValueChange(newValue);
};
return (
<input
ref={inputRef}
value={value}
onChange={handleChange}
style={{ width: '100%', height: '100%' }}
/>
);
});
// Dropdown editor with options
const SelectCellEditor = forwardRef<any, CustomCellEditorProps<any, string>>((props, ref) => {
const [value, setValue] = useState(props.initialValue || '');
const options = props.cellEditorParams?.options || [];
useImperativeHandle(ref, () => ({
getValue: () => value
}));
return (
<select
value={value}
onChange={(e) => {
setValue(e.target.value);
props.onValueChange(e.target.value);
}}
style={{ width: '100%' }}
>
{options.map((option: string) => (
<option key={option} value={option}>
{option}
</option>
))}
</select>
);
});
// Usage in column definitions
const columnDefs = [
{
field: 'name',
editable: true,
cellEditor: TextCellEditor
},
{
field: 'category',
editable: true,
cellEditor: SelectCellEditor,
cellEditorParams: {
options: ['Electronics', 'Books', 'Clothing']
}
}
];Custom React components for master-detail row rendering.
/**
* Props provided to custom detail cell renderer components
* @template TData - Type of master row data
* @template TDetail - Type of detail data
*/
interface CustomDetailCellRendererProps<TData = any, TDetail = any>
extends IDetailCellRendererParams<TData, TDetail> {}Custom React components for rendering grouped rows.
/**
* Props provided to custom group cell renderer components
* @template TData - Type of row data objects
* @template TValue - Type of cell value
*/
interface CustomGroupCellRendererProps<TData = any, TValue = any>
extends IGroupCellRendererParams<TData, TValue> {}Custom React components for rendering loading cells in server-side row model.
/**
* Props provided to custom loading cell renderer components
* @template TData - Type of row data objects
* @template TContext - Type of grid context
*/
interface CustomLoadingCellRendererProps<TData = any, TContext = any>
extends ILoadingCellRendererParams<TData, TContext> {}Usage Example:
import React from 'react';
import { CustomLoadingCellRendererProps } from 'ag-grid-react';
const LoadingCellRenderer: React.FC<CustomLoadingCellRendererProps> = () => {
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
<div className="spinner" />
<span>Loading...</span>
</div>
);
};
// Usage in grid options
const gridOptions = {
loadingCellRenderer: LoadingCellRenderer,
// ... other options
};Hook for integrating custom cell editor callbacks with the grid system.
/**
* Hook to allow custom cell editor component callbacks to be provided to the grid
* @param callbacks - Cell editor callback implementations
*/
function useGridCellEditor(callbacks: CustomCellEditorCallbacks): void;
/**
* Callbacks for custom cell editor components
*/
interface CustomCellEditorCallbacks extends BaseCellEditor {}Usage Example:
import React, { useState, useImperativeHandle, forwardRef } from 'react';
import { useGridCellEditor, CustomCellEditorProps } from 'ag-grid-react';
const AdvancedCellEditor = forwardRef<any, CustomCellEditorProps>((props, ref) => {
const [value, setValue] = useState(props.initialValue);
// Use hook for advanced grid integration
useGridCellEditor({
getValue: () => value,
isPopup: () => false,
isCancelBeforeStart: () => false,
isCancelAfterEnd: () => false,
focusIn: () => {
// Custom focus handling
},
focusOut: () => {
// Custom blur handling
}
});
return (
<input
ref={ref}
value={value || ''}
onChange={(e) => setValue(e.target.value)}
/>
);
});