Style the Filters Tool Panel and Columns Tool Panel.
This page describes the grid's legacy theming system that was the default in v32 and before, for the benefit of applications that have not yet migrated to the Theming API. These themes are deprecated and will be removed in a future major version. You may want to visit the new theming docs or check out the migration guide.
Styling the Tool Panel Area Copy Link
The Tool Panel is a tabbed container. It exposes CSS variables:
.ag-theme-quartz {
--ag-control-panel-background-color: #cc222244;
--ag-side-button-selected-background-color: #cc222244;
--ag-selected-tab-underline-color: deeppink;
--ag-selected-tab-underline-width: 2px;
--ag-selected-tab-underline-transition-speed: 0.5s;
--ag-side-bar-panel-width: 300px;
}"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-quartz.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
ModuleRegistry,
NumberEditorModule,
NumberFilterModule,
SideBarDef,
TextEditorModule,
Theme,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
FiltersToolPanelModule,
PivotModule,
SetFilterModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
const modules = [
NumberEditorModule,
TextEditorModule,
NumberFilterModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
FiltersToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
PivotModule,
SetFilterModule,
];
const GridExample = () => {
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<ColDef[]>([
{ field: "athlete", minWidth: 170 },
{ field: "age" },
{ field: "country" },
{ field: "year" },
{ field: "date" },
{ field: "sport" },
{ field: "gold" },
{ field: "silver" },
{ field: "bronze" },
{ field: "total" },
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
editable: true,
filter: true,
enableRowGroup: true,
enablePivot: true,
enableValue: true,
};
}, []);
const { data, loading } = useFetchJson<IOlympicData>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div style={gridStyle} className="ag-theme-quartz">
<AgGridReact<IOlympicData>
rowData={data}
loading={loading}
columnDefs={columnDefs}
theme={"legacy"}
defaultColDef={defaultColDef}
sideBar={true}
/>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
.ag-theme-quartz,
.ag-theme-quartz-dark {
--ag-control-panel-background-color: #cc222244;
--ag-side-button-selected-background-color: #cc222244;
--ag-selected-tab-underline-color: deeppink;
--ag-selected-tab-underline-width: 2px;
--ag-selected-tab-underline-transition-speed: 0.5s;
--ag-side-bar-panel-width: 300px;
}
.ag-theme-quartz .ag-filter-toolpanel-group-title-bar,
.ag-theme-quartz-dark .ag-filter-toolpanel-group-title-bar {
/* use a semi-transparent background to show the background colour behind */
background-color: rgb(255, 255, 255, 0.2);
}
export interface IOlympicData {
athlete: string,
age: number,
country: string,
year: number,
date: string,
sport: string,
gold: number,
silver: number,
bronze: number,
total: number
} import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
// StrictMode runs this effect twice: drop the superseded run's response rather than applying both.
let cancelled = false;
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
if (cancelled) {
return;
}
setData(data);
setLoading(false);
};
fetchData();
return () => {
cancelled = true;
};
}, [url, limit]);
return { data, loading };
}; Styling the Columns Tool Panel Copy Link
The --ag-column-select-indent-size CSS Variable sets the indent of each column group within the columns tool panel. For further customisation, use CSS selectors.
This example demonstrates changing the column indent and the style of the column drop component in the Row Groups area:
.ag-theme-quartz {
--ag-column-select-indent-size: 40px
}
.ag-theme-quartz .ag-column-drop-cell {
background-color: purple;
}
.ag-theme-quartz .ag-column-drop-cell .ag-icon {
color: white;
}
.ag-theme-quartz .ag-column-drop-cell-text {
color: white;
font-weight: bold;
}"use client";
import React, {
useCallback,
useMemo,
useRef,
useState,
StrictMode,
} from "react";
import { createRoot } from "react-dom/client";
import { AgGridReact, AgGridProvider } from "ag-grid-react";
import "./styles.css";
import "ag-grid-community/styles/ag-grid.css";
import "ag-grid-community/styles/ag-theme-quartz.css";
import {
ClientSideRowModelModule,
ColDef,
ColGroupDef,
GridApi,
GridOptions,
ModuleRegistry,
NumberEditorModule,
NumberFilterModule,
SideBarDef,
TextEditorModule,
Theme,
enableDevValidations,
} from "ag-grid-community";
import {
ColumnMenuModule,
ColumnsToolPanelModule,
ContextMenuModule,
PivotModule,
SetFilterModule,
} from "ag-grid-enterprise";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
const modules = [
NumberEditorModule,
TextEditorModule,
NumberFilterModule,
ClientSideRowModelModule,
ColumnsToolPanelModule,
ColumnMenuModule,
ContextMenuModule,
PivotModule,
SetFilterModule,
];
const GridExample = () => {
const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
{
headerName: "Athlete",
children: [
{
field: "athlete",
minWidth: 170,
rowGroup: true,
enableRowGroup: true,
enablePivot: true,
},
{
field: "age",
rowGroup: true,
enableRowGroup: true,
enablePivot: true,
},
{ field: "country", enableRowGroup: true, enablePivot: true },
],
},
{
headerName: "Event",
children: [
{ field: "year", enableRowGroup: true, enablePivot: true },
{ field: "date" },
{ field: "sport", enableRowGroup: true, enablePivot: true },
],
},
{
headerName: "Medals",
children: [
{ field: "gold", enableValue: true },
{ field: "silver", enableValue: true },
{ field: "bronze", enableValue: true },
{ field: "total", enableValue: true },
],
},
]);
const defaultColDef = useMemo<ColDef>(() => {
return {
editable: true,
filter: true,
};
}, []);
const { data, loading } = useFetchJson<IOlympicData>(
"https://www.ag-grid.com/example-assets/olympic-winners.json",
);
return (
<AgGridProvider modules={modules}>
<div style={containerStyle}>
<div style={gridStyle} className="ag-theme-quartz">
<AgGridReact<IOlympicData>
rowData={data}
loading={loading}
theme={"legacy"}
columnDefs={columnDefs}
defaultColDef={defaultColDef}
sideBar={"columns"}
/>
</div>
</div>
</AgGridProvider>
);
};
const root = createRoot(document.getElementById("root")!);
root.render(
<StrictMode>
<GridExample />
</StrictMode>,
);
.ag-theme-quartz,
.ag-theme-quartz-dark {
--ag-column-select-indent-size: 40px;
}
.ag-theme-quartz .ag-column-drop-cell,
.ag-theme-quartz-dark .ag-column-drop-cell {
background-color: purple;
}
.ag-theme-quartz .ag-column-drop-cell .ag-icon,
.ag-theme-quartz-dark .ag-column-drop-cell .ag-icon {
color: white;
}
.ag-theme-quartz .ag-column-drop-cell-text,
.ag-theme-quartz-dark .ag-column-drop-cell-text {
color: white;
font-weight: bold;
}
export interface IOlympicData {
athlete: string,
age: number,
country: string,
year: number,
date: string,
sport: string,
gold: number,
silver: number,
bronze: number,
total: number
} import { useState, useEffect } from 'react';
/**
* Fetch example Json data
* Not recommended for production use!
*/
export const useFetchJson = <T,>(url:string, limit?: number) => {
const [data, setData] = useState<T[]>();
const [loading, setLoading] = useState(true);
useEffect(() => {
// StrictMode runs this effect twice: drop the superseded run's response rather than applying both.
let cancelled = false;
const fetchData = async () => {
setLoading(true);
// Note error handling is omitted here for brevity
const response = await fetch(url);
const json = await response.json();
const data = limit ? json.slice(0, limit) : json;
if (cancelled) {
return;
}
setData(data);
setLoading(false);
};
fetchData();
return () => {
cancelled = true;
};
}, [url, limit]);
return { data, loading };
};