Skip to content

Dialog ​

A Dialog is a container that is overlaid on a web page or app in order to present necessary information and tasks. A Dialog is sometimes referred to as a modal or an overlay.

Overview ​

When to use Dialog ​

Dialogs facilitate communication between the system and user. They perform best when used for urgent decisions or as a workflow within a bigger task, as they don’t require loading a new page and keep actions in context.

Dialogs are intentionally disruptive, since the user needs to interact with or close the Dialog before moving on. For this reason, they should be used sparingly and only when necessary.

Use the Dialog component when:

  • The user needs to make a decision or provide input to the system before continuing with the task at hand.
  • Additional information needs to be displayed and separated from the page content.
  • The user needs to provide additional confirmation before taking an action.

Avoid using Dialog when:

  • The information can be displayed within the main interface.
  • The information is not important enough to interrupt the user's flow.
  • The content is long or complex, like a form with numerous fields, and cannot be split into multiple steps within a Dialog.

About Dialog ​

Dialog includes the following elements.

The Dialog header must contain a title, though it can be visually-hidden if the Dialog's purpose is clear from context. A subtitle can be used to provide additional information about the Dialog.

A quiet, icon-only Button may be used to close the Dialog. It can also be replaced with a text Button in some cases.

Body ​

Any type of content or components can be included within the Dialog’s body.

  • Avoid using Cards or other elevated components within the Dialog.

One to two action buttons should appear at the end of the Dialog. A primary Button (either progressive or destructive) is used to indicate the main action. A normal neutral Button can be used to indicate a default action (e.g. β€œCancel”).

  • Include at least one action button.
  • Stack action buttons based on text length when needed, placing the primary button on top.
  • Don't stack action buttons when they can be placed side by side.

The Dialog footer can include text above the action buttons to provide additional information (e.g. terms and conditions to read before publishing).

A permanent action can be included (e.g. a "Don't show again" checkbox) (refer to the Multi-step Dialog for an example).

Examples ​

Basic usage ​

This example includes a title, close button, footer text, primary action, and default action.

  • Write short titles and simple calls to action to help users understand what to do. Concise & Clear

<client-only> tag

The examples on this page are all wrapped with VitePress's built-in <client-only> component, since the Codex documentation site (built with VitePress) uses SSR. Other SSRed applications will need to do something similar (only rendering Dialog after the mounted hook has been fired, etc.).

This tag has been removed from the MediaWiki examples, as <client-only> is meaningless there.

With form inputs ​

A Dialog can be used to gather user input. For long forms with many inputs, consider splitting the Dialog into multiple steps or creating a separate page instead.

Stacked actions ​

The action buttons in the footer are stacked vertically on narrow screens, but appear side by side on wide screens. In some situations, like when the button text is long, you can force the action buttons to always be stacked vertically regardless of screen size.

Developer notes

When using the default Dialog footer, use the stackedActions prop to force the action buttons to be stacked vertically, even on wide screens.

Fixed height ​

By default, the height of a Dialog is dependent on its content. Use the fixedHeight prop to force a fixed height. The default fixed height will be the height of the entire screen unless a specific value is set.

  • Use a fixed height when needing to maintain the actions in the same position, such as for multistep Dialogs.

Developer notes

When using the fixedHeight prop, the default fixed height will be the entire height of the page. To set a custom height, set the fixedHeight prop to a number of pixels, e.g. :fixed-height="400".

By default, the Dialog displays a header with a title and optional subtitle and close button, and a footer with optional buttons and footer text.

The entire contents of the header and footer can be replaced with custom content, layout, and styles. You could:

  • Use a text button in place of the icon-only close button in the header.
  • Use icon-only action buttons in the footer (such as previous and next buttons in a multi-step Dialog).
  • Add a permanent action in the footer (such as a "Don't show again" checkbox), which should appear next to the buttons (or above them them, in the case of stacked actions).
  • Ensure the primary action button remains in the footer and place it after the default action, if there is one.
  • When stacking action buttons, ensure they are full-width.
  • Always use a quiet Button for the close button of the Dialog.

Developer notes

Override the default header and footer via the header and footer slots.

Multi-step Dialog ​

You can make a multi-step Dialog by customizing the header and footer and showing different content in the body section.

This example is based on the Growth Team's Add a Link Dialog.

Programmatic utilities ​

We have a group of utility functions to simply create basic dialogs.

You should add a CdxDialogManager to the root, this component managing dialogs that are created per utility functions. And you should use useDialogManager composable to get all of the utility functions; Also, you should and should only call this composable in setup() of the application root.

Developer notes

You must use useDialogManager composable if you used CdxDialogManager, because it creates the data source used by CdxDialogManager.

Basics ​

All of the utility functions have at least 2 arguments, the first is the title of dialog, the second is the body of dialog; and the body may be a VNode.

alert() ​

The alert() is used to create a modal dialog and display a notice, warning or a error to user; it does not allow the user to do something.

This method returns a Promise; it will resolve when the user closes the dialog. Also, you can pass the third argument to override the text of the 'Close' button.

  • Ensure no interactions are needed from the user.
  • Pass only important information by this way, try to use Toast for normal case.
  • Do not write too long body content because alerts should be read quickly.

confirm() ​

The confirm() is used to create a modal to ask user to confirm to take an action or not.

This method returns a Promise; it will resolve when the user answers 'Yes', and will reject when user answers 'No'. Also, you can pass the third argument to override the text of the 'Yes' button, and you can pass the fourth argument to override the text of the 'No' button.

  • Use to ask the user to confirm a destructive action.
  • Do not use confirm() for progressive actions.
  • Do not add any interactive elements to the body.

prompt() ​

The prompt() is used to create a modal to ask the user a question, and the user can type something into it.

This method returns a Promise; it will resolve when user presses Enter in the input or clicks the 'OK' button. Also, you can pass the third argument to override the label of the input box, and you can pass the fourth argument to override the placeholder of the input box.

  • Use short label and add longer instructions to body.
  • Do not use it to let the user fill complex forms.
  • In forms, usually do not use prompt or other modals.

Technical implementation ​

Vue usage ​

The parent component controls whether the Dialog is open via v-model:open.

A Dialog can offer two kinds of actions (represented by buttons of the appropriate type): primary action (can be progressive or destructive), and default action (typically a safe option like "cancel").

When open, the Dialog adds a class to the document body to prevent scrolling; this is applied whether or not teleport is used.

Attributes passed to inner element

This component forwards any attributes applied by the user to the inner .cdx-dialog element, instead of applying them to the outermost backdrop element.

Dialog and <teleport>

Dialogs rely on Vue's built-in <teleport> feature. By default, Dialogs will be teleported to the <body> element on the page, but this can be changed using Vue's provide/inject feature, with provide( 'CdxTeleportTarget', '#my-teleport-target' ). If Dialog is being used with SSR, a dedicated teleport target should be provided.

Dialog teleportation can be disabled by setting the renderInPlace prop.

Styling content in teleported Dialogs

When a Dialog is teleported (which is the default unless the renderInPlace prop is set), its contents will not be descendants of the element that contains the <cdx-dialog> tag. When styling the contents of a Dialog, be careful not to use CSS selectors that assume the Dialog is inside its parent component.

For example, CSS selectors like .my-component .cdx-dialog or .my-component .something-inside-the-dialog won't work. Instead, set e.g. class="my-component-dialog" on the <cdx-dialog> tag, and use that class to style the dialog and things inside it.

Props ​

Prop nameDescriptionTypeDefault
openWhether the dialog is visible. Should be provided via a v-model:open binding in the parent scope.booleanfalse
title(required)Title for the dialog header. Used for ARIA purposes even if no visible header element is displayed.string
subtitleOptional subtitle for the dialog.stringnull
hideTitleWhether the dialog header should hide the title & subtitlebooleanfalse
useCloseButtonAdd an icon-only close button to the dialog header.

On narrow screens, the close button is always displayed. On wide screens, it's only displayed if this prop is set.
booleanfalse
closeButtonLabelVisually-hidden label text for the icon-only close button in the header.

Omit this prop to use the default value, "Close".
string''
primaryActionPrimary user action. This will display a primary button with the specified action (progressive or destructive).PrimaryModalActionnull
defaultActionDefault user action. This will display a normal button.ModalActionnull
stackedActionsWhether action buttons should be vertically stacked and 100% width.booleanfalse
fixedHeightWhether the dialog should maintain a fixed maximum height on mobile screens, rather than expanding to fit the content height.boolean|numberfalse
targetSelector or DOM element identifying the container the dialog should be rendered in. The dialog will be <teleport>ed to this element. An ID selector is recommended, e.g. #foo-bar, but providing an actual element is also supported.

If this prop is not set, and the parent or one of its ancestors provides a teleport target using provide( 'CdxTeleportTarget', '#foo-bar' ), the provided target will be used. If there is no provided target, the dialog will be teleported to the end of the <body> element.
string|HTMLElement|nullnull
renderInPlaceWhether to disable the use of teleport and render the Dialog in its original location in the document. If this is true, the target prop is ignored.booleanfalse

Events ​

Event namePropertiesDescription
primaryWhen the primary action button is clicked.
defaultWhen the default action button is clicked.
update:opennewValue boolean - The new open/close state (true for open, false for closed)When the open/close state changes, e.g. when the close button is clicked.

Slots ​

NameDescriptionBindings
headerCustomizable Dialog header
defaultDialog content
footerCustomizable Dialog footer
footer-textOptional footer text

Keyboard navigation ​

KeyFunction
TabIt moves the focus to the next interactive element in tab order within the Dialog.
Shift + TabIt moves the focus to the previous interactive element within the Dialog.
EnterIf the focus is placed on one of the Dialog’s buttons, it activates the button.
EscIt closes the Dialog.