Note: Dialogs are designed to be attention-grabbing and prominent to ensure that the user sees and interacts with them, therefore, they should only be used to display critical information. For less critical information and tasks, consider using our drawer component or popover component for actionable UI and our tooltip component for non-actionable UI.
Anatomy
Note: Image not to scale
- Container
- Close button icon (optional)
- Scrim
- Footer (optional)
Options
Width
Dialog width can be defined. The default width of the dialog is 500px.
Height
Dialog height can be defined. The default height of the dialog is 300px.
Optional footer
The footer is optional when using the dialog. It provides recommended positioning and padding for buttons and links on a dialog for both inline (side-by-side) elements and stacked (vertical) elements.
Optional close
The dialog close button can be optional. By default, the close button renders in the top right of the dialog content. The button's asChild
property can be used to give any child button the ability to close the dialog.
Custom scrim color
The scrim color can be changed by defining the color using one of our tokens.
Custom container color
The container color can be changed by defining the color using one our tokens.
Behavior
Closing
When the close button is rendered, the dialog can be closed by clicking the scrim, the close button, or the cancel button if one is present.
Note: If the user is required to take action in order to dismiss the dialog, the dialog can be set to open and will remain open even if the scrim is clicked on. The user must then interact with the content in the dialog to close it.
On hover, a circular background color appears behind the close icon.
Content overflow
Content will overflow, both vertically and horizontally, in the dialog by default. Users can scroll within a dialog. See our guidance on complex and interactive content in dialogs.
Note: If a dialog has vertical overflow, the content in the scrollable area should flow behind the footer. In other words, the footer should be sticky so that the user can always see the action buttons available to them.
Guidance
Content should be accessible
Make sure color contrasts comply with WCAG accessible contrast requirements.
Buttons and links should be placed at the bottom of the container
Buttons should typically be placed at the bottom right of the container or in the center of the container at full-width. If using text links, they should typically be placed at the bottom-center of the dialog along with any buttons. Dialogs should include a maximum of two buttons.
Confirming buttons should be aligned to the end of the screen. See the example below for reference, where the confirming button is on the right and the dismissing button is to its left.
Avoid overly complex or interactive content in dialogs
Be careful with the level of interactivity and complexity of content inside of a dialog. Avoid using scrollbars in dialogs.
Make sure that the dialog contains only the essential information and actions. Consider other options, such as a separate page, for content that takes up a lot of space or requires several actions.
Dialog should be used with a scrim
Using a scrim with the dialog helps distinguish it from the primary screen in the background. It will help users understand that the dialog is layered above the parent page, shifting the user’s focus appropriately and aligning with best practices for accessibility.
When designing in Figma, pull in the scrim component from the WPDS UI kit to use it in your design.
Consider screen size when determining the appropriate size for the dialog
Avoid fullscreen dialogs on desktop. On desktop, a dialog should only take up a portion of the screen, with visibility of the primary screen behind it. Ideally, it shouldn’t take up more than 25% of the screen on large screens and desktop.
On tablets and mobile, dialogs may take up a larger portion of the screen, typically 50% to 100%, as the screen size will be smaller.
Note that these percentages are not exact rules but provide general guidelines to follow.
Ensure that the most critical information goes on the topmost layer
The most critical information should be on the topmost layer, regarding Z-index/layering of the dialog on the page.
Do not use nested dialogs
Using a nested dialog creates visual complexity. Multiple layers of information and actions can be confusing to users.
Use clear, consistent language in dialogs
Dialog content should be as concise as possible while still effectively communicating its message to users.
When writing headers and buttons, use explicit button text that indicates exactly what will happen and match headers to corresponding buttons. For example, for a dialog labeled “Save your changes,” instead of using buttons labeled “Yes” and “No,” use wording that is more direct and actionable such as “Save” and “Discard.”
Accessibility
Keyboard interaction
The dialog component is accessible via keyboard interaction. When the dialog trigger or close buttons are focused, the “space” key will open and close a dialog. The "tab" key can be used to navigate focus on the next interactive element contained in the dialog. Pressing “shift + tab” can be used to navigate focus on the previous interactive element contained in the dialog. The element currently in focus is denoted by an outline, using the CSS outline property. Pressing the "enter" ("return") key will trigger or commit the action of the focused element. Pressing the “escape” key closes the dialog.
Include a title and description
An accessible title and optional accessible description should be included to be announced by screen readers when the dialog is opened. Take a look at the code to see the title and description for this example dialog.
API Reference
DialogRoot
Prop | Description | Type | Default | Required |
---|---|---|---|---|
open | boolean | ---- | False | |
defaultOpen | boolean | ---- | False | |
onOpenChange | (open: boolean) => void | ---- | False | |
modal | boolean | ---- | False |
DialogContent
Prop | Description | Type | Default | Required |
---|---|---|---|---|
backgroundColor | Css background color of content | Color | Token<"background", string, "colors", "wpds"> | Token<"outline", string, "colors", "wpds"> | Token<"errorContainer", string, "colors", "wpds"> | ... 267 more ... | Token<...> | $gray700 | False |
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
width | Width in any valid css string | string | 500px | False |
height | Height in any valid css string | string | 300px | False |
zIndex | Css z-index | ZIndex | Token<"page", string, "zIndices", "wpds"> | Token<"offer", string, "zIndices", "wpds"> | Token<"shell", string, "zIndices", "wpds"> | Token<...> | 400 | False |
forceMount | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. | true | true | False |
asChild | boolean | ---- | False | |
onEscapeKeyDown | Event handler called when the escape key is down. Can be prevented. | (event: KeyboardEvent) => void | ---- | False |
onPointerDownOutside | Event handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented. | (event: PointerDownOutsideEvent) => void | ---- | False |
onFocusOutside | Event handler called when the focus moves outside of the `DismissableLayer`. Can be prevented. | (event: FocusOutsideEvent) => void | ---- | False |
onInteractOutside | Event handler called when an interaction happens outside the `DismissableLayer`. Specifically, when a `pointerdown` event happens outside or focus moves outside of it. Can be prevented. | (event: PointerDownOutsideEvent | FocusOutsideEvent) => void | ---- | False |
onOpenAutoFocus | Event handler called when auto-focusing on open. Can be prevented. | (event: Event) => void | ---- | False |
onCloseAutoFocus | Event handler called when auto-focusing on close. Can be prevented. | (event: Event) => void | ---- | False |
DialogTrigger
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
asChild | boolean | ---- | False | |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
DialogPortal
Prop | Description | Type | Default | Required |
---|---|---|---|---|
container | Specify a container element to portal the content into. | HTMLElement | ---- | False |
forceMount | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. | true | true | False |
DialogOverlay
Prop | Description | Type | Default | Required |
---|---|---|---|---|
backgroundColor | Css background color of overlay | Color | Token<"background", string, "colors", "wpds"> | Token<"outline", string, "colors", "wpds"> | Token<"errorContainer", string, "colors", "wpds"> | ... 267 more ... | Token<...> | rgba(0, 0, 0, .50) | False |
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
zIndex | Css z-index of overlay | ZIndex | Token<"page", string, "zIndices", "wpds"> | Token<"offer", string, "zIndices", "wpds"> | Token<"shell", string, "zIndices", "wpds"> | Token<...> | 400 | False |
forceMount | Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries. | true | true | False |
asChild | boolean | ---- | False |
DialogTitle
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
asChild | boolean | ---- | False |
DialogDescription
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
asChild | boolean | ---- | False |
DialogClose
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
asChild | boolean | ---- | False | |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | CSS | ---- | False |
DialogHeader
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | {} & { alignContent?: AlignContent | ScaleValue | Globals | Index; alignItems?: AlignItems | ScaleValue | Globals | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; } | ---- | False |
DialogBody
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | {} & { alignContent?: AlignContent | ScaleValue | Globals | Index; alignItems?: AlignItems | ScaleValue | Globals | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; } | ---- | False |
isOverflow | boolean | "true" | ({ "@sm"?: boolean | "true"; "@md"?: boolean | "true"; "@lg"?: boolean | "true"; "@xl"?: boolean | "true"; "@xxl"?: boolean | "true"; "@notSm"?: boolean | "true"; "@notMd"?: boolean | "true"; ... 17 more ...; "@initial"?: boolean | "true"; } & { ...; }) | ---- | False |
DialogFooter
Prop | Description | Type | Default | Required |
---|---|---|---|---|
children | Any React node may be used as a child | ReactNode | ---- | False |
css | WPDS provides a css prop for overriding styles easily. It’s like the style attribute, but it supports tokens, media queries, nesting and token-aware values. All WPDS Components include a css prop. Use it to pass in overrides. | {} & { alignContent?: AlignContent | ScaleValue | Globals | Index; alignItems?: AlignItems | ScaleValue | Globals | Index; ... 426 more ...; vectorEffect?: VectorEffect | ... 2 more ... | Index; } & ... 7 more ... & { ...; } | ---- | False |