Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recompute column widths when the number of columns changes #3392

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions src/hooks/useColumnWidths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,24 @@ export function useColumnWidths<R, SR>(
onColumnResize: DataGridProps<R, SR>['onColumnResize']
) {
const prevGridWidthRef = useRef(gridWidth);
const prevNbOfColumns = useRef(columns.length);

const columnsCanFlex: boolean = columns.length === viewportColumns.length;

const nbOfColumnsChanged = columns.length !== prevNbOfColumns.current;
// Allow columns to flex again when...
const ignorePreviouslyMeasuredColumns: boolean =
// there is enough space for columns to flex and the grid was resized
columnsCanFlex && gridWidth !== prevGridWidthRef.current;
// there is enough space for columns to flex and the grid was resized or
// the nb of columns changed
columnsCanFlex && (gridWidth !== prevGridWidthRef.current || nbOfColumnsChanged);
const newTemplateColumns = [...templateColumns];
const columnsToMeasure: string[] = [];

for (const { key, idx, width } of viewportColumns) {
const previousMeasureIsRelevant = measuredColumnWidths.has(key) && !nbOfColumnsChanged;
if (
typeof width === 'string' &&
(ignorePreviouslyMeasuredColumns || !measuredColumnWidths.has(key)) &&
(ignorePreviouslyMeasuredColumns || !previousMeasureIsRelevant) &&
!resizedColumnWidths.has(key)
) {
newTemplateColumns[idx] = width;
Expand Down
3 changes: 3 additions & 0 deletions website/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ export default function Nav({ direction, onDirectionChange }: Props) {
<NavLink to="/resizable-grid" end className={getActiveClassname}>
Resizable Grid
</NavLink>
<NavLink to="/add-remove-columns" end className={getActiveClassname}>
Add or Remove Columns
</NavLink>
<NavLink to="/rows-reordering" end className={getActiveClassname}>
Rows Reordering
</NavLink>
Expand Down
63 changes: 63 additions & 0 deletions website/demos/AddOrRemoveColumns.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useMemo, useState } from 'react';

import type { Column } from '../../src';
import DataGrid from '../../src';
import type { Props } from './types';

interface Row {
label: string;
first: number;
second: number;
third: number;
fourth: number;
fifth: number;
}

const allColumns: Column<Row>[] = ['Label', 'First', 'Second', 'Third', 'Fourth', 'Fifth'].map(
(x) => ({ key: x.toLowerCase(), name: x })
);

const rows: Row[] = Array.from({ length: 8 }, (_, i) => ({
label: `Attribute #${i + 1}`,
first: 0.5 + Math.random() * 2,
second: 0.5 + Math.random() * 2,
third: 0.5 + Math.random() * 2,
fourth: 0.5 + Math.random() * 2,
fifth: 0.5 + Math.random() * 2
}));

export default function AddOrRemoveColumns({ direction }: Props) {
const [nbCols, setNbCols] = useState(4);
const columns = useMemo(() => allColumns.slice(0, nbCols), [nbCols]);

return (
<>
<div style={{ width: '300px', marginBlock: "1rem" }}>
<label htmlFor="nbcols">Choose the number of columns:</label>
<br />
<input
type="range"
id="nbcols"
list="markers"
min="1"
max="5"
step="2"
onChange={(e) => setNbCols(parseInt(e.target.value, 10))}
/>

<datalist id="markers">
<option value="1" />
<option value="3" />
<option value="5" />
</datalist>
</div>

<DataGrid
columns={columns}
rows={rows}
style={{ resize: 'both', width: '800px', height: '3OOpx' }}
direction={direction}
/>
</>
);
}
2 changes: 2 additions & 0 deletions website/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import ScrollToCell from './demos/ScrollToCell';
import TreeView from './demos/TreeView';
import VariableRowHeight from './demos/VariableRowHeight';
import Nav from './Nav';
import AddOrRemoveColumns from './demos/AddOrRemoveColumns';

const mainClassname = css`
display: flex;
Expand Down Expand Up @@ -63,6 +64,7 @@ function Root() {
<Route path="million-cells" element={<MillionCells direction={direction} />} />
<Route path="no-rows" element={<NoRows direction={direction} />} />
<Route path="resizable-grid" element={<ResizableGrid direction={direction} />} />
<Route path="add-remove-columns" element={<AddOrRemoveColumns direction={direction} />} />
<Route path="rows-reordering" element={<RowsReordering direction={direction} />} />
<Route path="scroll-to-cell" element={<ScrollToCell direction={direction} />} />
<Route path="tree-view" element={<TreeView direction={direction} />} />
Expand Down