Page:
Dialog
Pages
Accordion
AccordionItem
Alert
Avatar
Badge
BarChart
Button
ButtonGroup
Card
Changelog
ChartLegend
Checkbox
CodeEditor
Collapsible
Combobox
CommandPalette
ContextMenu
CopyButton
DatePicker
Dialog
DonutChart
Drawer
Field
FileInput
FileList
Forms
Gauge
Getting started
Heatmap
Home
Image
InlineEdit
Input
Kbd
Label
LineChart
Menu
MultiSelect
NumberInput
Overlays
Pagination
Popover
Progress
RadioGroup
Scroller
Select
Separator
ShareBar
Sheet
Skeleton
Slider
Sparkline
Spinner
StatCard
Switch
Table
Tabs
TagsInput
Textarea
Theming
Toaster
Toggle
Tooltip
Tree
No results
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 |
|---|---|
![]() |
![]() |
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
driftwood
Layout
Actions
Forms
- Field
- Input
- FileInput
- FileList
- Textarea
- CodeEditor
- Combobox
- RadioGroup
- NumberInput
- InlineEdit
- Label
- Select
- MultiSelect
- DatePicker
- TagsInput
- Checkbox
- Switch
- Slider
Feedback
Charts
Overlays
Navigation
Generated from the source by pnpm wiki · repository · v0.24.0

