Skip to content

Commit 69360d2

Browse files
committed
Add columnWidths and onColumnWidthsChange props
1 parent 663f1d7 commit 69360d2

3 files changed

Lines changed: 58 additions & 32 deletions

File tree

src/DataGrid.tsx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ export interface DataGridHandle {
109109
element: HTMLDivElement | null;
110110
scrollToCell: (position: PartialPosition) => void;
111111
selectCell: (position: Position, enableEditor?: Maybe<boolean>) => void;
112-
resetMeasuredColumnWidths: () => void;
113112
}
114113

115114
type SharedDivProps = Pick<
@@ -236,6 +235,9 @@ export interface DataGridProps<R, SR = unknown, K extends Key = Key> extends Sha
236235
direction?: Maybe<Direction>;
237236
'data-testid'?: Maybe<string>;
238237
'data-cy'?: Maybe<string>;
238+
239+
columnWidths?: Maybe<ReadonlyMap<string, number>>;
240+
onColumnWidthsChange?: Maybe<(widths: ReadonlyMap<string, number>) => void>;
239241
}
240242

241243
/**
@@ -295,7 +297,10 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
295297
'aria-describedby': ariaDescribedBy,
296298
'aria-rowcount': rawAriaRowCount,
297299
'data-testid': testId,
298-
'data-cy': dataCy
300+
'data-cy': dataCy,
301+
302+
columnWidths,
303+
onColumnWidthsChange
299304
} = props;
300305

301306
/**
@@ -324,9 +329,17 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
324329
const [resizedColumnWidths, setResizedColumnWidths] = useState(
325330
(): ReadonlyMap<string, number> => new Map()
326331
);
327-
const [measuredColumnWidths, setMeasuredColumnWidths] = useState(
328-
(): ReadonlyMap<string, number> => new Map()
332+
const [measuredColumnWidthsInternal, setMeasuredColumnWidthsInternal] = useState(
333+
(): ReadonlyMap<string, number> => columnWidths ?? new Map()
329334
);
335+
const isColumnWidthsControlled = columnWidths != null && onColumnWidthsChange != null;
336+
const measuredColumnWidths = isColumnWidthsControlled
337+
? columnWidths
338+
: measuredColumnWidthsInternal;
339+
const setMeasuredColumnWidths = isColumnWidthsControlled
340+
? onColumnWidthsChange
341+
: setMeasuredColumnWidthsInternal;
342+
330343
const [isDragging, setDragging] = useState(false);
331344
const [draggedOverRowIdx, setOverRowIdx] = useState<number | undefined>(undefined);
332345
const [scrollToPosition, setScrollToPosition] = useState<PartialPosition | null>(null);
@@ -541,10 +554,7 @@ export function DataGrid<R, SR = unknown, K extends Key = Key>(props: DataGridPr
541554
setScrollToPosition({ idx: scrollToIdx, rowIdx: scrollToRowIdx });
542555
}
543556
},
544-
selectCell,
545-
resetMeasuredColumnWidths() {
546-
setMeasuredColumnWidths(new Map());
547-
}
557+
selectCell
548558
}));
549559

550560
/**

src/hooks/useColumnWidths.ts

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,18 @@ export function useColumnWidths<R, SR>(
1313
resizedColumnWidths: ReadonlyMap<string, number>,
1414
measuredColumnWidths: ReadonlyMap<string, number>,
1515
setResizedColumnWidths: StateSetter<ReadonlyMap<string, number>>,
16-
setMeasuredColumnWidths: StateSetter<ReadonlyMap<string, number>>,
16+
setMeasuredColumnWidths: (columnWidths: ReadonlyMap<string, number>) => void,
1717
onColumnResize: DataGridProps<R, SR>['onColumnResize']
1818
) {
1919
const [columnToAutoResize, setColumnToAutoResize] = useState<{
2020
readonly key: string;
2121
readonly width: ResizedWidth;
2222
} | null>(null);
2323
const [prevGridWidth, setPreviousGridWidth] = useState(gridWidth);
24+
const [temporaryMeasuredColumnWidths, setTemporaryMeasuredColumnWidths] = useState<ReadonlyMap<
25+
string,
26+
number
27+
> | null>(null);
2428
const columnsCanFlex: boolean = columns.length === viewportColumns.length;
2529
// Allow columns to flex again when...
2630
const ignorePreviouslyMeasuredColumns: boolean =
@@ -38,7 +42,10 @@ export function useColumnWidths<R, SR>(
3842
columnsToMeasure.push(key);
3943
} else if (
4044
typeof width === 'string' &&
41-
(ignorePreviouslyMeasuredColumns || !measuredColumnWidths.has(key)) &&
45+
(ignorePreviouslyMeasuredColumns ||
46+
(temporaryMeasuredColumnWidths !== null
47+
? temporaryMeasuredColumnWidths.has(key)
48+
: !measuredColumnWidths.has(key))) &&
4249
!resizedColumnWidths.has(key)
4350
) {
4451
newTemplateColumns[idx] = width;
@@ -54,22 +61,22 @@ export function useColumnWidths<R, SR>(
5461
setPreviousGridWidth(gridWidth);
5562
if (columnsToMeasure.length === 0) return;
5663

57-
setMeasuredColumnWidths((measuredColumnWidths) => {
58-
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
59-
let hasChanges = false;
60-
61-
for (const key of columnsToMeasure) {
62-
const measuredWidth = measureColumnWidth(gridRef, key);
63-
hasChanges ||= measuredWidth !== measuredColumnWidths.get(key);
64-
if (measuredWidth === undefined) {
65-
newMeasuredColumnWidths.delete(key);
66-
} else {
67-
newMeasuredColumnWidths.set(key, measuredWidth);
68-
}
64+
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
65+
let hasChanges = false;
66+
67+
for (const key of columnsToMeasure) {
68+
const measuredWidth = measureColumnWidth(gridRef, key);
69+
hasChanges ||= measuredWidth !== measuredColumnWidths.get(key);
70+
if (measuredWidth === undefined) {
71+
newMeasuredColumnWidths.delete(key);
72+
} else {
73+
newMeasuredColumnWidths.set(key, measuredWidth);
6974
}
75+
}
7076

71-
return hasChanges ? newMeasuredColumnWidths : measuredColumnWidths;
72-
});
77+
if (hasChanges) {
78+
setMeasuredColumnWidths(newMeasuredColumnWidths);
79+
}
7380

7481
if (columnToAutoResize !== null) {
7582
const resizingKey = columnToAutoResize.key;
@@ -93,15 +100,14 @@ export function useColumnWidths<R, SR>(
93100
flushSync(() => {
94101
if (columnsCanFlex) {
95102
// remeasure all the columns that can flex and are not resized by the user
96-
setMeasuredColumnWidths((measuredColumnWidths) => {
97-
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
98-
for (const { key, width } of viewportColumns) {
99-
if (resizingKey !== key && typeof width === 'string' && !resizedColumnWidths.has(key)) {
100-
newMeasuredColumnWidths.delete(key);
101-
}
103+
const newMeasuredColumnWidths = new Map(measuredColumnWidths);
104+
for (const { key, width } of viewportColumns) {
105+
if (resizingKey !== key && typeof width === 'string' && !resizedColumnWidths.has(key)) {
106+
newMeasuredColumnWidths.delete(key);
102107
}
103-
return newMeasuredColumnWidths;
104-
});
108+
}
109+
110+
setTemporaryMeasuredColumnWidths(newMeasuredColumnWidths);
105111
}
106112

107113
setColumnToAutoResize({
@@ -110,6 +116,8 @@ export function useColumnWidths<R, SR>(
110116
});
111117
});
112118

119+
setTemporaryMeasuredColumnWidths(null);
120+
113121
if (onColumnResize) {
114122
const previousWidth = resizedColumnWidths.get(resizingKey);
115123
const newWidth =

website/routes/CommonFeatures.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ function CommonFeatures() {
323323
const [isExporting, setIsExporting] = useState(false);
324324
const gridRef = useRef<DataGridHandle>(null);
325325
const columns = useMemo(() => getColumns(countries, direction), [direction]);
326+
const [columnWidths, setColumnWidths] = useState(
327+
(): ReadonlyMap<string, number> => new Map<string, number>()
328+
);
326329

327330
const summaryRows = useMemo((): readonly SummaryRow[] => {
328331
return [
@@ -382,6 +385,9 @@ function CommonFeatures() {
382385
<button type="button" onClick={handleExportToPdf}>
383386
Export to PDF
384387
</button>
388+
<button type="button" onClick={() => setColumnWidths(new Map())}>
389+
Reset Width
390+
</button>
385391
</div>
386392
<DataGrid
387393
ref={gridRef}
@@ -402,6 +408,8 @@ function CommonFeatures() {
402408
className="fill-grid"
403409
direction={direction}
404410
enableVirtualization={!isExporting}
411+
columnWidths={columnWidths}
412+
onColumnWidthsChange={setColumnWidths}
405413
/>
406414
</>
407415
);

0 commit comments

Comments
 (0)