CwDialog

Native <dialog> with focus trap, escape, backdrop click.

Confirm Action

Are you sure you want to proceed? This action cannot be undone.

No Backdrop Close

This dialog can only be closed via Escape key or the button below.

CwDialog example Copy code
let open = $state(false);

<CwButton onclick={() => (open = true)}>Open Dialog</CwButton>
<CwDialog bind:open={open} title="Confirm Action">
	{#snippet children()}
		<p>Are you sure you want to proceed?</p>
	{/snippet}
</CwDialog>
Documentation Upgrade

Start here

CwDialog wraps a native `<dialog>` element with the behavior most apps want by default: open state binding, title, actions, escape handling, and backdrop close.

How to think about it

  1. Control visibility from the parent Use `bind:open` so the surrounding page decides when the dialog appears and disappears.
  2. Put body content in `children` and footer buttons in `actions` This keeps the markup easy to scan and matches the built-in dialog layout.
  3. Tighten close behavior only when needed Leave backdrop and escape close enabled unless the user must complete an explicit step.

Props and callbacks

APITypeDetails
open

Default: false

booleanDialog visibility state.
title
stringTitle shown in the dialog header.
closeOnBackdrop

Default: true

booleanAllows clicking the backdrop to close the dialog.
closeOnEscape

Default: true

booleanAllows the Escape key to close the dialog.
children
SnippetMain dialog content.
actions
SnippetFooter actions row.
onclose
() => voidRuns whenever the dialog closes itself.

Copy-paste examples

These snippets intentionally show the full public API surface the live demo relies on.

Confirmation dialog

The parent owns the `open` state and the action buttons close the dialog explicitly.

Confirmation dialog Copy code
<script lang="ts">
	let confirmOpen = $state(false);
</script>

<CwButton onclick={() => (confirmOpen = true)}>Delete zone</CwButton>

<CwDialog bind:open={confirmOpen} title="Delete zone">
	{#snippet children()}
		<p>This removes the zone and its alert rules.</p>
	{/snippet}
	{#snippet actions()}
		<CwButton variant="ghost" onclick={() => (confirmOpen = false)}>Cancel</CwButton>
		<CwButton variant="danger" onclick={() => (confirmOpen = false)}>Delete</CwButton>
	{/snippet}
</CwDialog>
Blocking dialog

Only use this pattern when the user must complete an intentional workflow.

Blocking dialog Copy code
<script lang="ts">
	let blockingOpen = $state(true);
	let closed = $state(false);
</script>

<CwDialog
	bind:open={blockingOpen}
	title="Required acknowledgement"
	closeOnBackdrop={false}
	closeOnEscape={false}
	onclose={() => (closed = true)}
>
	{#snippet children()}
		<p>Read the maintenance notice before continuing.</p>
	{/snippet}
	{#snippet actions()}
		<CwButton onclick={() => (blockingOpen = false)}>I understand</CwButton>
	{/snippet}
</CwDialog>