Dialog

Displayed on top of the page content, focusing the user’s attention on one task or piece of information.

Installation

import { Dialog } from "@octopusdeploy/design-system-components"

Properties


The Dialog is a flexible modal for tasks and workflows. It supports an optional Side Panel, which can be toggled open or closed from within the Dialog, and it also includes multi-step support for breaking longer flows into clear, sequential steps.


Adding content in the Dialog

Because Dialogs can contain many different types of content, the component accepts any children. A set of basic styles is included to help with layout and spacing but you may need to add your own styles for unexpected combinations of elements.

You don’t need to wrap your content in a <div>. Use a React Fragment instead (e.g. <> <p>Your content</p> </>), so the built-in styles apply correctly.

Child elements are laid out using flexbox, with a 12px gap applied automatically between items. Some elements also receive additional spacing (typically 12px) for common patterns, or example, headings that follow a paragraph, to improve overall readability.

Scrollable Content

While we recommend keeping content concise, we understand longer content is sometimes unavoidable. When Dialog content exceeds the available space, scrolling is enabled automatically. A subtle fade appears at the edge of the content area to indicate there’s more to scroll.

Including a Progress Tracker

A common pattern is to show a Progress Tracker inside a Dialog. Instead of adding it in with regular content, the Dialog provides a dedicated slot for it. This slot accepts a Progress Tracker React element, ensuring it’s applied consistently across implementations.

For example:


                                                        
                                                        
                                                            progressTracker={
                                                            <ProgressTracker layout="normal">
                                                                <ProgressTrackerItem label="Details" state="Done" />
                                                                <ProgressTrackerItem label="Review" state="Pending" />
                                                                <ProgressTrackerItem label="Confirm" state="Current" />
                                                            </ProgressTracker>
                                                        }
                                                        
                                                            

showDismissButton property

The Dialog supports a few different ways to close:

  • Escape will always close the Dialog.
  • If side panel content is provided, the standard dismiss (“x”) button is hidden to avoid conflicting with the side panel toggle. In this case, a Cancel button is provided in the Dialog actions.

showDismissButton controls three behaviours:

  • Header dismiss (“x”) button: shown only when showDismissButton is true and there is no side panel (this is handled automatically).
  • Footer Cancel button: shown whenever showDismissButton is true, regardless of whether a side panel is present.
  • Backdrop click to close: enabled when showDismissButton is true. When false, clicking the backdrop won’t close the Dialog to help prevent accidental dismissal.

When a side panel is present, the header dismiss (“x”) is replaced by the side panel toggle instead.


Side Panel

The Dialog supports a Side Panel with an animated open/close interaction. Use defaultSidePanelOpen to control whether it starts open or closed.

If no side panel content is provided, the Side Panel won’t render.

When a Side Panel is used, the standard close (“x”) button is replaced with chevron icons to control the panel and avoid conflicting controls. A cancel button is also included to ensure it can be closed via actions.

Responsive Behaviour

The side panel will be hidden from the DOM at predefined breakpoints to avoid scrolling and content being cut off regardless of whether you have provided the content or not. It will also remove the side panel toggle button from the header.

Multi Step

Dialog supports multiple steps by passing a steps array instead of children. (Refer to Adding content section for adding content with a single step).

Each step is a configuration object with its own content (the body rendered for that step), an optional progressTracker element to display navigation state, and a sidePanel that overrides the dialog-level side panel for that step (allowing you to show step-specific illustrations or copy as the user moves through the flow).

Navigation between steps is handled automatically: the footer renders Cancel, Back and Next buttons, with a number indicator that tracks the current step position. The final step's Next button triggers the onComplete callback instead of advancing further, so you can close the dialog or kick off an action on completion. You can customise the final step Next button with the completeButtonLabel prop).

If you need to block navigation until a condition is met, for example, until a required field is filled, you can use onBeforeNext on a step. This accepts a function that returns a boolean that if it returns false, the step will not advance further.

Example Component


                                                        
                                                        
                                                            <StandardDialog
                                                            open={open}
                                                            onClose={handleClose}
                                                            title="Set up your project"
                                                            type="primary"
                                                            steps={steps}
                                                            onComplete={handleClose}
                                                        />
                                                        
                                                            

Example Steps


Callbacks

onClose: () => void (required)

A single close handler that runs after the Dialog’s fade-out animation finishes. It’s triggered by:

  • Header dismiss (“x”) button, only when there’s no side panel and showDismissButton is true
  • Footer Cancel button when showDismissButton is true
  • Backdrop click when showDismissButton is true
  • Escape key always, regardless of showDismissButton

Note: onClose fires after the closing animation completes, not immediately when the user initiates the close action.

primaryButton.onClick / secondaryButton.onClick

Button-level callbacks passed directly to the underlying Button component. These are independent of onClose—clicking a button does not automatically close the Dialog. The caller is responsible for updating state to close it.

Multi-step callbacks (steps)

Callback

When it fires

step.onBeforeNext

Async; runs before moving to the next step (can block navigation)

step.onBeforeBack

Async; runs before moving back a step (can block navigation)

step.onEnter

Runs when the step becomes active

onComplete

Runs when the user clicks the final step’s Complete button



Other documentation that will help guide your thinking when working with this component.


Help and support