Skip to content

Commit 005c9f2

Browse files
committed
Use state to handle column auto resize
1 parent d7ac70d commit 005c9f2

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

src/hooks/useColumnWidths.ts

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { useLayoutEffect, useRef } from 'react';
2-
import { flushSync } from 'react-dom';
1+
import { useLayoutEffect, useRef, useState } from 'react';
32

43
import type { CalculatedColumn, StateSetter } from '../types';
54
import type { DataGridProps } from '../DataGrid';
@@ -16,6 +15,7 @@ export function useColumnWidths<R, SR>(
1615
setMeasuredColumnWidths: StateSetter<ReadonlyMap<string, number>>,
1716
onColumnResize: DataGridProps<R, SR>['onColumnResize']
1817
) {
18+
const [columnToAutoresize, setColumnToAutoResize] = useState<string | null>(null);
1919
const prevGridWidthRef = useRef(gridWidth);
2020
const columnsCanFlex: boolean = columns.length === viewportColumns.length;
2121
// Allow columns to flex again when...
@@ -26,7 +26,10 @@ export function useColumnWidths<R, SR>(
2626
const columnsToMeasure: string[] = [];
2727

2828
for (const { key, idx, width } of viewportColumns) {
29-
if (
29+
if (key === columnToAutoresize) {
30+
newTemplateColumns[idx] = 'max-content';
31+
columnsToMeasure.push(key);
32+
} else if (
3033
typeof width === 'string' &&
3134
(ignorePreviouslyMeasuredColumns || !measuredColumnWidths.has(key)) &&
3235
!resizedColumnWidths.has(key)
@@ -62,40 +65,53 @@ export function useColumnWidths<R, SR>(
6265

6366
return hasChanges ? newMeasuredColumnWidths : measuredColumnWidths;
6467
});
68+
69+
if (columnToAutoresize !== null) {
70+
setColumnToAutoResize(null);
71+
setResizedColumnWidths((resizedColumnWidths) => {
72+
const newResizedColumnWidths = new Map(resizedColumnWidths);
73+
newResizedColumnWidths.set(
74+
columnToAutoresize,
75+
measureColumnWidth(gridRef, columnToAutoresize)!
76+
);
77+
return newResizedColumnWidths;
78+
});
79+
}
6580
}
6681

6782
function handleColumnResize(column: CalculatedColumn<R, SR>, nextWidth: number | 'max-content') {
6883
const { key: resizingKey } = column;
69-
const newTemplateColumns = [...templateColumns];
7084
const columnsToMeasure: string[] = [];
7185

72-
for (const { key, idx, width } of viewportColumns) {
73-
if (resizingKey === key) {
74-
const width = typeof nextWidth === 'number' ? `${nextWidth}px` : nextWidth;
75-
newTemplateColumns[idx] = width;
76-
} else if (columnsCanFlex && typeof width === 'string' && !resizedColumnWidths.has(key)) {
77-
newTemplateColumns[idx] = width;
86+
for (const { key, width } of viewportColumns) {
87+
if (
88+
resizingKey !== key &&
89+
columnsCanFlex &&
90+
typeof width === 'string' &&
91+
!resizedColumnWidths.has(key)
92+
) {
7893
columnsToMeasure.push(key);
7994
}
8095
}
8196

82-
gridRef.current!.style.gridTemplateColumns = newTemplateColumns.join(' ');
83-
const measuredWidth =
84-
typeof nextWidth === 'number' ? nextWidth : measureColumnWidth(gridRef, resizingKey)!;
97+
setMeasuredColumnWidths((measuredColumnWidths) => {
98+
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
99+
for (const columnKey of columnsToMeasure) {
100+
newMeasuredColumnWidths.delete(columnKey);
101+
}
102+
return newMeasuredColumnWidths;
103+
});
85104

86-
// TODO: remove
87-
// need flushSync to keep frozen column offsets in sync
88-
// we may be able to use `startTransition` or even `requestIdleCallback` instead
89-
flushSync(() => {
105+
if (typeof nextWidth === 'number') {
90106
setResizedColumnWidths((resizedColumnWidths) => {
91107
const newResizedColumnWidths = new Map(resizedColumnWidths);
92-
newResizedColumnWidths.set(resizingKey, measuredWidth);
108+
newResizedColumnWidths.set(resizingKey, nextWidth);
93109
return newResizedColumnWidths;
94110
});
95-
updateMeasuredWidths(columnsToMeasure);
96-
});
97-
98-
onColumnResize?.(column, measuredWidth);
111+
onColumnResize?.(column, nextWidth);
112+
} else {
113+
setColumnToAutoResize(resizingKey);
114+
}
99115
}
100116

101117
return {

0 commit comments

Comments
 (0)