Ag-Grid is a powerful data table library with tons of features. It requires some learning and doc reading, but I think it is worth it.
This post will share an Ag-Grid wrapper component that will resize columns sizes to fit its container's width automatically. If its container size changes, it will resize the columns to fit the new width.
The trick is straightforward, it watches its container's width, and window.resize
event and call sizeColumnsToFit
from AgGrid's API within an useEffect
hook.
The component props of this component extend AgGridReactProps
so we can use it the same way as we use the official AgGridReact
component.
-
useDebounce
hook from usehooks.com to reduce unnecessary calls tosizeColumnsToFit
. It is entirely optional.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport { useEffect, useState } from "react"; export function useDebounce<T>(value: T, delay = 150) { const [debouncedValue, setDebouncedValue] = useState<T>(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; } -
useWindowSize
hook subscribes towindow.resize
event and update statesize
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport { useLayoutEffect, useState } from "react"; import { useDebounce } from "./useDebounce"; export function useWindowSize(debounce = 150) { const [size, setSize] = useState([0, 0]); const debounceSize = useDebounce(size, debounce); useLayoutEffect(() => { function updateSize() { setSize([window.innerWidth, window.innerHeight]); } window.addEventListener("resize", updateSize); updateSize(); return () => window.removeEventListener("resize", updateSize); }, []); return debounceSize; } -
useContainerWidth
hook report width size withgetBoundingClientRect
API to report the element's width.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport { useState } from "react"; import {useDebounce} from './useDebounce'; export function useContainerWidth(debounce = 100){ const [size, setSize] = useState<number | undefined>(); const ref = (element: HTMLDivElement) => element && setSize(element.getBoundingClientRect().width); const debounceResize = useDebounce(size, debounce); return {width:debounceResize, ref}; } -
Finally, we have
AgGridAutoResizeToContainer
using the above hooks anduseEffect
.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport { AgGridReact, AgGridReactProps } from "ag-grid-react"; import { GridApi, GridReadyEvent } from "ag-grid-community"; import React, { useEffect, useState } from "react"; import { useContainerWidth } from "./useContainerWidth"; import { useWindowSize } from "./useWindowSize"; export function AgGridAutoResizeToContainer({ onGridReady, theme = "ag-theme-alpine", debounce = 0, ...props }: AgGridReactProps & { theme?: string; debounce?: number }) { const [gridApi, setGridApi] = useState<GridApi | undefined>(); const [windowWidth] = useWindowSize(debounce); const {width: containerWidth, ref} = useContainerWidth(debounce); useEffect(() => { if (gridApi) { gridApi.sizeColumnsToFit(); } }, [windowWidth, containerWidth, gridApi]); function handleGridReady(event: GridReadyEvent) { if (onGridReady) { onGridReady(event); } setGridApi(event.api); } return ( <div className={theme} ref={ref} style={{ width: "100%", height: "100%" }} > <AgGridReact onGridReady={handleGridReady} {...props} /> </div> ); }
The working sample is on CodeSandbox:
Happy coding…
Top comments (0)