Skip to content

Commit a905deb

Browse files
committed
Merge branch 'main' into am-refactor-minmax-logic
2 parents 45bbadd + 3887ea8 commit a905deb

File tree

3 files changed

+52
-40
lines changed

3 files changed

+52
-40
lines changed

src/hooks/useColumnWidths.ts

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { useLayoutEffect, useState } from 'react';
2+
import { flushSync } from 'react-dom';
23

34
import type { CalculatedColumn, ResizedWidth, StateSetter } from '../types';
45
import type { DataGridProps } from '../DataGrid';
@@ -49,63 +50,72 @@ export function useColumnWidths<R, SR>(
4950

5051
function updateMeasuredAndResizedWidths() {
5152
setPreviousGridWidth(gridWidth);
52-
53-
if (columnsToMeasure.length > 0) {
54-
setMeasuredColumnWidths((measuredColumnWidths) => {
55-
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
56-
let hasChanges = false;
57-
58-
for (const key of columnsToMeasure) {
59-
const measuredWidth = measureColumnWidth(gridRef, key);
60-
hasChanges ||= measuredWidth !== measuredColumnWidths.get(key);
61-
if (measuredWidth === undefined) {
62-
newMeasuredColumnWidths.delete(key);
63-
} else {
64-
newMeasuredColumnWidths.set(key, measuredWidth);
65-
}
53+
if (columnsToMeasure.length === 0) return;
54+
55+
setMeasuredColumnWidths((measuredColumnWidths) => {
56+
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
57+
let hasChanges = false;
58+
59+
for (const key of columnsToMeasure) {
60+
const measuredWidth = measureColumnWidth(gridRef, key);
61+
hasChanges ||= measuredWidth !== measuredColumnWidths.get(key);
62+
if (measuredWidth === undefined) {
63+
newMeasuredColumnWidths.delete(key);
64+
} else {
65+
newMeasuredColumnWidths.set(key, measuredWidth);
6666
}
67+
}
6768

68-
return hasChanges ? newMeasuredColumnWidths : measuredColumnWidths;
69-
});
70-
}
69+
return hasChanges ? newMeasuredColumnWidths : measuredColumnWidths;
70+
});
7171

7272
if (columnToAutoResize !== null) {
73-
setColumnToAutoResize(null);
73+
const resizingKey = columnToAutoResize.key;
7474
setResizedColumnWidths((resizedColumnWidths) => {
75-
const resizingKey = columnToAutoResize.key;
7675
const oldWidth = resizedColumnWidths.get(resizingKey);
7776
const newWidth = measureColumnWidth(gridRef, resizingKey);
7877
if (newWidth !== undefined && oldWidth !== newWidth) {
7978
const newResizedColumnWidths = new Map(resizedColumnWidths);
8079
newResizedColumnWidths.set(resizingKey, newWidth);
81-
onColumnResize?.(viewportColumns.find((c) => c.key === resizingKey)!, newWidth);
8280
return newResizedColumnWidths;
8381
}
8482
return resizedColumnWidths;
8583
});
84+
setColumnToAutoResize(null);
8685
}
8786
}
8887

8988
function handleColumnResize(column: CalculatedColumn<R, SR>, nextWidth: ResizedWidth) {
9089
const { key: resizingKey } = column;
9190

92-
if (columnsCanFlex) {
93-
// delete measured column widths for all other flex columns so they can be recalculated
94-
setMeasuredColumnWidths((measuredColumnWidths) => {
95-
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
96-
for (const { key, width } of viewportColumns) {
97-
if (resizingKey !== key && typeof width === 'string' && !resizedColumnWidths.has(key)) {
98-
newMeasuredColumnWidths.delete(key);
91+
flushSync(() => {
92+
if (columnsCanFlex) {
93+
// remeasure all the columns that can flex and are not resized by the user
94+
setMeasuredColumnWidths((measuredColumnWidths) => {
95+
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
96+
for (const { key, width } of viewportColumns) {
97+
if (resizingKey !== key && typeof width === 'string' && !resizedColumnWidths.has(key)) {
98+
newMeasuredColumnWidths.delete(key);
99+
}
99100
}
100-
}
101-
return newMeasuredColumnWidths;
102-
});
103-
}
101+
return newMeasuredColumnWidths;
102+
});
103+
}
104104

105-
setColumnToAutoResize({
106-
key: resizingKey,
107-
width: nextWidth
105+
setColumnToAutoResize({
106+
key: resizingKey,
107+
width: nextWidth
108+
});
108109
});
110+
111+
if (onColumnResize) {
112+
const previousWidth = resizedColumnWidths.get(resizingKey);
113+
const newWidth =
114+
typeof nextWidth === 'number' ? nextWidth : measureColumnWidth(gridRef, resizingKey);
115+
if (newWidth !== undefined && newWidth !== previousWidth) {
116+
onColumnResize(column, newWidth);
117+
}
118+
}
109119
}
110120

111121
return {

test/browser/column/resizable.test.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,10 @@ test('should auto resize column when resize handle is double clicked', async ()
113113
const [, col2] = getHeaderCells();
114114
await autoResize(col2);
115115
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '100px 327.703px' });
116-
// This is called twice in strict mode
117-
expect(onColumnResize).toHaveBeenCalledWith(expect.objectContaining(columns[1]), 327.703125);
116+
expect(onColumnResize).toHaveBeenCalledExactlyOnceWith(
117+
expect.objectContaining(columns[1]),
118+
327.703125
119+
);
118120
});
119121

120122
test('should use the maxWidth if specified on auto resize', async () => {
@@ -192,10 +194,9 @@ test('should remeasure flex columns when resizing a column', async () => {
192194
const [col1] = getHeaderCells();
193195
await autoResize(col1);
194196
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '79.1406px 919.422px 919.438px' });
195-
expect(onColumnResize).toHaveBeenCalled();
196-
onColumnResize.mockClear();
197+
expect(onColumnResize).toHaveBeenCalledOnce();
197198
// onColumnResize is not called if width is not changed
198199
await autoResize(col1);
199200
await expect.element(grid).toHaveStyle({ gridTemplateColumns: '79.1406px 919.422px 919.438px' });
200-
expect(onColumnResize).not.toHaveBeenCalled();
201+
expect(onColumnResize).toHaveBeenCalledOnce();
201202
});

website/routes/CommonFeatures.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ function getColumns(
9696
{
9797
key: 'title',
9898
name: 'Task',
99+
maxWidth: 500,
99100
frozen: true,
100101
renderEditCell: textEditor,
101102
renderSummaryCell({ row }) {
@@ -117,7 +118,7 @@ function getColumns(
117118
{
118119
key: 'country',
119120
name: 'Country',
120-
maxWidth: 150,
121+
maxWidth: 100,
121122
renderEditCell: (p) => (
122123
<select
123124
autoFocus

0 commit comments

Comments
 (0)