Skip to content
bref / ui

Svelte components, simply.

Star

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

Svelte
<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.

Closed · No action yet; close events: 0; cancel events: 0

Settings

Appearance
Header
Content
Footer actions
View generated code
Svelte
<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

Component props
PropTypeRequiredDefaultDescription
headerDialogHeaderDataPropsYes—Title, optional description, and optional decorative icon. Title/icon changes animate unless reduced motion is requested.
childrenSnippetYes—Dialog body.
openbooleanNofalseBindable modal state.
footerSnippet | { primary: DialogActionProps; secondary: DialogActionProps }NoOmittedCustom footer or exactly two actions; each action accepts label, icon, onClick, disabled, and status color.
dismissiblebooleanNotrueAllow Escape and show the close button.
sizeSize | 'full-screen'NomediumDialog 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.