-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Fix/dropdown accessibility (#4977) #4978
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
Fix/dropdown accessibility (#4977) #4978
Conversation
…avContext doesn't provide a value.
@taion Indeed, this would resolve my issue 👍 But for sure, this would be a breaking change in regards to the current behavior of |
In practice this is unlikely to break anyone. Also, I think this matches what's down in upstream TWBS. And we're still in betas, so strict semver compliance is not a concern. cc @jquense thoughts? |
A few things. I don't think The lazy rendering of dropdowns is an optimization but I don't think it was a premature one. We should some git and issue archaeology before removing it. React land is different than normal bootstrap, the lazily rendered tree isn't just HTML here, it's the component tree, with all it's logic like modals etc. I could be misremembering, but I think that lazy rendering was added in response to a real perf bottleneck |
Looks like you're right on the support, I hadn't realized it was mostly being ignored at this point. It was turned off in JAWS by default in April 2019 (w3c/aria#995), though NVDA might be looking to support it at some point (nvaccess/nvda#8983). From the JAWS patch notes
The dropdown menu here is a sibling to the button which seems to make the |
As far as optionally rendering the nav dropdown. I could add a prop to |
I think it'd be fine to add a prop like that to opt out of the logic. We should maybe separately think through what the default should be there going forward |
There is now a prop on |
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.
src/AbstractNavItem.js
Outdated
@@ -47,8 +50,9 @@ const AbstractNavItem = React.forwardRef( | |||
if (!props.role && navContext.role === 'tablist') props.role = 'tab'; | |||
|
|||
props['data-rb-event-key'] = navKey; | |||
props.id = navContext.getControllerId(navKey); | |||
props['aria-controls'] = navContext.getControlledId(navKey); | |||
props.id = navContext.getControllerId(navKey) || props.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.
shouldn't the explicitly-specified values take precedence over calculated ones?
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.
hmm normally yes, but in this case, if there is a context provided id the user would have to provide the id in both places otherwise you get a mismatch and it's broken. We used to warn saying the ID is ignored, and that one should use generateId or whatever it is on the parent to control ids
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 should we do about #3940, then?
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.
maybe just warn again?
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.
hmm, would this actually fix that issue? because the navcontext won't assign a controller 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.
we should always use the controller id, might just want to surface to a user that we are ignoring their props 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.
@taion That's correct, in that issue the getControllerId
function for ListGroupItem
will be a noop function giving an undefined id, so this would instead default to the user provided value.
@jquense I know you approved the changes earlier, but I just added a warning message when the user's id is overwritten here like you mentioned. I updated the Tabs
component to pass the id prop through to the inner tabs so that this component can know whether the user provided an id in that case. (but it's overwritten, so no change in behavior) I used the warning library for this, so technically it appears as a console error. Let me know if there are any changes you'd like me to make to that, or if it was fine before and I can revert it.
Also pass the user provided id through to Tab children so the inner AbstractNavItem knows the user's id is being overwritten.
Thanks!!! |
Fix for issue #4977
This update allows passing through
id
andaria-controls
props through AbstractNavItem to the resulting component.It also adds an
aria-controls
attribute to the dropdown button referring to the menu inNavDropdown
,DropdownButton
, andSplitButton
. The menus are now rendered in the DOM and hidden from the start, rather than being added after their first show. This is to allow settingaria-controls
with a valid id at the start.If the
aria-controls
attribute was intentionally not used I can remove it again.