4 Dialog
L4stIdi0t edited this page 2026-09-09 07:00:36 +02:00

Dialog

Accessible modal dialog that doubles as a bottom drawer on mobile.

  • role="dialog" aria-modal, labelled/described by title/description
  • focus moves in on open, is trapped (Tab/Shift+Tab cycle), restored on close
  • Escape and backdrop click close; body scroll is locked while open
  • portalled to <body>, so an ancestor with a transform cannot capture it, and the rest of the page is inert while it is up
  • it glides out as well as in: closing plays the entrance backwards rather than deleting the node mid-blink

Overlays · two-way: bind:open · portalled to <body> · keyboard contract

<script lang="ts">
	import { Dialog } from '@l4st/driftwood';
</script>
Light Dark
dialog dialog in dark mode

Props

Prop Type Default What it does
open bind: boolean false Opening moves focus in and makes the rest of the page inert.
title string — Names the dialog for assistive tech (aria-labelledby).
description string — One line under the title; also its aria-describedby.
class string — Merged with the component's own classes, last — so yours win.
children required Snippet — The content.
footer Snippet — Actions, laid out end-aligned. Put the confirming button last.

Keyboard

Key Does
Tab / Shift+Tab cycle within the dialog — focus is trapped
Escape close and return focus to the opener

Example

The markup behind the screenshot above, lifted from src/routes/shots/ — so it compiles, and it is exactly what produced the image.

<script lang="ts">
	import { Dialog, Button, Input, Label } from '$lib/index.js';
	const uid = $props.id();
	let open = $state(true);
</script>

<Dialog bind:open title="Start a new scan" description="Pick a root and the crawler walks it.">
	<div class="flex flex-col gap-2">
		<Label for="{uid}-path">Path</Label>
		<Input id="{uid}-path" value="/volume1" />
	</div>
	{#snippet footer()}
		<Button variant="outline">Cancel</Button>
		<Button>Start scan</Button>
	{/snippet}
</Dialog>

Notes

Notes

  • Which of the three. A Dialog is a question with a couple of buttons, up in the middle of the screen. Sheet is the same contract anchored to an edge, with room for a form a Dialog would crowd. Drawer comes up from the bottom and settles at more than one height, dragged or keyed between them — the phone-map pattern.

Overlays · Sheet · Drawer · Tooltip · Popover


← All components · Getting started · Theming · source