-
Notifications
You must be signed in to change notification settings - Fork 20
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 FirstOptionSelectionMode
:selected
clearing on typing
#82
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.
Looks great - just two suggestions to cover potential edge cases
@@ -141,10 +141,11 @@ export default class Combobox { | |||
for (const el of this.list.querySelectorAll('[aria-selected="true"]')) { | |||
el.removeAttribute('aria-selected') |
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 think we should probably also remove data-
attribute that indicates the 'active' default option here:
el.removeAttribute('aria-selected') | |
el.removeAttribute('aria-selected') | |
el.removeAttribute('data-combobox-option-default') |
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.
Totally, that's a good catch, will add!
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.
Addressed in 7182ef5 🙇
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't comment on unchanged lines (maybe one day 🙏) but I think maybe we should replace the indicateDefaultOption
call on line 82
with resetSelection
, just to make sure the state is cleared when the menu opens. It's shouldn't be necessary since selection is cleared on close, but it feels safer.
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.
Addressed in 7182ef5
src/index.ts
Outdated
@@ -108,7 +108,7 @@ export default class Combobox { | |||
const focusIndex = els.indexOf(focusEl) | |||
|
|||
if ((focusIndex === els.length - 1 && indexDiff === 1) || (focusIndex === 0 && indexDiff === -1)) { | |||
this.clearSelection() | |||
this.resetSelection() |
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 like this is the case where the user reaches the end of the options in either direction. Based on current behavior I think we do want to clear the selection in this case, not just reset it:
Screen.Recording.2024-02-26.at.9.35.13.AM.mov
Might be good to add a test for this, but it's not a blocker IMO.
this.resetSelection() | |
this.clearSelection() |
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.
If we clear the selection here instead; this will also be a regression in behaviour for the active
option which previously set the default attribute, in this case, we wouldn't reset that attribute and that may break the option being selected on enter press? 🤔
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 think that's an acceptable change - if the first option is active by default but then the user uses the arrow keys to navigate through all the options, it's fine to deselect the first option at that point. That's actually probably preferrable to the current behavior
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.
Makes sense! Updated in dbf90b5
When the
FirstOptionSelectionMode
prop is set toselected
, this would correctly set the first element to selected on open, but on typing, remove this state.This was easily reproducible with a test-case that I should have had in my prior PR here: #81
To encourage a simple code path that's shared with the
active
state forFirstOptionSelectionMode
, I refactored the code a bit and also cleaned up some call paths that were not necessary on closing flows.This PR adds:
resetSelection
to be distinct fromclearSelection
. Why?clearSelection
also handled the "state reset" for active/selected state, but this broken in the case for "active" as it would try to navigate when the list was not visible, asclearSelection
was called on.stop
,.destroy
etc. This flow didn't make sense, but didn't throw errors for theactive
state as there was no navigations on option lists but rather attribute settings.resetSelection
when appropriate, which is, on non-special character typing, and when we navigate through the last element (this should cycle back). (First open is applicable, but we callindicateDefaultOption
directly.