-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Use grid layout for rows, split column metrics from compute columns #2272
Conversation
column.frozen = true; | ||
column.rowGroup = true; | ||
} | ||
const columns = rawColumns.map(rawColumn => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We only create 1 columns array now in this useMemo
from 2 arrays before.
We also create the column object once, no more intermediary column object.
|
||
if (column.rowGroup) { | ||
groupBy.push(column.key); | ||
column.groupFormatter ??= ToggleGroupFormatter; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Browsers already support this syntax, and babel transpiles it. 👍
https://caniuse.com/mdn-javascript_operators_logical_nullish_assignment
Bonus point: it doesn't re-assign the value if it already exists.
https://v8.dev/blog/v8-release-85#logical-assignment-operators
}; | ||
}, [rawColumns, defaultFormatter, defaultResizable, defaultSortable, rawGroupBy]); | ||
|
||
const { layoutCssVars, totalColumnWidth, totalFrozenColumnWidth, columnMetrics } = useMemo(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now compute column metrics in a separate useMemo
, and store it in a separate Map
.
That way we can, for example, resize columns without re-creating the column objects, and reducing re-renders.
totalColumnWidth: totalWidth, | ||
groupBy | ||
const layoutCssVars: Record<string, string> = { | ||
'--template-columns': templateColumns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used for the grid-template-columns
css property in all rows now.
That way we set the template on the root, and we don't have to update all rows/cells (in js).
|
||
for (let i = 0; i <= lastFrozenColumnIndex; i++) { | ||
const column = columns[i]; | ||
layoutCssVars[`--frozen-left-${column.key}`] = `${columnMetrics.get(column)!.left}px`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The frozen columns still need to know their left
position otherwise position: sticky
won't work.
@@ -1,37 +1,3 @@ | |||
import type { CalculatedColumn } from '../types'; | |||
|
|||
export function getColumnScrollPosition<R, SR>(columns: readonly CalculatedColumn<R, SR>[], idx: number, currentScrollLeft: number, currentClientWidth: number): number { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This did way too much unnecessary work.
export function getCellStyle<R, SR>(column: CalculatedColumn<R, SR>): React.CSSProperties { | ||
return column.frozen | ||
? { left: `var(--frozen-left-${column.key})` } | ||
: { gridColumnStart: column.idx + 1 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This "picks" the correct grid column from the grid-template-columns
, regardless of its DOM position.
@@ -1,8 +1,6 @@ | |||
.rdg-cell { | |||
contain: strict; | |||
contain: size layout style paint; | |||
position: absolute; | |||
height: inherit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Height is set by the grid layout now.
@@ -1,11 +1,13 @@ | |||
.rdg-row { | |||
contain: strict; | |||
contain: size layout style paint; | |||
display: flex; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We know that flex+sticky position cells can be buggy in Firefox, but I wonder if grid+sticky works fine or not.
@@ -1,11 +1,13 @@ | |||
.rdg-row { | |||
contain: strict; | |||
contain: size layout style paint; | |||
display: flex; | |||
display: grid; | |||
grid-template-rows: var(--row-height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This basically means that we only have 1 row in this grid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall
src/hooks/useViewportColumns.ts
Outdated
} | ||
} | ||
|
||
const unallocatedWidth = viewportWidth - allocatedWidth; | ||
const unallocatedColumnWidth = Math.max( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to use Math.max
if we are using clampColumnWidth
later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't, I've removed it now, we also don't need to floor
it, now columns will always fill all the available space when possible.
For a before/after comparison, open the columns reordering story, and resize the browser, you'll see that with Math.floor()
there can be some space between the last column and the scrollbar.
@@ -58,15 +58,19 @@ export interface Column<TRow, TSummaryRow = unknown> { | |||
|
|||
export interface CalculatedColumn<TRow, TSummaryRow = unknown> extends Column<TRow, TSummaryRow> { | |||
idx: number; | |||
width: number; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if any formatter/editor uses width/left or not. What is the alternative if those values are needed? ref?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could pass them in editorProps
if it's ever needed.
What's the fun in making a grid component if you don't use
display: grid;
?