Dialogs display content in a layer above the application, focusing user attention on a specific task or message. Use them for confirmations, forms, and important information.
Basic Usage
import { Dialog } from "@soft-ui/react/dialog"
import { Button } from "@soft-ui/react/button"
function Example() {
return (
<Dialog.Root>
<Dialog.Trigger>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Close />
</Dialog.Header>
<Dialog.Body>
<p>Dialog content goes here.</p>
</Dialog.Body>
<Dialog.Footer>
<Dialog.Close>
<Button variant="secondary">Cancel</Button>
</Dialog.Close>
<Button>Confirm</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)
}
Positions
Control where the dialog appears with the position prop:
- center - Centered on screen (default)
- right - Slides in from the right as a panel
- sheet - Bottom sheet on mobile, centered on desktop
import { Dialog } from "@soft-ui/react/dialog"
import { Button } from "@soft-ui/react/button"
function Example() {
return (
<>
<Dialog.Root>
<Dialog.Trigger><Button>Center</Button></Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup position="center">
{/* ... */}
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
<Dialog.Root>
<Dialog.Trigger><Button>Right Panel</Button></Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup position="right">
{/* ... */}
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</>
)
}
Swipeable Sheet
Enable drag-to-dismiss for sheet-style dialogs:
import { Dialog } from "@soft-ui/react/dialog"
import { Button } from "@soft-ui/react/button"
function Example() {
return (
<Dialog.Root>
<Dialog.Trigger><Button>Open Sheet</Button></Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup position="sheet" swipeable>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Swipeable Sheet</Dialog.Title>
<Dialog.Close />
</Dialog.Header>
<Dialog.Body>
Drag down to dismiss
</Dialog.Body>
</Dialog.Content>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)
}
The drag indicator is automatically shown when swipeable={true} is set on sheet-style dialogs.
Nested Dialogs
Dialogs support nesting. When a child dialog opens, the parent dims and scales down:
import { Dialog } from "@soft-ui/react/dialog"
import { Button } from "@soft-ui/react/button"
function Example() {
return (
<Dialog.Root>
<Dialog.Trigger><Button>Open Parent</Button></Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Parent Dialog</Dialog.Title>
<Dialog.Close />
</Dialog.Header>
<Dialog.Body>
<Dialog.Root>
<Dialog.Trigger><Button>Open Child</Button></Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop />
<Dialog.Popup>
{/* Nested dialog content */}
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
</Dialog.Body>
</Dialog.Content>
</Dialog.Popup>
</Dialog.Portal>
</Dialog.Root>
)
}
API Reference
For complete prop documentation including controlled state and animation options, see the Dialog API reference.