accessible-menu icon indicating copy to clipboard operation
accessible-menu copied to clipboard

Top link disclosure menu

Open NickDJM opened this issue 2 years ago • 25 comments

Description

Adding the new subclass for Disclosure Navigation Menu with Top-Level Links.

Another good example (specifically for hover options): https://www.davidmacd.com/widgets/menu/tutorial-ar/wcag-tutorial-add-hover-invisible.html

Related Issues

See #164

Completion criteria

  • [x] ~~Handle new topLevelSubmenuToggleSelector~~
  • [ ] Update hover methods to properly handle the new split toggle/link
  • [ ] Update keybindings to properly handle toggle vs link focus
  • [ ] Write tests for new menu type
  • [ ] Browser test new menu type where automated tests can't cover
  • [ ] Add documentation to explain how new menu type works

NickDJM avatar Mar 28 '22 03:03 NickDJM

I believe the initialization for the top level toggles is covered now. Keybindings are still super messed up, but tabbing/clicking through the menu seems to work.

NickDJM avatar Mar 30 '22 02:03 NickDJM

The hover functionality doesn't work as expected either. Hovering over either the link or the dropdown should open the submenu- only the submenu triggers opening at the moment.

I have added another task item to the initial MR description to handle this.

NickDJM avatar Mar 30 '22 02:03 NickDJM

Edit: I'm realizing by looking at this example that the toggle elements are already supposed to be there: https://codepen.io/pyrello/pen/WNdEKRQ (Saved from the CodePen button on https://www.w3.org/TR/wai-aria-practices-1.2/examples/disclosure/disclosure-navigation-hybrid.html)

@NickDJM We are working on implementing it as a way of testing and contributing back. We are not seeing the toggles. Is there something we need to change in our implementation? https://github.com/uiowa/uiowa/blob/310b799e1fdb28b5e077920f40b76e0f4320b629/docroot/themes/custom/uids_base/assets/js/accessible-menu.init.js#L4-L9

pyrello avatar Mar 30 '22 21:03 pyrello

@pyrello awesome, sounds good! Yeah the buttons need to be there already.

I'll be curious to see how you implement this into Drupal. I've been tempted to write a module that just adds an option to the menu interface that will just allow you to select the kind of menu you want and have it work automatically.

NickDJM avatar Mar 30 '22 22:03 NickDJM

@NickDJM We built a quick demo of our implementation: https://sandbox.dev.drupal.uiowa.edu/media. It actually works great already, although we have not fully tested it from an accessibility standpoint.

You indicated in previous comments that there appears to be problems with hover states and keybindings. What do we need to do to reproduce those issues so that we can help troubleshoot? We are looking for some direction as to how we can help wrap this thing up.

Thank you very much for your work on this!

pyrello avatar Apr 01 '22 21:04 pyrello

@pyrello For keybinding tests you can set optionalKeySupport to true. Once that's set you'll be able to navigate the menu with your arrow keys once you tab in.

The behaviour I was seeing was the arrows would only target the links inside the menu items and skip over the buttons.

We'll need to make sure all of the enter/space key bindings work as well- which I don't think they do.


For the hover issues we'll need to test hoverType set to "on" and "dynamic" to make sure it behaves similarly to what is shown here: https://www.davidmacd.com/widgets/menu/tutorial-ar/wcag-tutorial-add-hover-invisible.html

NickDJM avatar Apr 04 '22 13:04 NickDJM

@pyrello Taking a look at your sandbox thats up. I see you're using the button dropdown for child submenus as well- the initial implementation I have assumes the buttons would only be on the top level menu, however I think yours makes more sense.

It makes me wonder if we're going in the wrong direction for the subclass of menu... Part of me thinks it may be best to take a look at how the base menu functions and possibly just split out how it handles menu links vs menu toggles. If the base menu knows when to differentiate between links and toggles then it would remove the need for the new subclass (and all existing subclasses would gain the ability to have split links and toggles).

NickDJM avatar Apr 05 '22 13:04 NickDJM

This being said, we should pursue the subclass for now. If it makes more sense to merge it into base menu, we will.

NickDJM avatar Apr 05 '22 14:04 NickDJM

@NickDJM I did some keybinding and hover tests on https://sandbox.dev.drupal.uiowa.edu/media yesterday and here's a few things that I noticed.

Hover

  • “dynamic” only starts working after a dropdown has been clicked on once
  • “on” works when hovering on the button but not on the link next to the button

Keybinding

Arrows

  • Left to right arrows skip links and only go to buttons

Tabs

  • Tabbing goes to each link and button
    • https://www.w3.org/TR/wai-aria-practices-1.2/examples/disclosure/disclosure-navigation-hybrid.html has the reverse behavior - tabbing goes to each button and skips the links

Enter/Space:

  • Enter and spacebar on button opens menu once but doesn’t close it
    • https://www.w3.org/TR/wai-aria-practices-1.2/examples/disclosure/disclosure-navigation-hybrid.html toggles open and close with enter on button

bspeare avatar Apr 05 '22 14:04 bspeare

@bspeare dynamic hovering is only supposed to activate once a menu is first opened, so that's fine.

Hover

We'll need to make sure hoverType: "on" works for both the link and the button, and hoverType: "dynamic" should wait for the first button toggle and then work for both the link and button from then on.

Keybindings

Arrows:

Arrows will need to be fixed so it properly cycles through links and buttons sequentially.

Tabs:

I believe tabbing is fine as-is, it should cycle through all the links and buttons sequentially- if the example one isn't doing that its definitely a bug since their documentation says tab/shift tab should:

Move keyboard focus among top-level links and buttons, and if a dropdown is open, through links in the dropdown.

Enter/Space

We'll need to make sure it closes the menu as well.

NickDJM avatar Apr 05 '22 14:04 NickDJM

@NickDJM Thanks for the clarification!

bspeare avatar Apr 05 '22 14:04 bspeare

@NickDJM Thanks for taking a look at our example and providing clarification. For our initial release of this feature in our platform:

  • We are not concerned with left/right arrow keybinding working, since Superfish does not have that functionality and that is what we are currently using for our top level menu.
  • We will set hoverType: off until that is working and then add it as an optional enhancement later.
  • The enter/space toggle is a blocker, so if you have any thoughts on how we can help resolve that, we would like to help.

I am assuming we will be ready to adopt this branch prior to it getting merged (since we are getting some pressure to wrap up the first slice of this work). Our intention is to target a particular commit hash to ensure that we are pulling what we expect for our build process. As soon as this gets merged and a new release is tagged, we'll switch to using that.

Also, FYI, at this point we are doing a pretty bespoke implementation. Our early use case focuses on adding the option for this type of menu to blocks that are placed by users via Layout Builder. Eventually we are interested in adopting this as a replacement for our Superfish-based top-level navigation (which is placed via configuration). At that point in time, it might make sense to write a module to implement the functionality in a more generic way.

pyrello avatar Apr 05 '22 15:04 pyrello

Ok I have removed topLevelSubmenuToggleSelector since it really just added a load of complexity that didn't need to be there. We'll go with assuming all toggles are buttons for this menu type and people can use a class selector if they want something different.

NickDJM avatar Apr 06 '22 01:04 NickDJM

@pyrello I have corrected the enter/space command to toggle the submenus open/closed.

Now, this is still an issue since the event listener is on the menu item, not the toggle itself. This means if a user hits enter on the link instead of the button it will still toggle the submenu.

This is where the biggest issue lies... Its possible we might need to make a new class called MenuLink so we can track both links and toggles separately. This is going to be a pretty big change.

NickDJM avatar Apr 06 '22 02:04 NickDJM

Regardless of the new class, we'll still need a list of all links + toggles in the menu, which will need to be hooked into currentChild somehow. I'll need to think about this one since it's going to be changing a whole whack of things.

NickDJM avatar Apr 06 '22 02:04 NickDJM

@NickDJM Thanks for your follow-up! We have updated our example at https://sandbox.dev.drupal.uiowa.edu/media to include your recent commits. What we are seeing is that the enter/space keys focused on a toggle button opens a menu, but does not close it. This is true at all levels of the menu. Not sure if this is a problem with our implementation or not: https://github.com/uiowa/uiowa/blob/1b0ec0076e8f29d47558cad493b00a69a7c4a26a/docroot/themes/custom/uids_base/assets/js/accessible-menu.init.js#L35-L43

If you know what file we should be tinkering with to try to fix this, that would be helpful.

pyrello avatar Apr 06 '22 14:04 pyrello

As I have researched this I have found that the escape key is the intended way to exit the second level menus. Additionally, I have found multiple sources saying that this is the correct way to implement accessible menu navigation. Here are a few sources: https://www.evinced.com/blog/a11y-nav-menus/ https://www.smashingmagazine.com/2017/11/building-accessible-menu-systems/#keyboard-and-focus-behavior

So it actually seems like the menu is functioning correctly in accordance to accessibility Guidelines. My initial impression is that it is supposed to work this way to keep interaction consistent across menus, modals, etc.

GaryRidgway avatar Apr 08 '22 19:04 GaryRidgway

@pyrello currentChild is all handled int he menu class itself, not in the toggle or item classes. You'll need to look there. There are API docs if you need more information on how it all works: https://accessible-menu.netlify.app/basemenu#currentChild

Mostly this is changed by using the focusChild methods which handle changing the current child/menu item and also they check to see if the menu should actually focus the new child. We'll need to change how currentChild works for selector links and buttons and possibly change how the focusChild mehtods work.

NickDJM avatar Apr 11 '22 12:04 NickDJM

@GaryRidgway I would agree- I believe the official docs used to just say that it opens the menu. However, it looks like the wording changed to "toggles" the menu on W3C and their example opens and closes the menu, so it seems as though it should have this new functionality.

NickDJM avatar Apr 11 '22 12:04 NickDJM

@pyrello I pushed up a compiled version of the changes. If you're using the dist/ then it should work now.

NickDJM avatar Apr 11 '22 12:04 NickDJM

This is working as you described now @NickDJM , thanks!

GaryRidgway avatar Apr 11 '22 16:04 GaryRidgway

@NickDJM, on our platform, we have the option to add a menu item that is not a link (called the <nolink> option). It gets rendered as a <span> instead of an <a>. In our current menu system, the essentially serves as a trigger to show a drop-down menu. Here is an example. In this example, the “Media - YouTube” menu item is a <nolink>. We are experiencing quite an odd phenomenon with our <nolinks>. If you tab forward to the “Media - YouTube” item and press enter or space, it activates the link that it most recently passed over, in our example, the Media - Vimeo link. Alternatively, if you tab past the “Media - YouTube” menu item and then back to it with shift+tab, it activates the dropdown button that it just passed over (just to the right of the “Media - YouTube” menu item). It seems that the menu is holding on to the last action and activating it on enter when focusing the span. This may be a consequence of how we have this set up: https://github.com/uiowa/uiowa/blob/79b56633f0f032061dc01456f8f43fe290020586/docroot/themes/custom/uids_base/assets/js/accessible-menu.init.js#L47 Do we need to configure our implementation differently? Or is this a bug?

GaryRidgway avatar Apr 14 '22 17:04 GaryRidgway

@GaryRidgway without being able to debug the instantiated menu itself, I'm not sure why that would be happening-. Is there a reason you would want users to be able to focus the span at all? It's just adding a non-interactive item to the tab order.

NickDJM avatar Apr 18 '22 17:04 NickDJM

@NickDJM We figured out that it was some of our own custom code that was causing this issue by adding tabindex to the spans. We tested this and were able to move forward with it in its current state. Thanks for all your help!

pyrello avatar Apr 21 '22 02:04 pyrello

@pyrello Cool.

When I have some more free time I'll look into getting more work done for this menu type. I can ping you when its feature-complete so you know when you can fully upgrade to the new version of accessible menu.

NickDJM avatar Apr 21 '22 18:04 NickDJM

It's been a while, but I have a bit of time to work on this today. I have fixed the issue with arrow keys not being able to target the toggles, as well as escape keybindings not working to close open menus when you have the toggle focused.

NickDJM avatar Dec 09 '22 20:12 NickDJM

I believe this is functionally ready to go.

Still need documentation and tests written, but through my (very limited) manual testing it looks like everything works. Obviously the documentation and tests are 100% required, so there won't be anything merged in until those are done.

NickDJM avatar Dec 12 '22 14:12 NickDJM

Going to be finalizing all functionality and written tests over the next couple weeks.

To get the tests working in a cleaner way, this will be part of a break change so TopLinkDisclosureMenus will be part of 4.0.0.

NickDJM avatar Feb 06 '23 20:02 NickDJM