Dialog

Dialogs are interactive pop-ups reserved for situations which do not require immediate attention.

yarn add @workday/canvas-kit-react
Install
yarn add @workday/canvas-kit-react

Anatomy

Image of a dialog container with annotation markers.

  1. Card: The Card contains content for a Dialog, it uses the depth 6 token for the drop-shadow styling.
  2. Heading (Optional): Heading should display the title of the content or task.
  3. Body: Dialogs contain many different types of content in the body. Typical types of content include media, alerts, dialogs, and/or task-oriented flows.
  4. In-line Buttons (Optional): Action should be at the bottom of the container when used. There are multiple alignments available for use; Left (Default), Center, Full Width & Full Width Stacked, or Right aligned.
  5. Close “X” Icon (Optional): Users must be able to intentionally dismiss a Dialog. This icon inherits styling and interactions from our Tertiary Icon-Only Button Variant.

Usage Guidance

  • Dialogs allow for entry of data or alert users on any given page after an action has been initiated and it doesn't require immediate attention.
  • On web platforms with browser windows 767px or wider, Dialogs show up next to the button that activated it.
  • On web platforms with browser windows less than 767px width, Dialogs show up at the bottom of the screen and in front of an overlay.
  • Dialogs are often used to display media, alerts, dialogs, and/or task-oriented flows. Links, buttons, field sets, icons, text inputs, and prompts can all exist within Dialogs.
  • In-line buttons used in Dialogs can be aligned Left (Default), Center, Full Width & Full Width Stacked, or Right aligned.

When to Use

  • Use Dialog to gather input from the user without blocking interaction with the rest of the page.
  • Use Dialog when alert content and text are too large for a standard Toast or Pop-up notification.

When to Use Something Else

  • Use Modal to gather immediate input from the user by blocking interaction with the rest of the page.
  • Do not use Dialogs to serve up easily accessible links or simple messages that can be dismissed quickly (use Toasts or Popups for this).
  • Do not use Dialogs to display dense information, such as Tables or Multi-View Containers.
  • Consider a Toast if you are communicating status or confirmation of the application process to the user.
  • Consider a Menu if the input is a single selection of options.

Responsive View

Dialog components adjust width and content presentation based on screen size. When content exceeds the length of the screen, the Dialog content will become scrollable in the body section of the Dialog. For long content on a small screen, inline buttons will continue to scroll with the content.

Touch Based Behavior

The overlay on Dialogs are not click or touch enabled to close the Dialog component view on small screens between 320-767px. This accounts for accidental touch on mobile devices. Background overlays will close the Dialog when clicked on larger devices when the screen reaches the minimum width.

Examples

Basic Example

Modal and Dialog are very similar: most of the examples from Modal can be adapted to Dialog by changing Modal to Dialog and replacing Modal.Overlay with Dialog.Popper.

Unlike Modal, Dialog does not render the rest of the page inert while it is active. Dialog should be used in situations where the task does not require immediate attention such as in the example below.

Focus Redirect

Since Modal requires immediate attention, it will trap the keyboard focus inside the Modal until an action is taken. Dialog manages focus differently, however, since it does not require immediate attention.

The following example shows how Dialog manages focus in and out of the component.

Instead of trapping focus within the Dialog, it is effectively treated as an inline element next to its triggering Dialog.Target button. Tabbing out of the Dialog will close the popup and move focus to the next button.

Dialog also adds an aria-owns to a <div> element which is rendered as a sibling of the Dialog.Target button. The aria-owns references the Dialog.Card and allows screen readers which support aria-owns to navigate the Dialog as if it weren't portalled to the bottom of the document body.

Component API

Dialog

This component is the container component and does not render any semantic elements. It provides a React Context model for the Dialog subcomponents. If you manually pass a model to all subcomponents, this container component isn't needed. If you do not pass a model, the Dialog container component will build a default one using useDialogModel. Dialog is a composition of a component and has a similar structure to Popup.

Props

Props extend from . If a model is passed, props from DialogModelConfig are ignored.

NameTypeDescriptionDefault
model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

Dialog.Card

A Dialog.Card is a wrapper around the component, but hooked up to a . By default, this element has a role=dialog, aria-labelledby and an id. The behavior hook used is called .

Layout Component

Dialog.Card supports all props from thelayout component.

Props

Props extend from div. Changing the as prop will change the element interface.

NameTypeDescriptionDefault
childrenReactNode

Children of the Card. Should contain a <Card.Body> and an optional <Card.Heading>

cs

The cs prop takes in a single value or an array of values. You can pass the CSS class name returned by , or the result of and . If you're extending a component already using cs, you can merge that prop in as well. Any style that is passed to the cs prop will override style props. If you wish to have styles that are overridden by the css prop, or styles added via the styled API, use wherever elemProps is used. If your component needs to also handle style props, use instead.

import {handleCsProp} from '@workday/canvas-kit-styling';
import {mergeStyles} from '@workday/canvas-kit-react/layout';
// ...
// `handleCsProp` handles compat mode with Emotion's runtime APIs. `mergeStyles` has the same
// function signature, but adds support for style props.
return (
<Element
{...handleCsProp(elemProps, [
myStyles,
myModifiers({ size: 'medium' }),
myVars({ backgroundColor: 'red' })
])}
>
{children}
</Element>
)
asReact.ElementType

Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using React.forwardRefand spread extra props to a root element.

Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care.

div
refReact.Ref<R = div>

Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If as is set to an element, it will be that element. If as is a component, the reference will be to that component (or element if the component uses React.forwardRef).

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

useDialogCard

(
  ,
  (
    model: ,
    elemProps: {},
    ref: React.Ref
  ) => {
    id: string;
  }
)

Dialog.Popper

A Dialog.Popper is a wrapper around . The behavior hook used is called .

Props

Props extend from div. Changing the as prop will change the element interface.

NameTypeDescriptionDefault
placement

The placement of the Popper contents relative to the anchorElement. Accepts auto, top, right, bottom, or left. Each placement can also be modified using any of the following variations: -start or -end.

fallbackPlacements[]

Define fallback placements by providing a list of in array (in order of preference). The default preference is following the order of top, right, bottom, and left. Once the initial and opposite placements are not available, the fallback placements will be in use. Use an empty array to disable the fallback placements.

popperOptions<PopperOptions>

The additional options passed to the Popper's popper.js instance.

anchorElement <Element> Element null

The reference element used to position the Popper. Popper content will try to follow the anchorElement if it moves and will reposition itself if there is no longer room in the window.

children ((props: {
    placement: ;
  }) => ReactNode)
ReactNode

The content of the Popper. If a function is provided, it will be treated as a Render Prop and pass the placement chosen by PopperJS. This placement value is useful if your popup needs to animate and that animation depends on the direction of the content in relation to the anchorElement.

getAnchorClientRect() => 

When provided, this optional callback will be used to determine positioning for the Popper element instead of calling getBoundingClientRect on the anchorElement prop. Use this when you need complete control over positioning. When this prop is specified, it is safe to pass null into the anchorElement prop. If null is passed into the anchorElement prop, an owner will not be provided for the PopupStack.

openboolean

Determines if Popper content should be rendered. The content only exists in the DOM when open is true

true
onPlacementChange(placement: ) => void

A callback function that will be called whenever PopperJS chooses a placement that is different from the provided placement preference. If a placement preference doesn't fit, PopperJS will choose a new one and call this callback.

portalboolean

If false, render the Popper within the DOM hierarchy of its parent. A non-portal Popper will constrained by the parent container overflows. If you set this to false, you may experience issues where you content gets cut off by scrollbars or overflow: hidden

true
popperInstanceRefRef<>

Reference to the PopperJS instance. Useful for making direct method calls on the popper instance like update.

asReact.ElementType

Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using React.forwardRefand spread extra props to a root element.

Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care.

div
refReact.Ref<R = div>

Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If as is set to an element, it will be that element. If as is a component, the reference will be to that component (or element if the component uses React.forwardRef).

model

Optional model to pass to the component. This will override the default model created for the component. This can be useful if you want to access to the state and events of the model, or if you have nested components of the same type and you need to override the model provided by React Context.

elemPropsHook(
  model: ,
  elemProps: TProps
) => HTML Attributes

Optional hook that receives the model and all props to be applied to the element. If you use this, it is your responsibility to return props, merging as appropriate. For example, returning an empty object will disable all elemProps hooks associated with this component. This allows finer control over a component without creating a new one.

Model

useDialogModel

useDialogModel (config: ):

Accessibility Guidelines

The accessibility for the Dialog component is identical to the guidelines detailed in the Modal component. Please refer to the accessibility guidelines in the Modal popup component.

Content Guidelines

See Popups, Modals, and Dialogs in the UI Text Section of Content Style Guide for Dialog language guidelines.

Can't Find What You Need?

Check out our FAQ section which may help you find the information you're looking for.

FAQ Section