-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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(react-dialog): supports 1st rule of ARIA #24525
feat(react-dialog): supports 1st rule of ARIA #24525
Conversation
📊 Bundle size report
Unchanged fixtures
|
Asset size changesSize Auditor did not detect a change in bundle size for any component! Baseline commit: 9e604a18ef914090301b4d0cd0b602f646f5719c (build) |
Perf Analysis (
|
Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
---|---|---|---|---|---|
Avatar | mount | 1329 | 1299 | 5000 | |
Button | mount | 943 | 963 | 5000 | |
FluentProvider | mount | 1571 | 1553 | 5000 | |
FluentProviderWithTheme | mount | 624 | 627 | 10 | |
FluentProviderWithTheme | virtual-rerender | 587 | 585 | 10 | |
FluentProviderWithTheme | virtual-rerender-with-unmount | 625 | 632 | 10 | |
MakeStyles | mount | 1913 | 1903 | 50000 | |
SpinButton | mount | 2498 | 2525 | 5000 |
6638c42
to
5afee67
Compare
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit e698797:
|
f7b63fd
to
b0338e1
Compare
not sure if |
according to our support matrix, we support native |
I'm concerned for desktop safari 13 in particular 👀 |
I hear you @Hotell, the most straight solution would be to use our own |
b0338e1
to
2c82768
Compare
Is there a benefit to using the native There's also the issue that only Safari 15.4+ supports Scott's dialog article has more or less the same recommendation (last updated March 2022): https://www.scottohara.me/blog/2019/03/05/open-dialog.html. He's been much more involved in the |
Thanks for the comment @smhigley, that's definitely a valid question! The initial focus behaviour wouldn't be an issue, as focus is handled internally no matter if a I'd love to hear more about it if you could get Scott's opinion on the usage of I guess the biggest benefit would be to ensure best native behaviour in cases where a browser actually supports |
After talking to Scott, I'm now more ambivalent 😅. Having
|
Well, the approach on v9 so far for
Fair enough, as @Hotell has already pointed for the
Can you elaborate on why @smhigley? for the tests I've done so far (visually), on major browsers all of them work fine with
Yeah, this definitely didn't cross my mind, I've already noticed some difficulties while trying to substitute |
does safari <15 support |
5a62f90
to
ea19f45
Compare
Yes it does work @ling1726! Only problem right now is regarding |
This PR got a little bigger than I expected, I'll try to split it |
ea19f45
to
52468fd
Compare
I'll keep this PR as draft and blocked meanwhile there are still one major discussion to be clarified regarding |
6683da8
to
cd7335b
Compare
Ok, after some testing and a few discussions, there's one main scenario (and Safari) that is troubling right now with native
|
d83de7b
to
871b334
Compare
871b334
to
e698797
Compare
const dialogRef = useDialogContext_unstable(ctx => ctx.dialogRef); | ||
const open = useDialogContext_unstable(ctx => ctx.open); | ||
const requestOpenChange = useDialogContext_unstable(ctx => ctx.requestOpenChange); | ||
const dialogTitleID = useDialogContext_unstable(ctx => ctx.dialogTitleID); | ||
const dialogBodyID = useDialogContext_unstable(ctx => ctx.dialogBodyID); | ||
const isNestedDialog = useDialogContext_unstable(ctx => ctx.isNestedDialog); | ||
|
||
const handleNativeClick = useEventCallback((event: React.MouseEvent<DialogSurfaceElementIntersection>) => { |
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.
nit: you could probably return the native control hooks from another hook
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.
Supports as="dialog" at DialogSurface by default with possibility to opt-out of semantic element with as="div"
Sorry, but I don't understand this. Our current browser support matrix starts with Safari 14.1 while dialog
works only in Safari 15.4 (according to MDN). What is expected from developers in a product if they support Safari 14.3? Go to every DialogSurface
and specify as="div"
?
@@ -0,0 +1,7 @@ | |||
{ | |||
"type": "prerelease", | |||
"comment": "feat(react-dialog): 1st rule of ARIA for Dialog", |
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.
"comment": "feat(react-dialog): 1st rule of ARIA for Dialog", | |
"comment": "feat(react-dialog): use native dialog element", |
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.
I'll be addressing any Safari related issues on a separate PR, since some cases need investigation @layershifter, but in the worst case scenario of not getting native <dialog>
to work out of of the box then I'll have to default to div
and add dialog
as an option
packages/react-components/react-dialog/src/components/Dialog/Dialog.types.ts
Show resolved
Hide resolved
@@ -15,7 +15,7 @@ export const NoFocusableElement = () => { | |||
<DialogTitle>Dialog Title</DialogTitle> | |||
<DialogBody> | |||
<p>⛔️ A Dialog without focusable elements is not recommended!</p> | |||
<p>⛔️ Escape key doesn't work here</p> | |||
<p>⚠️ Escape key only works with native dialog</p> |
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.
Why do we want to have this limitation? Is not it better to align implementations?
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.
Well, this limitation is due to the fact this a very specific edge case scenario that should not be implemented by the user.
Aligning implementations would require listening to events on the document itself and filtering out the case where Escape might do something else, like closing a Menu
or a Popover
. We could discuss adding this again for treating this very specific edge case, but this has already been removed on a previous PR actually #24668
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.
If I correctly understand the goal: div
& dialog
should be replaceable. So it would be great to align behaviors. Otherwise we could get a different behaviors across browsers that might be confusing.
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.
The argument here is... do we care for an incompatible behaviour on a very obscure edge case? is it worth adding a global listener that will not follow React's typing API to just resolve that very specific edge case?!
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.
another alternative would be to stop support Escape key to work on native dialog for this scenario also. @layershifter
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.
another alternative would be to stop support Escape key to work on native dialog for this scenario also. @layershifter
@bsunderhus It's also an option 👍 I think that we need to normalize behavior anyway, but it's your choice what to choose 😉
/** | ||
* The close event is fired on a <dialog> when it has been closed. | ||
*/ | ||
onClose?: (event: React.SyntheticEvent) => void; | ||
/** | ||
* The cancel event fires on a <dialog> when | ||
* the user instructs the browser that they wish to dismiss the current open dialog. | ||
* For example, the browser might fire this event when the user presses the Esc | ||
* key. | ||
*/ | ||
onCancel?: (event: React.SyntheticEvent) => void; |
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.
@@ -76,6 +76,9 @@ const useStyles = makeStyles({ | |||
...shorthands.margin('auto'), | |||
...shorthands.borderStyle('none'), | |||
...shorthands.overflow('unset'), | |||
'&::backdrop': { | |||
backgroundColor: 'rgba(0, 0, 0, 0.4)', |
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 be this a token?
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.
I'll reach design team and ask about it
const dialogTitleID = useDialogContext_unstable(ctx => ctx.dialogTitleID); | ||
const dialogBodyID = useDialogContext_unstable(ctx => ctx.dialogBodyID); |
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.
const dialogTitleID = useDialogContext_unstable(ctx => ctx.dialogTitleID); | |
const dialogBodyID = useDialogContext_unstable(ctx => ctx.dialogBodyID); | |
const dialogTitleId = useDialogContext_unstable(ctx => ctx.dialogTitleId); | |
const dialogBodyId = useDialogContext_unstable(ctx => ctx.dialogBodyId); |
nit: it's out of scope of this PR, but let's fix casing to be consistent
* master: (28 commits) Fix value font-weight inside heatmap chart (microsoft#24726) Fix legend overflow-indication-text role (microsoft#24756) Support custom locale in date axis (microsoft#24753) Cleanup env variables (microsoft#24739) ci(github): add GH Action to add issue labels based on new GH issue template (microsoft#24788) Update disallowedChangeTypes for newly created packages, to allow only 'prerelease' change types by default (microsoft#24763) feat(react-components): Adding missing AvatarGroup exports (microsoft#24770) remove unnecessary nohoist (microsoft#24760) feat(react-dialog): supports 1st rule of ARIA (microsoft#24525) BREAKING: TableCell layouts are handled by layout components (microsoft#24762) feat: Implement table cell layout components (microsoft#24773) applying package updates fix: remove readonly from DetailsList (microsoft#24615) chore: Cleaning up tokens in Button components so they better adhere to the design spec (microsoft#24732) fix: react-combobox listbox popup width matches trigger width (microsoft#24733) fix: react-combobox Option focus outline only shows with keyboard nav (microsoft#24700) feat: Publish react-field package, and export from react-components/unstable (microsoft#24235) fix: Replacing bottom border styles with text decoration underline in Link (microsoft#24734) docs(react-theme): Update readme (microsoft#24755) Add tests for hover states (microsoft#24390) ...
Current Behavior
Currently
Dialog
doesn't support 1st rule of ARIANew Behavior
as="dialog"
atDialogSurface
by default with possibility to opt-out of semantic element withas="div"
document
listeners since they're not required to controlEscape
🚀::backdrop
support for native element