Summit
ComponentsOverlays

Dialog

A Dialog shows users a window over the page and keeps focus inside it until it is closed.

When to Use

  • for a short form that changes one record, such as “Rename project”
  • for a task that users have to finish or cancel before anything else
  • to show a command palette, as CommandDialog in Command does

When Not to Use

  • to ask for a response before an action that can’t be undone (use an Alert Dialog)
  • for a panel docked to one side of the screen (use a Sheet)
  • for a panel that users swipe away (use a Drawer)
  • for content that belongs to one control and keeps the page interactive (use a Popover)
DialogAlert DialogSheetDrawer
PurposeA short formA message that needs a responseA side panel that needs no gesturesA panel that needs a swipe or snap points
PositionCenterCenterOne side, the right by defaultOne edge, the bottom by default
Width From 640px576px384px, or 320px at size="sm"384px on the left or right384px on the left or right
Click OutsideCloses itDoes nothingCloses itCloses it
EscapeCloses itCloses itCloses itCloses it
SwipeDoes nothingDoes nothingDoes nothingCloses it
Close ButtonShown by defaultNoneShown by defaultNone
Roledialogalertdialogdialogdialog

Anatomy

ElementUsage
OverlayRequired
Close buttonShown by default
PopupRequired
Title*Required
DescriptionOptional
FooterOptional

* The title is the Dialog’s accessible name. If the design shows no title, visually hide it and keep it in the markup.

DialogContent renders the portal, the overlay, and the close button, so you don’t need to add them. The figure is 352px wide, so its footer shows the stacked layout that is used below 640px.

Behavior

By default, a Dialog is modal: Base UI keeps focus in the popup, locks the page’s scroll, and prevents clicks from reaching the page. If you want the page to stay interactive, set modal={false} on Dialog. If you want the Dialog to stay open when users click the overlay, set disablePointerDismissal.

From 640px, the Buttons in the footer are placed in a row at its end. Below 640px, they are stacked in reverse order. Write the main action last so that it is at the end of the row and at the top of the stack.

Overflow

The popup is at most as tall as the screen. If the content is taller, the popup scrolls. To keep the header and the footer in view, place the content between them in a region that scrolls.

Content

StringRuleExampleCounterexample
TitleRepeat the trigger’s label so that the Dialog names its task“Rename project”“Project”
DescriptionSay in one sentence what the change affects“The new name shows on invoices and reports.”“Enter a new name below.”
Main actionUse the verb for what the click does“Save”“OK”

The label of the close button is labels.dialog.close, which is “Close” by default. To translate it, use the Summit Provider.

Accessibility

Base UI’s Dialog sets the role, moves focus in and out, and closes when users press Escape. You provide the title that names the Dialog.

Requirements

A Dialog needs a DialogTitle so that screen readers can announce what it is for, as WCAG 2.2 SC 4.1.2 Name, Role, Value requires. If the design shows no title, add sr-only to its DialogHeader to visually hide it, as CommandDialog does.

If showCloseButton is false, keep a DialogClose in the popup. The ARIA Authoring Practices Guide strongly recommends a visible button that closes a dialog. The overlay is hidden from assistive technology, so if there is no such button, Escape is the only way for screen reader users to close the Dialog, and users on a touch screen have no Escape key.

Installation

npx shadcn@latest add @summit/dialog

The CLI also adds @summit/button and @summit/summit-provider.

Usage

import { Button } from '@/components/ui/button';
import {
    Dialog,
    DialogClose,
    DialogContent,
    DialogDescription,
    DialogFooter,
    DialogHeader,
    DialogTitle,
    DialogTrigger,
} from '@/components/ui/dialog';

<Dialog>
    <DialogTrigger render={<Button variant="outline" />}>Rename project</DialogTrigger>
    <DialogContent>
        <DialogHeader>
            <DialogTitle>Rename project</DialogTitle>
            <DialogDescription>The new name shows on invoices and reports.</DialogDescription>
        </DialogHeader>
        <DialogFooter>
            <DialogClose render={<Button variant="outline" />}>Cancel</DialogClose>
            <DialogClose render={<Button />}>Save</DialogClose>
        </DialogFooter>
    </DialogContent>
</Dialog>;

Hide the Close Button

To remove the close button in the corner, set showCloseButton={false} on DialogContent. To add an outline Button with the same label to the footer, set showCloseButton on DialogFooter.

Hide the Close Button
<DialogContent showCloseButton={false}>
    <DialogTitle>Rename project</DialogTitle>
    <DialogFooter showCloseButton />
</DialogContent>

Change the Width

By default, the width is sm:max-w-xl. To change it, pass another width in className on DialogContent.

Change the Width
<DialogContent className="sm:max-w-sm">
    <DialogTitle>Rename project</DialogTitle>
</DialogContent>

API Reference

The parts accept the props of their matching parts in Base UI’s Dialog, where DialogContent is Dialog.Popup and DialogOverlay is Dialog.Backdrop. DialogHeader and DialogFooter accept the props of a div. See the Base UI Dialog documentation for the props of each part.

DialogContent

PropTypeDefaultDescription
showCloseButtonbooleantrueShows the close button in the top corner
overlayClassNamestringNoneClasses for the overlay

DialogFooter

PropTypeDefaultDescription
showCloseButtonbooleanfalseAdds an outline Button labeled by labels.dialog.close

On this page