Feedback
AlertDialog
A confirmation dialog that demands an explicit answer, with role alertdialog and async confirm handling.
<script>
import { AlertDialog } from "@codeatlasdev/ui";
let open = $state(false);
</script>
<AlertDialog
bind:open
title="Delete item?"
description="This action cannot be undone."
confirmLabel="Delete"
destructive
onconfirm={() => api.remove(id)}
/>
Unlike Dialog, there is no close button and a click outside does not dismiss it, and initial focus lands on the dialog itself instead of the first control. Escape and Cancel close it and fire oncancel. Both are ignored while a request is pending.
Basic and destructive
Confirm and cancel, with the destructive variant for irreversible actions.
Code
<script lang="ts">
import { AlertDialog, Button } from '@codeatlasdev/ui';
import { Trash2, LogOut } from '@lucide/svelte';
let signOutOpen = $state(false);
let deleteOpen = $state(false);
let log = $state<string[]>([]);
const push = (m: string) => (log = [m, ...log].slice(0, 4));
</script>
<Button variant="outlined" onclick={() => (signOutOpen = true)}>
{#snippet leading()}<LogOut size={14} />{/snippet}
Sign out
</Button>
<Button variant="destructive" onclick={() => (deleteOpen = true)}>
{#snippet leading()}<Trash2 size={14} />{/snippet}
Delete project
</Button>
<AlertDialog
bind:open={signOutOpen}
title="Sign out?"
description="You will need to sign in again to access your workspace."
confirmLabel="Sign out"
onconfirm={() => push('Signed out')}
oncancel={() => push('Sign out cancelled')}
/>
<AlertDialog
bind:open={deleteOpen}
title="Delete this project?"
description="This action cannot be undone. All data will be permanently removed."
confirmLabel="Delete"
destructive
onconfirm={() => push('Project deleted')}
/>
{#if log.length}
<ul class="log" aria-live="polite">
{#each log as entry, i (i + entry)}<li>{entry}</li>{/each}
</ul>
{/if}
<style>
.log {
flex-basis: 100%;
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 4px;
font-size: 13px;
color: var(--ca-text-secondary);
}
</style>
Async onconfirm
While the promise is pending the confirm button shows a spinner, Cancel is disabled and Escape is ignored. The dialog closes when it resolves and stays open if it throws.
Code
<script lang="ts">
import { AlertDialog, Button } from '@codeatlasdev/ui';
let open = $state(false);
let done = $state(false);
const wait = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
async function removeItem() {
await wait(1500);
done = true;
}
</script>
<Button variant="destructive" onclick={() => ((done = false), (open = true))}>Remove item (1.5s)</Button>
<AlertDialog
bind:open
title="Remove item?"
description="The request takes 1.5 seconds."
confirmLabel="Remove"
destructive
onconfirm={removeItem}
/>
{#if done}<span class="note" aria-live="polite">Item removed (async onconfirm resolved).</span>{/if}
<style>
.note { font-size: 13px; color: var(--ca-text-secondary); }
</style>
Controlled pending
Pass pending when the loading state lives outside, for example a mutation from your query client.
Code
<script lang="ts">
import { AlertDialog, Button } from '@codeatlasdev/ui';
let open = $state(false);
let pending = $state(false);
async function publish() {
pending = true;
await new Promise<void>((r) => setTimeout(r, 1500));
pending = false;
open = false;
}
</script>
<Button variant="outlined" onclick={() => (open = true)}>Open controlled</Button>
<AlertDialog bind:open title="Publish changes?" confirmLabel="Publish" {pending} onconfirm={publish} />
Props
| Prop | Type | Default | Description |
|---|
open | boolean | false | Bindable open state. |
title | string | – | Required. Dialog title and accessible name. |
description | string | – | Supporting text below the title. |
confirmLabel | string | 'Confirm' (localized) | Label of the confirm button. Defaults to the active locale's string. |
cancelLabel | string | 'Cancel' (localized) | Label of the cancel button. Defaults to the active locale's string. |
destructive | boolean | false | Confirm button uses the destructive variant. |
pending | boolean | false | Controls the loading state externally. Without it, pending is automatic while onconfirm is awaited. |
onconfirm | () => void | Promise<void> | – | Required. Closes the dialog when it resolves; if it throws, the dialog stays open and the error propagates. |
oncancel | () => void | – | Fires on Cancel or Escape. Never fires while pending. |
class | string | '' | Extra classes on the panel. |