Skip to main content

Modal

A modal works best for focusing users' attention on a short amount of content and getting them to make a decision, such as a confirmation. Use it to temporarily interrupt a user’s current task and block interactions to the content below it.

If your modal content is more complex, or requires considerable time to complete, consider using an EuiFlyout instead.

Each EuiModal requires a specific set of nested child components. They can be omitted if necessary, but the order cannot be changed or interrupted.

Components

Default

Modals come a wrapping EuiOverlayMask to obscure the content beneath, but unlike flyouts, modals cannot be dismissed by clicking on the overlay mask. This is inline with our modal usage guidelines which requires there to be a primary action button, even if that button simply closes the modal.

Confirm modal

Use the EuiConfirmModal to ask the user to confirm a decision. It is a contextual wrapper around EuiModal that provides some helpful props for filling in common modal pieces. By default, the button color indicates a positive or neutral action. Change the buttonColor property to danger to indicate a destructive action.

Loading and disabling confirm button

EuiConfirmModal supports being able to apply loading and disabled states to the confirm button with the confirmButtonDisabled and isLoading props respectively. This is helpful to indicate the fetching of data and/or to wait for a user's input before enabling the confirm action.

Usage

Configuring forms

Since the child components of EuiModal are required to be in a specific order, you can only wrap the contents within EuiModalBody with the <form /> element. You can then hook up your submit button inside EuiModalFooter by adding the id of the <form /> element to the form prop of the button.

Setting width

Modals start with a minimum width of 400px, just enough to display form rows. They will grow to fit the contents until it reaches the specified maxWidth, the default of which is set to the medium breakpoint.

If the modal is not growing wide enough to fit your contents, you can pass a specific style.width, just remember that modals will always shrink to fit the window width.

Confirming an action

Use a Modal when you need to interrupt a user and ask them to confirm an action.

Structure

  1. Title mandatory
    • Whenever possible, frame it as a question that provides context for the action. Don't use "Are you sure?"
    • Focus the question on what's important to the user and in a way that assumes intent from them. For example Discard 7 changes? instead of Exit without saving?
    • Avoid including text variables in the title, especially for things users can input without character limits, or with long limits. This is often the case with object labels. For example, Apply configuration changes? instead of Apply configuration changes to Loremipsum-dolorsitamet-consectetur-adipiscing-elit deployment?
  2. Body mandatory
    1. Cause optional
      • If the context is important to know, add it.
    2. Consequences mandatory
      • Let users know what happens if they continue.
      • If possible, list the objects that may be impacted.
      • Don't repeat the title.
    3. More information optional
      • If necessary, anticipate user questions or need for help by including a link to a relevant source of information (like docs).
  3. Calls to action mandatory
    • The main action confirms the question asked in the title.
    • If there's enough space and it is relevant, include the number of impacted objects and their noun. For example Invite 3 users instead of Send invite.
    • Always provide a secondary CTA that allows users to leave the prompt without taking an action.
    • Not all choices are binary. Add a third CTA when it makes sense for common that actions users would want to do.
    • Make sure each CTA is explicit and not ambiguous with the other CTAs next to it.

Confirming a destructive action

Asking to confirm a delete or remove action follows the same principles as the default pattern, with 2 additions:

  • The main CTA is extra clear on what is about to be deleted with a clear noun, in addition to visual clues (color.danger token).
  • The body is unambiguous about what won’t be recoverable after the action is confirmed.
  • Optionally, and depending on the importance of the destructive action, you may include an extra confirmation within the body of the modal. If you do so, use something generic, such as "delete" or that users can copy easily that will remind them of what they are actually deleting.

Guidelines

A modal says “pay attention to me and nothing else.”

A modal title should be one line

The modal body will automatically scroll if the content gets too tall. Try to keep this from happening by keeping your content short and to the point.

The header sets the context
Short and sentence-case, the header should indicate what the modal is about.

The body is for a single task
This task should not require a lot of explanation or user interaction.

Buttons are right-aligned
The primary action is a filled button, and the secondary action is a link button. Labels should use strong action verbs.

Use a modal to focus on a single action

A modal can gather input necessary for continuing the current workflow. This type of modal works best for a short, focused task. Use input modals sparingly—they interrupt the user's workflow.

Save dashboard

Do: A save action is a good use case for a modal. The meaning is clear and the content is simple.

Add a team member

Step 1 of 3: the basics

Don't: Modals aren't the best design solution for multiple steps or complex user input. An in-page form is more appropriate.

Open a modal on a user action
Let a user action, such as a button click, open a modal. Don't open a modal from a toolbar action—users don't expect it.

Avoid scrolling content
Modal content should fit in a single view. If your modal has a lot of detail or a long list of items, consider a different solution, such as a form or a table.

Don't stack modals
Opening a modal on top of a modal might mean your workflow is too complex. Instead, use a component that supports multiple steps, such as a form or steps.

Use a modal to confirm an action

The most common use of modals in the EUI Framework is to confirm a user action. This modal should start with a question, give users enough information to make a decision, and restate the action in the button label.

Save changes before leaving?

If you don't save, your changes will be lost.

Do: Use a modal for confirmation when the user might lose data. For the body text, use one to two short sentences that explain the consequences.

Great!

Your dashboard has been successfully created.

Don't: Confirmations aren't good for messages. Toasts are best for success messages because they are less disruptive. Error and warning messages often appear directly on the page.

State the action in both the header and button text

If the modal header is "Refresh this field?" then the button text should be "Refresh."

Refresh field list?

This action resets the popularity counter of each field.

Do: Use the same action verbs in the header and button text.

Are you sure you want to refresh this field list?

This action resets the popularity counter of each field.

Don't: Don't use a vague header such as "Are you sure?" or the button labels "Yes" and "No."

Create separate confirmations for single and bulk actions

It avoids the awkwardness of "Delete 1 pipeline(s)" and improves readability.'

Delete pipeline 'MyPipeline'?

You can't recover deleted data.

Do: Asking users to delete a single item should include the item name in the title, if possible. Use single quotes around the name if it helps clarify meaning.

Delete 6 pipelines?

You can't recover deleted data.

Do: For bulk actions, include the number of items in the title.

Sometimes a header and buttons are enough

You can omit the body if users understand the decision from the header and button text alone.

Remove index pattern?

Do: Here the header and body are enough. The modal asks the user whether to remove an index pattern — data won't be lost.

Remove index pattern?

This action removes your index pattern.

Don't: Don't write body text that simply repeats the title. It doesn't add value.

Props

EuiModal

This table contains 7 rows.
Prop
Description and type
Default value
children#

ReactNode to render as this component's content

Type: ReactNode
Required
onClose#
Type: (event?: any) => void
Required
className#
Type: string
maxWidth#

Sets the max-width of the modal.
Set to true to use the default (euiBreakpoints 'm'),
set to false to not restrict the width,
set to a number for a custom width in px,
set to a string for a custom width in custom measurement.

Type: string | number | boolean
true
initialFocus#

Specifies what element should initially have focus.
Can be a DOM node, or a selector string (which will be passed to document.querySelector() to find the DOM node), or a function that returns a DOM node.

Type: string | HTMLElement | (() => HTMLElement)
role#

Identifies a modal dialog to screen readers. Modal dialogs that confirm destructive actions
or need a user's attention should use "alertdialog".

Type: "dialog" | "alertdialog"
dialog
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string

EuiModalHeader

This table contains 4 rows.
Prop
Description and type
Default value
className#
Type: string
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string
data-test-subj#
Type: string
css#
Type: Interpolation<Theme>

EuiModalHeaderTitle

This table contains 8 rows.
Prop
Description and type
Default value
size#
Type: "xs" | "s" | "m" | "l" | "xxxs" | "xxs"
className#
Type: string
id#
Type: string
css#
Type: Interpolation<Theme>
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string
data-test-subj#
Type: string
textTransform#
Type: "uppercase"
component#

The tag to render. Can be changed to a lower heading
level like h2 or a container div.

Type: ElementType
h1

EuiModalBody

This table contains 4 rows.
Prop
Description and type
Default value
className#
Type: string
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string
data-test-subj#
Type: string
css#
Type: Interpolation<Theme>

EuiModalFooter

This table contains 4 rows.
Prop
Description and type
Default value
className#
Type: string
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string
data-test-subj#
Type: string
css#
Type: Interpolation<Theme>

EuiConfirmModal

This table contains 16 rows.
Prop
Description and type
Default value
onCancel#
Type: (event?: any) => void
Required
children#

ReactNode to render as this component's content

Type: ReactNode
title#
Type: ReactNode
titleProps#
Type: Omit<EuiTitleProps, "children"> & HTMLAttributes<HTMLHeadingElement> & { component?: ElementType; }
cancelButtonText#
Type: ReactNode
confirmButtonText#
Type: ReactNode
onConfirm#
Type: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void
confirmButtonDisabled#
Type: boolean
className#
Type: string
defaultFocusedButton#

Allows focusing either the confirm or cancel button on modal initialization.
Will take precedence over initialFocus, if initialFocus is passed.

Type: "cancel" | "confirm"
buttonColor#
Type: "primary" | "text" | "accent" | "success" | "warning" | "danger"
primary
maxWidth#

Sets the max-width of the modal.
Set to true to use the default (euiBreakpoints 'm'),
set to false to not restrict the width,
set to a number for a custom width in px,
set to a string for a custom width in custom measurement.

Type: string | number | boolean
isLoading#

Passes isLoading prop to the confirm button

Type: boolean
role#

Identifies a modal dialog to screen readers. Modal dialogs that confirm destructive actions
or need a user's attention should use "alertdialog".

Type: "dialog" | "alertdialog"
aria-label#

Defines a string value that labels the current element.
@see aria-labelledby.

Type: string
initialFocus#

Specifies what element should initially have focus.
Can be a DOM node, or a selector string (which will be passed to document.querySelector() to find the DOM node), or a function that returns a DOM node.

Type: string | HTMLElement | (() => HTMLElement)