Dialog.svelte

This component renders a native <dialog> opened with showModal(), which puts it in the top layer. The top layer escapes ancestor stacking/overflow contexts (so no Teleport is needed), traps focus, makes the rest of the page inert, closes on Escape, and restores focus to the previously focused element on close -- all natively. The dim background is the native ::backdrop.

We render a full-viewport overlay inside the dialog rather than a content-sized box, to preserve the scrolling and align="top" behaviors. The content surface itself is the consumer's -- pair this with DialogContent for the default .pane card and gutter, or render your own surface in children.

view source

Declarations
#

Dialog
#

Dialog.svelte view source

accepts children

import Dialog from '@fuzdev/fuz_ui/Dialog.svelte';

show?

Whether the dialog is shown. When the <dialog> mounts it opens via showModal(); when it unmounts it closes. Defaults to true so the {#if opened}<Dialog>...</Dialog>{/if} pattern works without passing show -- mounting the component opens the dialog. Pass show={opened} to skip the outer {#if} and let the component manage its own conditional rendering.

type boolean
optional default true

align?

How the content is aligned in the viewport. center vertically centers it; top aligns it to the top and grows downward, which avoids jank when the content's height changes.

optional default 'center'

dismissable?

Whether clicking outside the content (see content_selector) closes the dialog. Escape closes it regardless of this.

type boolean
optional default true

content_selector?

Fallback selector for a content surface you render in children yourself (rather than via DialogContent, which self-registers). When dismissable, a press that isn't inside a registered surface (e.g. DialogContent, which self-registers) and doesn't match this selector closes the dialog. Defaults to the fuz_css .pane card; set it to match your surface's outermost element -- with no registered surface and no match, presses anywhere close the dialog.

type string
optional default '.pane'

onbeforeclose?

Called before a user-initiated close (Escape, click-outside, or close). Return false to veto and keep the dialog open -- e.g. to confirm discarding unsaved changes. Programmatic close via show={false} bypasses this.

type () => boolean | void
optional

onclose?

Called when the dialog closes -- via Escape, click-outside, or close. Use it to sync your own open state, e.g. onclose={() => (opened = false)}. Like onbeforeclose, programmatic close via show={false} bypasses this.

type () => void
optional

children

Rendered inside the dialog overlay. Receives the DialogContext (e.g. {close}); pair with DialogContent or render your own surface.

type Snippet<[dialog: DialogContext]>
snippet parameters

intersects

Omit<SvelteHTMLElements['dialog'], 'children' | 'onclose'>

Depends on
#