fix: #9239 Focus on the first available option in the dropdown#10236
fix: #9239 Focus on the first available option in the dropdown#10236jsmitrah wants to merge 12 commits into
Conversation
snowystinger
left a comment
There was a problem hiding this comment.
Thanks for the PR. I'd like to see a storybook story which recreates the bug that was reported in the issue which included a Combobox and a long list of options which scrolled where the first non-disabled element was past the scrolling region.
| getFirstKey(): Key | null { | ||
| let key = this.collection.getFirstKey(); | ||
| return this.findNextNonDisabled(key, key => this.collection.getKeyAfter(key)); | ||
| getFirstKey(key?: Key, includeDisabled?: boolean): Key | null { |
There was a problem hiding this comment.
What are these arguments for? From what I can see, key isn't used in this function, and nothing in this PR calls getFirstKey with includeDisabled set.
The only place I see it set is in useSelectableCollection, but it appears to be more of an accident, as it would only "include" if the Ctrl key is pressed, which I don't think we want to be a condition for Home/End as it has to do with selection and something called "global" that determines row vs cell focus
finally, reverting the changes in this file still pass the added tests
There was a problem hiding this comment.
You're completely right. I have reverted ListKeyboardDelegate.ts to its original state and kept the check entirely within useSelectableCollection.ts by checking "manager.disabledKeys" directly during the autofocus lifecycle. Thanks for the guidance
|
|
||
| manager.setFocused(true); | ||
| manager.setFocusedKey(focusedKey); | ||
| manager.setFocusedKey(focusedKey); // Fires consistently now (even if null) |
There was a problem hiding this comment.
what does this code comment mean? what is it referencing? when did it not fire?
There was a problem hiding this comment.
That inline comment was a leftover trace from a temporary intermediate change. Now I have removed that
|
|
||
| // Safety check: If the resolved target item is explicitly disabled, | ||
| // fallback immediately to the first available enabled option. | ||
| if (focusedKey && manager.disabledKeys.has(focusedKey)) { |
There was a problem hiding this comment.
what is this block of code for? all tests pass without it.
Looking at the loop above, this line should make sure that the item isn't disabled. Did you see otherwise? please include a test.
if (manager.canSelectItem(key)) {
| // ========================================================================= | ||
| // ADDED: Tests for skipping disabled items automatically on mount/focus | ||
| // ========================================================================= |
There was a problem hiding this comment.
| // ========================================================================= | |
| // ADDED: Tests for skipping disabled items automatically on mount/focus | |
| // ========================================================================= |
| // Let any asynchronous layout microtasks complete smoothly | ||
| await new Promise(resolve => setTimeout(resolve, 0)); |
There was a problem hiding this comment.
What is this about? the test passes without it from what i can see
There was a problem hiding this comment.
You're right. I originally included this timeout helper to address a microtask timing race condition during an earlier iteration of the fix. Now I removed that.
| // Wrap the simulated user tabbing action cleanly in an async act block | ||
| // to handle the synchronous JSDOM focus state mutation |
There was a problem hiding this comment.
| // Wrap the simulated user tabbing action cleanly in an async act block | |
| // to handle the synchronous JSDOM focus state mutation |
This comment means nothing
| manager.setFocusedKey(focusedKey); // Fires consistently now (even if null) | ||
|
|
||
| // If no default focus key is selected, focus the collection itself. | ||
| // If no default focus key is selected, focus the collection container itself. |
There was a problem hiding this comment.
| // If no default focus key is selected, focus the collection container itself. | |
| // If no default focus key is selected, focus the collection itself. |
There was a problem hiding this comment.
Applied the suggestion for the comment
| navigateToKey(manager.lastSelectedKey ?? delegate.getLastKey?.()); | ||
| } else { | ||
| navigateToKey(manager.firstSelectedKey ?? delegate.getFirstKey?.()); | ||
| let firstKey = manager.firstSelectedKey ?? delegate.getFirstKey?.(); |
There was a problem hiding this comment.
something is wrong the tests, they pass without this change as well
There was a problem hiding this comment.
You're right, this block was redundant, so I have removed it and reverted this section.
|
I'm not sure there is actually a bug to fix anymore. I can't run the original authors codesandbox, and in the repro I made here, https://stackblitz.com/edit/adpc19dw?file=src%2FExample.tsx it's scrolling the first non-disabled item into view. Were you able to reproduce the initial issue? |
Closes #9239
✅ Pull Request Checklist:
📝 Test Instructions:
🧢 Your Project: