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

TreeView: Implement arrow key navigation #2331

Merged
merged 46 commits into from Sep 20, 2022
Merged

TreeView: Implement arrow key navigation #2331

merged 46 commits into from Sep 20, 2022

Conversation

colebemis
Copy link
Contributor

@colebemis colebemis commented Sep 14, 2022

Summary

Adds support for arrow key navigation of a TreeView using aria-activedescendant (based on the TreeView API spec).

πŸ‘‰ Try it out

CleanShot.2022-09-15.at.15.39.38.mp4

Impact

This PR will enable keyboard and screen reader users to navigate a TreeView.

VoiceOver demo

Screen.Recording.2022-09-15.at.3.51.06.PM.mov

Test cases

Here are the test cases I wrote for the TreeView keyboard interactions (based on the ARIA spec):

Keyboard interactions
    ArrowDown
      βœ“ moves aria-activedescendant to the next visible treeitem (118 ms)
    ArrowUp
      βœ“ moves aria-activedescendant to the previous visible treeitem (127 ms)
    ArrowLeft
      βœ“ collapses an expanded item (47 ms)
      βœ“ does nothing on a root-level collapsed item (27 ms)
      βœ“ does nothing on a root-level end item (19 ms)
      βœ“ moves aria-activedescendant to parent of end item (54 ms)
      βœ“ moves aria-activedescendant to parent of collapsed item (77 ms)
    ArrowRight
      βœ“ expands a collapsed item (42 ms)
      βœ“ moves aria-activedescendant to first child of an expanded item (45 ms)
      βœ“ does nothing on an end item (46 ms)
    Home
      βœ“ moves aria-activedescendant to first visible item (100 ms)
    End
      βœ“ moves aria-activedescendant to last visible item (141 ms)
    Enter
      βœ“ calls onSelect function if provided (18 ms)
      βœ“ toggles expanded state if no onSelect function is provided (72 ms)
      βœ“ navigates to href if provided (72 ms)

Reviewers

I'm open to feedback about any part of the implementation but specifically, I'd love confirmation that the keyboard and screen reader behavior work as expected.

Merge checklist

  • Added/updated tests
  • Added/updated documentation
  • Tested in Chrome
  • Tested in Firefox
  • Tested in Safari
  • Tested in Edge

@changeset-bot
Copy link

changeset-bot bot commented Sep 14, 2022

πŸ¦‹ Changeset detected

Latest commit: 574d2c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@primer/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Sep 14, 2022

size-limit report πŸ“¦

Path Size
dist/browser.esm.js 76.39 KB (0%)
dist/browser.umd.js 77.05 KB (0%)

@colebemis colebemis temporarily deployed to github-pages September 14, 2022 00:58 Inactive
@colebemis colebemis temporarily deployed to github-pages September 14, 2022 01:07 Inactive
@colebemis colebemis temporarily deployed to github-pages September 14, 2022 19:03 Inactive
@colebemis colebemis temporarily deployed to github-pages September 15, 2022 23:21 Inactive
@colebemis colebemis temporarily deployed to github-pages September 16, 2022 16:02 Inactive
Copy link
Contributor

@mperrotti mperrotti left a comment

Choose a reason for hiding this comment

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

This is very exciting! Everything is looking good, but we don't want Space to call onSelect or expand a parent node. We're reserving that for when/if we have nodes that can be checked or unchecked.

For future reference, check Primer's documentation on tree view accessibility, before the W3C's tree view APG. I worked with @jscholes and the a11y team to suss out what the APG gets "wrong" and define improved patterns.


I skimmed the implementation and mostly focused on testing the UI. I can look closer at the code once @ericwbailey gives his βœ… on the keyboard navigation.

src/TreeView/TreeView.tsx Show resolved Hide resolved
src/TreeView/TreeView.tsx Show resolved Hide resolved
src/TreeView/TreeView.test.tsx Show resolved Hide resolved
@mperrotti
Copy link
Contributor

Is it expected that none of the "links" in File Tree With Directory Links do anything when they're clicked or you press "Enter" when focused on them?

@colebemis colebemis temporarily deployed to github-pages September 16, 2022 22:13 Inactive
@colebemis colebemis temporarily deployed to github-pages September 16, 2022 22:32 Inactive
@jdrush89
Copy link
Contributor

@colebemis @mperrotti should loading items in the tree be focusable? Or should aria-activedescendant skip over them?

@ericwbailey
Copy link
Contributor

@jdrush89 We'll want only one focusable node for loading node(s), with an announcement that indicates how many loading nodes are present (if we know). More granular behavior to follow in the second round of TreeView API work.

@colebemis colebemis removed the request for review from rezrah September 19, 2022 15:00
@colebemis colebemis temporarily deployed to github-pages September 19, 2022 15:08 Inactive
Copy link
Contributor

@mperrotti mperrotti left a comment

Choose a reason for hiding this comment

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

Approval assumes @ericwbailey also approves.

)
}

// DOM utilities used for focus management
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking nitpicks:

  1. Would it make more sense to move these to a utilities file instead of keeping them in TreeView.tsx?
  2. Should these functions have their own unit tests? Or do we think the TreeView tests are sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Would it make more sense to move these to a utilities file instead of keeping them in TreeView.tsx?

Yeah, it might make sense to pull this out into a hook later. I'm going to keep it all in the same file for now so I can iterate more quickly

  1. Should these functions have their own unit tests? Or do we think the TreeView tests are sufficient?

I'd like to avoid testing implementation details like this because we'd need to update lots of tests if we decide to change the underlying implementation (even if we don't change behavior). I think the "Keyboard interactions" unit tests give us solid coverage.

Copy link
Contributor

@ericwbailey ericwbailey left a comment

Choose a reason for hiding this comment

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

I've just tested this in VoiceOver and NVDA and it's looking/sounding great! Amazing stuff πŸŽ‰

@colebemis colebemis enabled auto-merge (squash) September 20, 2022 16:08
@colebemis colebemis merged commit 31b8804 into main Sep 20, 2022
@colebemis colebemis deleted the treeview-arrow-keys branch September 20, 2022 16:15
@colebemis colebemis temporarily deployed to github-pages September 20, 2022 16:16 Inactive
@primer-css primer-css mentioned this pull request Sep 20, 2022
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.

None yet

4 participants