-
Notifications
You must be signed in to change notification settings - Fork 843
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
[EuiDataGrid] Refactor row height calculations to no longer need computed styles on grid init #5284
Conversation
Preview documentation changes for this PR: https://eui.elastic.co/pr_5284/ |
Looks like this change breaks the Setting a default height and line height for rows example. I think this is a race condition in FF+Safari between the css stylesheets being added to the document and this test. Navigating to the auto-height example appears to always work, and when I added
to test with, FF will hit the debugger on a hard refresh, but by the time I can debug the |
Doh, I was wondering what was going on there (but thought it was some weirdness with my computer 🙈) Race condition makes a ton of sense. Is there any way to wait to run this code until after stylesheets have loaded? |
Or alternatively, can we avoid using CSS for the padding calculations? For example, if we know the grid density, can we just hard code a map of padding heights (which we could later obtain from our CSS-in-JS work)? |
7c440a0
to
3e833d3
Compare
The static map works really well, except unfortunately for I have an idea for that issue that I'd like to pitch: when setting Alternatively, if we don't anticipate DataGrid being used in the legacy theme, or if we're deprecating the legacy theme soon, we could just leave this as-is?... |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5284/ |
- lineCount in elastic#5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again
If converting this PR to have Edit: I ended up exploring this but had to find a different solution as CSS |
- lineCount in elastic#5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again
…to` (#5281) * Remove isHeightSame check * Remove same height check from shouldComponentUpdate - if we're not checking for sameHeight in componentDidUpdate, we also likely don't need this anymore, and all dynamic user changes appear to work without this code * [Proposed refactors] - Rename `recalculateRowHeight` to `setAutoRowHeight` - DRY out setAutoRowHeight to be reusable by both the resize observer and during props update (NB: This leads to some repetition with the height being obtained twice, but will not be an issue shortly as I'll be refactoring/removing the cell wrapper observer in a future PR) - Refactor rowHeightUtils.isAutoHeight to accept an undefined rowHeightsOptions * Improve unit tests * Add changelog entry * [PR feedback] Fix `isAutoHeight` false positive - occurs if the `defaultHeight` is auto but a specific `rowHeights` line override is not auto TODO: Write a unit test for this in the future * [PR feedback/Discover testing] Trigger component update when rowHeightsOptions changes * [cleanup] Remove now-unused compareHeights util + clean up mock rowHeightUtils as well * [revert] rename setAutoRowHeight back to recalculateRowHeight - lineCount in #5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again * Add enqueue/timeout to recalculateRowHeight updates - to avoid race conditions with cache being cleared * Remove clearHeightsCache completely * Unset row+column height values on unmount (#3) * Add unit test for new unsetRowHeight + add optional isAutoHeight check * Remove hidden columns from row height cache * Early return in getRowHeight Co-authored-by: Chandler Prall <[email protected]>
c359430
to
8cbe865
Compare
…to` (elastic#5281) * Remove isHeightSame check * Remove same height check from shouldComponentUpdate - if we're not checking for sameHeight in componentDidUpdate, we also likely don't need this anymore, and all dynamic user changes appear to work without this code * [Proposed refactors] - Rename `recalculateRowHeight` to `setAutoRowHeight` - DRY out setAutoRowHeight to be reusable by both the resize observer and during props update (NB: This leads to some repetition with the height being obtained twice, but will not be an issue shortly as I'll be refactoring/removing the cell wrapper observer in a future PR) - Refactor rowHeightUtils.isAutoHeight to accept an undefined rowHeightsOptions * Improve unit tests * Add changelog entry * [PR feedback] Fix `isAutoHeight` false positive - occurs if the `defaultHeight` is auto but a specific `rowHeights` line override is not auto TODO: Write a unit test for this in the future * [PR feedback/Discover testing] Trigger component update when rowHeightsOptions changes * [cleanup] Remove now-unused compareHeights util + clean up mock rowHeightUtils as well * [revert] rename setAutoRowHeight back to recalculateRowHeight - lineCount in elastic#5284 will shortly be using the row height cache in addition to auto, so I'm making the fn name less specific again * Add enqueue/timeout to recalculateRowHeight updates - to avoid race conditions with cache being cleared * Remove clearHeightsCache completely * Unset row+column height values on unmount (elastic#3) * Add unit test for new unsetRowHeight + add optional isAutoHeight check * Remove hidden columns from row height cache * Early return in getRowHeight Co-authored-by: Chandler Prall <[email protected]>
NB: Saving this commit for historical purposes; but the issue with this solution is that lineHeight & fontSize change between legacy and Amsterdam theme and thus the calculations are wrong on the legacy theme - Switch to static padding/fontSize/lineHeights maps instead of classes - Undefined line height will NaN without euiDataGridRow CSS - Remove this.fakeCell class instance since it's only used in one place
- Export single default/initial row height const which data_grid_body imports, instead of declaring 2 slightly different heights in 2 different locations - fix rowIndex check that would fail on a rowIndex of 0
…nto a getRowHeightOption helper - this helper DRYs out returning either a specific row's height config or the defaultHeight - we had this logic essentially repeated in multiple places
2655093
to
2d9edf4
Compare
- Pull out shared/same props into a single obj instead of repeating it 3x & making it less clear which props are different depending on the cell type - remove getRowHeight fn from being passed down; it's not being used - pass setRowHeight only to first column as a performance optimization; this will be used for lineCount heights and since lineCount heights are all the same, we really only need to run it once - clean up footer row cells as well while we're here
…_grid_body - IIRC this is what the state was originally used for; might as well go back to using it for lineCount
- Those were only being used for lineCount calculations; otherwise only padding is needed + remove numberFromPx in favor of a map with existing numbers
…les & remove getComputedCellStyles - re: getComputedCellStyles - I'm not seeing this affect either numeric, lineCount, or auto heights when changing grid density, hence me removing this
Now that we aren't using this CSS for computed styles any longer, we can remove them
- we're exclusively watching the cell content now for both auto and line count heights
- to make it more specific and clearer from the fn name what row height behavior this belongs to
- add unit tests for recalculateLineCountHeight, - mockRowHeightUtils - allow some generic methods to return their actual fns for expedience - Remove jest.mock from data_grid.test.tsx - the __mocks__ folder automatically mocks it - update snapshots/returns accordingly
2d9edf4
to
e4a77cf
Compare
jenkins test this |
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 PR ended up being a whole lot of cleanup mixed in with the actual functionality fixes 🙈 I recommend following along by commit (the cleanups in particular I tried to separate out into their own commits), but I'll also attempt to walk through the actual functionality changes/fixes below!
// TODO: Once JS variables are available, use them here instead of hard-coded maps | ||
const cellPaddingsMap: Record<EuiDataGridStyleCellPaddings, number> = { | ||
s: 4, | ||
m: 6, | ||
l: 8, | ||
}; |
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.
calculateHeightForLineCount(cellRef: HTMLElement, lineCount: number) { | ||
const computedStyles = window.getComputedStyle(cellRef, null); | ||
const lineHeight = parseInt(computedStyles.lineHeight, 10) || 24; | ||
|
||
return Math.ceil( | ||
lineCount * this.styles.lineHeight + | ||
lineCount * lineHeight + | ||
this.styles.paddingTop + | ||
this.styles.paddingBottom | ||
); |
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 change here (getting the computed line-height from the cell rather than on grid init) is what makes the lineCount
height calculation work as before. In particular, the key to solving the 'styles not available on load' bug is that calculateHeightForLineCount
gets called by the cell content resizeObserver, which means that if styles load after grid init, the resizeObserver fires and row height will get calculated & updated after. This also applies to/works for density changes!
The full commit is here for reference: 905031a
Here's an example of this working locally on a demo with a lineCount: 10
:
lineCount.mp4
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 should also mention the way lineCount
cells now get and set their height also is from the minRowHeight
/setRowHeights
state set in data_grid_body.tsx
:
const [minRowHeight, setRowHeight] = useState(DEFAULT_ROW_HEIGHT); |
I believe this was also originally the way it worked previously on datagrid's first inception, so what's old becomes new, etc. 😅 (but I was able to clean up the cell wrapper observer so we're now down to just 1 observer!)
This comment has been minimized.
This comment has been minimized.
Preview documentation changes for this PR: https://eui.elastic.co/pr_5284/ |
FYI, once this PR lands, I have a follow-up PR for right after it that does some minor organization/clean up of |
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.
Changes LGreatTM! Lots of good refactoring into more followable code paths, couple extra bug fixes, solves the loading issue, etc. 🎉
Tested the published changes across Chrome, Firefox, and Safari, saw no issues with intermittent loading, flash of content or styles, virtualization, or performance.
Wahoo, thanks Chandler! 🎉 |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5284/ |
Preview documentation changes for this PR: https://eui.elastic.co/pr_5284/ |
Summary
This PR ended up being a more difficult problem to solve than anticipated, and took several twists and turns - see this comment for the most recent description
Checklist
- [ ] Check against all themes for compatibility in both light and dark modes- [ ] Checked in mobile- [ ] Props have proper autodocs and playground toggles- [ ] Added documentation- [ ] Checked Code Sandbox works for any docs examples- [ ] Added or updated jest and cypress testsNB: Jest tests have yet to be written for row_height_utils, but it's on my radar- [ ] Checked for breaking changes and labeled appropriately- [ ] Checked for accessibility including keyboard-only and screenreader modes