-
Notifications
You must be signed in to change notification settings - Fork 126
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
Label assertion fails when child is a Component #44
Comments
Looked into this problem yesterday. The short of it is I don't think we can rely on virtual DOM when evaluating labels as it's very likely the text of an element is nested inside a Component whose subtree isn't accessible until render. |
can just skip composite components? we'll capture all the createElements of the normal components and might still get away with it? I'm not sure, I'm in a training right now and can't think it all the way through. |
I'm fairly sure you're right, but I think it might help to try to explain what's going on to a Rubber Duck.
react-a11y hooks into
Now we find an opaque component. At the time this is called We can confirm this from the console:
If |
@AsaAyers yes, you've got it. Those were my findings yesterday as well. Glad we're on the same page. One idea I had to address this problem was to detect if an element's child is a Component and, if so, defer the evaluation of the label until it's been mounted. My initial thought was this would be easily achievable (famous last words) using the ref prop. However, I wasn't sure if that was a viable solution considering the element or Component might already have a ref defined. |
@ryanflorence not sure how we can skip evaluation. Consider the following simple case (this is from our codebase at Twitter):
When react-a11y evaluates the label for |
Also React 0.13 introduced using callbacks for refs. It's going to get really ugly trying to hook into that.
Everything is evaluated deepest call first, so I can see where you might use a ref if |
Just like linters can't catch 100% of things, I don't think react-a11y needs to catch 100% of the problems. This might just be an edge case that isn't worth adding the needed complexity to solve. If you know
|
@AsaAyers I agree with you; we don't need to catch 100% of the problems. However, when I incorporate react-a11y into our react-based Twitter client I end up getting a lot of label errors for the previously mentioned reason. I think this pattern of a component as a first-level descendant of an element could be a very common use case, so I'd be interested in attempting to solve this. While I can make the change you suggested to make a test pass, it won't solve the problem for us outside the scope of tests. |
Why is the
|
Good question. The timeline is it's own interactive component, with responsibilities and default behaviors independent of its content (Tweets). As a composite control, each of the items in the timeline is labeled by it's content (Tweets). Visually impaired users need to be able to perceive the timeline as an interactive control; for that reason we use the ARIA grid roles to describe it; and make it interactive by applying a tabindex and onClick listener to each cell. I hope that clears things up. |
…el is inside a child Component (fixes #44) [added] Tests to ensure anchors with a tabIndex but without an href require an ARIA button role (fixes #45) [added] selection and option to the list of interactive elements that require labels [removed] getFailures() method since all failures are now logged asynchronously
…el is inside a child Component (fixes #44) [added] Tests to ensure anchors with a tabIndex but without an href require an ARIA button role (fixes #45) [added] selection and option to the list of interactive elements that require labels [removed] getFailures() method since all failures are now logged asynchronously
We have tests covering the case where an element's label is a deeply nested text node. For example:
However, if an element's label is a text node nested inside a Component, the label test fails. For example:
Another, more simplified example that also fails:
The text was updated successfully, but these errors were encountered: