---
product: "AG Grid"
title: "Columns Tool Panel - Configuration"
description: "Choose which sections and columns the Columns Tool Panel shows, arrange its list of columns, and make grouping, aggregation and pivoting read only."
enterprise: true
framework: react
version: "36.3.0"
related:
    - title: "Deferred Updates"
      url: "https://www.ag-grid.com/react-data-grid/tool-panel-columns-deferred-updates/"
    - title: "Customisation"
      url: "https://www.ag-grid.com/react-data-grid/tool-panel-columns-customising/"
llms: "https://www.ag-grid.com/llms.txt"
---

# Columns Tool Panel - Configuration

Choose which sections and columns the Columns Tool Panel shows, arrange its list of columns, and make grouping, aggregation and pivoting read only.

#### Tool Panel Simple

```tsx
"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 {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  SideBarDef,
  TextFilterModule,
  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 = [
  NumberFilterModule,
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  PivotModule,
  SetFilterModule,
  TextFilterModule,
];

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",
          filter: "agTextColumnFilter",
          enableRowGroup: true,
          enablePivot: true,
          minWidth: 150,
        },
        { field: "age", enableRowGroup: true, enablePivot: true },
        {
          field: "country",
          enableRowGroup: true,
          enablePivot: true,
          minWidth: 125,
        },
      ],
    },
    {
      headerName: "Competition",
      children: [
        { field: "year", enableRowGroup: true, enablePivot: true },
        {
          field: "date",
          enableRowGroup: true,
          enablePivot: true,
          minWidth: 180,
        },
      ],
    },
    { field: "sport", enableRowGroup: true, enablePivot: true, minWidth: 125 },
    {
      headerName: "Medals",
      children: [
        { field: "gold", enableValue: true },
        { field: "silver", enableValue: true },
        { field: "bronze", enableValue: true },
        { field: "total", enableValue: true },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      filter: true,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 200,
    };
  }, []);

  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}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            autoGroupColumnDef={autoGroupColumnDef}
            sideBar={"columns"}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Tool Panel Simple](https://www.ag-grid.com/examples/tool-panel-columns-configuration/simple/reactFunctionalTs/)

The example above shows the Columns Tool Panel with its default configuration, `sideBar: 'columns'`. Note the following:

- Columns can only be dragged into the Row Groups, Values and Column Labels sections when their column definition allows it, using `enableRowGroup`, `enableValue` and `enablePivot` respectively.
- The athlete, age, country, year, date and sport columns set `enableRowGroup` and `enablePivot`, so they can be dragged to the Row Groups section, and to the Column Labels section once Pivot Mode is on.
- The medal columns set `enableValue`, so they can be dragged to the Values section.

## Section Visibility

To remove a section from the Columns Tool Panel, set `suppressPivotMode`, `suppressRowGroups`, `suppressValues` or `suppressPivots` in `toolPanelParams`. To remove a control from the top area, set `suppressColumnExpandAll`, `suppressColumnSelectAll` or `suppressColumnFilter`.

### Section Visibility API

Show or hide the Pivot Mode, Row Groups, Values and Column Labels sections after the grid is created by calling `setPivotModeSectionVisible()`, `setRowGroupsSectionVisible()`, `setValuesSectionVisible()` or `setPivotSectionVisible()`:

```jsx
// get the Columns Tool Panel instance
const columnsToolPanel = gridApi.getToolPanelInstance('columns');

// hides the Row Groups section
columnsToolPanel.setRowGroupsSectionVisible(false);

// shows the Column Labels section
columnsToolPanel.setPivotSectionVisible(true);
```

The example below hides all of these sections and controls with the parameters above. Note the following:

- The **Pivot Mode**, **Row Groups**, **Values** and **Column Labels** checkboxes show and hide each section using the api methods.
- The Expand / Collapse All, Select / Unselect All and Search controls stay hidden, as they can only be set through `toolPanelParams`.
- The date column is hidden from the tool panel; see [Hiding Columns](https://www.ag-grid.com/react-data-grid/tool-panel-columns-configuration/#hiding-columns).

#### Section Visibility

```tsx
"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 {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  SideBarDef,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  PivotModule,
} from "ag-grid-enterprise";
import "./styles.css";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  PivotModule,
];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { headerName: "Name", field: "athlete", minWidth: 200 },
    { field: "age", enableRowGroup: true },
    { field: "country", minWidth: 200 },
    { field: "year" },
    { field: "date", suppressColumnsToolPanel: true, minWidth: 180 },
    { field: "sport", minWidth: 200 },
    { field: "gold", aggFunc: "sum" },
    { field: "silver", aggFunc: "sum" },
    { field: "bronze", aggFunc: "sum" },
    { field: "total", aggFunc: "sum" },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      enablePivot: true,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 200,
    };
  }, []);
  const sideBar = useMemo<
    SideBarDef | string | string[] | boolean | null
  >(() => {
    return {
      toolPanels: [
        {
          id: "columns",
          labelDefault: "Columns",
          labelKey: "columns",
          iconKey: "columns",
          toolPanel: "agColumnsToolPanel",
          toolPanelParams: {
            suppressRowGroups: true,
            suppressValues: true,
            suppressPivots: true,
            suppressPivotMode: true,
            suppressColumnFilter: true,
            suppressColumnSelectAll: true,
            suppressColumnExpandAll: true,
          },
        },
      ],
      defaultToolPanel: "columns",
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const togglePivotModeSection = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns")!;
    columnsToolPanel.setPivotModeSectionVisible(
      document.querySelector<HTMLInputElement>("#pivotModeSection")!.checked,
    );
  }, []);

  const toggleRowGroupsSection = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns")!;
    columnsToolPanel.setRowGroupsSectionVisible(
      document.querySelector<HTMLInputElement>("#rowGroupsSection")!.checked,
    );
  }, []);

  const toggleValuesSection = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns")!;
    columnsToolPanel.setValuesSectionVisible(
      document.querySelector<HTMLInputElement>("#valuesSection")!.checked,
    );
  }, []);

  const togglePivotSection = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns")!;
    columnsToolPanel.setPivotSectionVisible(
      document.querySelector<HTMLInputElement>("#pivotSection")!.checked,
    );
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div className="example-header">
            <label>
              <input
                id="pivotModeSection"
                type="checkbox"
                onChange={togglePivotModeSection}
              />
              <span>Pivot Mode</span>
            </label>
            <label>
              <input
                id="rowGroupsSection"
                type="checkbox"
                onChange={toggleRowGroupsSection}
              />
              <span>Row Groups</span>
            </label>
            <label>
              <input
                id="valuesSection"
                type="checkbox"
                onChange={toggleValuesSection}
              />
              <span>Values</span>
            </label>
            <label>
              <input
                id="pivotSection"
                type="checkbox"
                onChange={togglePivotSection}
              />
              <span>Column Labels</span>
            </label>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}

              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              autoGroupColumnDef={autoGroupColumnDef}
              sideBar={sideBar}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Section Visibility](https://www.ag-grid.com/examples/tool-panel-columns-configuration/section-visibility/reactFunctionalTs/)

## Hiding Columns

To remove a column from the tool panel, set `suppressColumnsToolPanel` on its column definition. This is useful for a column that works in the background, such as one the grid groups by, that users should not see.

## Suppress Column Reordering

By default, reordering columns in the grid also reorders them in the Columns section. Set `suppressSyncLayoutWithGrid` to keep the tool panel order fixed.

Users can also reorder columns by dragging them within the Columns section. Set `suppressColumnMove` to prevent this. `suppressSyncLayoutWithGrid` also prevents it, so `suppressColumnMove` is only needed on its own when the tool panel should still follow the grid order.

```jsx
const sideBar = useMemo(() => { 
	return {
        toolPanels: [
            {
                id: 'columns',
                labelDefault: 'Columns',
                labelKey: 'columns',
                iconKey: 'columns',
                toolPanel: 'agColumnsToolPanel',
                toolPanelParams: {
                    // tool panel columns won't move when columns are reordered in the grid
                    suppressSyncLayoutWithGrid: true,
                    // prevents columns being reordered from the Columns Tool Panel
                    suppressColumnMove: true,
                },
            },
        ],
        defaultToolPanel: 'columns',
    };
}, []);

<AgGridReact sideBar={sideBar} />
```

The example below enables both properties. Note the following:

- Moving columns in the grid doesn't reorder columns in the Columns Tool Panel, as `suppressSyncLayoutWithGrid=true`.
- Columns can't be reordered from the Columns Tool Panel, as both properties are enabled.

#### Suppress Column Reordering

```tsx
"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 {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  SideBarDef,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  PivotModule,
} 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 = [
  NumberFilterModule,
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  PivotModule,
  TextFilterModule,
];

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: [
        {
          headerName: "Name",
          field: "athlete",
          minWidth: 200,
          filter: "agTextColumnFilter",
        },
        { field: "age" },
        { field: "country", minWidth: 200 },
      ],
    },
    {
      headerName: "Competition",
      children: [{ field: "year" }, { field: "date", minWidth: 180 }],
    },
    { colId: "sport", field: "sport", minWidth: 200 },
    {
      headerName: "Medals",
      children: [
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      // allow every column to be aggregated
      enableValue: true,
      // allow every column to be grouped
      enableRowGroup: true,
      // allow every column to be pivoted
      enablePivot: true,
      filter: true,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 200,
    };
  }, []);
  const sideBar = useMemo<
    SideBarDef | string | string[] | boolean | null
  >(() => {
    return {
      toolPanels: [
        {
          id: "columns",
          labelDefault: "Columns",
          labelKey: "columns",
          iconKey: "columns",
          toolPanel: "agColumnsToolPanel",
          toolPanelParams: {
            // tool panel columns won't move when columns are reordered in the grid
            suppressSyncLayoutWithGrid: true,
            // prevents columns being reordered from the columns tool panel
            suppressColumnMove: true,
          },
        },
      ],
      defaultToolPanel: "columns",
    };
  }, []);

  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}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            autoGroupColumnDef={autoGroupColumnDef}
            sideBar={sideBar}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Suppress Column Reordering](https://www.ag-grid.com/examples/tool-panel-columns-configuration/suppress-column-reordering/reactFunctionalTs/)

## Custom Column Layout

By default, the Columns section follows the order of `columnDefs` and stays in sync as columns move in the grid. To define a different layout, pass [Column Definitions](https://www.ag-grid.com/react-data-grid/column-definitions/) to `setColumnLayout()` on the [Columns Tool Panel instance](https://www.ag-grid.com/react-data-grid/tool-panel-columns-configuration/#columns-tool-panel-instance).

Given these column definitions supplied to the grid:

```jsx
const [columnDefs, setColumnDefs] = useState([
    { field: 'a' },
    { field: 'b' },
    { field: 'c' }
]);

<AgGridReact columnDefs={columnDefs} />
```

The following layout adds a group, reorders the columns and omits column `b`:

```jsx
const columnsToolPanel = gridApi.getToolPanelInstance('columns');
columnsToolPanel.setColumnLayout([
    {
        headerName: 'Group 1', // group doesn't appear in grid
        children: [
            { field: 'c' }, // custom column order with column "b" omitted
            { field: 'a' }
        ]
    }
]);
```

The layout can contain column groups that don't exist in the grid, and can omit or reorder columns, but every column it references must already exist in the grid.

> **Note**
>
> When providing a custom layout, enable `suppressSyncLayoutWithGrid` so that moving columns in the grid does not replace it (see [Suppress Column Reordering](https://www.ag-grid.com/react-data-grid/tool-panel-columns-configuration/#suppress-column-reordering)).

The example below shows two custom layouts for the Columns Tool Panel. Note the following:

- When the grid is initialised, the Columns Tool Panel layout matches `gridOptions.columnDefs`.
- **Custom Sort Layout** calls `setColumnLayout(colDefs)` with the columns in ascending order.
- **Custom Group Layout** calls `setColumnLayout(colDefs)` with column groups that don't appear in the grid.
- Moving columns in the grid doesn't affect the custom layouts, as `suppressSyncLayoutWithGrid` is enabled.
- Moving columns within the Columns Tool Panel is disabled, as `suppressSyncLayoutWithGrid` and `suppressColumnMove` are enabled.

#### Custom Column Layout

```tsx
"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 {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  NumberFilterModule,
  SideBarDef,
  TextFilterModule,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  PivotModule,
  SetFilterModule,
} from "ag-grid-enterprise";
import "./styles.css";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  NumberFilterModule,
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  SetFilterModule,
  PivotModule,
  TextFilterModule,
];

const sortedToolPanelColumnDefs = [
  {
    headerName: "Athlete",
    children: [
      { field: "age" },
      { field: "country" },
      { headerName: "Name", field: "athlete" },
    ],
  },
  {
    headerName: "Competition",
    children: [{ field: "date" }, { field: "year" }],
  },
  {
    headerName: "Medals",
    children: [
      { field: "bronze" },
      { field: "gold" },
      { field: "silver" },
      { field: "total" },
    ],
  },
  { colId: "sport", field: "sport" },
];

const customToolPanelColumnDefs = [
  {
    headerName: "Dummy Group 1",
    children: [
      { field: "age" },
      { headerName: "Name", field: "athlete" },
      {
        headerName: "Dummy Group 2",
        children: [{ colId: "sport" }, { field: "country" }],
      },
    ],
  },
  {
    headerName: "Medals",
    children: [
      { field: "total" },
      { field: "bronze" },
      {
        headerName: "Dummy Group 3",
        children: [{ field: "silver" }, { field: "gold" }],
      },
    ],
  },
];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Athlete",
      children: [
        {
          headerName: "Name",
          field: "athlete",
          minWidth: 200,
          filter: "agTextColumnFilter",
        },
        { field: "age" },
        { field: "country", minWidth: 200 },
      ],
    },
    {
      headerName: "Competition",
      children: [{ field: "year" }, { field: "date", minWidth: 180 }],
    },
    { colId: "sport", field: "sport", minWidth: 200 },
    {
      headerName: "Medals",
      children: [
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 100,
      // allow every column to be aggregated
      enableValue: true,
      // allow every column to be grouped
      enableRowGroup: true,
      // allow every column to be pivoted
      enablePivot: true,
      filter: true,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 200,
    };
  }, []);
  const sideBar = useMemo<
    SideBarDef | string | string[] | boolean | null
  >(() => {
    return {
      toolPanels: [
        {
          id: "columns",
          labelDefault: "Columns",
          labelKey: "columns",
          iconKey: "columns",
          toolPanel: "agColumnsToolPanel",
          toolPanelParams: {
            // prevents custom layout changing when columns are reordered in the grid
            suppressSyncLayoutWithGrid: true,
            // prevents columns being reordered from the columns tool panel
            suppressColumnMove: true,
          },
        },
      ],
      defaultToolPanel: "columns",
    };
  }, []);

  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const setCustomSortLayout = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns");
    columnsToolPanel!.setColumnLayout(sortedToolPanelColumnDefs);
  }, [sortedToolPanelColumnDefs]);

  const setCustomGroupLayout = useCallback(() => {
    const columnsToolPanel =
      gridRef.current!.api.getToolPanelInstance("columns");
    columnsToolPanel!.setColumnLayout(customToolPanelColumnDefs);
  }, [customToolPanelColumnDefs]);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div>
            <span className="button-group">
              <button onClick={setCustomSortLayout}>Custom Sort Layout</button>
              <button onClick={setCustomGroupLayout}>
                Custom Group Layout
              </button>
            </span>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}

              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              autoGroupColumnDef={autoGroupColumnDef}
              sideBar={sideBar}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Custom Column Layout](https://www.ag-grid.com/examples/tool-panel-columns-configuration/custom-layout/reactFunctionalTs/)

## Read Only Functions

Set the grid option `functionsReadOnly=true` to prevent users changing grouping, pivoting or aggregation through the UI. The Row Groups, Values and Column Labels sections stay visible, so users can see which columns are in use but cannot change them.

The example below starts with `functionsReadOnly=true`. Note the following:

- The grid is in pivot mode, grouped by country and sport, pivoted by year, with silver and bronze aggregated.
- Columns cannot be dragged into or removed from the Row Groups, Values and Column Labels sections.
- Untick **Functions Read Only** to allow changes again.

#### Read Only Example

```tsx
"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 {
  AutoGroupColumnDef,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  SideBarDef,
  enableDevValidations,
} from "ag-grid-community";
import {
  ColumnMenuModule,
  ColumnsToolPanelModule,
  ContextMenuModule,
  PivotModule,
  RowGroupingPanelModule,
} from "ag-grid-enterprise";
import "./styles.css";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

if (process.env.NODE_ENV !== "production") {
  // Enable extended validations only for development
  enableDevValidations();
}

const modules = [
  ClientSideRowModelModule,
  ColumnsToolPanelModule,
  ColumnMenuModule,
  ContextMenuModule,
  PivotModule,
  RowGroupingPanelModule,
];

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IOlympicData>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    {
      field: "athlete",
      minWidth: 200,
      enableRowGroup: true,
      enablePivot: true,
    },
    {
      field: "age",
      enableValue: true,
    },
    {
      field: "country",
      minWidth: 200,
      enableRowGroup: true,
      enablePivot: true,
      rowGroupIndex: 1,
    },
    {
      field: "year",
      enableRowGroup: true,
      enablePivot: true,
      pivotIndex: 1,
    },
    {
      field: "date",
      minWidth: 180,
      enableRowGroup: true,
      enablePivot: true,
    },
    {
      field: "sport",
      minWidth: 200,
      enableRowGroup: true,
      enablePivot: true,
      rowGroupIndex: 2,
    },
    {
      field: "gold",
      hide: true,
      enableValue: true,
    },
    {
      field: "silver",
      hide: true,
      enableValue: true,
      aggFunc: "sum",
    },
    {
      field: "bronze",
      hide: true,
      enableValue: true,
      aggFunc: "sum",
    },
    {
      headerName: "Total",
      field: "total",
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      flex: 1,
      minWidth: 150,
    };
  }, []);
  const autoGroupColumnDef = useMemo<AutoGroupColumnDef>(() => {
    return {
      minWidth: 250,
    };
  }, []);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    (document.getElementById("read-only") as HTMLInputElement).checked = true;
  }, []);
  const { data, loading } = useFetchJson<IOlympicData>(
    "https://www.ag-grid.com/example-assets/olympic-winners.json",
  );

  const setReadOnly = useCallback(() => {
    gridRef.current!.api.setGridOption(
      "functionsReadOnly",
      (document.getElementById("read-only") as HTMLInputElement).checked,
    );
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="test-container">
          <div className="test-header">
            <label>
              <input type="checkbox" id="read-only" onChange={setReadOnly} />{" "}
              Functions Read Only
            </label>
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              ref={gridRef}

              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              autoGroupColumnDef={autoGroupColumnDef}
              pivotMode={true}
              sideBar={"columns"}
              rowGroupPanelShow={"always"}
              pivotPanelShow={"always"}
              functionsReadOnly={true}
              onGridReady={onGridReady}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

const root = createRoot(document.getElementById("root")!);
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>,
);
```

[Live example: Read Only Example](https://www.ag-grid.com/examples/tool-panel-columns-configuration/read-only/reactFunctionalTs/)

## Parameters

The Columns section and the [Column Chooser](https://www.ag-grid.com/react-data-grid/column-chooser/) use the same column selection panel. Their shared options are defined by `IColumnSelectionPanelParams`, while `IToolPanelColumnCompParams` adds options specific to the Columns Tool Panel. See [Providing Parameters to Tool Panels](https://www.ag-grid.com/react-data-grid/side-bar/#providing-parameters-to-tool-panels) for how to pass these to the tool panel.

### IColumnSelectionPanelParams

Properties available on the `IColumnSelectionPanelParams` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressSyncLayoutWithGrid` | `boolean` |  |  | To suppress updating the layout of columns as they are rearranged in the grid. |
| `suppressColumnFilter` | `boolean` |  |  | To suppress the column search. |
| `suppressColumnSelectAll` | `boolean` |  |  | To suppress the Select / Unselect All widget. |
| `suppressColumnExpandAll` | `boolean` |  |  | To suppress the Expand / Collapse All widget. |
| `contractColumnSelection` | `boolean` |  |  | By default, column groups start expanded. Pass `true` to start with groups collapsed. |
| `columnLabelRenderer` | `any` |  |  | Component used to render column and column group labels. The checkbox, drag handle and expand controls remain grid managed. |
| `columnLabelRendererParams` | `any` |  |  | Additional parameters passed to the `columnLabelRenderer`. |
| `columnLabelRendererSelector` | `ColumnSelectionLabelRendererSelectorFunc` |  |  | Callback to select which renderer to use for an individual column or column group label. The result can also provide renderer-specific `params`. Return `undefined` to use `columnLabelRenderer`. |

### IToolPanelColumnCompParams

Properties available on the `IToolPanelColumnCompParams` interface.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `suppressColumnMove` | `boolean` |  |  | Suppress Column Move |
| `suppressRowGroups` | `boolean` |  |  | Suppress Row Groups section |
| `suppressValues` | `boolean` |  |  | Suppress Values section |
| `suppressPivots` | `boolean` |  |  | Suppress Column Labels (Pivot) section |
| `suppressPivotMode` | `boolean` |  |  | Suppress Pivot Mode selection |
| `buttons` | `ColumnToolPanelAction[]` |  |  | Buttons to display at the bottom of the Columns Tool Panel, in the order they should be displayed in. `'apply'`: Changes are deferred until the Apply button is clicked. `'cancel'`: Discards any deferred changes. Only has an effect when `'apply'` is also included. `'reset'`: Immediately resets the columns to the state defined in the current column definitions, discarding any pending changes. Only the `'apply'` button enables deferred changes. |

## API

### Columns Tool Panel Instance

Get the Columns Tool Panel instance from the grid API using its tool panel `id`, which is `'columns'` by default:

```jsx
const columnsToolPanel = gridApi.getToolPanelInstance('columns');
```

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `setColumnLayout` | `Function` |  |  | Sets a custom layout of columns and column groups for the Columns section. Every referenced column must already exist in the grid. |
| `setPivotModeSectionVisible` | `Function` |  |  | Shows or hides the Pivot Mode section. |
| `setRowGroupsSectionVisible` | `Function` |  |  | Shows or hides the Row Groups section. |
| `setValuesSectionVisible` | `Function` |  |  | Shows or hides the Values section. |
| `setPivotSectionVisible` | `Function` |  |  | Shows or hides the Column Labels (pivot) section. |
