Dialogs

A modal dialog is used to display important information and ask for user input. XD Plugins can display user interface in the form of modal dialogs.

Example of a Modal Dialog

Dialogs appear over the XD document, and prevent further interaction with the underlying document. Dialogs are dismissed in any one of the following manners:

Dialogs are highly intrusive, and should only be used when absolutely necessary.

Anatomy

{% tabs anatomy="Dialog", examplesmac="macOS", examplesuwp="Windows" %}

{% content "anatomy" %}

Dialog Anatomy

{% content "examplesmac" %}

macOS Dialog Example

{% content "examplesuwp" %}

Windows Dialog Example

{% endtabs %}

Usage

When it comes to building the user interface, XD exposes an API surface that looks and feels a lot like what you would get in a web browser, namely:

These APIs and standards can be used to create compelling user interfaces, even inside modal dialogs.

The above example is a typical modal dialog. Modal dialogs consist of:

The margins and padding that surround the structure are provided automatically. There is generally no need to specify or override these margins in your own user interface, unless you want to do so.

Building Modal Dialogs

You can build modal dialogs using any method that creates an HTML5 DOM structure. This means you can use document.createElement, innerHTML, jQuery, React, and other frameworks.

Let's examine a simple dialog and how we might create it.

{% tabs sample="Sample", html="HTML", js="JS", react="React" %}

{% content "sample" %}

A Simple Dialog

{% content "html" %}

<style>
    #dialog form {
        width: 360px;
    }
    .h1 {
        align-items: center;
        justify-content: space-between;
        display: flex;
        flex-direction: row;
    }
    .icon {
        border-radius: 4px;
        width: 24px;
        height: 24px;
        overflow: hidden;
    }
</style>
<dialog id="dialog">
    <form method="dialog">
        <h1 class="h1">
            <span>Create Shape</span>
            <img class="icon" src="./assets/icon.png" />
        </h1>
        <hr />
        <p>Please enter the kind of shape you'd like to create. You can also include additional options by separating them with spaces.</p>
        <label>
            <span>Shape</span>
            <input type="text" placeholder="e.g., Rectangle 10 10 20 40" />
        </label>
        <footer>
            <button uxp-variant="primary">Cancel</button>
            <button type="submit" uxp-variant="cta">Create</button>
        </footer>
    </form>
</dialog>

{% content "js" %}

let ourDialog;
function showOurDialog() {
    if (!ourDialog) {
        ourDialog = document.createElement("dialog");
        ourDialog.innerHTML = `
<style>
    form {
        width: 360px;
    }
    .h1 {
        align-items: center;
        justify-content: space-between;
        display: flex;
        flex-direction: row;
    }
    .icon {
        border-radius: 4px;
        width: 24px;
        height: 24px;
        overflow: hidden;
    }
</style>
<form method="dialog">
    <h1 class="h1">
        <span>Create Shape</span>
        <img class="icon" src="./assets/icon.png" />
    </h1>
    <hr />
    <p>Please enter the kind of shape you'd like to create. You can also include additional options by separating them with spaces.</p>
    <label>
        <span>Shape</span>
        <input type="text" placeholder="e.g., Rectangle 10 10 20 40" />
    </label>
    <footer>
        <button uxp-variant="primary">Cancel</button>
        <button type="submit" uxp-variant="cta">Create</button>
    </footer>
</form>
        `;
    }
    return ourDialog.showModal();
}

{% content "react" %}

const React = require("react");
const ReactDOM = require("react-dom");

function Form() {
    const styles = {
        form: {
            width: 360;
        },
        h1: {
            alignItems: "center";
            justifyContent: "space-between";
            display: "flex";
            flexDirection: "row";
        },
        icon: {
            borderRadius: 4;
            width: 24;
            height: 24;
            overflow: "hidden";
        }
    };

    return (
        <form styles={styles.form} method="dialog">
            <h1 styles={styles.h1}>
                <span>Create Shape</span>
                <img styles={styles.icon} src="./assets/icon.png" />
            </h1>
            <hr />
            <p>Please enter the kind of shape you'd like to create. You can also include additional options by separating them with spaces.</p>
            <label>
                <span>Shape</span>
                <input type="text" placeholder="e.g., Rectangle 10 10 20 40" />
            </label>
            <footer>
                <button uxp-variant="primary">Cancel</button>
                <button type="submit" uxp-variant="cta">Create</button>
            </footer>
        </form>
    );
}

let ourDialog;
function showOurDialog() {
    if (!ourDialog) {
        ourDialog = document.createElement("dialog");
    }
    ReactDOM.render(<Form />, ourDialog);
    return ourDialog.showModal();
}
function render() {
    return (
        <button>Click Me</button>
    );
}

{% endtabs %}

Once a dialog is built, you will need to manage its lifecycle:

Variations

Alert

A simple "alert" can be used to display a message along with a Close button. You can customize the content of the title and message, but you cannot customize the button itself.

Example Alert

Error

An error "alert" (with a red heading). These are useful for rendering error messages. Just like regular alerts, you cannot customize the button itself.

Example Error Alert

Confirmation

Confirmation dialogs display a message and two buttons. The user is free to pick which of the buttons they wish to invoke.

Example Confirmation Dialog

Danger

Do not use confirmation dialogs for destructive actions.

Warning

Warning dialogs display a message and two buttons, one of which is destructive. Pressing ENTER in this case should not invoke the destructive action. Otherwise it is the same as a confirmation dialog.

Example Warning Dialog

Prompt

Prompts display a single line text field in addition to a message and two buttons.

Example Prompt Dialog

Guidelines

You should always strive to provide a good user experience with a modal dialog. That means providing easy access to dismissive buttons, avoiding dark patterns, and ensuring that your dialog doesn't block the user from forward progress in their work.

You should definitely read up on our UX patterns for modals to learn more about what to do and what not to do.

When to Use Dialogs

Dialogs are very intrusive to the user's workflow. As such, you should consider their use very carefully.

No Nested Dialogs

You should avoid nesting dialogs within other dialogs. The only exception to this guideline is when displaying file or folder pickers.

Three Buttons

In general, try to strive to avoid dialogs with lots of buttons in the footer. You should try to use up to three buttons in the footer.

Dismissive Buttons

Dismissive dialog buttons live within a footer element. Within the footer, you can have any number of buttons, but you should follow these guidelines when defining variants (which you can use to indicate if a button is the default or is destructive):

Tip

Dismissive buttons should always be visible on screen without scrolling. If a dismissive button isn't visible, the user may think they are trapped in the dialog.

Dismissal by other means

You should avoid dismissing a dialog using other means, including action buttons, checkboxes, etc.

Keyboard Interaction

Key
Action
ENTER
Submits the dialog's form
ESC
Cancels the dialog
TAB
Moves to the next focusable element.
SHIFT+TAB
Moves to the previous focusable element.

Known Issues