-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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: Enhance The FormTokenField component's accesibility #1141
Conversation
f4fb9e7
to
bc3c80e
Compare
@@ -59,3 +59,7 @@ global.window._wpDateSettings = { | |||
string: 'America/New_York', | |||
}, | |||
}; | |||
global.wp = global.wp || {}; |
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 is a separate section and should have a newline + comment before it.
@@ -314,6 +316,7 @@ class FormTokenField extends Component { | |||
|
|||
addNewToken( token ) { | |||
this.addNewTokens( [ token ] ); | |||
this.speak( this.props.messages.added ); |
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.
Why abstract out this.props.messages
instead of just including the message here? Item added
is generic enough to cover any situation.
Edit: never mind, I see that for tags, this is replaced with Tag added
below.
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.
Yeah, but this is still a good question to ask. Maybe we don't need them.
Is there functionality introduced here that should be tested as part of the TokenField tests? RUN_SLOW_TESTS=y npm run test-unit -- --grep 'FormTokenField' While these are not currently run on every build, I plan to introduce a task to automatically run these and other slow tests every hour or so. |
Nothing fancy here, just adding some aria attributes essentially, but let's wait for the accessibility review and test the markup once it's validated |
Thanks very much for this PR :) I'm sorry I don't have so much time to test in depth, will try to do after WCEU. Couple things so far: testing with Safari+VoiceOver the highlighted option in the list gets announced and this is a great step forward! ❤️ There is a small issue with the bolded letters though. For example, typing "c" I get a list of suggested tags that contain "c" and the option markup is something like this:
Unfortunately, VoiceOver reads out this as two words: Re: wp.speak, if you don't want to use the core one (based on jQuery), at Yoast we've ported it to a JS module thanks to @omarreiss. See https://github.com/Yoast/a11y-speak/ |
@afercia Thanks for the review.
I was able to fix this using
I think Gutenberg should rely on the Core implementation. That said, the Core implementation should probably be updated to use Yoast package. |
Can I have some 👀 here? |
@@ -189,3 +189,15 @@ input[type="text"].components-form-token-field__input { | |||
.components-form-token-field__suggestion-match { | |||
color: $dark-gray-800; | |||
} | |||
|
|||
.components-form-token__howto { |
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 we apply the built-in .screen-reader-text
class to avoid repeating it here?
components/form-token-field/index.js
Outdated
}; | ||
|
||
export default FormTokenField; | ||
FormTokenField.instances = 0; |
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.
Why do we need to assign this property? Shouldn't this be handled by withInstanceId
?
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 should it wasn't available when I opened the PR :)
<ul ref={ this.bindList } className={ classes } tabIndex="-1"> | ||
<ul | ||
ref={ this.bindList } | ||
className={ classes } |
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 element renders with an is-expanded
modifier class. Should it also apply aria-expanded
? Or is this the role of the input? I'm not really sure.
components/form-token-field/index.js
Outdated
@@ -469,6 +481,9 @@ class FormTokenField extends Component { | |||
|
|||
return ( | |||
<div { ...tokenFieldProps } > | |||
<label htmlFor={ `components-form-token-input-${ instanceId }` } className="components-form-token__howto"> |
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 we be rendering this if there's an empty placeholder
? Maybe want a more useful default placeholder
?
Looking a bit more in depth, there are a few issues to address.
Not 100% correct but I think it could be acceptable. However, chatting with @mtias at WCEU we were wondering if the filtering/search should work a bit differently. Currently, it searches also for tags that contain the search term. Not sure this is so useful. Say I'm typing I see an issue with the initial value of also, notice the Testing also on Windows with NVDA, the Please notice also it keeps saying "nn of 10" even if the number of options is less than 10. Not sure why this happens, I'd suggest to try to fix the One more thing noticed so far: I see there's an issue with the value of the Also, the hidden description: could use the Lastly, I'd consider to remove the CSS class |
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.
Some issues to address, see comments. Once solved, it would need a second round of testing.
Fixed some of the issues above, I'm testing with VoiceOver and I'm not seeing any error with the count or with the value of aria-activedescendan
. Let me know if it's better now.
Worth noting Safari+VoiceOver don't announce the count, while Firefox+NVDA do. I've tested a bit more on Windows and can still reproduce the count issue with Firefox+NVDA. Will try to understand what's going on here, my guess is it's something about timings. For example: when Note in the second screenshot: in the initial list, which is limited to 10 items, "audio" is in the 5th position. After typing some letters, the list is filtered to 2 results but "audio" is still announced as "5 of 10". There are a few more things that would be nice to add, for feature parity with the current implementation, for example:
Please let me know if it's better I split these other things in a separate issue (I guess yes?) |
done
done Maybe we should investigate any other issue separately. |
Aside: not sure this is really needed:
as far as I see, the input always gets focus when |
Re: last commit, not sure it will work correctly across all browsers/screen reader combos. Couple of things:
Will split the other pending issues in a separate GH issue! |
I can still display it at initial render and update its content. That's how jQueryUI autocomplete works |
@youknowriad thanks!. However, the core |
…how an accessibility hint
a83c0c6
to
38b6edf
Compare
updated to use |
Tested again on Windows, Firefox+NVDA and the live messages work nicely. Thanks @youknowriad Ideally, the call to wp.a11y.speak should be debounced while users are still typing. This is important to avoid "bombarding" users with messages while they're still typing. What we've done at Yoast in similar cases is taking advantage, depending on the cases, of |
Sure thing, happy to make this component more accessible :) Anyway, I've throttled the speak messages, Will probably merge this soon. |
@@ -503,6 +558,11 @@ FormTokenField.defaultProps = { | |||
isBorderless: false, | |||
disabled: false, | |||
tokenizeOnSpace: false, | |||
messages: { | |||
added: __( 'Item added.' ), |
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.
Given that these are assigned at load-time, I anticipate the strings are not correctly localized because setLocaleData
for the editor is called as an inline script before wp-edit-post
(but after wp-components
).
This PR tries to close #1107
My VoiceOver skills are not that high. So I'd appreciate some eyes to see if I got all the accessibility requirements right.