@fluentui/react-dialog 9.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +527 -0
- package/CHANGELOG.md +199 -0
- package/LICENSE +15 -0
- package/README.md +5 -0
- package/Spec.md +537 -0
- package/assets/AlertDialogKeyboardInteraction.png +0 -0
- package/assets/AlertDialogMouseInteraction.png +0 -0
- package/assets/ModalDialogKeyboardInteraction.png +0 -0
- package/assets/ModalDialogMouseInteraction.png +0 -0
- package/assets/NonModalDialogKeyboardInteraction.png +0 -0
- package/assets/NonModalDialogMouseInteraction.png +0 -0
- package/dist/index.d.ts +451 -0
- package/lib/Dialog.js +2 -0
- package/lib/Dialog.js.map +1 -0
- package/lib/DialogActions.js +2 -0
- package/lib/DialogActions.js.map +1 -0
- package/lib/DialogBody.js +2 -0
- package/lib/DialogBody.js.map +1 -0
- package/lib/DialogContent.js +2 -0
- package/lib/DialogContent.js.map +1 -0
- package/lib/DialogSurface.js +2 -0
- package/lib/DialogSurface.js.map +1 -0
- package/lib/DialogTitle.js +2 -0
- package/lib/DialogTitle.js.map +1 -0
- package/lib/DialogTrigger.js +2 -0
- package/lib/DialogTrigger.js.map +1 -0
- package/lib/components/Dialog/Dialog.js +19 -0
- package/lib/components/Dialog/Dialog.js.map +1 -0
- package/lib/components/Dialog/Dialog.types.js +2 -0
- package/lib/components/Dialog/Dialog.types.js.map +1 -0
- package/lib/components/Dialog/index.js +5 -0
- package/lib/components/Dialog/index.js.map +1 -0
- package/lib/components/Dialog/renderDialog.js +18 -0
- package/lib/components/Dialog/renderDialog.js.map +1 -0
- package/lib/components/Dialog/useDialog.js +87 -0
- package/lib/components/Dialog/useDialog.js.map +1 -0
- package/lib/components/Dialog/useDialogContextValues.js +31 -0
- package/lib/components/Dialog/useDialogContextValues.js.map +1 -0
- package/lib/components/DialogActions/DialogActions.js +16 -0
- package/lib/components/DialogActions/DialogActions.js.map +1 -0
- package/lib/components/DialogActions/DialogActions.types.js +2 -0
- package/lib/components/DialogActions/DialogActions.types.js.map +1 -0
- package/lib/components/DialogActions/index.js +6 -0
- package/lib/components/DialogActions/index.js.map +1 -0
- package/lib/components/DialogActions/renderDialogActions.js +16 -0
- package/lib/components/DialogActions/renderDialogActions.js.map +1 -0
- package/lib/components/DialogActions/useDialogActions.js +27 -0
- package/lib/components/DialogActions/useDialogActions.js.map +1 -0
- package/lib/components/DialogActions/useDialogActionsStyles.js +49 -0
- package/lib/components/DialogActions/useDialogActionsStyles.js.map +1 -0
- package/lib/components/DialogBody/DialogBody.js +16 -0
- package/lib/components/DialogBody/DialogBody.js.map +1 -0
- package/lib/components/DialogBody/DialogBody.types.js +2 -0
- package/lib/components/DialogBody/DialogBody.types.js.map +1 -0
- package/lib/components/DialogBody/index.js +6 -0
- package/lib/components/DialogBody/index.js.map +1 -0
- package/lib/components/DialogBody/renderDialogBody.js +16 -0
- package/lib/components/DialogBody/renderDialogBody.js.map +1 -0
- package/lib/components/DialogBody/useDialogBody.js +25 -0
- package/lib/components/DialogBody/useDialogBody.js.map +1 -0
- package/lib/components/DialogBody/useDialogBodyStyles.js +50 -0
- package/lib/components/DialogBody/useDialogBodyStyles.js.map +1 -0
- package/lib/components/DialogContent/DialogContent.js +16 -0
- package/lib/components/DialogContent/DialogContent.js.map +1 -0
- package/lib/components/DialogContent/DialogContent.types.js +2 -0
- package/lib/components/DialogContent/DialogContent.types.js.map +1 -0
- package/lib/components/DialogContent/index.js +6 -0
- package/lib/components/DialogContent/index.js.map +1 -0
- package/lib/components/DialogContent/renderDialogContent.js +15 -0
- package/lib/components/DialogContent/renderDialogContent.js.map +1 -0
- package/lib/components/DialogContent/useDialogContent.js +28 -0
- package/lib/components/DialogContent/useDialogContent.js.map +1 -0
- package/lib/components/DialogContent/useDialogContentStyles.js +40 -0
- package/lib/components/DialogContent/useDialogContentStyles.js.map +1 -0
- package/lib/components/DialogSurface/DialogSurface.js +18 -0
- package/lib/components/DialogSurface/DialogSurface.js.map +1 -0
- package/lib/components/DialogSurface/DialogSurface.types.js +2 -0
- package/lib/components/DialogSurface/DialogSurface.types.js.map +1 -0
- package/lib/components/DialogSurface/index.js +6 -0
- package/lib/components/DialogSurface/index.js.map +1 -0
- package/lib/components/DialogSurface/renderDialogSurface.js +20 -0
- package/lib/components/DialogSurface/renderDialogSurface.js.map +1 -0
- package/lib/components/DialogSurface/useDialogSurface.js +158 -0
- package/lib/components/DialogSurface/useDialogSurface.js.map +1 -0
- package/lib/components/DialogSurface/useDialogSurfaceContextValues.js +7 -0
- package/lib/components/DialogSurface/useDialogSurfaceContextValues.js.map +1 -0
- package/lib/components/DialogSurface/useDialogSurfaceStyles.js +95 -0
- package/lib/components/DialogSurface/useDialogSurfaceStyles.js.map +1 -0
- package/lib/components/DialogTitle/DialogTitle.js +16 -0
- package/lib/components/DialogTitle/DialogTitle.js.map +1 -0
- package/lib/components/DialogTitle/DialogTitle.types.js +2 -0
- package/lib/components/DialogTitle/DialogTitle.types.js.map +1 -0
- package/lib/components/DialogTitle/index.js +6 -0
- package/lib/components/DialogTitle/index.js.map +1 -0
- package/lib/components/DialogTitle/renderDialogTitle.js +16 -0
- package/lib/components/DialogTitle/renderDialogTitle.js.map +1 -0
- package/lib/components/DialogTitle/useDialogTitle.js +48 -0
- package/lib/components/DialogTitle/useDialogTitle.js.map +1 -0
- package/lib/components/DialogTitle/useDialogTitleStyles.js +116 -0
- package/lib/components/DialogTitle/useDialogTitleStyles.js.map +1 -0
- package/lib/components/DialogTrigger/DialogTrigger.js +20 -0
- package/lib/components/DialogTrigger/DialogTrigger.js.map +1 -0
- package/lib/components/DialogTrigger/DialogTrigger.types.js +2 -0
- package/lib/components/DialogTrigger/DialogTrigger.types.js.map +1 -0
- package/lib/components/DialogTrigger/index.js +5 -0
- package/lib/components/DialogTrigger/index.js.map +1 -0
- package/lib/components/DialogTrigger/renderDialogTrigger.js +7 -0
- package/lib/components/DialogTrigger/renderDialogTrigger.js.map +1 -0
- package/lib/components/DialogTrigger/useDialogTrigger.js +48 -0
- package/lib/components/DialogTrigger/useDialogTrigger.js.map +1 -0
- package/lib/contexts/constants.js +11 -0
- package/lib/contexts/constants.js.map +1 -0
- package/lib/contexts/dialogContext.js +19 -0
- package/lib/contexts/dialogContext.js.map +1 -0
- package/lib/contexts/dialogSurfaceContext.js +10 -0
- package/lib/contexts/dialogSurfaceContext.js.map +1 -0
- package/lib/contexts/index.js +4 -0
- package/lib/contexts/index.js.map +1 -0
- package/lib/index.js +8 -0
- package/lib/index.js.map +1 -0
- package/lib/utils/index.js +6 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/isEscapeKeyDown.js +12 -0
- package/lib/utils/isEscapeKeyDown.js.map +1 -0
- package/lib/utils/isHTMLDialogElement.js +4 -0
- package/lib/utils/isHTMLDialogElement.js.map +1 -0
- package/lib/utils/useControlNativeDialogOpenState.js +20 -0
- package/lib/utils/useControlNativeDialogOpenState.js.map +1 -0
- package/lib/utils/useDisableBodyScroll.js +60 -0
- package/lib/utils/useDisableBodyScroll.js.map +1 -0
- package/lib/utils/useFocusFirstElement.js +41 -0
- package/lib/utils/useFocusFirstElement.js.map +1 -0
- package/lib-commonjs/Dialog.js +10 -0
- package/lib-commonjs/Dialog.js.map +1 -0
- package/lib-commonjs/DialogActions.js +10 -0
- package/lib-commonjs/DialogActions.js.map +1 -0
- package/lib-commonjs/DialogBody.js +10 -0
- package/lib-commonjs/DialogBody.js.map +1 -0
- package/lib-commonjs/DialogContent.js +10 -0
- package/lib-commonjs/DialogContent.js.map +1 -0
- package/lib-commonjs/DialogSurface.js +10 -0
- package/lib-commonjs/DialogSurface.js.map +1 -0
- package/lib-commonjs/DialogTitle.js +10 -0
- package/lib-commonjs/DialogTitle.js.map +1 -0
- package/lib-commonjs/DialogTrigger.js +10 -0
- package/lib-commonjs/DialogTrigger.js.map +1 -0
- package/lib-commonjs/components/Dialog/Dialog.js +30 -0
- package/lib-commonjs/components/Dialog/Dialog.js.map +1 -0
- package/lib-commonjs/components/Dialog/Dialog.types.js +6 -0
- package/lib-commonjs/components/Dialog/Dialog.types.js.map +1 -0
- package/lib-commonjs/components/Dialog/index.js +16 -0
- package/lib-commonjs/components/Dialog/index.js.map +1 -0
- package/lib-commonjs/components/Dialog/renderDialog.js +29 -0
- package/lib-commonjs/components/Dialog/renderDialog.js.map +1 -0
- package/lib-commonjs/components/Dialog/useDialog.js +101 -0
- package/lib-commonjs/components/Dialog/useDialog.js.map +1 -0
- package/lib-commonjs/components/Dialog/useDialogContextValues.js +40 -0
- package/lib-commonjs/components/Dialog/useDialogContextValues.js.map +1 -0
- package/lib-commonjs/components/DialogActions/DialogActions.js +27 -0
- package/lib-commonjs/components/DialogActions/DialogActions.js.map +1 -0
- package/lib-commonjs/components/DialogActions/DialogActions.types.js +6 -0
- package/lib-commonjs/components/DialogActions/DialogActions.types.js.map +1 -0
- package/lib-commonjs/components/DialogActions/index.js +18 -0
- package/lib-commonjs/components/DialogActions/index.js.map +1 -0
- package/lib-commonjs/components/DialogActions/renderDialogActions.js +27 -0
- package/lib-commonjs/components/DialogActions/renderDialogActions.js.map +1 -0
- package/lib-commonjs/components/DialogActions/useDialogActions.js +37 -0
- package/lib-commonjs/components/DialogActions/useDialogActions.js.map +1 -0
- package/lib-commonjs/components/DialogActions/useDialogActionsStyles.js +60 -0
- package/lib-commonjs/components/DialogActions/useDialogActionsStyles.js.map +1 -0
- package/lib-commonjs/components/DialogBody/DialogBody.js +27 -0
- package/lib-commonjs/components/DialogBody/DialogBody.js.map +1 -0
- package/lib-commonjs/components/DialogBody/DialogBody.types.js +6 -0
- package/lib-commonjs/components/DialogBody/DialogBody.types.js.map +1 -0
- package/lib-commonjs/components/DialogBody/index.js +18 -0
- package/lib-commonjs/components/DialogBody/index.js.map +1 -0
- package/lib-commonjs/components/DialogBody/renderDialogBody.js +27 -0
- package/lib-commonjs/components/DialogBody/renderDialogBody.js.map +1 -0
- package/lib-commonjs/components/DialogBody/useDialogBody.js +35 -0
- package/lib-commonjs/components/DialogBody/useDialogBody.js.map +1 -0
- package/lib-commonjs/components/DialogBody/useDialogBodyStyles.js +61 -0
- package/lib-commonjs/components/DialogBody/useDialogBodyStyles.js.map +1 -0
- package/lib-commonjs/components/DialogContent/DialogContent.js +27 -0
- package/lib-commonjs/components/DialogContent/DialogContent.js.map +1 -0
- package/lib-commonjs/components/DialogContent/DialogContent.types.js +6 -0
- package/lib-commonjs/components/DialogContent/DialogContent.types.js.map +1 -0
- package/lib-commonjs/components/DialogContent/index.js +18 -0
- package/lib-commonjs/components/DialogContent/index.js.map +1 -0
- package/lib-commonjs/components/DialogContent/renderDialogContent.js +26 -0
- package/lib-commonjs/components/DialogContent/renderDialogContent.js.map +1 -0
- package/lib-commonjs/components/DialogContent/useDialogContent.js +39 -0
- package/lib-commonjs/components/DialogContent/useDialogContent.js.map +1 -0
- package/lib-commonjs/components/DialogContent/useDialogContentStyles.js +52 -0
- package/lib-commonjs/components/DialogContent/useDialogContentStyles.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/DialogSurface.js +30 -0
- package/lib-commonjs/components/DialogSurface/DialogSurface.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/DialogSurface.types.js +6 -0
- package/lib-commonjs/components/DialogSurface/DialogSurface.types.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/index.js +18 -0
- package/lib-commonjs/components/DialogSurface/index.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/renderDialogSurface.js +33 -0
- package/lib-commonjs/components/DialogSurface/renderDialogSurface.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurface.js +171 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurface.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurfaceContextValues.js +16 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurfaceContextValues.js.map +1 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurfaceStyles.js +107 -0
- package/lib-commonjs/components/DialogSurface/useDialogSurfaceStyles.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/DialogTitle.js +27 -0
- package/lib-commonjs/components/DialogTitle/DialogTitle.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/DialogTitle.types.js +6 -0
- package/lib-commonjs/components/DialogTitle/DialogTitle.types.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/index.js +18 -0
- package/lib-commonjs/components/DialogTitle/index.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/renderDialogTitle.js +27 -0
- package/lib-commonjs/components/DialogTitle/renderDialogTitle.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/useDialogTitle.js +64 -0
- package/lib-commonjs/components/DialogTitle/useDialogTitle.js.map +1 -0
- package/lib-commonjs/components/DialogTitle/useDialogTitleStyles.js +129 -0
- package/lib-commonjs/components/DialogTitle/useDialogTitleStyles.js.map +1 -0
- package/lib-commonjs/components/DialogTrigger/DialogTrigger.js +31 -0
- package/lib-commonjs/components/DialogTrigger/DialogTrigger.js.map +1 -0
- package/lib-commonjs/components/DialogTrigger/DialogTrigger.types.js +6 -0
- package/lib-commonjs/components/DialogTrigger/DialogTrigger.types.js.map +1 -0
- package/lib-commonjs/components/DialogTrigger/index.js +16 -0
- package/lib-commonjs/components/DialogTrigger/index.js.map +1 -0
- package/lib-commonjs/components/DialogTrigger/renderDialogTrigger.js +16 -0
- package/lib-commonjs/components/DialogTrigger/renderDialogTrigger.js.map +1 -0
- package/lib-commonjs/components/DialogTrigger/useDialogTrigger.js +62 -0
- package/lib-commonjs/components/DialogTrigger/useDialogTrigger.js.map +1 -0
- package/lib-commonjs/contexts/constants.js +17 -0
- package/lib-commonjs/contexts/constants.js.map +1 -0
- package/lib-commonjs/contexts/dialogContext.js +30 -0
- package/lib-commonjs/contexts/dialogContext.js.map +1 -0
- package/lib-commonjs/contexts/dialogSurfaceContext.js +21 -0
- package/lib-commonjs/contexts/dialogSurfaceContext.js.map +1 -0
- package/lib-commonjs/contexts/index.js +14 -0
- package/lib-commonjs/contexts/index.js.map +1 -0
- package/lib-commonjs/index.js +214 -0
- package/lib-commonjs/index.js.map +1 -0
- package/lib-commonjs/utils/index.js +18 -0
- package/lib-commonjs/utils/index.js.map +1 -0
- package/lib-commonjs/utils/isEscapeKeyDown.js +23 -0
- package/lib-commonjs/utils/isEscapeKeyDown.js.map +1 -0
- package/lib-commonjs/utils/isHTMLDialogElement.js +13 -0
- package/lib-commonjs/utils/isHTMLDialogElement.js.map +1 -0
- package/lib-commonjs/utils/useControlNativeDialogOpenState.js +31 -0
- package/lib-commonjs/utils/useControlNativeDialogOpenState.js.map +1 -0
- package/lib-commonjs/utils/useDisableBodyScroll.js +73 -0
- package/lib-commonjs/utils/useDisableBodyScroll.js.map +1 -0
- package/lib-commonjs/utils/useFocusFirstElement.js +54 -0
- package/lib-commonjs/utils/useFocusFirstElement.js.map +1 -0
- package/package.json +68 -0
package/Spec.md
ADDED
|
@@ -0,0 +1,537 @@
|
|
|
1
|
+
# Dialog
|
|
2
|
+
|
|
3
|
+
## Background
|
|
4
|
+
|
|
5
|
+
This spec defines the default function of a `Dialog` a window overlaid on either the primary window or another dialog window. Windows under a modal dialog are inert. That is, users cannot interact with content outside an active dialog window. Inert content outside an active dialog is typically visually obscured or dimmed so it is difficult to discern, and in some implementations, attempts to interact with the inert content cause the dialog to close.
|
|
6
|
+
|
|
7
|
+
The interactions that result in the opening/closing of the `Dialog` component should be configurable.
|
|
8
|
+
|
|
9
|
+
## Prior Art
|
|
10
|
+
|
|
11
|
+
- All mentions of v7 or v8 refer to Fabric - `@fluentui/react` ([docsite](https://developer.microsoft.com/en-us/fluentui#/))
|
|
12
|
+
- All mentions of v0 refer to Northstar - `@fluentui/react-northstar` ([docsite](https://fluentsite.z22.web.core.windows.net/))
|
|
13
|
+
|
|
14
|
+
- [Github epic](https://github.com/microsoft/fluentui/issues/20953)
|
|
15
|
+
- [Open UI Research](https://open-ui.org/components/dialog.research)
|
|
16
|
+
- Dialogs in 3rd party UI systems:
|
|
17
|
+
- [Carbon](https://react.carbondesignsystem.com/?path=/docs/components-modal--default)
|
|
18
|
+
- [Chakra UI](https://chakra-ui.com/docs/overlay/modal)
|
|
19
|
+
- [FAST](https://explore.fast.design/components/fast-dialog)
|
|
20
|
+
- [Material UI](https://mui.com/components/dialogs/)
|
|
21
|
+
- [Radix](https://www.radix-ui.com/docs/primitives/components/dialog)
|
|
22
|
+
- [Reach UI](https://reach.tech/dialog/)
|
|
23
|
+
- [Reakit](https://reakit.io/docs/dialog/)
|
|
24
|
+
- [Ariakit](https://github.com/reakit/reakit/tree/v2)
|
|
25
|
+
- [Spectrum](https://react-spectrum.adobe.com/react-spectrum/Dialog.html)
|
|
26
|
+
|
|
27
|
+
### Comparison between v0 and v8
|
|
28
|
+
|
|
29
|
+
Note that the below code samples are not meant to be complete, but to highlight differences between the two libraries. Please refer to official docsites for actual API references.
|
|
30
|
+
|
|
31
|
+
#### v8
|
|
32
|
+
|
|
33
|
+
In v8 there are Dialog and Modal components which are relevant to the Dialog component for v9. The Dialog component was intended to be used primarily for confirming actions, whereas Modal component was intended to be used for lengthy content that may contain forms and other controls. This spec will only cover the comparison to the Dialog component.
|
|
34
|
+
|
|
35
|
+
The visibility of the dialog is controlled through the `hidden` prop whose its value should be a react state boolean provided from the consumer.
|
|
36
|
+
|
|
37
|
+
[Documentation for v8 Dialog](https://developer.microsoft.com/en-us/fluentui#/controls/web/dialog)
|
|
38
|
+
|
|
39
|
+
Sample code:
|
|
40
|
+
|
|
41
|
+
```jsx
|
|
42
|
+
<DefaultButton secondaryText="Opens the Sample Dialog" onClick={toggleHideDialog} text="Open Dialog" />
|
|
43
|
+
|
|
44
|
+
<Dialog
|
|
45
|
+
hidden={hideDialog}
|
|
46
|
+
onDismiss={toggleHideDialog}
|
|
47
|
+
dialogContentProps={dialogContentProps}
|
|
48
|
+
modalProps={modalProps}
|
|
49
|
+
>
|
|
50
|
+
<DialogFooter>
|
|
51
|
+
<PrimaryButton onClick={toggleHideDialog} text="Send" />
|
|
52
|
+
<DefaultButton onClick={toggleHideDialog} text="Don't send" />
|
|
53
|
+
</DialogFooter>
|
|
54
|
+
</Dialog>
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
#### v0
|
|
59
|
+
|
|
60
|
+
In v0, the Dialog component expects all the content through props, including the content, actions etc. The dialog component uses the `trigger` prop that expects a React component to control its visibility. The element passed to this prop will be rendered in-place where the dialog is defined.
|
|
61
|
+
|
|
62
|
+
[Documentation for v0 Dialog](https://fluentsite.z22.web.core.windows.net/components/dialog/definition)
|
|
63
|
+
|
|
64
|
+
```jsx
|
|
65
|
+
<Dialog
|
|
66
|
+
cancelButton="Connect protocol"
|
|
67
|
+
confirmButton="Transmit capacitor"
|
|
68
|
+
content="Connect driver"
|
|
69
|
+
header="Transmit capacitor"
|
|
70
|
+
headerAction="Generate protocol"
|
|
71
|
+
trigger={<Button content="A trigger" />}
|
|
72
|
+
/>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## API
|
|
76
|
+
|
|
77
|
+
The `Dialog` should implement a `children` based API as is one of the standards across all the surveyed alternatives as a part of Open UI research in [Prior Art](#prior-art). The component will leverage the use of `context` in the interaction and data flows of child compound components.
|
|
78
|
+
|
|
79
|
+
Sample usages will be give in the following section of this document [Sample code](#sample-code)
|
|
80
|
+
|
|
81
|
+
### Dialog
|
|
82
|
+
|
|
83
|
+
The root level component serves as an interface for interaction with all possible behaviors exposed. It provides context down the hierarchy to `children` compound components to allow functionality. This component expects to receive as children either a `DialogSurface` or a `DialogTrigger` and a `DialogSurface` (or some component that will eventually render one of those compound components) in this specific order
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
type DialogSlots = {};
|
|
87
|
+
|
|
88
|
+
type DialogProps = ComponentProps<DialogSlots> & {
|
|
89
|
+
/**
|
|
90
|
+
* Dialog variations.
|
|
91
|
+
*
|
|
92
|
+
* `modal`: When this type of dialog is open, the rest of the page is dimmed out and cannot be interacted with. The tab sequence is kept within the dialog and moving the focus outside the dialog will imply closing it. This is the default type of the component.
|
|
93
|
+
*
|
|
94
|
+
* `non-modal`: When a non-modal dialog is open, the rest of the page is not dimmed out and users can interact with the rest of the page. This also implies that the tab focus can move outside the dialog when it reaches the last focusable element.
|
|
95
|
+
*
|
|
96
|
+
* `alert`: is a special type of modal dialogs that interrupts the user's workflow to communicate an important message or ask for a decision. Unlike a typical modal dialog, the user must take an action through the options given to dismiss the dialog, and it cannot be dismissed through the dimmed background or escape key.
|
|
97
|
+
*
|
|
98
|
+
* @default 'modal'
|
|
99
|
+
*/
|
|
100
|
+
modalType?: 'modal' | 'non-modal' | 'alert';
|
|
101
|
+
/**
|
|
102
|
+
* Controls the open state of the dialog
|
|
103
|
+
* @default undefined
|
|
104
|
+
*/
|
|
105
|
+
open?: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Default value for the uncontrolled open state of the dialog.
|
|
108
|
+
* @default false
|
|
109
|
+
*/
|
|
110
|
+
defaultOpen?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Callback fired when the component changes value from open state.
|
|
113
|
+
* @default undefined
|
|
114
|
+
*/
|
|
115
|
+
onOpenChange?(event: MouseEvent | KeyboardEvent, data: DialogOpenChangeData): void;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
type DialogOpenChangeData = {
|
|
119
|
+
/**
|
|
120
|
+
* The event source of the callback invocation
|
|
121
|
+
*/
|
|
122
|
+
type: 'escapeKeyDown' | 'backdropClick' | 'triggerClick';
|
|
123
|
+
/**
|
|
124
|
+
* The next value for the internal state of the dialog
|
|
125
|
+
*/
|
|
126
|
+
open: boolean;
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### DialogTrigger
|
|
131
|
+
|
|
132
|
+
A non-visual component that wraps its child and configures them to be the trigger that will open or close a `Dialog`. This component should only accept one child.
|
|
133
|
+
|
|
134
|
+
In case the trigger is used outside `Dialog` component it'll still provide basic [ARIA related attributes](#aria-roles-and-states) to it's wrapped child, but it won't be able to alter the dialog `open` state anymore, in that case the user must provide a [`controlled state`](#controlled-dialog)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
export type DialogTriggerProps = {
|
|
138
|
+
/**
|
|
139
|
+
* Explicitly declare if the trigger is responsible for opening or
|
|
140
|
+
* closing a Dialog visibility state.
|
|
141
|
+
* @default 'open' // if it's outside DialogSurface
|
|
142
|
+
* @default 'close' // if it's inside DialogSurface
|
|
143
|
+
*/
|
|
144
|
+
action?: 'open' | 'close';
|
|
145
|
+
/**
|
|
146
|
+
* Explicitly require single child or render function
|
|
147
|
+
* to inject properties
|
|
148
|
+
*/
|
|
149
|
+
children: (React.ReactElement & { ref?: React.Ref<unknown> }) | (() => React.ReactElement | null);
|
|
150
|
+
};
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### DialogSurface
|
|
154
|
+
|
|
155
|
+
The `DialogSurface` component represents the visual part of a `Dialog` as a whole, it contains everything that should be visible.
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
type DialogSurfaceSlots = {
|
|
159
|
+
/**
|
|
160
|
+
* Dimmed background of dialog.
|
|
161
|
+
* The default backdrop is rendered as a `<div>` with styling.
|
|
162
|
+
* This slot expects a `<div>` element which will replace the default backdrop.
|
|
163
|
+
* The backdrop should have `aria-hidden="true"`.
|
|
164
|
+
*
|
|
165
|
+
* By default if `DialogSurface` is `<dialog>` element the backdrop is ignored,
|
|
166
|
+
* since native `<dialog>` element supports [::backdrop](https://developer.mozilla.org/en-US/docs/Web/CSS/::backdrop)
|
|
167
|
+
*/
|
|
168
|
+
backdrop?: Slot<'div'>;
|
|
169
|
+
root: NonNullable<Slot<'dialog', 'div'>>;
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
type DialogTitleProps = ComponentProps<DialogSurfaceSlots>;
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### DialogTitle
|
|
176
|
+
|
|
177
|
+
The `DialogTitle` component expects to have a title/header and when `Dialog` is `non-modal` a close (X icon) button is provided through `action` slot by default.
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
type DialogTitleSlots = {
|
|
181
|
+
/**
|
|
182
|
+
* By default this is a div, but can be a heading.
|
|
183
|
+
*/
|
|
184
|
+
root: Slot<'div', 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'>;
|
|
185
|
+
/**
|
|
186
|
+
* By default a Dialog with modalType='non-modal' will have a close button action
|
|
187
|
+
*/
|
|
188
|
+
action?: Slot<'div'>;
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
type DialogTitleProps = ComponentProps<DialogTitleSlots>;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### DialogBody
|
|
195
|
+
|
|
196
|
+
The `DialogBody` is a container where the content of the dialog is rendered. Apart from styling, this component does not have other behavior.
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
type DialogBodySlots = {
|
|
200
|
+
root: Slot<'div'>;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
type DialogBodyProps = ComponentProps<DialogBodySlots>;
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### DialogActions
|
|
207
|
+
|
|
208
|
+
`DialogActions` is a container for the actions of the dialog. Apart from styling, this component does not have other behavior.
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
type DialogActionsSlots = {
|
|
212
|
+
root: Slot<'div'>;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
type DialogActionsProps = ComponentProps<DialogActionsSlots>;
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Sample Code
|
|
219
|
+
|
|
220
|
+
The below samples do not represent the definitive props of the final implemented component, but represent the ideal final implementations. Can be subject to change during the implementation phase.
|
|
221
|
+
|
|
222
|
+
### Basic Dialog
|
|
223
|
+
|
|
224
|
+
```tsx
|
|
225
|
+
const dialog = <Dialog>
|
|
226
|
+
<DialogTrigger>
|
|
227
|
+
<Button>Open Dialog</Button>
|
|
228
|
+
<DialogTrigger>
|
|
229
|
+
<DialogSurface>
|
|
230
|
+
This is as basic as it gets.
|
|
231
|
+
</DialogSurface>
|
|
232
|
+
</Dialog>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```html
|
|
236
|
+
<!-- expected DOM output -->
|
|
237
|
+
<button aria-haspopup="true" class="fui-button">Open Dialog</button>
|
|
238
|
+
<!-- ... portal ... -->
|
|
239
|
+
<div aria-hidden="true" class="fui-dialog-backdrop"></div>
|
|
240
|
+
<div aria-modal="true" role="dialog" class="fui-dialog-content">This is as basic as it gets</div>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Alert Dialog
|
|
244
|
+
|
|
245
|
+
An alert dialog is a modal dialog that interrupts the user's workflow to communicate an important message and acquire a response. Examples include action confirmation prompts and error message confirmations. The alertdialog role enables assistive technologies and browsers to distinguish alert dialogs from other dialogs so they have the option of giving alert dialogs special treatment, such as playing a system alert sound.
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
const dialog = <Dialog type="alert">
|
|
249
|
+
<DialogTrigger>
|
|
250
|
+
<Button>Open Dialog</Button>
|
|
251
|
+
<DialogTrigger>
|
|
252
|
+
<DialogSurface>
|
|
253
|
+
<DialogTitle>
|
|
254
|
+
This is an alert
|
|
255
|
+
</DialogTitle>
|
|
256
|
+
<DialogBody>
|
|
257
|
+
This is going to be inside the dialog
|
|
258
|
+
</DialogBody>
|
|
259
|
+
<DialogActions>
|
|
260
|
+
<DialogTrigger type="close">
|
|
261
|
+
<Button>Close</Button>
|
|
262
|
+
</DialogTrigger>
|
|
263
|
+
<Button>Action</Button>
|
|
264
|
+
</DialogActions>
|
|
265
|
+
</DialogSurface>
|
|
266
|
+
</Dialog>
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
```html
|
|
270
|
+
<button aria-haspopup="true" class="fui-button">Open Dialog</button>
|
|
271
|
+
<!-- ... portal ... -->
|
|
272
|
+
<div aria-hidden="true" class="fui-dialog-backdrop"></div>
|
|
273
|
+
<div
|
|
274
|
+
aria-describedby="fui-dialog-body-id"
|
|
275
|
+
aria-labelledby="fui-dialog-title-id"
|
|
276
|
+
aria-modal="true"
|
|
277
|
+
role="alertdialog"
|
|
278
|
+
class="fui-dialog-content"
|
|
279
|
+
>
|
|
280
|
+
<div id="fui-dialog-title-id" class="fui-dialog-title">
|
|
281
|
+
<span>Title</span>
|
|
282
|
+
<!-- action -->
|
|
283
|
+
</div>
|
|
284
|
+
<div id="fui-dialog-body-id" class="fui-dialog-body">This is going to be inside the dialog</div>
|
|
285
|
+
<div class="fui-dialog-actions">
|
|
286
|
+
<button class="fui-button">Close</button>
|
|
287
|
+
<button class="fui-button">Action</button>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<!-- ... portal ... -->
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
### Controlled Dialog
|
|
294
|
+
|
|
295
|
+
```tsx
|
|
296
|
+
const CustomDialog = () => {
|
|
297
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
298
|
+
const handleOpenChange = (ev, { open }) => setIsOpen(open);
|
|
299
|
+
const handleOpen = () => setIsOpen(true);
|
|
300
|
+
return (
|
|
301
|
+
<>
|
|
302
|
+
{/*
|
|
303
|
+
the trigger component is still useful outside of the Dialog,
|
|
304
|
+
to provide ARIA attributes, but it will no longer speak with the dialog.
|
|
305
|
+
A controlled state is required in this case
|
|
306
|
+
*/}
|
|
307
|
+
<DialogTrigger>
|
|
308
|
+
<Button onClick={handleOpen}>Button outside Dialog Context</Button>
|
|
309
|
+
</DialogTrigger>
|
|
310
|
+
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
|
|
311
|
+
<DialogSurface>
|
|
312
|
+
<DialogTitle>This is an alert</DialogTitle>
|
|
313
|
+
<DialogBody>This is going to be inside the dialog</DialogBody>
|
|
314
|
+
<DialogActions>
|
|
315
|
+
{/*
|
|
316
|
+
In this case the trigger can be used to request close through `onOpenChange`,
|
|
317
|
+
as it's inside Dialog context
|
|
318
|
+
*/}
|
|
319
|
+
<DialogTrigger type="close">
|
|
320
|
+
<Button>Close</Button>
|
|
321
|
+
</DialogTrigger>
|
|
322
|
+
<Button>Action</Button>
|
|
323
|
+
</DialogActions>
|
|
324
|
+
</DialogSurface>
|
|
325
|
+
</Dialog>
|
|
326
|
+
</>
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
```html
|
|
332
|
+
<button aria-haspopup="true" class="fui-button">Open Dialog</button>
|
|
333
|
+
<!-- ... portal ... -->
|
|
334
|
+
<div aria-hidden="true" class="fui-dialog-backdrop"></div>
|
|
335
|
+
<div
|
|
336
|
+
aria-describedby="fui-dialog-body-id"
|
|
337
|
+
aria-labelledby="fui-dialog-title-id"
|
|
338
|
+
aria-modal="true"
|
|
339
|
+
role="dialog"
|
|
340
|
+
class="fui-dialog-content"
|
|
341
|
+
>
|
|
342
|
+
<div id="fui-dialog-title-id" class="fui-dialog-title">
|
|
343
|
+
<span>Title</span>
|
|
344
|
+
<!-- action -->
|
|
345
|
+
</div>
|
|
346
|
+
<div id="fui-dialog-body-id" class="fui-dialog-body">This is going to be inside the dialog</div>
|
|
347
|
+
<div class="fui-dialog-actions">
|
|
348
|
+
<button class="fui-button">Close</button>
|
|
349
|
+
<button class="fui-button">Action</button>
|
|
350
|
+
</div>
|
|
351
|
+
</div>
|
|
352
|
+
<!-- ... portal ... -->
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Async Input submission dialog
|
|
356
|
+
|
|
357
|
+
```tsx
|
|
358
|
+
function AsyncConfirmDialog() {
|
|
359
|
+
const [input, setInput] = useState('');
|
|
360
|
+
const [state, sendInput] = useSendInput();
|
|
361
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
362
|
+
const handleInputChange = ev => {
|
|
363
|
+
setInput(ev.target.value.trim());
|
|
364
|
+
};
|
|
365
|
+
const handleOpenChange = (ev, { open }) => {
|
|
366
|
+
setIsOpen(open);
|
|
367
|
+
setInput(''); // clean up on cancel/close
|
|
368
|
+
};
|
|
369
|
+
const handleSubmit = async ev => {
|
|
370
|
+
ev.preventDefault();
|
|
371
|
+
await sendInput(input); // sending data on confirm
|
|
372
|
+
setIsOpen(false);
|
|
373
|
+
};
|
|
374
|
+
return (
|
|
375
|
+
<>
|
|
376
|
+
<Dialog open={isOpen} onOpenChange={handleOpenChange}>
|
|
377
|
+
<DialogTrigger>
|
|
378
|
+
<Button>Open Dialog</Button>
|
|
379
|
+
</DialogTrigger>
|
|
380
|
+
<DialogSurface>
|
|
381
|
+
<DialogTitle>This is a dialog</DialogTitle>
|
|
382
|
+
<DialogBody>
|
|
383
|
+
<form id="form-id" onSubmit={handleSubmit}>
|
|
384
|
+
<Input required placeholder="Some input..." value={input} onChange={handleInputChange} />
|
|
385
|
+
</form>
|
|
386
|
+
</DialogBody>
|
|
387
|
+
<DialogActions>
|
|
388
|
+
<DialogTrigger type="close">
|
|
389
|
+
<Button>Close</Button>
|
|
390
|
+
</DialogTrigger>
|
|
391
|
+
<Button disabled={input === ''} form="form-id" type="submit">
|
|
392
|
+
{state === 'idle' && 'Submit'}
|
|
393
|
+
{state === 'submitting' && 'Submitting...'}
|
|
394
|
+
</Button>
|
|
395
|
+
</DialogActions>
|
|
396
|
+
</DialogSurface>
|
|
397
|
+
</Dialog>
|
|
398
|
+
</>
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Opting out of native `<dialog>`
|
|
404
|
+
|
|
405
|
+
```tsx
|
|
406
|
+
const dialog = <Dialog>
|
|
407
|
+
<DialogTrigger>
|
|
408
|
+
<Button>Open Dialog</Button>
|
|
409
|
+
<DialogTrigger>
|
|
410
|
+
<DialogSurface as="div">
|
|
411
|
+
This is as basic as it gets.
|
|
412
|
+
</DialogSurface>
|
|
413
|
+
</Dialog>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
```html
|
|
417
|
+
<!-- expected DOM output -->
|
|
418
|
+
<button aria-haspopup="true" class="fui-button">Open Dialog</button>
|
|
419
|
+
<!-- ... portal ... -->
|
|
420
|
+
<div aria-hidden="true" class="fui-dialog-backdrop"></div>
|
|
421
|
+
<div aria-modal="true" role="dialog" class="fui-dialog-content">This is as basic as it gets</div>
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
## Migration
|
|
425
|
+
|
|
426
|
+
_TBA: Link to migration guide doc_
|
|
427
|
+
|
|
428
|
+
## Behaviors
|
|
429
|
+
|
|
430
|
+
Dialog will use **Tabster** to handle the keyboard navigation and ensure focus trapping.
|
|
431
|
+
|
|
432
|
+
The below references were used to decide appropriate keyboard interaction from an a11y perspective.
|
|
433
|
+
|
|
434
|
+
- https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/
|
|
435
|
+
- https://www.w3.org/WAI/ARIA/apg/example-index/dialog-modal/dialog.html
|
|
436
|
+
- https://www.w3.org/WAI/ARIA/apg/example-index/dialog-modal/alertdialog.html
|
|
437
|
+
|
|
438
|
+
### Modal
|
|
439
|
+
|
|
440
|
+
#### Mouse & Touch
|
|
441
|
+
|
|
442
|
+

|
|
443
|
+
|
|
444
|
+
1. Clicking on the trigger (element / button component) a Dialog is displayed with a dimmed background.
|
|
445
|
+
2. Clicking on the dimmed background dismisses the dialog.
|
|
446
|
+
3. The dialog can be dismissed also when confirmation button is clicked (footer).
|
|
447
|
+
|
|
448
|
+
#### Keyboard
|
|
449
|
+
|
|
450
|
+

|
|
451
|
+
|
|
452
|
+
1. **(1)** TabKey to set focus on Trigger, use EnterKey to open.
|
|
453
|
+
2. **(2-6)** Focus is moved to the first focusable control inside the dialog.
|
|
454
|
+
3. **(5-6)** After the dialog is dismissed, keyboard focus should be moved back to where it was before it moved into the dialog. Otherwise the focus can be dropped to the beginning of the page. Or if the item is no longer available it can be moved to the next logical location in that region i.e. next / previous item.
|
|
455
|
+
4. **TabKey** Moves focus to next focusable element inside the dialog. When focus is on the last focusable element in the dialog, moves focus to the next focusable action in the browser window.
|
|
456
|
+
5. **Shift+Tab** Moves focus to previous focusable element inside the dialog. When focus is on the first focusable element in the dialog, moves focus to the last focusable action within the browser window.
|
|
457
|
+
6. **EscKey** Closes the dialog, returning focus to the trigger, in case the trigger is gone or not possible to focus, the use might require to setup focus manually.
|
|
458
|
+
|
|
459
|
+
### Non-Modal
|
|
460
|
+
|
|
461
|
+
#### Mouse & touch
|
|
462
|
+
|
|
463
|
+

|
|
464
|
+
|
|
465
|
+
1. Clicking on the trigger (element / button component) a Dialog is displayed without a dimmed background.
|
|
466
|
+
2. A user can continue to interact with elements on the page behind the dialog.
|
|
467
|
+
3. Clicking the dismiss button (X icon in header), or cancel/dismiss buttons (footer) will close the dialog.
|
|
468
|
+
|
|
469
|
+
#### Keyboard
|
|
470
|
+
|
|
471
|
+

|
|
472
|
+
|
|
473
|
+
1. **(1)** **TabKey** to set focus on Trigger, use **EnterKey** to open.
|
|
474
|
+
2. - **(2a)** Focus is moved to the default focusable control inside the dialog.
|
|
475
|
+
- **(2b)** **EnterKey** on dismiss action to close dialog,
|
|
476
|
+
3. After the dialog is dismissed, keyboard focus should be moved back to where it was before it moved into the dialog. Otherwise the focus can be dropped to the beginning of the page.
|
|
477
|
+
4. **TabKey** Moves focus to next focusable element inside the dialog, once you get to the end of the focusable items within the dialog focus moves to next actionable item outside of the dialog container.
|
|
478
|
+
5. **Shift+Tab** Moves focus to previous focusable element inside the dialog and back to the trigger control.
|
|
479
|
+
6. **EscKey** Closes the dialog when the focus is on the dialog.
|
|
480
|
+
|
|
481
|
+
### Alert dialog
|
|
482
|
+
|
|
483
|
+
#### Mouse & Touch
|
|
484
|
+
|
|
485
|
+

|
|
486
|
+
|
|
487
|
+
1. Clicking on the trigger (element / button component) a Dialog is displayed with a dimmed background.
|
|
488
|
+
2. Windows under the dialog are are inert, their scrolling is blocked and clicking on the dimmed background will not close the dialog.
|
|
489
|
+
3. Clicking the dismiss button (X icon in header), or cancel/dismiss buttons (footer) will dismiss the dialog.
|
|
490
|
+
|
|
491
|
+
#### Keyboard
|
|
492
|
+
|
|
493
|
+

|
|
494
|
+
|
|
495
|
+
1. **(1)** **TabKey** to set focus on Trigger, use **EnterKey** to open.
|
|
496
|
+
2. **(2 & 3)** Focus is automatically set to the first focusable element inside the dialog
|
|
497
|
+
3. **EnterKey** Confirms or cancels the alert message and dialog is dismissed.
|
|
498
|
+
4. **TabKey** Moves focus to next focusable element inside the dialog. When focus is on the last focusable element in the dialog, moves focus to the next focusable action in the browser window.
|
|
499
|
+
5. **Shift+Tab** Moves focus to previous focusable element inside the dialog. When focus is on the first focusable element in the dialog, moves focus to the last focusable action within the browser window.
|
|
500
|
+
|
|
501
|
+
## Accessibility
|
|
502
|
+
|
|
503
|
+
> ⚠️ _Note: All other accessibility information, not covered in this section, is provided throughout the spec._
|
|
504
|
+
|
|
505
|
+
The dialog component follows the [Dialog WAI-Aria design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/).
|
|
506
|
+
|
|
507
|
+
### Aria roles and states
|
|
508
|
+
|
|
509
|
+
#### Modal
|
|
510
|
+
|
|
511
|
+
- Trigger button
|
|
512
|
+
- [`aria-haspopup="dialog"`](https://w3c.github.io/aria/#aria-haspopup)
|
|
513
|
+
- Dialog
|
|
514
|
+
- [`role="dialog"`](https://w3c.github.io/aria/#dialog)
|
|
515
|
+
- [`aria-modal=true`](https://w3c.github.io/aria/#aria-modal)
|
|
516
|
+
- [`aria-labelledby={dialog-title-idref}`](https://w3c.github.io/aria/#aria-labelledby)
|
|
517
|
+
- [`aria-describedby={dialog-body-idref}`](https://w3c.github.io/aria/#aria-describedby)
|
|
518
|
+
|
|
519
|
+
#### Non-modal
|
|
520
|
+
|
|
521
|
+
- Trigger button
|
|
522
|
+
- [`aria-haspopup="dialog"`](https://w3c.github.io/aria/#aria-haspopup)
|
|
523
|
+
- Dialog
|
|
524
|
+
- [`role="dialog"`](https://w3c.github.io/aria/#dialog)
|
|
525
|
+
- [`aria-modal=false`](https://w3c.github.io/aria/#aria-modal)
|
|
526
|
+
- [`aria-labelledby={dialog-title-idref}`](https://w3c.github.io/aria/#aria-labelledby)
|
|
527
|
+
- [`aria-describedby={dialog-body-idref}`](https://w3c.github.io/aria/#aria-describedby)
|
|
528
|
+
|
|
529
|
+
#### Alert dialog
|
|
530
|
+
|
|
531
|
+
- Trigger button
|
|
532
|
+
- [`aria-haspopup="dialog"`](https://w3c.github.io/aria/#aria-haspopup)
|
|
533
|
+
- Dialog
|
|
534
|
+
- [`role="alertdialog"`](https://w3c.github.io/aria/#dialog)
|
|
535
|
+
- [`aria-modal=true`](https://w3c.github.io/aria/#aria-modal)
|
|
536
|
+
- [`aria-labelledby={dialog-title-idref}`](https://w3c.github.io/aria/#aria-labelledby)
|
|
537
|
+
- [`aria-describedby={dialog-body-idref}`](https://w3c.github.io/aria/#aria-describedby)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|