Dialog
A modal window overlaid on the page with backdrop, focus trap, and keyboard support. Built on bits-ui.
Component Source
View the source code for the dialog component.
$lib/components/ui/dialog/dialog-content.svelteInstallation
npx nnuikit add dialog
# Dialog uses bits-ui under the hood
# Also add button for trigger/actions
npx nnuikit add buttonimport * as Dialog from "$lib/components/ui/dialog";
import Button from "$lib/components/ui/button/button.svelte";Quick Start
<Dialog.Root>
<Dialog.Trigger>
<Button variant="primary">Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>
A short description of what this dialog does.
</Dialog.Description>
</Dialog.Header>
<div class="py-5">
<p>Your content goes here.</p>
</div>
<Dialog.Footer>
<Dialog.Close>
<Button variant="tertiary">Cancel</Button>
</Dialog.Close>
<Button variant="primary">Confirm</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>Interactive Playground
Toggle options and see the generated code.
Close button: visible
Options
<script lang="ts">
import * as Dialog from "$lib/components/ui/dialog";
import Button from "$lib/components/ui/button/button.svelte";
</script>
<Dialog.Root>
<Dialog.Trigger>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Edit Profile</Dialog.Title>
<Dialog.Description>
Make changes to your profile here.
</Dialog.Description>
</Dialog.Header>
<div class="py-5">
<!-- Your content here -->
</div>
<Dialog.Footer>
<Dialog.Close>
<Button variant="tertiary">Cancel</Button>
</Dialog.Close>
<Button variant="primary">Save</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>Examples
Programmatic control
Use bind:open to open/close the dialog from code.
<script lang="ts">
let open = $state(false);
</script>
<Button onclick={() => (open = true)}>Open</Button>
<Dialog.Root bind:open>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Controlled Dialog</Dialog.Title>
<Dialog.Description>
Opened programmatically via state.
</Dialog.Description>
</Dialog.Header>
<Dialog.Footer>
<Button onclick={() => (open = false)}>Close</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>Form dialog
A common pattern — form inputs inside a dialog with cancel/save actions.
<Dialog.Root>
<Dialog.Trigger>
<Button>Edit Profile</Button>
</Dialog.Trigger>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Edit Profile</Dialog.Title>
<Dialog.Description>
Update your name and email below.
</Dialog.Description>
</Dialog.Header>
<form class="flex flex-col gap-4 py-5">
<div class="flex flex-col gap-1.5">
<label class="text-sm font-medium">Name</label>
<Input placeholder="John Doe" />
</div>
<div class="flex flex-col gap-1.5">
<label class="text-sm font-medium">Email</label>
<Input type="email" placeholder="john@example.com" />
</div>
</form>
<Dialog.Footer>
<Dialog.Close>
<Button variant="tertiary">Cancel</Button>
</Dialog.Close>
<Button variant="primary">Save Changes</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>Accessibility
Focus trap: focus is locked inside the dialog when open
Keyboard: Escape closes the dialog
Click outside: clicking the overlay dismisses the dialog
ARIA: role="dialog", aria-modal="true", aria-labelledby linked to title
Screen reader: title and description are announced on open
Focus restore: focus returns to the trigger element on close
API Reference
Dialog.Content
The modal panel — only prop you typically customize.
| Prop | Type | Default | Description |
|---|---|---|---|
showCloseButton | boolean | true | Show/hide the close (X) button in the top corner. |
class | string | "" | Additional CSS classes for the content container. |
portalProps | PortalProps | - | Props passed to the underlying Portal component. |
Sub-components
| Component | Description |
|---|---|
| Dialog.Root | Container that manages open/close state. Accepts open and onOpenChange props. |
| Dialog.Trigger | Wraps the element that opens the dialog on click. |
| Dialog.Content | The modal panel. Renders inside a portal with overlay and focus trap. |
| Dialog.Header | Semantic header area for title and description. |
| Dialog.Title | The dialog's heading. Required for accessibility. |
| Dialog.Description | Supporting text below the title. |
| Dialog.Footer | Action area at the bottom for buttons. |
| Dialog.Close | Wraps a button that closes the dialog on click. |
| Dialog.Overlay | Backdrop overlay. Rendered automatically by Content. |
Built on bits-ui —
Dialog uses Dialog from bits-ui for focus trapping, portal rendering, and ARIA attributes.
For the full primitive API (animations, forceMount, etc.), see the bits-ui Dialog docs.