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][#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

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

Footer actions may stack depending on the length of the text.

Developer notes

When using the default Dialog footer, use the stackedActions prop to stack the action buttons vertically.

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.

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, and a "target" prop can be supplied which will be passed to the teleport's to prop. This prop is optional and defaults to the <body> element on the page (although if Dialog is being used with SSR, a dedicated target should be provided).

An alternative default target can be set using Vue's provide/inject feature, with provide( 'CdxTeleportTarget', '#my-teleport-target' ). This provided target will be used if the "target" prop is not set.

Finally, Dialog teleportation behavior can be disabled by setting renderInPlace: true.

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

Use of the Dialog component in features which don't rely on SSR (which includes all MediaWiki usage for now) can dispense with this.

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.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).PrimaryDialogActionnull
defaultActionDefault user action. This will display a normal button.DialogActionnull
stackedActionsWhether action buttons should be vertically stacked and 100% width.booleanfalse
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.