feat: #10121 Implemented the Table Column Header Focus - #10369
Conversation
snowystinger
left a comment
There was a problem hiding this comment.
Thanks, this looks pretty good. Will bring it to the team and see how we feel about the prop/name etc
|
Thanks @snowystinger, I'll wait for the team feedback |
|
@LFDanLu Thanks for the feedback. I have removed the prop and moved those tests into RAC. |
|
@snowystinger Cleaned up the code and made the suggested changes |
| } else { | ||
| // If on the root, go to the item a page below the top. Otherwise a page below the current item. | ||
| let targetKey = keyboardDelegate.getFirstKey?.(); | ||
| let targetKey = getFirstItemKey(keyboardDelegate, localState.state.collection); |
There was a problem hiding this comment.
This is starting to worry me that we're making a breaking change
There was a problem hiding this comment.
Thanks for the feedback. I looked into both points a bit more
I agree that we should avoid a breaking change! The reason I added getFirstItemKey is to make the DnD code use an actual item key. DnD expects drop target to be either item or root, so the column header returned by getFirstKey() shouldn't be passed to it, and this helper function will skip non-item nodes and find the first valid item instead.
So this supports columnheader as the initial focus for Tables without changing the shared APIs or passing an invalid key into the DnD logic.
There was a problem hiding this comment.
Right, but the fact that this helper is needed means that we broke an assumption on how the function worked. So even though we didn't break the api contract, there was an implicit requirement. And it's one that typescript has trouble representing, so hard to see.
There was a problem hiding this comment.
I have handled different approaches without breaking. This keeps the existing getFirstKey() behavior unchanged while allowing it to return the columnheader when explicitly requested during focus entry.
| return node.type === 'cell' || node.type === 'rowheader' || node.type === 'column'; | ||
| } | ||
|
|
||
| getFirstKey(fromKey?: Key, global?: boolean, initialFocus?: 'row' | 'columnheader'): Key | null { |
There was a problem hiding this comment.
@snowystinger and I have been discussing this a bit and would like to explore some different options. IMO, I think the "initialFocus" option is a bit unclear (just like how global is pretty unclear), maybe it would be good to either have the option declare intent (aka "interaction" where only the first drag and droppable table row key would be returned if "interaction=drag", and the first column would be returned for "interaction=navigation", naming TBD), or to borrow from
react-spectrum/packages/react-aria/src/grid/GridKeyboardDelegate.ts
Lines 91 to 93 in 4ab7d39
Closes #10121
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: