---
product: "AG Grid"
title: "Column Sizing"
description: "Column Sizing controls the way Columns are sized within the React Data Grid. Use auto-sizing or column-flex to control Column Size programmatically."
framework: react
version: "36.2.0"
related:
    - title: "Configuration"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/configuration/"
    - title: "Column Headers"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-headers/"
    - title: "Column Groups"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-groups/"
    - title: "Column Moving"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-moving/"
    - title: "Column Pinning"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-pinning/"
    - title: "Column Spanning"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-spanning/"
    - title: "Calculated Columns"
      url: "https://www.ag-grid.com/archive/36.2.0/react-data-grid/calculated-columns/"
llms: "https://www.ag-grid.com/archive/36.2.0/llms.txt"
---

# Column Sizing

Columns can be resized by dragging the right edge of the column header or by using the keyboard.

## Sizing

Column resizing is enabled by default for all columns. To control resizing for individual columns, set the boolean `resizable` property in the column definitions.

The snippet below allows all columns except Address to be resized.

```jsx
const [columnDefs, setColumnDefs] = useState([
    { field: 'name' },
    { field: 'age' },
    { field: 'address', resizable: false },
]);

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

The snippet below shows how to only allow the Address column to be resized by setting `resizable=false` on the default column definition and then `resizable=true` on the Address column.

```jsx
const defaultColDef = useMemo(() => { 
	return {
        resizable: false,
    };
}, []);
const [columnDefs, setColumnDefs] = useState([
    { field: 'name' },
    { field: 'age' },
    { field: 'address', resizable: true },
]);

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

## Column Flex

It's often required that one or more columns fill the entire available space in the grid. For this scenario, it is possible to use the `flex` config. Some columns could be set with a regular `width` config, while other columns would have a flex config.

Flex sizing works by dividing the remaining space in the grid among all flex columns in proportion to their flex value. For example, suppose the grid has a total width of 450px and it has three columns: the first with `width: 150`; the second with `flex: 1`; and third with `flex: 2`. The first column will be 150px wide, leaving 300px remaining. The column with `flex: 2` has twice the size with `flex: 1`. So final sizes will be: 150px, 100px, 200px.

If a column has no width or flex properties set, it will default to 200px.

> **Note**
>
> The flex config does **not** work with a `width` config in the same column. If you need to provide a minimum width for a column, you should use flex and the `minWidth` config. Flex will also take `maxWidth` into account.

> **Note**
>
> If you manually resize a column with flex either via the API or by dragging the resize handle, flex will automatically be disabled for that column.

The example below shows flex in action. Things to note are as follows:

- Column A is fixed size. You can resize it with the drag handle and the other two columns will adjust to fill the available space
- Column B has `flex: 2`, `minWidth: 200` and `maxWidth: 350`, so it should be constrained to this max/min width.
- Column C has `flex: 1` so should be half the size of column B, unless column B is being constrained by its `minWidth`/`maxWidth` rules, in which case it should take up the remaining available space.

#### Column Flex

```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 {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColSpanParams,
  GridApi,
  GridOptions,
  GridReadyEvent,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";

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

const modules = [ClientSideRowModelModule];

const colSpan = function (params: ColSpanParams) {
  return params.data === 2 ? 3 : 1;
};

function fillAllCellsWithWidthMeasurement() {
  Array.prototype.slice
    .call(document.querySelectorAll(".ag-cell"))
    .forEach((cell) => {
      const width = cell.offsetWidth;
      const isFullWidthRow = cell.parentElement.childNodes.length === 1;
      cell.textContent = (isFullWidthRow ? "Total width: " : "") + width + "px";
    });
}

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<any[]>([1, 2]);
  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "A",
      colId: "a",
      width: 300,
      colSpan: colSpan,
    },
    {
      headerName: "Flexed Columns",
      children: [
        {
          headerName: "B",
          colId: "b",
          minWidth: 200,
          maxWidth: 350,
          flex: 2,
        },
        {
          headerName: "C",
          colId: "c",
          flex: 1,
        },
      ],
    },
  ]);

  const onGridReady = useCallback((params: GridReadyEvent) => {
    setInterval(fillAllCellsWithWidthMeasurement, 50);
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div style={gridStyle}>
          <AgGridReact
            rowData={rowData}
            columnDefs={columnDefs}
            onGridReady={onGridReady}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Column Flex](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/flex-columns/reactFunctionalTs/)

## Auto-Sizing Columns

Columns can be auto-sized in two main ways:

1. Auto-size columns to fit grid - The columns will scale to fit the available grid width (or a provided width if desired).
2. Auto-size columns to fit cell contents - The columns will resize to fit their visible cell contents.

### Auto-Size Columns to Fit Grid

Columns can be resized to fit the width of the grid. The columns will scale (growing or shrinking) to fit the available width unless they have `suppressSizeToFit=true`. In the example below, the Athlete column will not be affected when columns are sized to fit the grid because it's setting `suppressSizeToFit=true`.

#### Auto-Size Columns to Fit Grid

```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 "./styles.css";
import {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnAutoSizeModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ColumnAutoSizeModule, ClientSideRowModelModule];

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", width: 150, suppressSizeToFit: true },
    { field: "age", width: 50, maxWidth: 50 },
    { colId: "country", field: "country", maxWidth: 300 },
    { field: "year", width: 90 },
    { field: "sport", width: 110 },
    { field: "gold", width: 100 },
  ]);
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitGridWidth",
      defaultMinWidth: 100,
      columnLimits: [
        {
          colId: "country",
          minWidth: 900,
        },
      ],
    };
  }, []);

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

  const sizeToFit = useCallback(() => {
    gridRef.current!.api.sizeColumnsToFit({
      defaultMinWidth: 100,
      columnLimits: [{ key: "country", minWidth: 900 }],
    });
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="outer-div">
          <div className="button-bar">
            <button onClick={sizeToFit}>
              Resize Columns to Fit Grid Width
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                columnDefs={columnDefs}
                autoSizeStrategy={autoSizeStrategy}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Auto-Size Columns to Fit Grid](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/column-sizing-to-fit/reactFunctionalTs/)

Provide the grid option `autoSizeStrategy` to size the columns to fit when the grid is loaded. This can either be set to size to the actual grid width (`type = 'fitGridWidth'`), or to a fixed width that is provided (`type = 'fitProvidedWidth'`).

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitGridWidth',
        defaultMinWidth: 100,
        columnLimits: [
            {
                colId: 'country',
                minWidth: 900
            }
        ]
    };
}, []);

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

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `autoSizeStrategy` | `AutoSizeStrategy` |  |  |  |
| `animateColumnResizing` | `boolean` |  |  |  |

The columns can also be sized on demand via `api.sizeColumnsToFit(params)`.

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `sizeColumnsToFit` | `Function` |  |  |  |

If you don't want a particular column to be included in the auto-resize, then set the column definition `suppressSizeToFit=true`. This is helpful if, for example, you want the first column to remain fixed width, but all other columns to fill the width of the table.

The grid calculates new column widths while maintaining the ratio of the column default widths. So for example if Column A has a default size twice as wide as Column B, then after the sizing is performed, Column A will still be twice the size of Column B, assuming no column min-width or max-width constraints are violated.

Column default widths, rather than current widths, are used while calculating the new widths. This ensures the result is deterministic and does not depend on any column resizing the user may have manually done.

A parameters object can be provided with minimum and maximum widths, either for all columns or for specific columns, to further restrain the column's resulting width from that function call. These widths will not exceed the column's defined minimum and maximum widths.

> **Note**
>
> For example assuming a grid with three columns, the algorithm will be as follows:
>
> `scale = availableWidth / (w1 + w2 + w3)`
>
> `w1 = round(w1 * scale)`
>
> `w2 = round(w2 * scale)`
>
> `w3 = totalGridWidth - (w1 + w2)`
>
> Assuming the grid is 1,200 pixels wide and the columns have default widths of `50`, `120` and `300`, then the calculation is as follows:
>
> `availableWidth = 1,198` (available width is typically smaller as the grid typically has left and right borders)
>
> `scale = 1198 / (50 + 120 + 300) = 2.54`
>
> `col1 = round(50 * 2.54) = 127`
>
> `col2 = round(120 * 2.54) = 306`
>
> `col3 = 1198 - (127 + 306) = 765` (the last column gets any space that's left, which ensures all space is used, so no rounding issues)

### Auto-Size Columns to Fit Cell Contents

Columns can be resized to fit the contents of the cells. By default the grid will resize the column to fit the header. If you do not want the headers to be included in the auto-size calculation, set the grid property `skipHeaderOnAutoSize = true`, or pass `skipHeader = true` to the `autoSizeStrategy` params or the API method. If you don't want a particular column to be included in the auto-resize, then set the column definition `suppressAutoSize = true`. The grid also provides the `scaleUpToFitGridWidth` option which proportionally scales up columns to fill any empty space in the grid after autosizing them.

The example below demonstrates the use of `autoSizeStrategy` to size the columns by default. The example button can reapply this sizing via the API at any time. There are also controls provided to toggle on the `skipHeader` and `scaleUpToFitGridWidth` parameters. The "Athlete" column has `suppressAutoSize = true`.

#### Auto-Size Columns to Fit Cell Contents

```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 "./styles.css";
import {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  ColumnAutoSizeModule,
  ColumnResizedEvent,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  ColumnApiModule,
  ColumnAutoSizeModule,
  ClientSideRowModelModule,
];

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", width: 150, suppressAutoSize: true },
    {
      field: "age",
      headerName: "Age of Athlete",
      width: 90,
      minWidth: 50,
      maxWidth: 150,
    },
    { field: "country", width: 120 },
    { field: "year", width: 90 },
    { field: "date", width: 110 },
  ]);
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitCellContents",
      defaultMaxWidth: 150,
      defaultMinWidth: 80,
    };
  }, []);

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

  const onColumnResized = useCallback((params: ColumnResizedEvent) => {
    console.log(params);
  }, []);

  const autoSizeAll = useCallback(() => {
    const skipHeader =
      document.querySelector<HTMLInputElement>("#toggle-ignore-headers")
        ?.checked ?? false;
    const scaleUpToFitGridWidth =
      document.querySelector<HTMLInputElement>("#toggle-scale-up")?.checked ??
      false;
    gridRef.current!.api.autoSizeColumns({ skipHeader, scaleUpToFitGridWidth });
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="outer-div">
          <div className="interaction-bar">
            <button className="resize-button" onClick={autoSizeAll}>
              Resize to Fit Cell Contents
            </button>
            <label>
              <input id="toggle-ignore-headers" type="checkbox" />
              <span>skipHeader</span>
            </label>
            <label>
              <input id="toggle-scale-up" type="checkbox" />
              <span>scaleUpToFitGridWidth</span>
            </label>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                columnDefs={columnDefs}
                autoSizeStrategy={autoSizeStrategy}
                onColumnResized={onColumnResized}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Auto-Size Columns to Fit Cell Contents](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/column-resizing/reactFunctionalTs/)

Provide the grid option `autoSizeStrategy` with `type = 'fitCellContents'` to size the columns to fit their content when the first data is rendered in the grid.

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitCellContents',
    };
}, []);

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

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `autoSizeStrategy` | `AutoSizeStrategy` |  |  |  |
| `animateColumnResizing` | `boolean` |  |  |  |

By default the **Autosize This Column** and **Autosize All Columns** actions in the [Column Menu](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-menu/) size to cell contents without the strategy's options. Set `applyToUiActions` to have them reuse the strategy instead, including `scaleUpToFitGridWidth`, `skipHeader` and any column limits.

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitCellContents',
        scaleUpToFitGridWidth: true,
        applyToUiActions: true
    };
}, []);

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

In the example below, narrow the columns and then run **Autosize All Columns** from the column menu. The columns scale back up to fill the grid, as the strategy specifies.

#### Auto-Size Actions Respecting the Strategy

```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 "./styles.css";
import {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  ColumnAutoSizeModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { ColumnMenuModule } 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 = [
  ColumnApiModule,
  ColumnAutoSizeModule,
  ClientSideRowModelModule,
  ColumnMenuModule,
];

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" },
    { field: "country" },
    { field: "sport" },
    { field: "year" },
    { field: "total" },
  ]);
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitCellContents",
      scaleUpToFitGridWidth: true,
      applyToUiActions: true,
    };
  }, []);

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

  const narrowColumns = useCallback(() => {
    gridRef.current!.api.applyColumnState({
      state: ["athlete", "country", "sport", "year", "total"].map((colId) => ({
        colId,
        width: 100,
      })),
    });
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="outer-div">
          <div className="interaction-bar">
            <button className="narrow-button" onClick={narrowColumns}>
              Narrow Columns
            </button>
            <span>Then use Autosize All Columns from the column menu</span>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IOlympicData>
                ref={gridRef}
                rowData={data}
                loading={loading}
                columnDefs={columnDefs}
                autoSizeStrategy={autoSizeStrategy}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Auto-Size Actions Respecting the Strategy](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/auto-size-ui-actions/reactFunctionalTs/)

This can also be performed on demand via the following API methods:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `autoSizeColumns` | `Function` |  |  |  |
| `autoSizeAllColumns` | `Function` |  |  |  |

[Column Groups](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-groups/) are never considered when calculating the column widths.

Just like Excel, each column can also be auto-resized by double clicking the right side of the header rather than dragging it. When you do this, the grid will work out the best width to fit the contents of the cells in the column.

> **Note**
>
> - The grid works out the best width by considering the virtually rendered rows only. For example, if your grid has 10,000 rows, but only 50 rendered due to virtualisation of rows, then only these 50 will be considered for working out the width to display. The rendered rows are all the rows you can see on the screen through the vertical scroll plus a small buffer (default buffer size is 20). With [Continuous Auto-Sizing](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#continuous-auto-sizing) opted into [scroll-driven re-sizes](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#scrolling), the width is worked out again from the rows rendered at each new scroll position.
> - The same applies across columns. Column Virtualisation renders only the columns the horizontal scroll position makes visible, so a grid of 1,000 columns may have only 10 rendered, and the grid can measure only what it renders. A one-off auto-size therefore leaves off-screen columns untouched. To size them, either set `suppressColumnVirtualisation=true` so every column is rendered and measured in one go, or keep virtualisation and use [Continuous Auto-Sizing](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#continuous-auto-sizing) with [scroll-driven re-sizes](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#scrolling), which fits each column as the scroll brings it into view.
> - Note that [Pinned Columns](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-pinning/), the [Selection Column](https://www.ag-grid.com/archive/36.2.0/react-data-grid/row-selection-multi-row/#customising-the-checkbox-column) and the [Row Numbers](https://www.ag-grid.com/archive/36.2.0/react-data-grid/row-numbers/) column will not be scaled up to fill any empty space when using `scaleUpToFitGridWidth`.

## Continuous Auto-Sizing

By default `autoSizeStrategy` is applied once, when the grid first renders. Set `continuous` to re-apply it whenever the grid changes in a way that affects column widths.

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitCellContents',
        continuous: true,
    };
}, []);

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

- `fitCellContents` re-sizes when the row data or the displayed columns change.
- `fitGridWidth` and `fitProvidedWidth` re-size when the available grid width or the displayed columns change, including changes caused by pagination or scrollbars.
- Re-sizes are debounced while the grid is being resized.

The example below spreads the grid width across five columns with `fitGridWidth`:

- Add or remove a column and the rest give up or take back space.
- Add rows until a vertical scrollbar appears and the columns re-fit to the width it leaves behind.
- Narrow the grid itself and the columns follow, still filling it exactly.

The example sets `animateColumnResizing` so each re-size transitions instead of jumping to the new widths.

#### Continuous Auto-Sizing to Fit Grid Width

```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 "./styles.css";
import {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnAutoSizeModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IRow } from "./interfaces";

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

const modules = [ColumnAutoSizeModule, ClientSideRowModelModule];

const INITIAL_COLUMNS = 5;

const MIN_COLUMNS = 1;

const MAX_COLUMNS = 12;

const INITIAL_ROWS = 4;

const MIN_ROWS = 0;

const MAX_ROWS = 40;

const ROW_STEP = 8;

let columnCount = INITIAL_COLUMNS;

let rowCount = INITIAL_ROWS;

const field: (index: number) => string = (index: number) => {
  return `column${index + 1}`;
};

const buildColumnDefs: (count: number) => ColDef<IRow>[] = (count: number) => {
  return Array.from({ length: count }, (_, index) => ({
    field: field(index),
    headerName: `Column ${index + 1}`,
  }));
};

const buildRows: (count: number) => IRow[] = (count: number) => {
  return Array.from({ length: count }, (_, rowIndex) =>
    Object.fromEntries(
      Array.from({ length: MAX_COLUMNS }, (_, columnIndex) => [
        field(columnIndex),
        `R${rowIndex + 1} C${columnIndex + 1}`,
      ]),
    ),
  );
};

const clampColumns: (count: number) => number = (count: number) => {
  return Math.min(MAX_COLUMNS, Math.max(MIN_COLUMNS, count));
};

const clampRows: (count: number) => number = (count: number) => {
  return Math.min(MAX_ROWS, Math.max(MIN_ROWS, count));
};

const MIN_WIDTH_PERCENT = 55;

const MAX_WIDTH_PERCENT = 100;

const WIDTH_STEP = 15;

let widthPercent = MAX_WIDTH_PERCENT;

function setGridWidth(percent: number) {
  widthPercent = Math.min(
    MAX_WIDTH_PERCENT,
    Math.max(MIN_WIDTH_PERCENT, percent),
  );
  document.querySelector<HTMLElement>("#gridSizer")!.style.width =
    `${widthPercent}%`;
}

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IRow>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<IRow[]>(buildRows(rowCount));
  const [columnDefs, setColumnDefs] = useState<ColDef[]>(
    buildColumnDefs(columnCount),
  );
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitGridWidth",
      continuous: true,
    };
  }, []);

  const addColumn = useCallback(() => {
    columnCount = clampColumns(columnCount + 1);
    gridRef.current!.api.setGridOption(
      "columnDefs",
      buildColumnDefs(columnCount),
    );
  }, [columnCount]);

  const removeColumn = useCallback(() => {
    columnCount = clampColumns(columnCount - 1);
    gridRef.current!.api.setGridOption(
      "columnDefs",
      buildColumnDefs(columnCount),
    );
  }, [columnCount]);

  const addRows = useCallback(() => {
    rowCount = clampRows(rowCount + ROW_STEP);
    setRowData(buildRows(rowCount));
  }, [rowCount]);

  const removeRows = useCallback(() => {
    rowCount = clampRows(rowCount - ROW_STEP);
    setRowData(buildRows(rowCount));
  }, [rowCount]);

  const narrower = useCallback(() => {
    setGridWidth(widthPercent - WIDTH_STEP);
  }, []);

  const wider = useCallback(() => {
    setGridWidth(widthPercent + WIDTH_STEP);
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="outer-div">
          <div className="interaction-bar">
            <button className="add-column-button" onClick={addColumn}>
              Add Column
            </button>
            <button className="remove-column-button" onClick={removeColumn}>
              Remove Column
            </button>
            <button className="add-rows-button" onClick={addRows}>
              Add Rows
            </button>
            <button className="remove-rows-button" onClick={removeRows}>
              Remove Rows
            </button>
            <button className="narrower-button" onClick={narrower}>
              Narrower
            </button>
            <button className="wider-button" onClick={wider}>
              Wider
            </button>
          </div>
          <div id="gridSizer" className="grid-sizer">
            <div style={gridStyle} className="grid">
              <AgGridReact<IRow>
                ref={gridRef}
                rowData={rowData}
                columnDefs={columnDefs}
                autoSizeStrategy={autoSizeStrategy}
                animateColumnResizing={true}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Continuous Auto-Sizing to Fit Grid Width](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/continuous-auto-size-fit-grid-width/reactFunctionalTs/)

### Controlling Each Re-Size

`shouldAutoSizeColumns` is called before each re-size, with the eligible `columns` and a `reason` of `'dataChanged'`, `'columnsChanged'`, `'viewportChanged'` or `'gridSizeChanged'`. Return `false` to skip that re-size. It has no effect unless `continuous` is `true`.

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitCellContents',
        continuous: true,
        // re-size on new data only, so the widths hold still as the grid is resized
        shouldAutoSizeColumns: ({ reason }) => reason === 'dataChanged',
    };
}, []);

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

The callback is passed the following params:

| Property | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `reason` | `'dataChanged' \| 'columnsChanged' \| 'viewportChanged' \| 'gridSizeChanged'` |  |  |  |
| `columns` | `Column[]` |  |  |  |
| `api` | `GridApi` |  |  |  |
| `context` | `TContext` |  |  |  |

### Scrolling

Scrolling never re-sizes columns by default, in either direction. `fitCellContents` can opt in: vertical scrolling brings new rows into view and horizontal scrolling brings new columns into view, and both change what there is to measure. Provide `shouldAutoSizeColumns` and allow the `'viewportChanged'` reason.

```jsx
const autoSizeStrategy = useMemo(() => { 
	return {
        type: 'fitCellContents',
        continuous: true,
        // re-size as rows and columns scroll into view, as well as on data and column changes
        shouldAutoSizeColumns: () => true,
    };
}, []);

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

Scroll-driven re-sizes are debounced, so the columns settle once the gesture stops. `fitGridWidth` and `fitProvidedWidth` are not affected by scrolling.

The example below sizes a grouped, paginated grid of 34 columns and over 8,000 rows with `fitCellContents`. Scrolling right fits the remaining columns as they arrive. The medal columns at the far end are narrow, and stay narrow. The text columns hold sentences of differing lengths, so moving between pages or changing the page size visibly re-fits them to the rows now on screen.

#### Scroll-Driven Auto-Sizing

```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 {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnAutoSizeModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  PaginationModule,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [
  ColumnAutoSizeModule,
  PaginationModule,
  ClientSideRowModelModule,
];

// The text columns below are built by pairing a phrase shape with a rotating pair of fields, so that
// every generated column holds a different sentence of a different length. That variety is the point:
// with continuous auto-sizing each column tracks the longest value on the page currently in view, so
// the columns move independently as you page through the data.
const PHRASE_SHAPES: ((
  first: string,
  second: string,
  data: IOlympicData,
) => string)[] = [
  (first) => first,
  (first, second) => `${first} / ${second}`,
  (first, second, data) => `${first} — ${second}, ${data.year}`,
  (first, second) => `${first} (${second})`,
  (first, second, data) => `${first} of ${second}, ${data.total} medal(s)`,
  (first, second, data) =>
    `${first} competing in ${second} at the ${data.year} games`,
];

const PHRASE_FIELDS: (keyof IOlympicData)[] = [
  "athlete",
  "country",
  "sport",
  "date",
];

const GENERATED_GROUPS = ["Profile", "Season", "Coverage", "Records"];

const COLUMNS_PER_GENERATED_GROUP = 6;

const generatedColumn: (index: number) => ColDef<IOlympicData> = (
  index: number,
) => {
  // The shape cycles fastest and the field pair advances only once the shapes have been exhausted,
  // so the two never come back into step: all 6 x 4 combinations are used before any repeats.
  const shape = PHRASE_SHAPES[index % PHRASE_SHAPES.length];
  const fieldIndex =
    Math.floor(index / PHRASE_SHAPES.length) % PHRASE_FIELDS.length;
  const first = PHRASE_FIELDS[fieldIndex];
  const second = PHRASE_FIELDS[(fieldIndex + 1) % PHRASE_FIELDS.length];
  return {
    colId: `text${index + 1}`,
    headerName: `Text ${index + 1}`,
    valueGetter: ({ data }) =>
      data ? shape(String(data[first]), String(data[second]), data) : "",
  };
};

const generatedGroups: ColGroupDef<IOlympicData>[] = GENERATED_GROUPS.map(
  (headerName, groupIndex) => ({
    headerName,
    children: Array.from(
      { length: COLUMNS_PER_GENERATED_GROUP },
      (_, childIndex) =>
        generatedColumn(groupIndex * COLUMNS_PER_GENERATED_GROUP + childIndex),
    ),
  }),
);

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Competitor",
      children: [{ field: "athlete" }, { field: "age" }, { field: "country" }],
    },
    ...generatedGroups,
    {
      headerName: "Event",
      children: [{ field: "sport" }, { field: "year" }, { field: "date" }],
    },
    {
      headerName: "Medals",
      children: [
        { field: "gold" },
        { field: "silver" },
        { field: "bronze" },
        { field: "total" },
      ],
    },
  ]);
  const paginationPageSizeSelector = useMemo<number[] | boolean>(() => {
    return [20, 50, 100];
  }, []);
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitCellContents",
      continuous: true,
      shouldAutoSizeColumns: () => 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}>
          <AgGridReact<IOlympicData>
            rowData={data}
            loading={loading}
            columnDefs={columnDefs}
            pagination={true}
            paginationPageSize={20}
            paginationPageSizeSelector={paginationPageSizeSelector}
            autoSizeStrategy={autoSizeStrategy}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Scroll-Driven Auto-Sizing](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/continuous-auto-size-in-action/reactFunctionalTs/)

### Column Width Ownership

Continuous sizing never changes the width of a column the user has sized themselves. A column becomes theirs through a header drag resize, a keyboard resize or a double-click auto-size, and through `applyColumnState` with an explicit `width`. Their width is then treated as fixed, so the width-distribution strategies hold the column out of the distribution and share the remaining space between the rest.

`width` and `initialWidth` in a column definition are both only starting widths: the grid may re-size either of them. To hold a column at a fixed width, set `suppressAutoSize` for `fitCellContents` or `suppressSizeToFit` for the width-distribution strategies.

Also excluded are [flex](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#column-flex) columns and the special [Selection](https://www.ag-grid.com/archive/36.2.0/react-data-grid/row-selection-multi-row/#customising-the-checkbox-column) and [Row Numbers](https://www.ag-grid.com/archive/36.2.0/react-data-grid/row-numbers/) columns.

When `scaleUpToFitGridWidth` is also set, only the eligible columns are scaled, and the grid shows a horizontal scrollbar when the fixed widths alone cannot fit.

Ownership is released by `api.resetColumnState()`, which returns every column to its column definition and so makes the user-sized ones eligible again. Note that it also resets sort, order, visibility and pivot state.

In the example below

- "Athlete" column sets `suppressAutoSize`, so it does not re-size
- Press "Next Values" to load values of a different length.
- Manually re-size the "Sport" column and note how it keeps the width you gave it while changing the values.
- Click "Reset Column State" to have the "Sport" column auto size again.

#### Column Width Ownership

```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 "./styles.css";
import {
  AutoSizeStrategy,
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  ColumnApiModule,
  ColumnAutoSizeModule,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";

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

const modules = [
  ColumnApiModule,
  ColumnAutoSizeModule,
  ClientSideRowModelModule,
];

interface IRow {
  athlete: string;
  country: string;
  sport: string;
}

const ROW_DATA_SETS: IRow[][] = [
  [
    { athlete: "Michael Phelps", country: "US", sport: "Swimming" },
    { athlete: "Natalie Coughlin", country: "US", sport: "Swimming" },
    { athlete: "Aleksey Nemov", country: "RU", sport: "Gymnastics" },
  ],
  [
    {
      athlete: "Michael Fred Phelps II, the most decorated Olympian",
      country: "United States of America",
      sport: "Swimming, Individual Medley and Butterfly",
    },
    {
      athlete: "Natalie Anne Coughlin Hall, twelve-time medallist",
      country: "United States of America",
      sport: "Swimming, Backstroke and Freestyle",
    },
    {
      athlete: "Aleksey Yuryevich Nemov, twelve-time medallist",
      country: "Russian Federation",
      sport: "Artistic Gymnastics, All-Around",
    },
  ],
  [
    { athlete: "Ian Thorpe", country: "Australia", sport: "Swimming" },
    {
      athlete: "Marit Bjoergen",
      country: "Norway",
      sport: "Cross Country Skiing",
    },
    { athlete: "Ole Einar Bjoerndalen", country: "Norway", sport: "Biathlon" },
  ],
  [
    { athlete: "Sun Yang", country: "China", sport: "Swimming" },
    {
      athlete: "Kohei Uchimura",
      country: "Japan",
      sport: "Artistic Gymnastics",
    },
    { athlete: "Yohan Blake", country: "Jamaica", sport: "Athletics" },
  ],
];

let dataSetIndex = 0;

const GridExample = () => {
  const gridRef = useRef<AgGridReact<IRow>>(null);
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  const [rowData, setRowData] = useState<IRow[]>(ROW_DATA_SETS[0]);
  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", width: 150, suppressAutoSize: true },
    { field: "country", initialWidth: 120 },
    { field: "sport" },
  ]);
  const autoSizeStrategy = useMemo<AutoSizeStrategy>(() => {
    return {
      type: "fitCellContents",
      continuous: true,
    };
  }, []);

  const nextValues = useCallback(() => {
    dataSetIndex = (dataSetIndex + 1) % ROW_DATA_SETS.length;
    setRowData(ROW_DATA_SETS[dataSetIndex]);
  }, [dataSetIndex]);

  const releaseWidths = useCallback(() => {
    gridRef.current!.api.resetColumnState();
  }, []);

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="outer-div">
          <div className="interaction-bar">
            <button className="next-values-button" onClick={nextValues}>
              Next Values
            </button>
            <button className="release-widths-button" onClick={releaseWidths}>
              Reset Column State
            </button>
          </div>
          <div className="grid-wrapper">
            <div style={gridStyle}>
              <AgGridReact<IRow>
                ref={gridRef}
                rowData={rowData}
                columnDefs={columnDefs}
                autoSizeStrategy={autoSizeStrategy}
              />
            </div>
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Column Width Ownership](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/continuous-auto-size/reactFunctionalTs/)

> **Note**
>
> Two limits apply to continuous `fitCellContents`:
>
> - It is subject to the same [virtualisation limits](https://www.ag-grid.com/archive/36.2.0/react-data-grid/column-sizing/#auto-size-columns-to-fit-cell-contents) as a one-off auto-size: only the rendered cells can be measured, so columns are sized progressively as scrolling renders more content.
> - It is not supported by the [Viewport Row Model](https://www.ag-grid.com/archive/36.2.0/react-data-grid/viewport/), where the grid logs a warning and ignores the option.

## Resize via Keyboard

Column headers can be resized using the keyboard. When a column header is focused, press `⌥ Alt` + `←` / `→` to resize the column in that direction.

See [Column Header Navigation](https://www.ag-grid.com/archive/36.2.0/react-data-grid/keyboard-navigation/#column-header-navigation) for a full list of header keyboard interactions.

## Shift Resizing

If you hold the `⇧ Shift` key while dragging the resize handle, the column will take space away from the column adjacent to it. This means the total width for all columns will be constant.

You can also change the default behaviour for resizing. Set the grid property `colResizeDefault='shift'` to have shift resizing as the default and normal resizing to happen when the `⇧ Shift` key is pressed.

In the example below, note the following:

- Grid property `colResizeDefault='shift'` so default column resizing will behave as if `⇧ Shift` key is pressed.
- Holding down `⇧ Shift` will then resize the normal default way.

#### Shift Resizing

```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 {
  ClientSideRowModelModule,
  ColDef,
  ColGroupDef,
  GridApi,
  GridOptions,
  ModuleRegistry,
  enableDevValidations,
} from "ag-grid-community";
import { IOlympicData } from "./interfaces";
import { useFetchJson } from "./useFetchJson";

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

const modules = [ClientSideRowModelModule];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<ColDef[]>([
    { field: "athlete", width: 150 },
    { field: "age", width: 90 },
    { field: "country", width: 150 },
    { field: "year", width: 90 },
    { field: "date", width: 110 },
    { field: "sport", width: 150 },
    { field: "gold", width: 100 },
    { field: "silver", width: 100 },
    { field: "bronze", width: 100 },
    { field: "total", width: 100 },
  ]);

  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}
            colResizeDefault={"shift"}
          />
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Shift Resizing](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/shift-resizing/reactFunctionalTs/)

## Resizing Groups

When you resize a group, it will distribute the extra room to all columns in the group equally. In the example below the groups can be resized as follows:

- The group 'Everything Resizes' will resize all columns.
- The group 'Only Year Resizes' will resize only year, because the other columns have `resizable=false`.
- The group 'Nothing Resizes' cannot be resized at all because all the columns in the groups have `resizable=false`.

#### Resizing Groups

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

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

const modules = [ClientSideRowModelModule];

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);

  const [columnDefs, setColumnDefs] = useState<(ColDef | ColGroupDef)[]>([
    {
      headerName: "Everything Resizes",
      children: [
        {
          field: "athlete",
          headerClass: "resizable-header",
        },
        { field: "age", headerClass: "resizable-header" },
        {
          field: "country",
          headerClass: "resizable-header",
        },
      ],
    },
    {
      headerName: "Only Year Resizes",
      children: [
        { field: "year", headerClass: "resizable-header" },
        {
          field: "date",
          resizable: false,
          headerClass: "fixed-size-header",
        },
        {
          field: "sport",
          resizable: false,
          headerClass: "fixed-size-header",
        },
      ],
    },
    {
      headerName: "Nothing Resizes",
      children: [
        {
          field: "gold",
          resizable: false,
          headerClass: "fixed-size-header",
        },
        {
          field: "silver",
          resizable: false,
          headerClass: "fixed-size-header",
        },
        {
          field: "bronze",
          resizable: false,
          headerClass: "fixed-size-header",
        },
        {
          field: "total",
          resizable: false,
          headerClass: "fixed-size-header",
        },
      ],
    },
  ]);
  const defaultColDef = useMemo<ColDef>(() => {
    return {
      width: 150,
    };
  }, []);

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

  return (
    <AgGridProvider modules={modules}>
      <div style={containerStyle}>
        <div className="example-wrapper">
          <div className="legend-bar">
            <span className="legend-box resizable-header"></span> Resizable
            Column &nbsp;&nbsp;&nbsp;&nbsp;
            <span className="legend-box fixed-size-header"></span> Fixed Width
            Column
          </div>

          <div style={gridStyle}>
            <AgGridReact<IOlympicData>
              rowData={data}
              loading={loading}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
            />
          </div>
        </div>
      </div>
    </AgGridProvider>
  );
};

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

[Live example: Resizing Groups](https://www.ag-grid.com/archive/36.2.0/examples/column-sizing/resizing-groups/reactFunctionalTs/)
