Dialog

Dialog displays content that requires user interaction, via a layer that sits on top of the page content.

Just want a text notification? Try Toaster component.

Import#

import { Dialog } from '@volue/wave-react';
// you may also access Dialog's context via hook:
// import { useDialogContext } from '@volue/wave-react';

Dialog is a compound component that consists of multiple parts to help you create all kinds of dialogs:

  • Dialog: The wrapper that contains all the parts of a dialog and provides context for its children.
  • Dialog.Trigger: The button that opens the dialog.
  • Dialog.Box: The container for the dialog's content.
  • Dialog.Header: The header of the dialog.
  • Dialog.Title: The title that labels the dialog.
  • Dialog.Body: The wrapper that houses the dialog's main content.
  • Dialog.Footer: The footer that houses the dialog actions.
  • Dialog.Close: The button that closes the dialog.

Examples#

Basic#

Dialog works in an uncontrolled way by default, meaning each Dialog component instance is responsible for managing its own state internally.

The Dialog.Trigger component can be instructed via as prop to render as something else. In our case we want to render it as a <Button> component.

Controlled Dialog#

You can easily make the dialog controlled, by passing your own state to isOpen prop. onIsOpenChange handler is called when the state of the dialog changes, allowing you to sync state.

Dialog with header and body#

Use Dialog.Header, Dialog.Title, Dialog.Close and Dialog.Body parts to construct dialog box with a header and scrollable content.

  • Dialog.Title takes the title you pass in and labels the dialog with it through ARIA attributes to provide accessible experience.
  • Dialog.Body ensures that the body of the dialog becomes scrollable when there is not enough space to fit.

Dialog with footer#

Use Dialog.Footer to add a footer to your dialog and include any action buttons inside.

Stack component can be helpful to layout the buttons.

Dialog with dividers#

Use withDividers prop on Dialog.Body to add subtle dividers between dialog sections.

Use useHasOverflow hook to dynamically apply dividers only when content overflows Dialog.Body area.

import { useHasOverflow } from '@volue/wave-react';

Customizable width#

Use width prop to customize width of the Dialog.Box. It will act as a maximum width of the dialog, but if the viewport width is less than that, the dialog will shrink accordingly.

Confirmation dialog example#

Confirmation on dialog hide#

You can prevent users from accidentally closing a dialog with unsaved changes by displaying a nested confirmation dialog. This can be achieved by preventing the default close behavior and programatically opening a controlled, nested dialog.


Accessibility features#

  • When the dialog opens, focus is sent into the dialog and set to the first tabbable element. Focus stays trapped within the dialog until close is requested. After closing, focus is restored back to the trigger element.

  • Clicking on the overlay closes the dialog.

  • Pressing ESC closes the dialog.

  • Scrolling is blocked on the elements behind the dialog.

  • The dialog is portaled (via Portal utility) to the end of document.body to break it out of the source order.

  • Manages screen reader announcements with Dialog.Title.


API Reference#

Dialog#

Prop
Type
Default
isOpen
boolean
false
defaultIsOpen
boolean
No default value
onIsOpenChange
function
No default value

Dialog.Trigger#

Prop
Type
Default
as
enum
button
css
StitchesCss
No default value

Dialog.Box#

Prop
Type
Default
css
StitchesCss
No default value
width
string | number
"38rem"
padding
SpacingToken
No default value
zIndex
number
No default value
onExitComplete
function
() => void
onPointerDownOutside
function
No default value
onEscapeKeyDown
function
No default value
shouldCloseOnOverlayClick
boolean
true
shouldCloseOnEsc
boolean
true

Dialog.Header#

In addition to the props below, you can pass Box props to control the spacing.

Prop
Type
Default
css
StitchesCss
No default value

Dialog.Title#

In addition to the props below, you can pass Heading props.

Prop
Type
Default
as
enum
button
css
StitchesCss
No default value

Dialog.Body#

In addition to the props below, you can pass Box props to control the spacing.

Prop
Type
Default
css
StitchesCss
No default value
withDividers
boolean
false

Dialog.Footer#

In addition to the props below, you can pass Box props to control the spacing.

Prop
Type
Default
css
StitchesCss
No default value

Dialog.Close#

Prop
Type
Default
as
enum
button
css
StitchesCss
No default value

Guidelines#

Dialogs help focus the user’s attention exclusively on one task or part of the information by displaying it in a window that sits on top of the page content.

Dialogs should be used for:

  1. Confirmation of an action

    If the user decides to delete an important entity, such critical actions must get additional confirmation.

  2. Notifying of errors that block an app’s standard performance

    For less severe notifications, toast notification components must be used.

Types of dialogs#

Correct location of the map controller in the bottom right corner

Modal dialog

Such dialogs can display more complex data like application forms or description of an entity.
Correct location of the map controller in the bottom right corner

Confirmation dialog

This type of dialog is used to request a confirmation of action from a user.

Scaling#

Wave dialogs have a fixed with initially and scaling depending on the device's resolution.

Button banner

Alignment#

Dialogs should only be aligned my the centre of the viewport.

Dialog - correct alignment
Correct alignment by the centre of the viewport.
Dialog - wrong alignment
Wrong alignment of the dialog.

Content#

The content of dialogs should deliver the message efficiently and not be overcomplicated.

Dialog - correct content
Do use simple sentences to deliver the main message of the dialog.
Dialog - wrong content
Don't overcomplicate the message of the dialog.
Dialog - correct scroll
Do use vertical scroll if the content exceeds the available height of the dialog.
Dialog - wrong scroll
Dialog can't exceed the height of the viewport.