-
Notifications
You must be signed in to change notification settings - Fork 3
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
Accessibility question: restoring and preventing focus to trigger on overlay/sheet dismissal? #29
Comments
Note that right now, as an experiment on develop, the following behaviour is implemented for testing purposes on settings:
|
I am not sure the behavior listed is worth moving away from a more vanilla react-aria-components approach. Especially as react-aria-componets are in such a state of constant change and improvement. At this point I would recommend using the components as-is (which are hard enough to figure out and keep up with). So the decision is kind of: should we use react-aria-components, for better or worse, to which I would vote: yes. And I would advocate for as 'traditional' an approach to their implementation as is possible. This may well include using their hooks but perhaps not using stately. It's a hard call but that is my two cents. |
@bluefirepatrick Thanks for your input. That’s very helpful. Yeah, on second thought I’m resetting what I currently have on develop to try something else. It is how modals are expected to behave, as explained in multiple articles (aria-modal on MDN, Accessible Modals, etc.) so let’s not degrade accessibility in that case. Given the issue is primarily tied to keyboard and tap/click, I’ll be exploring We’ll probably have to set styles for focus anyway, so that they have enough contrast in all reading modes, as explained in this article by Sara Soueidan. |
Keyboard focus management in "normal" web frontends is hard enough, but to do this correctly (i.e. with predictable outcome for users, in all different interaction paths, which may involve the mouse too) with nested iframes is quite hard. Just as in this project, in Thorium we face a similar challenge because an Electron webview is essentially an out-of-process sandboxed iframe hosted in shadow DOM. Thankfully nowadays we don't have to "roll our own" half-baked GUI lib full of missing edge cases. That's what we did in Thorium pre-v3, but actually in the early days the test Electron app GUI was implemented with Google's Material Components for the Web which was VERY alpha and introduced breaking changes at a rapid pace (looking back, I am glad we discarded this option and chose to keep-it-simple with in-house minimal UI components). I am a big proponent of Adobe's react-aria-components (Spectrum foundation) but there is also Radix etc. (personally I am a big fan of RAC's dedication to detail, the quality of their documentation, their pragmatic design and empirical testing/validation of a11y patterns). Right now in Thorium we still have user navigation / focus steal bugs, the asynchronous nature of which makes it hard to troubleshoot and reason about. When a user follows a TOC hyperlink we force-focus inside the iframe DOM on Elements that are not focussable by default, so that screen readers are redirected to the correct location (well, by "correct" I mean HTML element, which is not quite character-level precision but this meets the vast majority of navigation needs, with some acceptable accuracy loss / tradeoff when linking into annotations or search results) RAC or Radix (etc.) own built-in focus management certainly interferes with Thorium's own iframe focus in/out heuristics, and frankly at that point this is not a solved problem yet in Thorium v3 ... working on it. |
So in order to improve accessibility, React Aria restores focus to overlay triggers by default, and unlike other component libraries, no prop seems to be provided to prevent this on ready-to-use components, it requires FocusScope – and eventually something custom depending on the behaviour you’re trying to implement.
This means focus will be restored to the action buttons when the overlay/modal/sheet is dismissed, in all manners:
Escape
keyonPress
within the overlay (click, tap,Enter
andSpace
)onPress
(outside the overlay)onAction
(likeonPress
but forMenu
)Now, this perhaps creates a subpar experience with immersive mode, as it will then take 2 presses (click/tap) to toggle the mode: first one to
focusOut/blur
the trigger, second one to toggle the mode.What would be ideal in terms of accessibility and usability to mitigate this issue?
It’s especially important to get that right as we may have to switch to custom components and implement this behaviour.
The text was updated successfully, but these errors were encountered: