-
Notifications
You must be signed in to change notification settings - Fork 538
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
Add support for nested submenus to ActionMenu
#4386
Conversation
🦋 Changeset detectedLatest commit: d207bf7 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
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 |
size-limit report 📦
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @iansan5653 👋🏻 Thanks so much for creating this PR 🙏🏻
I am not sure if we have had any discussions around the API, please let me know if I miss any context on that but I wonder if we have explored other options before settling on creating a new sub components. I think the functionality works great, thanks so much again, I just wanted to make sure we are not overloading the component with sub components if we have other feasible alternatives. Like using an existing anchor component maybe 🤷🏻♀️
<ActionMenu.Anchor>
<ActionList.Item>
Paste special
<ActionList.TrailingVisual>
<ChevronRightIcon />
</ActionList.TrailingVisual>
</ActionList.Item>
</ActionMenu.Anchor>
vs
<ActionMenu.MenuItemAnchor>Paste special</ActionMenu.MenuItemAnchor>
Especially since we are relying on context to determine if the menu is a submenu. This option is more manually constructing it but I wonder if it feels intuitive enough to folks without introducing more sub components to ActionMenu. Or maybe introducing a new sub component reduces complexity under the hood, it is just food for thoughts to talk about the api options.
Tagging @siddharthkp to get his thoughts around the API
Thanks again for pushing this PR, super super helpful! 🙌🏻
expect(subSubmenuAnchor).toHaveAttribute('aria-expanded') | ||
|
||
await user.keyboard('{Escape}') | ||
expect(subSubmenuAnchor).not.toHaveAttribute('aria-expanded') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we also check if the sub sub menu is not in the documents? like expect(component.queryByRole('menu')).not.toBeInTheDocument()
or not really needed?
Unlike
For (1) I agree it's pretty straightforward for consumers to just build it themselves - we're not gaining much by providing a component for that. Although I do prefer to provide the trailing visual by default because I'm concerned we might end up with inconsistent iconography otherwise. It's important to have a consistent visual here so we can intuitively indicate (to sighted users) that a submenu is available. If some apps use For (2) I think we definitely have to do this internally somehow - we can't expect consumers to always wire up the correct keyboard event in a consistent manner. 💭 We definitely could explore alternative APIs that meet those requirements. Since we do have the context The tricky part then is actually just the trailing visual (1). How do we render that by default? One option might be for
This could work - we could easily change Maybe we can update it for now, then in a future major release we could plan to rename |
Hey @iansan5653 thanks for the reply!
That is true, I underestimated the trailing visual issue.
😄 Yeah that is not a good enough reason to manipulate the children, I agree.
This could definitely work and make it intuitive enough when we update the name to make it more generic as you mentioned like |
440aa28
to
e8223b1
Compare
Hi @iansan5653 !
|
This will work in practice even if it's a lint error, because |
<ActionList.Item> | ||
<ActionList.LeadingVisual> | ||
<SparkleFillIcon /> | ||
</ActionList.LeadingVisual> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳
Right!! That is great to know. Yeah I thought that it is not very straightforward to solve this but wanted to mention anyway. I was mainly worry about the sighted keyboard users but seems like this is a common learnt pattern, I guess we are good here as well 👍🏻
Yeah this is what I was thinking as a test case. Like https://github.com/github/github/blob/master/ui/packages/copilot-chat/components/ChatReference.tsx#L90. I tried with a pseudo story and it works 👍🏻 |
@iansan5653 I just realised that the tests are failing. Could you please make sure they are all green as well before going ahead with merge? |
This reverts commit 4e281b2.
This reverts commit 4e281b2.
* Add new props to `FormControl.Label` * Add conditional * Add changeset * Update docs json * Add more examples * chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 (#4549) Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/mde/ejs/releases) - [Commits](mde/ejs@v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: ejs dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * BranchName: Add style for span and add v8 tokens (#4556) * add style for branchName as span adn add v8 tokens * added changeset * Update thin-ligers-turn.md * test(vrt): update snapshots * use not a instead of matching for span --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: lukasoppermann <lukasoppermann@users.noreply.github.com> * refactor(Banner): update region to use a dedicated aria-label (#4539) * refactor(Banner): update region to use a dedicated aria-label * chore: add changeset, update config to exclude codesandbox * feat: add aria-label to Banner * Update packages/react/src/Banner/Banner.test.tsx Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * Update packages/react/src/Banner/Banner.test.tsx Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * test: update test label with aria-label --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * chore(deps-dev): bump cross-env from 7.0.2 to 7.0.3 (#4561) Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 7.0.2 to 7.0.3. - [Release notes](https://github.com/kentcdodds/cross-env/releases) - [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md) - [Commits](kentcdodds/cross-env@v7.0.2...v7.0.3) --- updated-dependencies: - dependency-name: cross-env dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/plugin-transform-modules-commonjs (#4562) Bumps [@babel/plugin-transform-modules-commonjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-commonjs) from 7.23.3 to 7.24.1. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.1/packages/babel-plugin-transform-modules-commonjs) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-modules-commonjs" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump jest-fail-on-console from 3.1.1 to 3.2.0 (#4563) Bumps [jest-fail-on-console](https://github.com/ValentinH/jest-fail-on-console) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/ValentinH/jest-fail-on-console/releases) - [Commits](ValentinH/jest-fail-on-console@v3.1.1...v3.2.0) --- updated-dependencies: - dependency-name: jest-fail-on-console dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(FeatureFlags): broaden feature flag type to accept undefined (#4554) * feat(FeatureFlags): loosen feature flag type to accept undefined * chore: add changeset * Update .changeset/grumpy-coats-worry.md --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * prevent form submit (#4551) * deprecate title prop on ActionList.Group component on docs (#4544) * chore: add hydro analytics to storybook (#4558) * chore: add hydro analytics to storybook * chore: use previewHead over managerHead * Update build-docs --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * Revert "Revert "Add support for nested submenus to `ActionMenu`"" (#4486) * Revert "Revert "Add support for nested submenus to `ActionMenu` (#4386)" (#4472)" This reverts commit 82072eb. * just want a change to trigger rebuild --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: Pavithra Kodmad <pksjce@github.com> * chore(deps): update typescript to 5.4.5 (#4568) Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * Use dynamic height and width for dialogs (#4567) * Use dynamic height and width for dialogs * Update tall-forks-bathe.md --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> * Make asterisk default, update story scenarios * Update packages/react/src/FormControl/FormControl.docs.json Co-authored-by: Owen Niblock <owenniblock@github.com> * Update packages/react/src/internal/components/InputLabel.tsx Co-authored-by: Owen Niblock <owenniblock@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lukas Oppermann <lukasoppermann@github.com> Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: lukasoppermann <lukasoppermann@users.noreply.github.com> Co-authored-by: Josh Black <joshblack@github.com> Co-authored-by: Josh Black <joshblack@users.noreply.github.com> Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> Co-authored-by: Armağan <broccolinisoup@github.com> Co-authored-by: Ian Sanders <iansan5653@github.com> Co-authored-by: Pavithra Kodmad <pksjce@github.com> Co-authored-by: Dusty Greif <dgreif@users.noreply.github.com> Co-authored-by: Owen Niblock <owenniblock@github.com>
* Add new props to `FormControl.Label` * Add conditional * Add changeset * Update docs json * Add more examples * chore(deps-dev): bump ejs from 3.1.9 to 3.1.10 (#4549) Bumps [ejs](https://github.com/mde/ejs) from 3.1.9 to 3.1.10. - [Release notes](https://github.com/mde/ejs/releases) - [Commits](mde/ejs@v3.1.9...v3.1.10) --- updated-dependencies: - dependency-name: ejs dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * BranchName: Add style for span and add v8 tokens (#4556) * add style for branchName as span adn add v8 tokens * added changeset * Update thin-ligers-turn.md * test(vrt): update snapshots * use not a instead of matching for span --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: lukasoppermann <lukasoppermann@users.noreply.github.com> * refactor(Banner): update region to use a dedicated aria-label (#4539) * refactor(Banner): update region to use a dedicated aria-label * chore: add changeset, update config to exclude codesandbox * feat: add aria-label to Banner * Update packages/react/src/Banner/Banner.test.tsx Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * Update packages/react/src/Banner/Banner.test.tsx Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * test: update test label with aria-label --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> * chore(deps-dev): bump cross-env from 7.0.2 to 7.0.3 (#4561) Bumps [cross-env](https://github.com/kentcdodds/cross-env) from 7.0.2 to 7.0.3. - [Release notes](https://github.com/kentcdodds/cross-env/releases) - [Changelog](https://github.com/kentcdodds/cross-env/blob/master/CHANGELOG.md) - [Commits](kentcdodds/cross-env@v7.0.2...v7.0.3) --- updated-dependencies: - dependency-name: cross-env dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @babel/plugin-transform-modules-commonjs (#4562) Bumps [@babel/plugin-transform-modules-commonjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-commonjs) from 7.23.3 to 7.24.1. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.24.1/packages/babel-plugin-transform-modules-commonjs) --- updated-dependencies: - dependency-name: "@babel/plugin-transform-modules-commonjs" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump jest-fail-on-console from 3.1.1 to 3.2.0 (#4563) Bumps [jest-fail-on-console](https://github.com/ValentinH/jest-fail-on-console) from 3.1.1 to 3.2.0. - [Release notes](https://github.com/ValentinH/jest-fail-on-console/releases) - [Commits](ValentinH/jest-fail-on-console@v3.1.1...v3.2.0) --- updated-dependencies: - dependency-name: jest-fail-on-console dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feat(FeatureFlags): broaden feature flag type to accept undefined (#4554) * feat(FeatureFlags): loosen feature flag type to accept undefined * chore: add changeset * Update .changeset/grumpy-coats-worry.md --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * prevent form submit (#4551) * deprecate title prop on ActionList.Group component on docs (#4544) * chore: add hydro analytics to storybook (#4558) * chore: add hydro analytics to storybook * chore: use previewHead over managerHead * Update build-docs --------- Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * Revert "Revert "Add support for nested submenus to `ActionMenu`"" (#4486) * Revert "Revert "Add support for nested submenus to `ActionMenu` (#4386)" (#4472)" This reverts commit 82072eb. * just want a change to trigger rebuild --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: Pavithra Kodmad <pksjce@github.com> * chore(deps): update typescript to 5.4.5 (#4568) Co-authored-by: Josh Black <joshblack@users.noreply.github.com> * Use dynamic height and width for dialogs (#4567) * Use dynamic height and width for dialogs * Update tall-forks-bathe.md --------- Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> * Make asterisk default, update story scenarios * Update packages/react/src/FormControl/FormControl.docs.json Co-authored-by: Owen Niblock <owenniblock@github.com> * Update packages/react/src/internal/components/InputLabel.tsx Co-authored-by: Owen Niblock <owenniblock@github.com> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Lukas Oppermann <lukasoppermann@github.com> Co-authored-by: Siddharth Kshetrapal <siddharthkp@github.com> Co-authored-by: lukasoppermann <lukasoppermann@users.noreply.github.com> Co-authored-by: Josh Black <joshblack@github.com> Co-authored-by: Josh Black <joshblack@users.noreply.github.com> Co-authored-by: Kate Higa <16447748+khiga8@users.noreply.github.com> Co-authored-by: Armağan <broccolinisoup@github.com> Co-authored-by: Ian Sanders <iansan5653@github.com> Co-authored-by: Pavithra Kodmad <pksjce@github.com> Co-authored-by: Dusty Greif <dgreif@users.noreply.github.com> Co-authored-by: Owen Niblock <owenniblock@github.com>
ActionMenu
has Primer designs and docs for nesting, but has never actually supported it, reading:👋 I am a contributor! And huge kudos to @cheshire137 as well since this PR is mostly stealing our work from the internal
NestableActionMenu
recipe.Based on my understanding of the W3 guidance on menus, submenus should meet the following requirements:
aria-haspopup
andaria-expanded
(when expanded)Fortunately meeting these requirements with the existing
ActionMenu
architecture is actually pretty straightforward:A new componentAutomatic application of a trailing visual and right arrow event handler when the submenu anchor isActionMenu.MenuItemAnchor
renders anActionList.Item
with a trailing visual as the menu's anchorActionList.Item
ActionMenu
internally determines if it is a submenu in order to close parent menus when necessary and to bind left/right navigationAnchoredOverlay
already assigns the right ARIA attributes to the menu item anchorThe result is an intuitive submenu API that 'just works':
Screen.Recording.2024-03-13.at.12.50.45.PM.mov
The only thing I'm not so sure of is the naming ofActionMenu.MenuItemAnchor
. It's not consistent withActionMenu.Button
, but I figured just calling itActionMenu.MenuItem
would be confusing. Open to suggestions here.Changelog
New
ActionMenu
Rollout strategy
Testing & Reviewing
Merge checklist