-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Description
Splitting this out from #56396 (comment) for a broader discussion. Cc @ciampo @andrewhayward @alexsanford @joedolson
As noted in this comment, focusable elements that are dynamically added or removed / hidden / disabled potentially trigger a focus loss and impact other utilities, components and hooks like the @wordpress/dom
utilities focusable
and tabbable
, useConstrainedTabbing
and useFocusOutside
. There have been several cases so far where focus losses were triggered because of this. When using a keyboard, focus losses are a terrible user experience that needs to be avoided.
RIght now, the Button component has an __experimentalIsFocusable
prop that is meant to render aria-disabled
instead of the disabled
attribute to keep disabled buttons focusable. In #56396 (comment) a proposal was made to make this prop true
bu default:
any potential drawbacks if the Button component had the
__experimentalIsFocusable
prop true by default?
I'm not sure this would be ideal. If I understand correctly, the current situation is something like this, in pseudo-code:
<Button disabled __experimentalIsFocusable />
Conceptually, I find this confusing. disabled
is a HTML attribute, it should not be used as a prop name. I think this is source of confusion for many new-generation contributors that are used to just use components props without a deep understanding of what happens in terms of the DOM and the rendered HTML.
If I understand correctly, what has been proposed in #56396 (comment) would be, in pseudo-code, something like this:
<Button disabled __experimentalIsFocusable={ true } />
And when both props are true, under the hood the button would use aria-disabled
. I'd think this would be even more confusing because it dosn't explain what it does and it doesn't educate contributors.
What we need for accessibility
In 90% of the cases, the disabled
attribute should not be used. In fact, in the editor we established a pattern for 'disabled' buttons to:
- use
aria-disabled
to keep buttons focusable noop
the disabled button
This is in place for two reasons:
- avoid focus losses
- discoverablity of disabled controls
See W3C: ARIA Authoring Practices Guide (APG) > Developing a Keyboard Interface > Focusability of disabled controls
https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols
Considering that this is what we'd want in 90% of the caees, I'd like to propose to consider to reverse the logic.
Instead of making the exception the default behavior, disabled buttons should render aria-disabled
and be noop-ed
by default.
- The
disabled
prop should be renamed toisDisabled
and implement the above behavior. - A new prop
isFullyDisabled
(or a better name) should be used to render adisabled
attribute instead of the above. - A new custom eslint rule should be added to detect the usage of the
isFullyDisabled
prop or any otherdisabled
HTML attribute being rendered. The rule should prevent rendering adisabled
HTML attribute unless aneslint-disable*
comment is added that requires to specify the disable reason.
I may entirely be missing something but I think the editor needs a solid way to prevent focus losses that are often triggered by disabling buttons while they are focused. Also, contributors education is key and all this should be very well documented.
Any thoughts and feedback more than welcome.
Step-by-step reproduction instructions
Not applicable.
Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
Yes
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Yes
Metadata
Metadata
Assignees
Labels
Type
Projects
Status