-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: Clear Autocomplete virtualFocus upon paste/undo/redo and other focus fixes #8438
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
base: main
Are you sure you want to change the base?
Conversation
Build successful! 🎉 |
packages/react-aria-components/test/AriaAutocomplete.test-util.tsx
Outdated
Show resolved
Hide resolved
Build successful! 🎉 |
@@ -419,7 +418,11 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions | |||
|
|||
// If no focusable items exist in the list, make sure to clear any activedescendant that may still exist | |||
if (keyToFocus == null) { | |||
let previousActiveElement = getActiveElement(); | |||
// TODO: Bit gross, but we need the first moveVirtualFocus to clear the previous aria-activeDescendant, then |
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 don't quite follow, what's going on here? and what are the repercussions across other collections?
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 sorry, I'll add a more illustrative comment once I confirm this is the only way to do this. What this is handling is the case where the user types into the autocomplete input -> tells the filtered collection to try to virtually focus its first key -> the filtered collection filters itself and ends up in a state where there are no focusable items (aka only disabled items/no matching items at all) -> it needs to then tell the autocomplete input to clear its old aria-activeDescendant and that the input should be focused instead.
I was hoping to remove moveVirtualFocus(ref.current)
in favor of the dispatchVirtualFocus
below since it feels weird to do two separate virtual focus move operation but the autocomplete input will only clear its focused node when it detects that a focusin
on the collection itself
This shouldn't have an repercussions for other standalone collections because it only runs when FOCUS_EVENT
is fired from useAutocomplete
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's very helpful, thank you for explaining again <3
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.
only has cut/paste, undo and redo didn't seem to fire properly
Build successful! 🎉 |
// If 500ms hasn't elapsed the aria-activedecendant hasn't been updated | ||
act(() => jest.advanceTimersByTime(300)); |
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.
500 v 300?
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.
yep, if I advance more than 500ms, the aria-activedescendant
will be set which is the typical flow tested by the other tests via runAllTimers
. The buggy flow was if the user then backspaces before that 500ms finishes resulting in a state where the input "blurred" away from itself, but then interrupts updating the activedescendant, resulting in a state where getVirtuallyFocusedElement
doesn't return a value and moveVirtualFocus
will think that virtual focus didn't move away from the input.
Co-authored-by: Robert Snow <rsnow@adobe.com>
Build successful! 🎉 |
## API Changes
react-aria-components/react-aria-components:useContextProps useContextProps <E extends Element, T, U extends SlotProps> {
props: (T & SlotProps)
- ref: ForwardedRef<E> | undefined
+ ref: ForwardedRef<E>
context: Context<ContextValue<U, E>>
returnVal: undefined
} /react-aria-components:TabPanel TabPanel {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ChildrenOrFunction<TabPanelRenderProps>
className?: ClassNameOrFunction<TabPanelRenderProps>
- id?: Key
+ id?: string
shouldForceMount?: boolean = false
style?: StyleOrFunction<TabPanelRenderProps>
} /react-aria-components:TabPanelProps TabPanelProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children?: ChildrenOrFunction<TabPanelRenderProps>
className?: ClassNameOrFunction<TabPanelRenderProps>
- id?: Key
+ id?: string
shouldForceMount?: boolean = false
style?: StyleOrFunction<TabPanelRenderProps>
} @react-aria/tabs/@react-aria/tabs:AriaTabPanelProps AriaTabPanelProps {
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
- id?: Key
+ id?: string
} @react-spectrum/s2/@react-spectrum/s2:TabPanel TabPanel {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode
- id?: Key
+ id?: string
shouldForceMount?: boolean = false
styles?: StylesPropWithHeight
} /@react-spectrum/s2:TabPanelProps TabPanelProps {
UNSAFE_className?: UnsafeClassName
UNSAFE_style?: CSSProperties
aria-describedby?: string
aria-details?: string
aria-label?: string
aria-labelledby?: string
children: ReactNode
- id?: Key
+ id?: string
shouldForceMount?: boolean = false
styles?: StylesPropWithHeight
} |
Closes RSP Component Milestones (view)
✅ Pull Request Checklist:
📝 Test Instructions:
Go to the RAC autocomplete stories and try typing/backspacing/cut/paste/redo/undo operations. Only typing forward should autofocus the first item in the list, the rest should clear virtual focus. Sanity check announcements, most should not be interrupted since we clear virtual focus so you should be able to hear what you've just typed/pasted/etc
🧢 Your Project:
RSP