Skip to content

Conversation

@TylerJDev
Copy link
Member

@TylerJDev TylerJDev commented Sep 19, 2024

Closes https://github.com/github/primer/issues/3378

Usages of Overlay tend to lean more towards a dialog across GH. This PR aims to define it as a dialog in most cases, provided with a focus trap that's toggled via the newly added focusTrap prop.

Changelog

New

  • Add role="dialog" and aria-modal="true" to Overlay component

Rollout strategy

  • Patch release
  • Minor release
  • Major release; if selected, include a written rollout or migration plan
  • None; if selected, include a brief description as to why

Testing & Reviewing

Merge checklist

@changeset-bot
Copy link

changeset-bot bot commented Sep 19, 2024

🦋 Changeset detected

Latest commit: 5627e4f

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 Minor

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 19, 2024

size-limit report 📦

Path Size
packages/react/dist/browser.esm.js 97.85 KB (+0.02% 🔺)
packages/react/dist/browser.umd.js 98.16 KB (+0.1% 🔺)

@TylerJDev TylerJDev changed the title Overlay: Add role="dialog", focus trap to Overlay` Overlay: Add role="dialog", focus trap to Overlay Sep 19, 2024
@github-actions github-actions bot temporarily deployed to storybook-preview-4990 September 19, 2024 14:38 Inactive
@primer-integration
Copy link

👋 Hi from github/github! Your integration PR is ready: https://github.com/github/github/pull/343407

@TylerJDev
Copy link
Member Author

This change essentially turns Overlay into a "Dialog" in the sense of role="dialog" and aria-modal="true" being added. A focus trap is also added by default, and is enabled if there are focusable elements inside of the overlay. This change will not affect overlays that already have a role attribute, as long as that role attribute isn't role="dialog".

Rollout plan:

  • Add role="none" to existing Overlay components that do not implicitly set role already
  • Add focusTrap={false} to Overlay components that are used as Dialogs currently, but do not utilize a focus trap.

portalContainerName?: string
preventFocusOnOpen?: boolean
role?: AriaRole
focusTrap?: boolean
Copy link
Member Author

Choose a reason for hiding this comment

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

Added a new prop in case there's an implementation that wants to be a dialog, but doesn't want the focus trap applied. This is a very specific case, and ideally won't be necessary in more than a handful of instances.

@TylerJDev TylerJDev marked this pull request as ready for review September 20, 2024 23:22
@TylerJDev TylerJDev requested a review from a team as a code owner September 20, 2024 23:22
@TylerJDev TylerJDev requested a review from jonrohan September 20, 2024 23:22
@TylerJDev
Copy link
Member Author

@primer/engineer-reviewers - Hey team! Would love any additional eyes on this PR, mainly in regards to my rollout plan.

Copy link
Member

@francinelucca francinelucca left a comment

Choose a reason for hiding this comment

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

LGTM! One minor suggestion and one question:
https://github.com/github/primer/issues/3378 suggests:

allow users to switch to/from the non-modal dialog using Ctrl+F6 / Command+F6

Did we implement that? I couldn't get that to go in my tests

},
{
"name": "focusTrap",
"type": "string",
Copy link
Member

Choose a reason for hiding this comment

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

should this be a boolean instead?

Suggested change
"type": "string",
"type": "boolean",

Copy link
Contributor

@keithamus keithamus left a comment

Choose a reason for hiding this comment

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

If it is a role=dialog and has focus trapping, it should be a <dialog> element with showModal() called.

We should steer away from useFocusTrap and use showModal() on <dialog> elements instead. It comes with many other small benefits such as retaining previously-focused-element.

If you need any assistance on this please reach out and I'll happily pair.

@TylerJDev
Copy link
Member Author

If it is a role=dialog and has focus trapping, it should be a <dialog> element with showModal() called.

We should steer away from useFocusTrap and use showModal() on <dialog> elements instead. It comes with many other small benefits such as retaining previously-focused-element.

That makes sense! I'm curious if we'd want this to be true for components that consume Overlay or AnchoredOverlay (e.g. ActionMenu, SelectPanel), as they rely on Overlay internally. I guess it would be worth making those components utilize Dialog, as we utilize it in the PVC SelectPanel already. But I'm curious what you think? This seems like it would require more effort and testing, but could be worth it in the long run.

Right now, this PR will only affect components that utilize Overlay in a standalone context. Components that utilize Overlay like ActionMenu would retain the same semantics/roles even though it technically uses it internally to render the menu. We could see about conditionally rendering a <dialog> vs the current <div> container but only in instances where it's being used as a standalone component, but I'm wondering if that's worth it or not 🤔

@keithamus
Copy link
Contributor

I think Dialog and components that use <dialog> can be discrete. I see little value in mapping our React library to individual HTML elements.

As for conditionally rendering <dialog> vs <div>, that kind of seems fine to me but I’d actually sooner see us split out ActionMenu to not use Overlay which is a case I’ve made before about the general reuse of these components; I don’t think there is enough overlap to consider reuse here. There can be multiple discrete types of floating UI.

@jonrohan jonrohan removed their request for review September 26, 2024 21:04
@TylerJDev TylerJDev marked this pull request as draft November 4, 2024 17:35
@TylerJDev TylerJDev closed this Dec 2, 2024
@jonrohan jonrohan deleted the tylerjdev/overlay-dialog branch May 9, 2025 18:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants