@octopusdeploy/design-system-components
Version:
The design systems component library.
99 lines (69 loc) • 3.72 kB
Markdown
# Overlays: Dialog, Drawer, Popover, Menu
## Dialog
Use `Dialog` from `@octopusdeploy/design-system-components` for all modal overlays.
❌ Never use `Modal` directly — it is deprecated (deprecated 13/01/2026).
```tsx
import { Dialog } from "@octopusdeploy/design-system-components";
<Dialog open={isOpen} onExited={handleExited}>
{/* Dialog content uses Dialog's own sub-components */}
</Dialog>
```
Available widths via `dialogWidth`: `"480px"` | `"600px"` | `"800px"` | `"1000px"`, but determine
what the available values are based on the discriminated union provided by the prop itself.
Avoid `fullScreen` unless there is no alternative — full-screen dialogs remove all page context
and are disorienting. Prefer a standard dialog width or a `Drawer` instead.
Do not attempt to override dialog sizing or positioning via `className` or `style` — those props
do not exist on `Dialog`.
## Drawer
Use `Drawer` for side-panel overlays that slide in from the edge of the viewport. Appropriate for
supplementary detail panels or multi-step flows that should not fully interrupt the page context.
Dialog vs Drawer:
- Use `Dialog` when the user must make a decision or complete an action before continuing
- Use `Drawer` when showing detail or a secondary workflow alongside the current context
`Drawer` is specifically for long, complex forms connected to editing and management tasks. This scope is
intentional — the right-side anchor is hardcoded with no prop to change it, enforcing consistent UX for
that use case across the portal.
Do not use `Drawer` for other purposes (dev tools, side panels, notifications, etc.). For those, build a
custom component styled with design system tokens.
## Popover
`Popover` is a low-level primitive intended for use **inside the design system**, not for general
consumer use in portal features. Attaching a `Popover` directly to arbitrary elements is an
anti-pattern — it bypasses the design system's intent and produces inconsistent UX.
The preferred pattern is for components to expose a `popover` prop (typed as
`React.ReactElement<PopoverBasicHelpProps>`) that the component itself positions and manages.
Several components already do this (e.g. `Form.TextField`, `Switch`).
```tsx
// ✅ Use the component's built-in popover prop where available
<TextField
label="Retention policy"
value={value}
onChange={setValue}
popover={<PopoverBasicHelp content="How long to keep releases before they are cleaned up." />}
/>
// ❌ Don't attach Popover to arbitrary elements in feature code
<Popover anchor={myRef} open={open}>
Some help text
</Popover>
```
Not all components expose a `popover` prop yet — this is a known inconsistency in the design
system. If you need contextual help on a component that does not have one, check with the
frontend foundations team rather than reaching for the raw `Popover` primitive.
❌ Don't use `LegacyPopover` — use `Popover`.
## Menu and MenuItems
Use `Menu` / `MenuItems` / `MenuList` for dropdown action menus (e.g. a "..." actions button).
These are not the same as a Select input — use `Form.Select` for data selection.
Use `MenuItemToggle` for toggle items within a menu.
## Dropdown
`Dropdown` is a lower-level primitive. Prefer `Menu` / `Popover` / `Select` over `Dropdown`
unless you have a specific composability requirement that those do not meet.
## Choosing between overlays
```
Does the user need to complete an action before continuing?
→ Dialog
Is it supplementary detail or a secondary workflow?
→ Drawer
Is it anchored help text or detail for a specific element?
→ Popover
Is it a list of actions triggered from a button?
→ Menu / MenuItems
```