Skip to content

Dialog

A window overlaid on the primary window, rendering the content underneath inert.
<Dialog>
<DialogTrigger />
<DialogContent>
<DialogHeader />
<DialogMain />
<DialogFooter />
</DialogContent>
</Dialog>

Compose <Dialog>, <DialogTrigger>, and <DialogContent>.

import { Button } from "stylus-ui/Button";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
} from "stylus-ui/Dialog";
export default () => (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Delete Scribe</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader
title="Delete Scribe?"
description="This action cannot be undone. All data will be deleted."
/>
<DialogFooter
primaryAction={{ children: "Delete", variant: "danger" }}
secondaryAction={{ children: "Cancel" }}
/>
</DialogContent>
</Dialog>
);

To set the width of the dialog, pass a className to <DialogContent>. Beneath 380px, the buttons in the footer will stack vertically, with the primary button on top. There is no additional configuration required.

import { Button } from "stylus-ui/Button";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
} from "stylus-ui/Dialog";
export default () => (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Provision Users</Button>
</DialogTrigger>
<DialogContent className="max-w-[320px]">
<DialogHeader
title="Confirm user provisioning"
description="Once user provisioning is enabled, only users in mapped groups on this page can access Scribe."
/>
<DialogFooter
primaryAction={{ children: "Confirm" }}
secondaryAction={{ children: "Cancel" }}
/>
</DialogContent>
</Dialog>
);

A close button will display in the top right by default. To remove it, pass hideClose to <DialogContent>.

import { Button } from "stylus-ui/Button";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
} from "stylus-ui/Dialog";
export default () => (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Open Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader
title="Information"
description="This is an informational dialog. The close button is hidden."
hideClose
/>
<DialogFooter
primaryAction={{ children: "Confirm" }}
secondaryAction={{ children: "Cancel" }}
/>
</DialogContent>
</Dialog>
);

If the content of the dialog exceeds the height of the viewport, the dialog will scroll. If default scrolling interferes with other functionality or you want to implement your own scrolling, set scrollable to false.

import { faker } from "@faker-js/faker";
import { Button } from "stylus-ui/Button";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogMain,
DialogFooter,
} from "stylus-ui/Dialog";
export default () => (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">View Terms of Service</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader title="Terms of Service" />
<DialogMain>{faker.lorem.paragraphs(40)}</DialogMain>
<DialogFooter
primaryAction={{ children: "Accept" }}
secondaryAction={{ children: "Decline" }}
/>
</DialogContent>
</Dialog>
);

To add an image to the header of the dialog, pass an img object containing src and alt to <DialogHeader>.

import { Button } from "stylus-ui/Button";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogFooter,
} from "stylus-ui/Dialog";
export default () => (
<Dialog>
<DialogTrigger asChild>
<Button variant="secondary">Open Image Dialog</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader
title="Look at this image"
description="This is a random image from the internet."
img={{ src: "https://picsum.photos/800/400", alt: "Random image" }}
/>
<DialogFooter
primaryAction={{ children: "Confirm" }}
secondaryAction={{ children: "Cancel" }}
/>
</DialogContent>
</Dialog>
);

A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.

defaultOpen

boolean

modal

boolean

onOpenChange

(open: boolean) => void

open

boolean

A button that opens a Dialog.

asChild

boolean

A header for a Dialog, containing a title, optional description, and close button.

title

Required
string

Dialog title text.


description

string | ReactNode

Optional subtitle or description below the title.


hideClose

boolean = false

Hide the close (X) button.


img

{ src: string; alt: string; }

Optional header image (src and alt).


The main content of a Dialog.

children

Required
ReactNode

Main body content of the dialog.


A footer for a Dialog that can display one or more buttons.

children

ReactNode

Additional content before or alongside the action buttons.


className

string

Optional class for the footer.


primaryAction

BaseButtonProps | BaseAnchorProps

Primary button (e.g. “Save”); typically closes the dialog when clicked.


primaryActionClose

boolean = true

Whether the primary action closes the dialog.


secondaryAction

BaseButtonProps | BaseAnchorProps

Secondary button (e.g. “Cancel”).


secondaryActionClose

boolean = true

Whether the secondary action closes the dialog.


Contains content to be rendered in the open dialog.

asChild

boolean

container

null | HTMLElement = "document.body"

The container where the dialog content will be rendered.


forceMount

true

Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.


onCloseAutoFocus

(event: Event) => void

Event handler called when auto-focusing on close. Can be prevented.


onEscapeKeyDown

(event: KeyboardEvent) => void

Event handler called when the escape key is down. Can be prevented.


onFocusOutside

(event: FocusOutsideEvent) => void

Event handler called when the focus moves outside of the DismissableLayer. Can be prevented.


onInteractOutside

(event: PointerDownOutsideEvent | FocusOutsideEvent) => void

Event handler called when an interaction happens outside the DismissableLayer. Specifically, when a pointerdown event happens outside or focus moves outside of it. Can be prevented.


onOpenAutoFocus

(event: Event) => void

Event handler called when auto-focusing on open. Can be prevented.


onPointerDownOutside

(event: PointerDownOutsideEvent) => void

Event handler called when the a pointerdown event happens outside of the DismissableLayer. Can be prevented.


scrollable

boolean = true

Whether the dialog should be scrollable.


theme

"light" | "dark" = "light"

The theme of the dialog.