Dialog
Native modal dialog with focus return.
beta
Examples
Confirm delete
<script lang="ts">
import Button from '@tcpsystems/ui/foundation/Button';
import Dialog from '@tcpsystems/ui/foundation/Dialog';
import Field from '@tcpsystems/ui/foundation/Field';
import Input from '@tcpsystems/ui/foundation/Input';
const uid = $props.id();
</script>
<Button data-tcp-open={uid}>Delete deployment</Button>
<Dialog id={uid} title="Delete gateway-vnext?">
<p>This deletes 14 release records and removes the production route. It cannot be undone.</p>
<Field label="Type gateway-vnext to confirm">
{#snippet control(c)}<Input id={c.id} kind="mono" describedby={c.describedby} autocomplete="off" />{/snippet}
</Field>
{#snippet foot()}
<form method="dialog"><Button type="submit">Cancel</Button></form>
<Button variant="danger">Delete deployment</Button>
{/snippet}
</Dialog>Share invite
<script lang="ts">
import Button from '@tcpsystems/ui/foundation/Button';
import Dialog from '@tcpsystems/ui/foundation/Dialog';
import Field from '@tcpsystems/ui/foundation/Field';
import Input from '@tcpsystems/ui/foundation/Input';
import Textarea from '@tcpsystems/ui/foundation/Textarea';
import Stack from '@tcpsystems/ui/foundation/Stack';
const uid = $props.id();
</script>
<Button data-tcp-open={uid}>Share deployment</Button>
<Dialog id={uid} title="Share gateway-vnext">
<Stack>
<Field label="Invitee email">
{#snippet control(c)}<Input id={c.id} type="email" describedby={c.describedby} placeholder="mara@tcp.systems" />{/snippet}
</Field>
<Field label="Message">
{#snippet control(c)}<Textarea id={c.id} describedby={c.describedby} rows={3}>Can you review this deployment before we promote it?</Textarea>{/snippet}
</Field>
</Stack>
{#snippet foot()}
<form method="dialog"><Button type="submit">Cancel</Button></form>
<Button variant="primary">Send invite</Button>
{/snippet}
</Dialog>Sizes
<script lang="ts">
import Button from '@tcpsystems/ui/foundation/Button';
import Dialog from '@tcpsystems/ui/foundation/Dialog';
import Cluster from '@tcpsystems/ui/foundation/Cluster';
const uid = $props.id();
const sm = uid + '-sm';
const lg = uid + '-lg';
</script>
<Cluster>
<Button data-tcp-open={sm}>Small dialog</Button>
<Button data-tcp-open={lg}>Large dialog</Button>
</Cluster>
<Dialog id={sm} title="Rotate access key" size="sm">
<p>This creates a new key for billing-api. The current key keeps working for 24 hours.</p>
{#snippet foot()}
<form method="dialog"><Button type="submit">Cancel</Button></form>
<Button variant="primary">Rotate key</Button>
{/snippet}
</Dialog>
<Dialog id={lg} title="Invoice INV-2048" size="lg">
<p>Acme Labs · April 2026 · €4,820.00 · Paid on 2026-04-03. Includes gateway traffic, 3 team members, and priority support.</p>
{#snippet foot()}
<form method="dialog"><Button type="submit">Close</Button></form>
<Button variant="primary">Download PDF</Button>
{/snippet}
</Dialog>API
import Dialog from '@tcpsystems/ui/foundation/Dialog';| Prop | Type | Default |
|---|---|---|
mode? | 'dialog' | 'alert' | 'dialog' |
id | string | none |
title | string | none |
size? | 'sm' | 'lg' | none |
confirmLabel? | string | 'Confirm' |
cancelLabel? | string | 'Cancel' |
tone? | 'danger' | 'neutral' | 'danger' |
pending? | boolean | false |
pendingLabel? | string | none |
confirmText? | string | none |
confirmTextLabel? | string | none |
| Snippet |
|---|
foot |
children |
| Hook | Kind |
|---|---|
.tcp-dialog | Root class |
data-size | Data attribute |
data-tcp-confirm-text | Data attribute |
data-variant | Data attribute |