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

Kdropdown keyboard navigation #185

Merged

Conversation

marcellamaki
Copy link
Member

@marcellamaki marcellamaki commented Mar 9, 2021

Description

This PR adds tab navigability for KDropdownModal. Currently, a user cannot use keyboard navigation to enter into the dropdown.

Issue addressed

Fixes #178

Before/after screenshots

BEFORE

tab-nav (1)

AFTER

tab-nav-updated

Steps to test

  1. Use the tab key to navigate to a dropdown menu
  2. Use the enter key to open the dropdown
  3. The focus should be directed to the first item in the menu
  4. Using the tab key should direct you down each item in the menu, and then a double-tab at the end should bring you back to the first element
  5. Using escape key when you are inside the menu should close the menu, and bring the focus back to the dropdown menu button

Comments

Any feedback for general code improvement (and if I'm using some of the existing KDS patterns correctly) or about how this affects other components that I might not be thinking of would be very helpful.

Also, @jtamiace / @khangmach, I am not sure if there is already a design convention for the focus on menu items. I did review the existing docs but know they're a WIP and it's possible you have some work on this that I'm just unaware of. If you have design feedback or recommendations of how I can improve this, please let me know! So far, I just tried to adapt existing patterns and styles, but I'm sure there is room for improvement.

Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

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

The code looks good aside from the console.log

@radinamatic might have some more insights here on the a11y.

When I got focused into the first element of the dropdown, I tried using the arrow keys to navigate the menu items which scrolled the whole page and I realized you can only tab through the children.

I did some digging and found this: https://www.w3.org/TR/wai-aria-practices/examples/listbox/listbox-collapsible.html - if you scroll down you see some specs for Keyboard Navigation.

Perhaps the use case there is slightly different than ours? In any case - I'll let @radinamatic weigh in on that aspect.

lib/keen/UiMenu.vue Outdated Show resolved Hide resolved
@marcellamaki
Copy link
Member Author

@nucleogenesis - thanks for your notes! You are right about the arrow keys and not the tab. I had read some resources saying either was fine, but I think it's a better idea to go with the w3 standard. I'll make those changes today or tomorrow and hopefully get this wrapped up before we move into all-product sprints 😊

Copy link
Member

@jtamiace jtamiace left a comment

Choose a reason for hiding this comment

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

Approving from the design side - the behaviors you implemented make a lot of sense, and so does the highlight itself

@marcellamaki
Copy link
Member Author

@nucleogenesis - I made some changes to the code since you last reviewed. One making sure the arrow keys worked and two adding a $focus-outline variable. Previously I had been using some javascript and active styles, but it was getting unnecessarily complicated to be creating so many computed properties just to add some basic css. That said, I'm not sure if there is a reason why there wasn't this variable already, and why the value was mostly being accessed in different ways. I'd be happy to switch back to using javascript if either you or Devon could give me a few hints on a simpler approach. Thanks for your feedback!

lib/keen/styles/variables.scss Outdated Show resolved Hide resolved
Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

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

With @indirectlylit's note about the CSS and the fiddly a11y tab/keyboard navigation stuff I noted both resolved this should be good to go, thanks @marcellamaki !

// identify the menu state and length
const popover = this.$refs.popover.$el;
const menuElements = this.$refs.menu.$el.querySelector('div').children;
const lastChild = menuElements[menuElements.length - 1];
Copy link
Member

Choose a reason for hiding this comment

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

When we're on the lastChild and hit tab (keycode 9) then the focus outline is lost altogether and I'm not sure where it is. The menu stays open as well.

On that W3 link I shared in my previous comment, if you keyboard navigate to the dropdown (you'll have to eyeball it because it doesn't show a focus indicator on that site) - but if you hit space to open it, arrows to navigate within it, and then hit tab - the tab key moves the focus to the next element in the DOM.

So the listed items in the drop-down should not be a part of the tab navigation.

@marcellamaki marcellamaki force-pushed the kdropdown-keyboard-navigation branch from f32776b to 07ca4ef Compare May 12, 2022 15:23
…ter manage keyboard event focus by default on interactive elements, while allowing explicit support for keyboard navigation
@marcellamaki
Copy link
Member Author

marcellamaki commented May 12, 2022

I've made some changes in this PR that were not changes when I started it, but now are reverting other changes that have been made in the interim around focus and keyboard navigation. Would especially appreciate review from @sairina and @MisRob in regards to these changes, as it essentially undid some recent changes.

For context and the thought process:

  • Most of the elements that are accessed through keyboard navigation are through tab navigation
  • However, a handful of elements such as dropdown menus, radio buttons, and scolling, use the arrow keys (as @nucleogenesis mentioned above) Further details
  • The original logic applied a focus outline to the default elements but did not check for whether or not there was a keyboard event, which caused the issue with the focus outline appearing around textbox elements on the sign in page, even when the user was not navigating with keyboard
  • The other consideration is when the focus is added through javascript, and is not tied to a keyboard event, but we want to set the focus outline (i.e. for the select dropdown menu), then we need to manage this as well
  • The original logic also did not include focus outline for KSwitch which was addressed

General approach to changes:

  • Some elements should always default to having a focus outline, and this should be associated only with keyboard events
  • Focus outline should not appear around "focusable elements" when navigated with the keyboard
  • There may be use cases where we want to add focus outline and keyboard navigation ability, especially around arrow keys, so we should have an option to add this explicitly
  • Goal: to reduce the number of places in future development that we need to manage an "activeClass" that requires an outline as a one off within Kolibri, especially for non-tabbable elements.

Outcomes of implementation:

Element and interaction Functionality
Navigating checkboxes with keyboard checkboxes-keyboard
Download resource button with keyboard download-keyboard
Dropdown menu with keyboard (arrow keys) dropdown-keyboard
Dropdown with mouse click (no focus) dropdown-mouseclick
Logging in using mouse (no focus outline) login-mouseclick
Logging in when starting to use the tab key to navigate login-start-tabbing
KSwitch (a variation of input=checkbox) with keyboard kswitch-keyboard

NOT SOLVED BY THIS

The user profile dropdown menu in the top right corner does not use this same style of menu. It is currently navigable with tab keys, which might be confusing to users... However it is being removed in 0.16. Worth discussing whether there should be a follow up issue to change this... I think it might be a low lift and the consistency might be beneficial?

@radinamatic
Copy link
Member

radinamatic commented May 13, 2022

Progress looks very exciting, thank you @marcellamaki!
I see nothing concerning in the screenshots and the description, very much looking forward to have an actual asset to test 😍

Copy link
Member

@MisRob MisRob left a comment

Choose a reason for hiding this comment

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

Thank you @marcellamaki, this is great work. I've only checked the code so far. To be honest, I don't recall exactly all updates to the tracking input modality script I did and reasons for them but I think that your updates with all background information and comments in this PR make sense overall. Thank you for sharing the WebAIM resource on keyboard testing, that's very helpful. I learned a lot from the discussion and work in this PR.

I left some minor comments, neither of them is blocking.

The only thing that needs to be resolved is kolibri-tools upgrade. I saw that you posted a message on Slack about it so I responded there with some issues I experienced.

lib/KDropdownMenu.vue Outdated Show resolved Hide resolved
lib/KDropdownMenu.vue Outdated Show resolved Hide resolved
@marcellamaki marcellamaki force-pushed the kdropdown-keyboard-navigation branch from 57a48ab to f60af80 Compare May 18, 2022 14:34
@marcellamaki marcellamaki requested a review from MisRob May 20, 2022 10:16
Comment on lines +120 to +123
document.body.setAttribute('modality', 'keyboard');
} else {
globalThemeState.inputModality = null;
document.body.setAttribute('modality', '');
Copy link
Contributor

@indirectlylit indirectlylit May 20, 2022

Choose a reason for hiding this comment

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

See learningequality/kolibri#4822 and learningequality/kolibri#4847 for some historical context on how the code got into its current state.

Copy link
Member

@rtibbles rtibbles left a comment

Choose a reason for hiding this comment

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

One thing still missing for the body modality attribute.

lib/KDropdownMenu.vue Outdated Show resolved Hide resolved
lib/styles/trackInputModality.js Outdated Show resolved Hide resolved
lib/styles/trackInputModality.js Show resolved Hide resolved
This pull request was closed.
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.

KDropdownMenu not keyboard navigable
7 participants