Skip to content

Commit b5de11b

Browse files
authored
Use grid layout for rows, split column metrics from compute columns (adazzle#2272)
* Use grid layout for rows * Fix getCellStyle type * Split column and column metrics * sticky -> left * Allow decimals in column widths, also fix resiverobserver handling in Firefox * move onEditorNavigation to keyboardUtils * -width
1 parent a543cc9 commit b5de11b

17 files changed

+153
-156
lines changed

src/Cell.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { forwardRef, memo, useRef } from 'react';
22
import clsx from 'clsx';
33

44
import type { CellRendererProps } from './types';
5-
import { wrapEvent } from './utils';
5+
import { getCellStyle, wrapEvent } from './utils';
66
import { useCombinedRefs } from './hooks';
77

88
function Cell<R, SR>({
@@ -72,10 +72,7 @@ function Cell<R, SR>({
7272
aria-selected={isCellSelected}
7373
ref={useCombinedRefs(cellRef, ref)}
7474
className={className}
75-
style={{
76-
width: column.width,
77-
left: column.left
78-
}}
75+
style={getCellStyle(column)}
7976
onClick={wrapEvent(handleClick, onClick)}
8077
onDoubleClick={wrapEvent(handleDoubleClick, onDoubleClick)}
8178
onContextMenu={wrapEvent(handleContextMenu, onContextMenu)}

src/DataGrid.tsx

+9-8
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import GroupRowRenderer from './GroupRow';
1616
import SummaryRow from './SummaryRow';
1717
import {
1818
assertIsValidKeyGetter,
19-
getColumnScrollPosition,
2019
onEditorNavigation,
2120
getNextSelectedCellPosition,
2221
isSelectedCellEditable,
@@ -248,7 +247,7 @@ function DataGrid<R, SR>({
248247
const clientHeight = gridHeight - totalHeaderHeight - summaryRowsCount * rowHeight;
249248
const isSelectable = selectedRows !== undefined && onSelectedRowsChange !== undefined;
250249

251-
const { columns, viewportColumns, totalColumnWidth, lastFrozenColumnIndex, totalFrozenColumnWidth, groupBy } = useViewportColumns({
250+
const { columns, viewportColumns, layoutCssVars, columnMetrics, totalColumnWidth, lastFrozenColumnIndex, totalFrozenColumnWidth, groupBy } = useViewportColumns({
252251
rawColumns,
253252
columnWidths,
254253
scrollLeft,
@@ -637,12 +636,13 @@ function DataGrid<R, SR>({
637636

638637
if (typeof idx === 'number' && idx > lastFrozenColumnIndex) {
639638
const { clientWidth } = current;
640-
const { left, width } = columns[idx];
641-
const isCellAtLeftBoundary = left < scrollLeft + width + totalFrozenColumnWidth;
639+
const { left, width } = columnMetrics.get(columns[idx])!;
640+
const isCellAtLeftBoundary = left < scrollLeft + totalFrozenColumnWidth;
642641
const isCellAtRightBoundary = left + width > clientWidth + scrollLeft;
643-
if (isCellAtLeftBoundary || isCellAtRightBoundary) {
644-
const newScrollLeft = getColumnScrollPosition(columns, idx, scrollLeft, clientWidth);
645-
current.scrollLeft = scrollLeft + newScrollLeft;
642+
if (isCellAtLeftBoundary) {
643+
current.scrollLeft = left - totalFrozenColumnWidth;
644+
} else if (isCellAtRightBoundary) {
645+
current.scrollLeft = left + width - clientWidth;
646646
}
647647
}
648648

@@ -884,7 +884,8 @@ function DataGrid<R, SR>({
884884
'--header-row-height': `${headerRowHeight}px`,
885885
'--filter-row-height': `${headerFiltersHeight}px`,
886886
'--row-width': `${totalColumnWidth}px`,
887-
'--row-height': `${rowHeight}px`
887+
'--row-height': `${rowHeight}px`,
888+
...layoutCssVars
888889
} as unknown as React.CSSProperties}
889890
ref={gridRef}
890891
onScroll={handleScroll}

src/EditCell.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useState, useCallback } from 'react';
22
import clsx from 'clsx';
33

44
import EditorContainer from './editors/EditorContainer';
5+
import { getCellStyle } from './utils';
56
import type { CellRendererProps, SharedEditorProps, Omit } from './types';
67

78
type SharedCellRendererProps<R, SR> = Pick<CellRendererProps<R, SR>,
@@ -69,10 +70,7 @@ export default function EditCell<R, SR>({
6970
aria-selected
7071
ref={cellRef}
7172
className={className}
72-
style={{
73-
width: column.width,
74-
left: column.left
75-
}}
73+
style={getCellStyle(column)}
7674
{...props}
7775
>
7876
{getCellContent()}

src/FilterRow.tsx

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { memo } from 'react';
22
import clsx from 'clsx';
33

4+
import { getCellStyle } from './utils';
45
import type { CalculatedColumn, Filters } from './types';
56
import type { DataGridProps } from './DataGrid';
67

@@ -32,21 +33,16 @@ function FilterRow<R, SR>({
3233
>
3334
{columns.map(column => {
3435
const { key } = column;
35-
3636
const className = clsx('rdg-cell', {
3737
'rdg-cell-frozen': column.frozen,
3838
'rdg-cell-frozen-last': column.isLastFrozenColumn
3939
});
40-
const style: React.CSSProperties = {
41-
width: column.width,
42-
left: column.left
43-
};
4440

4541
return (
4642
<div
4743
key={key}
48-
style={style}
4944
className={className}
45+
style={getCellStyle(column)}
5046
>
5147
{column.filterRenderer && (
5248
<column.filterRenderer

src/GroupCell.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { memo } from 'react';
22
import clsx from 'clsx';
33

4+
import { getCellStyle } from './utils';
45
import type { CalculatedColumn } from './types';
56
import type { GroupRowRendererProps } from './GroupRow';
67

@@ -56,8 +57,7 @@ function GroupCell<R, SR>({
5657
'rdg-cell-selected': isCellSelected
5758
})}
5859
style={{
59-
width: column.width,
60-
left: column.left,
60+
...getCellStyle(column),
6161
cursor: isLevelMatching ? 'pointer' : 'default'
6262
}}
6363
onClick={isLevelMatching ? toggleGroup : undefined}

src/HeaderCell.tsx

+2-5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import clsx from 'clsx';
33
import type { CalculatedColumn } from './types';
44
import type { HeaderRowProps } from './HeaderRow';
55
import SortableHeaderCell from './headerCells/SortableHeaderCell';
6+
import { getCellStyle } from './utils';
67
import type { SortDirection } from './enums';
78

89
function getAriaSort(sortDirection?: SortDirection) {
@@ -109,18 +110,14 @@ export default function HeaderCell<R, SR>({
109110
'rdg-cell-frozen': column.frozen,
110111
'rdg-cell-frozen-last': column.isLastFrozenColumn
111112
});
112-
const style: React.CSSProperties = {
113-
width: column.width,
114-
left: column.left
115-
};
116113

117114
return (
118115
<div
119116
role="columnheader"
120117
aria-colindex={column.idx + 1}
121118
aria-sort={sortColumn === column.key ? getAriaSort(sortDirection) : undefined}
122119
className={className}
123-
style={style}
120+
style={getCellStyle(column)}
124121
onPointerDown={column.resizable ? onPointerDown : undefined}
125122
>
126123
{getCell()}

src/SummaryCell.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { memo } from 'react';
22
import clsx from 'clsx';
33

4+
import { getCellStyle } from './utils';
45
import type { CellRendererProps } from './types';
56

67
type SharedCellRendererProps<R, SR> = Pick<CellRendererProps<R, SR>, 'column'>;
@@ -13,7 +14,7 @@ function SummaryCell<R, SR>({
1314
column,
1415
row
1516
}: SummaryCellProps<R, SR>) {
16-
const { summaryFormatter: SummaryFormatter, width, left, summaryCellClass } = column;
17+
const { summaryFormatter: SummaryFormatter, summaryCellClass } = column;
1718
const className = clsx(
1819
'rdg-cell',
1920
{
@@ -28,7 +29,7 @@ function SummaryCell<R, SR>({
2829
role="gridcell"
2930
aria-colindex={column.idx + 1}
3031
className={className}
31-
style={{ width, left }}
32+
style={getCellStyle(column)}
3233
>
3334
{SummaryFormatter && <SummaryFormatter column={column} row={row} />}
3435
</div>

src/hooks/useGridDimensions.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ export function useGridDimensions(): [React.RefObject<HTMLDivElement>, number, n
2424
// don't break in jest/jsdom and browsers that don't support ResizeObserver
2525
if (ResizeObserver == null) return;
2626

27-
const resizeObserver = new ResizeObserver(entries => {
28-
const { width, height } = entries[0].contentRect;
29-
setGridWidth(width);
30-
setGridHeight(height);
27+
const resizeObserver = new ResizeObserver(() => {
28+
// Get dimensions without scrollbars.
29+
// The dimensions given by the callback entries in Firefox do not substract the scrollbar sizes.
30+
const { clientWidth, clientHeight } = gridRef.current!;
31+
setGridWidth(clientWidth);
32+
setGridHeight(clientHeight);
3133
});
3234

3335
resizeObserver.observe(gridRef.current!);

0 commit comments

Comments
 (0)