Skip to content
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

Added managed keyboard nav and roles to NxDropdown - RSC-989 #845

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from

Conversation

entroform
Copy link
Contributor

@entroform entroform commented Nov 8, 2022

https://issues.sonatype.org/browse/RSC-989

Curiously, in the example here, https://www.w3.org/WAI/ARIA/apg/example-index/menu-button/menu-button-links.html, it focuses on the menuitem when you hover over it with mouse.

Still working on this ticket, but would appreciate feedbacks!

@entroform
Copy link
Contributor Author

According to the pattern, when the dropdown menu is opened, it first focuses on the menu as shown here in the snapshot.

nx-dropdown-js-nx-dropdown-nx-dropdown-links-looks-right-when-focused-via-keyboard-1-snap

Will be reaching out to the designer about how it should look like when focused.

@entroform

This comment was marked as resolved.

@entroform entroform requested a review from a team November 8, 2022 21:20
@rpokorny

This comment was marked as resolved.

@rpokorny
Copy link
Contributor

rpokorny commented Nov 9, 2022

According to the pattern, when the dropdown menu is opened, it first focuses on the menu as shown here in the snapshot

That's not what I'm seeing in the ARIA patterns docs and examples. Everything I'm seeing says to focus the first item in the dropdown, except if it was opened by the user pressing UP, in which case the last item should be focused.

<span className="nx-dropdown-button-content">
Text Link - this link should trigger truncation
</span>
</a>
<NxButton onClick={() => alert('icon click')}
className="nx-dropdown-right-button"
variant="icon-only"
title="Delete Button Link2">
title="Delete Button Link2"
role="menuitem">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check with design about how these buttons should be added into the recommended patterns. These are pretty nonstandard, so I think we're on our own in terms of how they behave. Having them just be part of the up/down key cycling doesn't necessarily seem right though.

const page = getPage();

await moveMouseAway();
await page.keyboard.press('ArrowLeft');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any behavior for the Left arrow key defined in the ARIA docs; what's this for?

expect(button).toHaveProp('aria-controls', menuId);
expect(menu).toHaveProp('id', menuId);
});

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aria-expanded should be tested too

@rpokorny
Copy link
Contributor

rpokorny commented Nov 9, 2022

A key aspect of compound ARIA widgets like this is that the whole thing is one tabstop. That is, the user can tab to the dropdown, and regardless of whether it is open or not or how many menu items it has, they can tab away from it with a single press of the Tab key. Moving focus within the component should not be possible with Tab, but only with the arrow keys. This is typically accomplished by setting tabIndex to -1 on all of the menu items and using either aria-activedesendant or programmatic focus to keep track of which menu item is currently focused (I recommend the latter as it makes activation of the menu items more natural).

}
}, [disableMenuKeyNav]);

function setFocusToMenuItem(direction: -1 | 1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both NxSearchDropdown and NxComboxbox have also had to implement logic to do what this is doing, which they did with a function called adjustBtnFocus. As this is the third time we've needed similar logic, I think it probably makes sense to see if we can extract that out into a utility and reuse it here too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both NxSearchDropdown and NxComboxbox have also had to implement logic to do what this is doing, which they did with a function called adjustBtnFocus. As this is the third time we've needed similar logic, I think it probably makes sense to see if we can extract that out into a utility and reuse it here too.

For that matter, both of those other components rely on this one. It'd be great if we could find a way to encapsulate this logic only in this component and remove it from the others.

}
}

function activateMenuItem(event: React.KeyboardEvent<HTMLElement>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it's replicating built-in behavior; is it really necessary?

@@ -68,12 +68,16 @@ function NxFilterDropdownRender<T extends string | number = string>(props: Props

function onResetClick() {
onChange(new Set());
if (menuRef.current) {
menuRef.current.focus();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in another comment, I'm not seeing anything indicating that focusing the menu itself is truly a part of the pattern. If we get rid of that, what you could do here instead is focus the dropdown toggle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants