-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Make aria-describedby able to reference both the placeholder and the description #1741
base: main
Are you sure you want to change the base?
Make aria-describedby able to reference both the placeholder and the description #1741
Conversation
Seems to me Instead, |
042719c
to
cc30a80
Compare
_getAriaDescribedByIDs(): ?string { | ||
const ariaDescribedByIDs = [ | ||
this._placeholderAccessibilityID, | ||
this.props.ariaDescribedBy, |
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.
Without type safety, I'm concerned that folks might pass in either a string or an Array for this prop value. Is there a way to guarantee a string? Or, if not, you should run this prop through Array.isArray
and spread it (or join it) before joining with the placeholder id.
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 understand the concern. On the other hand, should this apply also to other props, for example ariaLabelledBy
? I couldn't find in the codebase other examples of checking for a prop value this way, and it would look a bit overkill to me. If you strongly feel it's necessary, please do let me know.
@@ -21,7 +21,7 @@ const React = require('React'); | |||
const cx = require('cx'); | |||
|
|||
type Props = { | |||
accessibilityID: string, | |||
accessibilityID: ?string, |
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.
Rather than making the value nullable, make the property optional. If the property is defined, it must be a string.
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.
Looking better at this, I think it should be nullable. When the placeholder prop is not set, it's necessary to avoid to render the HTML attribute aria-describedby
that would point to a non-existing element.
@jessebeach thanks for your review! I'll try to address your points as soon as I have some spare time 😄 On a side note: should the files in |
ede0b99
to
1f33588
Compare
I think we should automate the generation of those files and/or add them to |
@afercia - just wanted to ping this! We'd love to merge this PR when you get a chance to make the changes :) |
@niveditc thanks for the ping. About those changes, there are a couple of question I've asked on Sep. 30 that would need some feedback first 🙂Anyways, I'm afraid I won't have much time to dedicate in the next months. Please do feel free to take over this PR, when you have a chance. |
Summary
I've read a6af3e1 and the related issue #1214
I'd like to propose an improvement to the way the
placeholder
andariaDescribedBy
props work. For more details, please see the related issue #1739.This PR introduces a new
_getAriaDescribedByIDs()
function to calculate a proper value for thearia-describedby
attribute.null
whenplaceholder
andariaDescribedBy
aren't set, to avoid to render anaria-describedby
attribute that points to nothingplaceholder
orariaDescribedBy
is set, it just uses its valueplaceholder
andariaDescribedBy
are set, it uses both values, separated by a spaceThe third point would allow to replicate the native behavior: when both a
placeholder
and anaria-describedby
pointing to some description are set in a textarea, assistive technologies use both.If you want, you can verify this on a pen I've prepared: https://codepen.io/afercia/full/GdZOmX/
Screen readers announce first the placeholder, then the description referenced by
aria-describedby
. This is the expected behavior, since theplaceholder
andaria-describedby
have different purposes andaria-describedby
is not an "override" of the placeholder as mentioned in #1214 (comment)Recommended combos to test:
Specifically, the placeholder is meant to help users with data entry, for example providing a sample value or brief description of the expected format while
aria-describedby
is meant for a longer description.Seems to me allowing both is essential to replicate the native behavior.
Worth noting that currently, when the prop
ariaDescribedBy
is set, the placeholder is not announced at all. As per backwards compatibility concerns, this change shouldn't change so much: everything should work as before, with the added bonus that both props will work.Test Plan
I've tested using the "plaintext" example:
placeholder
prop and verify noaria-describedby
attribute is renderedplaceholder
prop and verify thearia-describedby
attribute value is the same of the placeholder IDariaDescribedBy
with a test ID (you can also add a paragraph with that ID and some content) and verify thearia-describedby
attribute value takes both IDsaria-describedby
attribute value is the expected oneWorth noting
npm run lint
fails for me (also on master, see error below) andnpm run flow
shows a few errors, also on master. Seems to me they're unrelated errors, unless I'm missing something. In that case I'd appreciate any feedback and guidance 🙂npm run lint
error: