Closed lawrencewin closed 1 month ago
EDIT: Apple HIG changed from when I last looked at it. Maybe this is better, I need to find a canonical guide: https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#kbd_focus_vs_selection . The basic idea is that components like lists and comboboxes (where multiple elements exist) will have a "selection" state, so that the main element keeps focus, and keyboard events move selection / which inner element is intractable. There's no general way to do that AFAIK, so it needs to be a per control basis. I like having a SyntheticFocusManager help with that, though I might personally name it "SelectionManager".
Isn't this basically the difference between focus and selection? https://developer.apple.com/design/human-interface-guidelines/focus-and-selection (Apple docs, but I think the general distinction applies cross platform) As in, we can call "synthetic focus" selection, and incorporate that as a state that FURN components can take?
[discussion]
Oooh, neat -- I'm definitely in favor of having ergonomic components that ease implementing accessibilityControls
-qualifying UI patterns, they're annoying to get right (@ mention dropdown, ahhhh)
I'm intrigued by how this will show up in the accessibility tree and be handled by styling with regards to [real] focus
, [synthetic] focus
, and selection
-- small bikeshedding opportunity where Apple refers to [synthetic] focus
as highlighted
.
Inside useTab.win32
I see that it's mapping the SyntheticFocus changes to Focus/Blur state though it seems you're looking at supporting additional UI patterns long-term -- are these patterns in your longer vision?
Along these lines I'm wondering if the SyntheticFocus state should be kept distinct from Focus state, and alignment between the styles for each state be managed by the component? If an outside controlling component is directing this state I'd wonder if the "SyntheticFocusable" capability could be written as a higher-order component to avoid requiring components that should be synthetically-focusable from needing to directly integrate with the FURN SyntheticFocusManager 🤔
Thoughts?
For this example with the TabList, "selection" refers to changing which Tab is indicated by the underline. Having the synthetic focus we want be referred to as "selection" seems confusing in this case, though a "highlight" state mentioned by pat is interesting.
Inside
useTab.win32
I see that it's mapping the SyntheticFocus changes to Focus/Blur state though it seems you're looking at supporting additional UI patterns long-term -- are these patterns in your longer vision?
SyntheticFocus === Selection
- ComboBox, @ Mention dropdowns
SyntheticFocus !== Selection
- single-state containers e.g. current tablist
SyntheticFocus stacks with Selection state
- multi-select containers
I haven't thought about other UI patterns in the long term because this is a customer ask for a specific feature. The goal is to be closest to #2, but I'd like to leave flexibility to support those additional patterns. I'm also interested in exploring the HOC approach to integrate the synthetic focus functionality in existing FURN components.
Closing for now due to a lack of need from a partner
Platforms Impacted
Description of changes
When implementing a component, such as a combobox, there is a need to allow keyboard navigation while native focus is locked to a certain UI element. In the combobox case, a user needs to be able to navigate between dropdown items while focus is locked to the textbox element.
This PR implements a class,
SyntheticFocusManager
that can be passed to a component and allows visual focus to rendered and switched between FURN components. all while native focus remains locked to a different element. Currently, compatibility is limited to the TabList component, but the goal is for more compatibility to be locked for other needed FURN components.Verification
https://github.com/user-attachments/assets/b1c0cf82-8ace-4c04-a450-62fae8e565e9
Pull request checklist
This PR has considered (when applicable):