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

feat(web): keyboard accessible context menus #10017

Merged
merged 32 commits into from
Jun 18, 2024
Merged

Conversation

ben-basten
Copy link
Member

@ben-basten ben-basten commented Jun 7, 2024

Description

Enable arrow key navigation of dropdown menus. Accessibility features are based on this WCAG "actions menu" pattern:

https://www.w3.org/WAI/ARIA/apg/patterns/menu-button/examples/menu-button-actions-active-descendant/

This also simplifies implementing a ContextMenu dropdown, because the implementing component no longer needs to keep track of the dropdown visibility state or position. All of that logic is handled internally within the component.

Also in this change:

  • rename AssetSelectContextMenu to ButtonContextMenu, to make the naming more accurately reflect what it does
  • albums list dropdown menu now uses the i18n translations
  • darken the active option color in the context menu to make it easier to see
  • context menu is scrollable on short screen sizes
  • maintain context menu position on screen resize
  • the right click context menu on the albums list page supports arrow key navigation

How Has This Been Tested?

  • VoiceOver screen reader testing
    • works with Firefox, Chrome, and Safari on MacOS
    • example test scenarios: navigating with arrow keys, hovering over items with a mouse, clicking options with enter/spacebar/mouse, clicking away to dismiss, using the tab key to dismiss, using the escape key to dismiss
  • NVDA testing on Windows
    • I do not have a Windows environment, so if anyone has the tools to try this it would be very helpful :)

Verified that options in affected context menus behave as expected:

  • Asset viewer options
  • External library admin settings
  • Albums card, in the albums list
  • Albums detail, in the control bar
  • Albums detail, when a photo is selected
  • Album share options modal, to change permissions and remove users
  • People card, in the people list
  • Memory viewer, when a photo is selected
  • Archive, when a photo is selected
  • Favorites, when a photo is selected
  • Partners, on the album card
  • Person detail, in the control bar
  • Person detail, when a photo is selected
  • Photos, when a photo is selected
  • Search, when a photo is selected

Screenshots

Example dropdown menu, with the darker selected color.

Expand for screenshot

dropdown

@ben-basten ben-basten changed the title feat(web,a11y): keyboard accessible dropdown menus feat(web): keyboard accessible dropdown menus Jun 7, 2024
- configurable title
- focus management: tab keys, clicks, closing the menu
- automatically closing when an option is selected
- adjust the aria attributes
- intuitive escape key propagation
- extract context into its own file
- export selectedColor to prevent unexpected styling
- better context function naming
Copy link
Contributor

@jrasm91 jrasm91 left a comment

Choose a reason for hiding this comment

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

It is a lot of changes. It seems like the list enhancements could have been separated out into a different change set.

Comment on lines +27 to +29
export let ariaHasPopup: boolean | undefined = undefined;
export let ariaExpanded: boolean | undefined = undefined;
export let ariaControls: string | undefined = undefined;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there is an export HTML*Type field you can use to get the actual type for these properties.

Copy link
Member Author

Choose a reason for hiding this comment

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

In my opinion, I find the syntax for automatically adding the HTML props a little confusing/cumbersome, especially because this CircleIconButton component has so many props. Here's a similar example:

interface $$Props extends HTMLImgAttributes {
noText?: boolean;
draggable?: boolean;
}
export let noText = false;
export let draggable = false;

I'm wondering if this would be an easier change to do once we have the new Svelte 5 prop typing? Happy to add the automatic HTML props now if that's preferred.

https://svelte-5-preview.vercel.app/docs/runes#$props

web/src/lib/components/faces-page/people-card.svelte Outdated Show resolved Hide resolved
web/src/lib/components/faces-page/people-card.svelte Outdated Show resolved Hide resolved
web/src/lib/actions/list-navigation.ts Outdated Show resolved Hide resolved
@ben-basten
Copy link
Member Author

It is a lot of changes. It seems like the list enhancements could have been separated out into a different change set.

Thank you for the time and feedback, @jrasm91!

I agree, the list changes expanded the scope of the PR. I'll revert those and put them into their own Svelte action, which I think would still be helpful to prevent duplicated code between the ButtonContextMenu and RightClickContextMenu.

…/accessible-menu-v2, fix merge conflicts
- better prop naming for ButtonContextMenu
@ben-basten ben-basten changed the title feat(web): keyboard accessible dropdown menus feat(web): keyboard accessible context menus Jun 15, 2024
- also: minor cleanup of the context-menu-navigation Svelte action
@ben-basten ben-basten marked this pull request as ready for review June 16, 2024 16:13
@ben-basten
Copy link
Member Author

This is ready for review! I've responded to open feedback and closed the remaining tasks on my list.

@alextran1502 alextran1502 self-assigned this Jun 17, 2024
Copy link
Contributor

@alextran1502 alextran1502 left a comment

Choose a reason for hiding this comment

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

Good work! Thanks Ben!

@alextran1502 alextran1502 merged commit b71aa44 into main Jun 18, 2024
22 checks passed
@alextran1502 alextran1502 deleted the feat/accessible-menu-v2 branch June 18, 2024 03:52
@waclaw66
Copy link
Contributor

waclaw66 commented Jun 25, 2024

@ben-basten this PR introduces a bug that makes three dot button still visible after context menu is closed.

2024-06-25.14.22.24.mp4

@ben-basten
Copy link
Member Author

@waclaw66 This is working as designed - focus is on the 3 dot button after the context menu closes, so it stays visible.

New in this PR is that focus returns to the button that triggered the context menu when it is closed. This allows keyboard users to regain their previous focus position after interacting with a context menu. The same behavior occurs when a mouse user clicks away from the menu.

Test scenario to check this:

  1. Click the 3 dots to open the album context menu
  2. Click away to close the menu
  3. Press the enter key or spacebar. The context menu should open again, because the button has focus.

I thought this made sense since buttons/links on the screen aren't interactive when clicking away from the context menu. An option we have is to consider disabling this refocus behavior for clicking away.

@waclaw66
Copy link
Contributor

waclaw66 commented Jun 25, 2024

@ben-basten That make sense, thanks for detailed explanation as usual.

@waclaw66
Copy link
Contributor

I thought this made sense since buttons/links on the screen aren't interactive when clicking away from the context menu. An option we have is to consider disabling this refocus behavior for clicking away.

Loosing focus and forwarding click event should be consolidated though. Some context menus (asset viewer, face) allow to click outside and forward click event to the target control (e.g. left panel), album menu doesn't allow that. Please check a compare the behaviour.

@ben-basten
Copy link
Member Author

Loosing focus and forwarding click event should be consolidated though. Some context menus (asset viewer, face) allow to click outside and forward click event to the target control (e.g. left panel), album menu doesn't allow that. Please check a compare the behaviour.

Yeah, the albums page is unique because it has a context menu that appears when you right click on the album cover. When I right click on a website on my Mac, the default MacOS context menu doesn't let me click anything behind it until the context menu is dismissed. So, it makes sense to imitate that behavior with our custom right click context menu.

However, this behavior doesn't make as much sense when the 3 dots button on the top right of the album cover is clicked, because we already have an established pattern for how that should work everywhere else.

The fix here would be to move the 3 dot menu from using the RightClickContextMenu component to the ButtonContextMenu component. I determined this change to be out of scope in this PR because this is how it was previously built, but I agree that it would be a better experience for that button to have the same behavior as other menus. For example, a benefit of migrating would include automatically selecting the first item in the menu when it is opened using the enter key or space bar.

Feel free to pitch out a PR for this, I'm not sure when I'll have time to make this change yet. This can certainly be improved, thanks for calling it out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants