-
Notifications
You must be signed in to change notification settings - Fork 1.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
feat: Add colspan to Table #7638
base: main
Are you sure you want to change the base?
Conversation
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 the PR! Had a quick look, it looks like the right direction to go, I'll bring it up with the team later this week.
Some notes for the team:
Looks like VO support isn't great for colspans, announcement is only "x of n" where "n" is less than overall number of columns. It doesn't mention anything about how many columns it covers or what the title/owning column is. I tested it against the MDN docs as well, appears to be the same, so this may be expected. It behaves the same with the virtualized RSP table as well.
We'll need to do more testing with the other screen readers.
@oyvinmar I've recently worked a lot on the grid edit mode, so I'm hoping to be able to be of help with some of your questions.
Usually The value of this gets automatically populated on the first render, when the collection is built. That is also why you don't see most of the cell props inside of the
Via the before-mentioned pattern you can trivially check for the existence of a specific prop, since only then it will exist in the prop object of the node item. This is also not a DOM operation so no worries on that front.
Afaik, the EDIT: Saw that @snowystinger also provided feedback on VO support for this already, so I'm sure the core maintainers will get back to you shortly with more specific guidance. Thanks again for the PR 👍 |
Thanks for the fast feedback! I've changed to setting the grid node attributes in the collections and only include aria-col-index when the row has a colSpan cell (and when virtualized). |
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 briefly discussed this today. Again, thank you so much for contributing this feature. It looks like this is the correct direction. Adding tests is a good next step while we review the code.
One thing we'd like to add in the logic is some validation:
num cols === sum of col spans
and throw if this isn't true
Will this also add support for |
column group support will have to come later, we don't have an API for it yet and I'd prefer not to add more to this pr colspan is only added on |
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.
In general this looks awesome, I only have a few comments. Thanks for adding tests and doing the React Spectrum implementation.
Question to team: Should we track column keys for repetitive arrow key up/down so that you stay in the same column until you intentionally change columns?
Go to /?path=/story/tableview--table-cell-col-span-with-various-spans-example, press Tab, ArrowRight, then ArrowDown x3, you'll have focus on the cell in Col1 instead of Col2.
@@ -251,6 +253,8 @@ export function useGridCell<T, C extends GridCollection<T>>(props: GridCellProps | |||
let gridCellProps: DOMAttributes = mergeProps(itemProps, { | |||
role: 'gridcell', | |||
onKeyDownCapture, | |||
'aria-colspan': node.colspan, |
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.
can colspan
match the capitalisation of the GridCellProps' colSpan
?
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.
It should be a fairly straightforward to change, but I think it would introduce a breaking change in table header (useTableColumnHeader
): https://react-spectrum.adobe.com/react-aria/useTable.html#table-header
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.
Ah, then probably we should go the other direction to match.
@@ -1213,6 +1257,7 @@ export const Cell = /*#__PURE__*/ createLeafComponent('cell', (props: CellProps, | |||
<TD | |||
{...mergeProps(filterDOMProps(props as any), gridCellProps, focusProps, hoverProps)} | |||
{...renderProps} | |||
colSpan={cell.colspan} |
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.
it looks like in our table hooks we check for isVirtualized
as a proxy for the elementType at the moment. let's move this down into the useGridCell hook
we may expand the support to actually checking elementType later and i'd prefer that all the logic is together
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 you mean something like adding something like this: colSpan: isVirtualized? undefined: node.colspan,
? One potential issue I see with that is that it might be semantically wrong if you add virtualization to a RAC implementation. But that might be an edge case, and you would still have the aria-colspan attribute.
if (child.type === 'cell' && rowHasCellWithColSpan) { | ||
child.colspan = child.props?.colSpan; | ||
child.colIndex = !last ? child.index : (last.colIndex ?? last.index) + (last.colspan ?? 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.
we have access to column count here, we should do the same check as we're doing in RAC, otherwise this is the message in React Spectrum
Uncaught TypeError: Cannot read properties of undefined (reading 'props')
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.
Yes, I tried adding it there but got a lot of failing tests before I figured out I needed to check that node is of item
type 😅 .
I've added it now.
@@ -90,10 +90,6 @@ Row.getCollectionNode = function* getCollectionNode<T>(props: RowProps<T>, conte | |||
} | |||
}); | |||
|
|||
if (cells.length !== context.columns.length) { |
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.
that or we can check here again
It's really great that this has been implemented, thank you very much! We are looking forward to start using this as soon as possible. |
Closes #5334, closes #5862
This change adds support for colSpan to the table. The changes can be reviewed commit by commit. The first commit adds
colSpan
support; the second addsaria-col-index
, which makes keyboard navigation slightly simpler but adds some complexity to updating the cells with the correct column index.Some implementation details/concerns/questions:
I'm unsure if this is the best way to update the grid nodes with the attributes. If there's a better way, please let me know.aria-col-index
is added to every cell, even in rows wherecolspan
isn't used. I could probably look this up before adding it, but I'm worried that could be an expensive operation.✅ Pull Request Checklist:
📝 Test Instructions:
I've provided Storybook examples, which I have used to test the changes. They should be findable by searching for «colspan».
🧢 Your Project:
We are evaluating react-aria-components for a new implementation of a table provided by our internal design system.