Dialog
Present modal content with native focus and accessible naming.
Usage
Open a modal with a named header and a body snippet.
No action yet
<script lang="ts">
import { Button, Dialog, TextInput } from 'bref-ui';
let open = $state(false);
</script>
<Button label="Open dialog" onClick={() => (open = true)} />
<Dialog bind:open header={{ title: 'Edit details', description: 'Changes are local until saved.' }}>
<label>
Display name <TextInput value="Example name" />
</label>
</Dialog>
Header transitions
Title and icon changes enter together. Reduced motion skips the entrance.
Playground
Live preview
Open the modal to test its current settings and native focus behavior.
Settings
View generated code
<script>
import { Button, Dialog, TextInput } from 'bref-ui';
let open = $state(false);
let lastEvent = $state('No action yet');
let closeCount = $state(0);
let cancelCount = $state(0);
</script>
<Button label="Open preview dialog" onClick={() => (open = true)} />
<Dialog
bind:open
header={{
title: 'Edit details',
description: 'Changes are local until saved.',
icon: { name: 'edit', filled: false }
}}
size="medium"
dismissible={true}
onclose={() => {
lastEvent = 'Closed';
closeCount++;
}}
oncancel={() => {
lastEvent = 'Cancel event';
cancelCount++;
}}
footer={{
primary: {
label: 'Save changes',
color: 'info',
disabled: false,
icon: { name: 'check' },
onClick: () => (lastEvent = 'Primary action')
},
secondary: {
label: 'Keep editing',
disabled: false,
onClick: () => (lastEvent = 'Secondary action')
}
}}
>
<label for="dialog-preview-name">Display name</label>
<TextInput id="dialog-preview-name" value="Example name" />
<Button label="Close via binding" onClick={() => (open = false)} />
</Dialog>
<p role="status">{lastEvent}; close events: {closeCount}; cancel events: {cancelCount}</p>
Dismissal and focus
Tab remains inside the modal. Escape and the close button follow the dismissible control.
Close from the caller by setting the state bound to open to false . Focus returns to the opener after the exit animation.
Sizes and actions
Choose a size and status color, then test the two action callbacks. Small screens always use full-screen.
Long content
Long content scrolls inside the panel while the header stays available.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
header | DialogHeaderDataProps | Yes | — | Title, optional description, and optional decorative icon. Title/icon changes animate unless reduced motion is requested. |
children | Snippet | Yes | — | Dialog body. |
open | boolean | No | false | Bindable modal state. |
footer | Snippet | { primary: DialogActionProps; secondary: DialogActionProps } | No | Omitted | Custom footer or exactly two actions; each action accepts label, icon, onClick, disabled, and status color. |
dismissible | boolean | No | true | Allow Escape and show the close button. |
size | Size | 'full-screen' | No | medium | Dialog width or full-screen; screens up to 36rem always use full-screen. |
The header title and optional description supply accessible names. Native dialog attributes, close and cancel events are forwarded. The body and optional footer accept snippets.