-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
fix(DataTable): align items top on text wrapping #13525
fix(DataTable): align items top on text wrapping #13525
Conversation
✅ Deploy Preview for carbon-components-react ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site settings. |
✅ Deploy Preview for carbon-elements ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
I haven't dug into the code yet, but should we hide this functionality behind a prop? it visually changes things, so technically adding this in now could be classified as breaking. Thoughts @francinelucca @tay1orjones |
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
@alisonjoseph We did the feature flag for the new disabled styling for Tile because it was changes to styling of existing selectors. In this case it's all behind a new classname. Yes in theory there could still be conflicts with downstream consumers' styling but I think the surface area of this is relatively minimal and doesn't warrant a feature flag. We can always add a feature flag in the future if we receive feedback of it causing unintended consequences downstream. |
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.
Kudos for diving into this, it's complicated and difficult to figure out something that works! I'm a bit concerned about the reliability of measuring with canvas and the performance hit of measuring each cell.
If this method proves to be reliable and performant though, I could see it being useful in other situations where we need to intelligently test for truncation when we can't rely on text-overflow: ellipsis
. What do you think about moving the measurement logic to a reusable useTextMeasurement
hook?
// something like this maybe?
const hasOverflow = useTextMeasurement(myRef);
const isMultiline = Array.from( | ||
tableRef.current.querySelectorAll('td') | ||
).some((td) => { |
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.
Iterating over every table cell on every render seems really expensive. Do you think this will be performant enough to use on tables with large datasets that don't use pagination? Might be worth testing to assess the usability impact.
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.
yeah I agree it's not the most elegant code out there 😅. I couldn't figure out any other way to do it though, any one cell could be wrapping content, so we need to check all of them - or stop when we find one that is wrapping, which I'm doing but if none of them are wrapping then yeah, it'll run through all-.
I can add a large datatable to test, how many rows/columns are you thinking will be a good enough test?
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.
1000+ rows is where we've seen other performance issues #4338
If we're not 100% confident in the performance, we could consider putting the behavior behind a an experimental prop so users can opt into it rather than it be on by default. Document that it has performance implications, etc
} | ||
}, [prefix]); | ||
|
||
useEvent(window, 'resize', setTableAlignment); |
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.
Similar concern here with performance, iterating over every table cell for every resize event could really impact usability if the updates are blocking. I don't think useEvent
debounces or throttles the events either.
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
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.
Thanks for providing those testing stories! The 10000 cells example looks pretty rough
Would it be more applicable for this code to live within TableCell or TableRow and be inside a useLayoutEffect
instead of useEffect
? I wonder if that would break this work up into multiple tasks instead of one long running one. I also wonder if react might then be able to assist in yielding to the main thread since each task is contained within a multiple components instead of in the Table
.
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
@laurenmrice this should be ready for re-review, pending header wrapping confirmation |
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 looks great! pending design approval 😄
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
This should be ready for re-rev @laurenmrice |
@alisonjoseph @tay1orjones re-requesting revs 'cause I added a decent amount of code to handle TableHeaders independently of the body 😬 |
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.
Expansion story
- When I am on the
Xs
size, without text wrapping to multiple lines in rows, I notice the focus around the chevron icon is the correct size (32 x24), but when the text starts wrapping to multiple lines in rows, the focus box becomes larger in size. The focus box should always remain the same size (32 x 24) in both cases so that the chevron is in the center of the focus box.
- This also happens with the
Lg
size, but it's at first showing a very small focus box around the chevron icons when text lines do not wrap in rows, but once the text does start to wrap, the focus box is the correct size (32 x 32). It should always be 32 x 32 for both cases.
With Overflow Menu story
- Looks like there is some added padding to rows in the LG size than the XL size.
…610-bug-data-table-content-inside-cells-should-top-align-when-with-text-wrap-in-some-cells
…ould-top-align-when-with-text-wrap-in-some-cells
This should be good for re-rev @laurenmrice 🙏🏻 |
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 good to me! ✅
re-requested
…ould-top-align-when-with-text-wrap-in-some-cells
Hey there! v11.31.0 was just released that references this issue/PR. |
Closes #12610
Programmatically determine if a
Table
has a cell that is wrapping text content inside of it, if so apply a newcds--data-table--top-aligned
class that will make the table align items top.My approach here is for any given table cell, measure the textWidth inside a canvas when it is not being wrapped and compare it to the cell's width, if the rendered text is wider than the cell then the text is being wrapped. This was the only way I found to do this, definitely open to suggestion on a better implementation.
Shoutout @guidari for pairing up with me on this 🚀
Changelog
Changed
setTableAlignment
function inTable
component on first render and on resize to determine wether table should be top aligned.Table
css to align items top and appropriate padding when necessarylg
size inTable
Testing / Reviewing
https://deploy-preview-13525--carbon-components-react.netlify.app/?path=/story/components-datatable-basic--default
Playground
storyexperimentalAutoAlign
control onexperimentalAutoAlign
control off and confirm items do not align to the top when text is wrappingSizes:
xs
,sm
,md
,lg
,xl
Variations: