Skip to main content
Design system

Dialog

A dialog is an overlay used to display important content or request input from the user. It is layered on top of the primary screen and typically requires the user to take action before continuing.

Bundle size: 192.97 kB
Install:
npm install @washingtonpost/wpds-ui-kit
|Copy
Usage:
import { Dialog } from "@washingtonpost/wpds-ui-kit"
|Copy
Storybook:  View on Storybook
Source:  View on Github
Primitive:  View their docs

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

  1. Container
  2. Close button icon (optional)
  3. Scrim
  4. 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.

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 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

PropDescriptionTypeDefaultRequired
open
boolean
----False
defaultOpen
boolean
----False
onOpenChange
(open: boolean) => void
----False
modal
boolean
----False

DialogContent

PropDescriptionTypeDefaultRequired
backgroundColorCss background color of content
Color | Token<"background", string, "colors", "wpds"> | Token<"outline", string, "colors", "wpds"> | Token<"errorContainer", string, "colors", "wpds"> | ... 292 more ... | Token<...>
$gray700 False
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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
widthWidth in any valid css string
string
500px False
heightHeight in any valid css string
string
300px False
zIndexCss z-index
ZIndex | Token<"page", string, "zIndices", "wpds"> | Token<"offer", string, "zIndices", "wpds"> | Token<"shell", string, "zIndices", "wpds"> | Token<...>
400 False
forceMountUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
true
true False
asChild
boolean
----False
onEscapeKeyDownEvent handler called when the escape key is down. Can be prevented.
(event: KeyboardEvent) => void
----False
onPointerDownOutsideEvent handler called when the a `pointerdown` event happens outside of the `DismissableLayer`. Can be prevented.
(event: PointerDownOutsideEvent) => void
----False
onFocusOutsideEvent handler called when the focus moves outside of the `DismissableLayer`. Can be prevented.
(event: FocusOutsideEvent) => void
----False
onInteractOutsideEvent 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
onOpenAutoFocusEvent handler called when auto-focusing on open. Can be prevented.
(event: Event) => void
----False
onCloseAutoFocusEvent handler called when auto-focusing on close. Can be prevented.
(event: Event) => void
----False

DialogTrigger

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
asChild
boolean
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
containerSpecify a container element to portal the content into.
HTMLElement
----False
forceMountUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
true
true False

DialogOverlay

PropDescriptionTypeDefaultRequired
backgroundColorCss background color of overlay
Color | Token<"background", string, "colors", "wpds"> | Token<"outline", string, "colors", "wpds"> | Token<"errorContainer", string, "colors", "wpds"> | ... 292 more ... | Token<...>
rgba(0, 0, 0, .50) False
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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
zIndexCss z-index of overlay
ZIndex | Token<"page", string, "zIndices", "wpds"> | Token<"offer", string, "zIndices", "wpds"> | Token<"shell", string, "zIndices", "wpds"> | Token<...>
400 False
forceMountUsed to force mounting when more control is needed. Useful when controlling animation with React animation libraries.
true
true False
asChild
boolean
----False

DialogTitle

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
asChild
boolean
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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

PropDescriptionTypeDefaultRequired
childrenAny React node may be used as a child
ReactNode
----False
cssWPDS 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
Edit this page on GitHub.