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 |
Related Components
Recommended reading
Other documentation that will help guide your thinking when working with this component.
Help and support