Column Resizing
To enable column resizing, simply define your columns within the your component and set the onResizeColumn
prop on the ReactGrid component.
/**
* Callback function that is triggered when a column is resized.
*
* @param width - The new width of the column.
* @param columnIdx - An array of column indexes that were resized. There may be more than one index in the case of spanned headers.
* @returns void
*/
onResizeColumn?: (width: number, columnIdx: number[]) => void;
Live example
Code
const peopleData = [ { id: "66d61077035753f369ddbb16", name: "Jordan Rodriquez", age: 30, email: "jordanrodriquez@cincyr.com", company: "Zaggles", }, { id: "66d61077794e7949ab167fd5", email: "allysonrios@satiance.com", name: "Allyson Rios", age: 30, company: "Zoxy", }, { id: "66d61077dd754e88981ae434", name: "Pickett Lucas", age: 25, email: "pickettlucas@zoxy.com", company: "Techade", }, { id: "66d61077115e2f8748c334d9", name: "Louella David", age: 37, email: "louelladavid@techade.com", company: "Ginkogene", }, { id: "66d61077540d53374b427e4b", name: "Tricia Greene", age: 27, email: "triciagreene@ginkogene.com", company: "Naxdis", }, ]; const cellStyles = { header: { backgroundColor: "#55bc71", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: "bold", }, }; const getRows = (people: Person[]): Row[] => [ // header row { rowIndex: 0, height: 40, }, // data rows ...people.map((_, i) => ({ rowIndex: i + 1, height: 40, })), ]; const getColumns = (): Column[] => [ { colIndex: 0, width: 220 }, { colIndex: 1, width: 220 }, { colIndex: 2, width: 220 }, { colIndex: 3, width: 220 }, ]; type UpdatePerson = <T>(id: string, key: string, newValue: T) => void; const generateCells = (people: Person[], updatePerson: UpdatePerson): Cell[] => { const generateHeaderCells = () => { const titles = ["Name", "Age", "Email", "Company"]; return titles.map((title, colIndex) => ({ rowIndex: 0, colIndex, Template: NonEditableCell, props: { value: title, style: cellStyles.header, }, })); }; const generateRowCells = (rowIndex: number, person: Person): Cell[] => { const { id, name, age, email, company } = person; return [ { rowIndex, colIndex: 0, Template: TextCell, props: { text: name, onTextChanged: (newText: string) => updatePerson(id, "name", newText), }, }, { rowIndex, colIndex: 1, Template: NumberCell, props: { value: age, onValueChanged: (newValue: number) => updatePerson(id, "age", newValue), }, }, { rowIndex, colIndex: 2, Template: TextCell, props: { text: email, onTextChanged: (newText: string) => updatePerson(id, "email", newText), }, }, { rowIndex, colIndex: 3, Template: TextCell, props: { text: company, onTextChanged: (newText: string) => updatePerson(id, "company", newText), }, }, ]; }; const headerCells = generateHeaderCells(); const rowCells = people.flatMap((person, idx) => generateRowCells(idx + 1, person)); return [...headerCells, ...rowCells]; }; const ReactGridExample = () => { const [people, setPeople] = useState(peopleData); const updatePerson = (id, key, newValue) => { setPeople((prev) => { return prev.map((p) => (p.id === id ? { ...p, [key]: newValue } : p)); }); }; const rows = getRows(people); const [columns, setColumns] = useState(getColumns()); const cells = generateCells(people, updatePerson); return ( <div> <ReactGrid rows={rows} columns={columns} onResizeColumn={(width, columnIdx) => handleResizeColumn(width, columnIdx, setColumns)} cells={cells} /> </div> ); }; const handleResizeColumn = ( newWidth: number, columnIndexes: number[], setColumns: Dispatch<SetStateAction<Column[]>> ) => { setColumns((prevColumns) => { // If resizing spans multiple columns (e.g., header cells with colSpan > 1), divide the new width by the number of columns const newWidthPerColumn = columnIndexes.length > 1 ? newWidth / columnIndexes.length : newWidth; return prevColumns.map((column, idx) => { if (columnIndexes.includes(idx)) { return { ...column, width: newWidthPerColumn }; } return column; }); }); }; render(<ReactGridExample />, document.getElementById("root"));
Preview