Building rich, interactive data grids in React applications often involves combining the power of AG Grid with the aesthetic and functional consistency of modern UI frameworks like Bootstrap or Material-UI (MUI). This integration allows developers to leverage AG Grid's robust data handling capabilities while maintaining a unified design language across their application.
Why Integrate UI Frameworks with AG Grid?
While AG Grid provides excellent built-in themes, integrating with a UI framework offers several compelling advantages:
- Consistent User Experience: Ensures that your grid components visually align with the rest of your application, which is built using Bootstrap or MUI standards.
- Access to Rich Component Libraries: You can embed highly interactive and styled components from your chosen UI framework directly within AG Grid cells, headers, or even as custom tools.
- Accelerated Development: Reusing existing design systems and components from Bootstrap or MUI can speed up the development of custom grid features.
- Simplified Theming: Centralized theme management from your UI framework can be extended to influence AG Grid's appearance.
Prerequisites
Before diving into the integration, ensure you have a basic understanding of:
- React Fundamentals: Including component lifecycle, props, and state.
- AG Grid React: Basic setup,
columnDefs,rowData, and common grid options. - Your Chosen UI Framework: Familiarity with Bootstrap's utility classes or MUI's components and theming system.
Understanding AG Grid's Theming and Styling
AG Grid ships with several professional themes (e.g., ag-theme-alpine, ag-theme-balham). You apply a theme by wrapping your <AgGridReact> component with a <div> that has the appropriate theme class:
import 'ag-grid-community/styles/ag-grid.css'; // Core grid CSS
import 'ag-grid-community/styles/ag-theme-alpine.css'; // Theme CSS
const MyGrid = () => (
<div className="ag-theme-alpine" style={{ height: 500, width: '100%' }}>
<AgGridReact rowData={rowData} columnDefs={columnDefs} />
</div>
);
The key to integration is leveraging AG Grid's flexibility to inject custom React components (cell renderers, cell editors, header components) or apply custom CSS classes directly to grid elements, allowing your UI framework's styles to take effect.
Integrating Bootstrap with AG Grid
Bootstrap is a widely adopted CSS framework known for its responsive grid system and pre-styled components. Here's how to integrate it with AG Grid.
1. Installation
First, install Bootstrap and optionally Bootstrap Icons for a richer UI:
npm install bootstrap --save
npm install bootstrap-icons --save
Then, import Bootstrap's CSS into your main application file (e.g., App.js or index.js):
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap-icons/font/bootstrap-icons.css'; // If using Bootstrap Icons
2. Applying Bootstrap Styles to the Grid Container
You can apply Bootstrap classes to the grid container, or create a custom class that combines AG Grid's theme with Bootstrap's utility styles.
import React from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css';
import 'bootstrap/dist/css/bootstrap.min.css';
const MyBootstrapGrid = () => {
const columnDefs = [
{ field: 'make', headerName: 'Make' },
{ field: 'model', headerName: 'Model' },
{ field: 'price', headerName: 'Price' }
];
const rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxster', price: 72000 }
];
return (
<div className="ag-theme-alpine p-3 border rounded shadow-sm" style={{ height: 400, width: '600px' }}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
/>
</div>
);
};
export default MyBootstrapGrid;
In this example, Bootstrap classes like p-3 (padding), border, rounded, and shadow-sm are applied directly to the container holding the grid, making it look integrated within a Bootstrap layout.
3. Custom Components with Bootstrap
The real power of integration comes when you use Bootstrap components or utility classes within custom AG Grid cell renderers, cell editors, or header components.
Example: Bootstrap Custom Header Component
Let's create a custom header component that uses Bootstrap classes and icons for a more styled look and sorting indicators.
// components/BootstrapHeaderComponent.jsx
import React from 'react';
// Ensure 'bootstrap-icons' CSS is imported in your app
const BootstrapHeaderComponent = (props) => {
const onSortRequested = (sort, event) => {
props.setSort(sort, event.shiftKey);
};
const isAscSorting = props.sort === 'asc';
const isDescSorting = props.sort === 'desc';
return (
<div className="d-flex align-items-center h-100 ps-2">
<span className="fw-bold me-2 text-primary">{props.displayName}</span>
{props.enableSorting && (
<div className="d-flex flex-column">
<i
className={`bi bi-caret-up-fill cursor-pointer ${isAscSorting ? 'text-dark' : 'text-secondary'}`}
onClick={() => onSortRequested('asc', null)}
></i>
<i
className={`bi bi-caret-down-fill cursor-pointer ${isDescSorting ? 'text-dark' : 'text-secondary'}`}
onClick={() => onSortRequested('desc', null)}
></i>
</div>
)}
{/* Add more Bootstrap elements if needed, e.g., a filter icon */}
</div>
);
};
export default BootstrapHeaderComponent;
Then, use this component in your columnDefs:
import BootstrapHeaderComponent from './components/BootstrapHeaderComponent';
const columnDefs = [
{
field: 'value',
headerName: 'Custom Header',
headerComponent: BootstrapHeaderComponent,
headerComponentParams: {
displayName: 'Product Value',
enableSorting: true, // This prop is handled by AG Grid, passed to custom component
},
sortable: true, // Must be true for sorting to work
},
// ... other column definitions
];
Integrating Material-UI (MUI) with AG Grid
Material-UI provides a comprehensive set of React components that implement Google's Material Design. Integrating MUI involves using its components directly within AG Grid's custom renderers/editors and ensuring consistent theming.
1. Installation
Install MUI core components and its styling engine:
npm install @mui/material @emotion/react @emotion/styled
2. Applying MUI Theming to the Grid Container
For consistent theming, wrap your AG Grid instance within MUI's ThemeProvider. You might also use MUI's Box component for container styling.
import React from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/styles/ag-grid.css';
import 'ag-grid-community/styles/ag-theme-alpine.css'; // Or a simpler 'ag-theme-base.css' for full customisation
import { ThemeProvider, createTheme } from '@mui/material/styles';
import { Box } from '@mui/material';
const myMuiTheme = createTheme({
palette: {
primary: {
main: '#1976d2', // Example primary color
},
// ... other theme customizations
},
});
const MyMuiGrid = () => {
const columnDefs = [
{ field: 'brand', headerName: 'Brand' },
{ field: 'product', headerName: 'Product' },
{ field: 'quantity', headerName: 'Quantity' }
];
const rowData = [
{ brand: 'Apple', product: 'MacBook', quantity: 5 },
{ brand: 'Samsung', product: 'Galaxy S21', quantity: 12 },
{ brand: 'Google', product: 'Pixel 6', quantity: 8 }
];
return (
<ThemeProvider theme={myMuiTheme}>
<Box sx={{
height: 400,
width: '600px',
'& .ag-theme-alpine': { // Target AG Grid theme class for overrides
'& .ag-header-cell-label': {
color: myMuiTheme.palette.primary.main,
fontWeight: 'bold',
},
'& .ag-cell': {
fontSize: '0.875rem', // Match MUI default body text size
},
}
}}>
<div className="ag-theme-alpine" style={{ height: '100%', width: '100%' }}>
<AgGridReact
rowData={rowData}
columnDefs={columnDefs}
/>
</div>
</Box>
</ThemeProvider>>
);
};
export default MyMuiGrid;
In this example, the Box component's sx prop is used to apply custom styles that target AG Grid's internal classes, allowing you to fine-tune the grid's appearance to better match your MUI theme.
3. Custom Components with MUI
MUI components truly shine when used within AG Grid's custom cell renderers or editors, providing rich interactive elements.
Example: MUI Custom Cell Renderer with Rating
Let's create a cell renderer that displays a Material-UI Rating component.
// components/MuiRatingCellRenderer.jsx
import React from 'react';
import Rating from '@mui/material/Rating';
import Box from '@mui/material/Box';
const MuiRatingCellRenderer = (props) => {
const [value, setValue] = React.useState(props.value);
// This function will be called if the cell is editable
const handleChange = (event, newValue) => {
setValue(newValue);
// Inform AG Grid about the value change
if (props.node) {
props.node.setDataValue(props.colDef.field, newValue);
}
};
return (
<Box sx={{ display: 'flex', alignItems: 'center', height: '100%' }}>
<Rating
name="cell-rating"
value={value}
precision={0.5}
readOnly={!props.colDef.editable} // Make it read-only unless column is editable
onChange={props.colDef.editable ? handleChange : undefined}
size="small"
/>
{props.colDef.showValue && <span style={{ marginLeft: '8px' }}>({value})</span>}
</Box>
);
};
export default MuiRatingCellRenderer;
Use this component in your columnDefs:
import MuiRatingCellRenderer from './components/MuiRatingCellRenderer';
const columnDefs = [
{ field: 'item', headerName: 'Item' },
{
field: 'rating',
headerName: 'User Rating',
cellRenderer: MuiRatingCellRenderer,
editable: true, // Allow editing the rating
cellRendererParams: {
showValue: true, // Custom prop to display numerical value next to stars
},
width: 180,
},
// ...
];
This example demonstrates how to pass custom props to your renderer via cellRendererParams and how to update the grid's data when an interactive MUI component changes its value.
Best Practices for Seamless Integration
- Consistency is Key: Strive for visual and behavioral consistency. Use your UI framework's design tokens (colors, typography, spacing) when overriding AG Grid styles or creating custom components.
- Leverage AG Grid's API: AG Grid provides numerous properties like
className,rowClass,cellClass, andheaderClassincolumnDefsorgridOptions. Use these to apply your framework's utility classes or custom CSS tailored to your framework's theme. - Custom Components are Your Friends: For complex interactions or specific framework styling, always opt for custom cell renderers, cell editors, header components, or floating filters. This allows you to fully utilize the framework's React components.
- Performance Considerations: When embedding complex components in every cell, be mindful of performance. AG Grid is highly optimized, but custom renderers can impact rendering time. Use
React.memofor your custom components where appropriate. - Accessibility: Ensure that your custom components adhere to accessibility standards. UI frameworks often provide good ARIA support, but custom implementations require careful attention.
- CSS Overrides: Sometimes, you'll need to write specific CSS to override AG Grid's default styling to perfectly match your UI framework. Target AG Grid's CSS classes (e.g.,
.ag-header-cell,.ag-cell) within a scoped stylesheet or using MUI'ssxprop.
Conclusion
Integrating UI frameworks like Bootstrap or Material-UI with AG Grid in your React applications offers a powerful way to deliver both robust data management and a visually consistent, engaging user experience. By leveraging AG Grid's flexible API for custom components and smart CSS overrides, you can seamlessly blend the strengths of both worlds. Experiment with different approaches, starting with simple class applications and progressing to complex custom renderers, to find the perfect synergy for your projects.