-
Notifications
You must be signed in to change notification settings - Fork 83
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
feat: make disabled buttons focusable with feature flag #8513
Conversation
6446b00
to
911d0b4
Compare
@@ -119,7 +119,8 @@ describe('crud buttons', () => { | |||
expect(spy.firstCall.args[0].detail.value).to.deep.eql({ foo: 'bar' }); | |||
}); | |||
|
|||
it('should save a new pre-filled item', async () => { | |||
// FIXME: Why is this test failing in Webkit with Lit? | |||
it.skip('should save a new pre-filled item', async () => { |
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.
note: This test started failing in Webkit with Lit after interaction events were blocked for disabled buttons. It seems that the test was previously passing by mistake. When running this test in Webkit or Safari, the save button remains disabled for some reason when the click is performed. Blocking interaction events just exposed this issue. I tried adding various timeouts, but without success. The attributeChangedCallback simply doesn't get triggered when isDirty
becomes true
:
saveButton.toggleAttribute('disabled', this.__isSaveBtnDisabled(isDirty)); |
Since it seems to be an issue with the test itself and is only reproducible in Webkit and Safari, I decided to skip this test for now.
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.
This change was extracted into #8541
911d0b4
to
35f06ee
Compare
const INTERACTION_EVENTS = [ | ||
'mousedown', | ||
'mouseup', | ||
'touchstart', | ||
'touchend', | ||
'click', | ||
'dblclick', | ||
'keydown', | ||
'keyup', | ||
'pointerstart', | ||
'pointerend', | ||
]; |
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.
What is the purpose of disabling these events? It doesn't look like it's needed for preventing click events. Otherwise I wonder if keypress
is missing here, which is still being fired.
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.
All these events were disabled by the browser with pointer-events: none
, and by not disabling them now, we risk breaking apps that didn't check for disabled but did subscribe to events like mousedown
. That said, events like touchmove
or mouseenter
need to be allowed since they are used by tooltips. So, in other words, I thought it would be safer to keep the behavior as close to the original as possible. Good catch on keypress
– I'll add it to the list.
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.
It turns out that adding some events to this list was incorrect. Native buttons don't suppress pointer and touch events when disabled. I've removed those and added keypress
.
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.
Checked this and found that pointer events are intentionally not suppressed for native disabled controls.
Regarding mouse events, as described here, Firefox also blocks contextmenu
event but other browsers don't.
BTW there's also auxclick
event mentioned there but it's mentioned it is "not about activation".
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've decided to extract the suppression logic into a separate PR: #8541
if (this._shouldAllowFocusWhenDisabled()) { | ||
return; | ||
} |
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.
Could test new tabindex-mixin
logic in a11y-base/test/tabindex-mixin.test.js
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.
Considering that this is now a private method, does it still make sense to test it?
/** | ||
* Overrides the default element `focus` method in order to prevent | ||
* focusing the element when it is disabled. | ||
* | ||
* @protected | ||
* @override | ||
*/ | ||
focus() { | ||
if (!this.disabled || this._shouldAllowFocusWhenDisabled()) { | ||
super.focus(); | ||
} | ||
} |
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.
Previously it was possible to programmatically move focus to a disabled
button. This change affects the behaviour even with the feature flag off. It is intentional?
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.
Yes, because native buttons don't allow programmatic focus when disabled.
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 can extract this change into a separate PR by the way, as it's more like a fix.
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.
Should the change also go to focus-mixin
rather than tabindex-mixin
?
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 also had this dilemma. However, my reasoning for placing this change to TabindexMixin was that focus()
has to be prevented only for components that are made focusable with tabindex=0
, because otherwise, it already works out of the box.
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.
Created a separate PR with this change: #8540
Quality Gate passedIssues Measures |
Description
To improve accessibility, the PR introduces an option to make disabled buttons focusable so that screen readers can reach and announce them to users, including any attached tooltips and popovers. This behavior is currently experimental and can be enabled with the feature flag:
Depends on
Part of #4585
Type of change