Modal dialog for confirmations and important actions
Tags: component modal dialog
AlertDialog provides a modal dialog for confirmations and important decisions that require user action.
Import
<script>
import { AlertDialog } from '@classic-homes/theme-svelte';
</script>Basic Usage
<script>
let showDialog = $state(false);
</script>
<Button onclick={() => (showDialog = true)}>Delete Item</Button>
<AlertDialog
open={showDialog}
onOpenChange={(open) => (showDialog = open)}
title="Delete Item?"
description="This action cannot be undone. This will permanently delete the item."
confirmText="Delete"
confirmVariant="destructive"
onConfirm={() => deleteItem()}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
open |
boolean |
false |
Open state (bindable) |
onOpenChange |
(open: boolean) => void |
- | Open change callback |
title |
string |
required | Dialog title |
description |
string |
- | Description text |
cancelText |
string |
'Cancel' |
Cancel button text |
confirmText |
string |
'Continue' |
Confirm button text |
confirmVariant |
'default' | 'destructive' | 'outline' | 'ghost' |
'default' |
Confirm button style |
onConfirm |
() => void |
- | Confirm callback |
onCancel |
() => void |
- | Cancel callback |
class |
string |
- | Additional classes |
trigger |
Snippet<[{ props }]> |
- | Optional trigger; spread props on your own button |
children |
Snippet |
- | Custom content |
With Trigger
Use an inline trigger:
<AlertDialog
title="Discard changes?"
description="You have unsaved changes that will be lost."
onConfirm={discardChanges}
>
{#snippet trigger({ props })}
<Button {...props} variant="outline">Discard</Button>
{/snippet}
</AlertDialog>Destructive Confirmation
For dangerous actions:
<AlertDialog
title="Delete Account"
description="This will permanently delete your account and all associated data. This action cannot be undone."
confirmText="Delete Account"
confirmVariant="destructive"
onConfirm={deleteAccount}
>
{#snippet trigger({ props })}
<Button {...props} variant="destructive">Delete Account</Button>
{/snippet}
</AlertDialog>Custom Button Text
<AlertDialog
title="Publish Post"
description="This will make your post visible to everyone."
cancelText="Not yet"
confirmText="Publish Now"
onConfirm={publishPost}
>
{#snippet trigger({ props })}
<Button {...props}>Publish</Button>
{/snippet}
</AlertDialog>Custom Content
Add additional content to the dialog:
<AlertDialog
title="Transfer Ownership"
description="Select the new owner for this project."
onConfirm={transferOwnership}
>
{#snippet trigger({ props })}
<Button {...props}>Transfer</Button>
{/snippet}
<Select bind:value={newOwner} label="New Owner">
{#each teamMembers as member}
<option value={member.id}>{member.name}</option>
{/each}
</Select>
</AlertDialog>Controlled State
Full control over open state:
<script>
let dialogOpen = $state(false);
async function handleConfirm() {
await saveChanges();
dialogOpen = false;
}
</script>
<Button onclick={() => (dialogOpen = true)}>Save</Button>
<AlertDialog
bind:open={dialogOpen}
title="Save Changes"
description="Your changes will be saved."
onConfirm={handleConfirm}
onCancel={() => (dialogOpen = false)}
/>Callbacks
Handle both confirm and cancel:
<AlertDialog
title="Logout"
description="Are you sure you want to log out?"
onConfirm={() => {
logout();
trackEvent('logout');
}}
onCancel={() => {
trackEvent('logout_cancelled');
}}
>
{#snippet trigger({ props })}
<Button {...props} variant="ghost">Logout</Button>
{/snippet}
</AlertDialog>Examples
Delete Confirmation
<AlertDialog
title="Delete Project"
description={`Are you sure you want to delete "${project.name}"? All project data including files, tasks, and comments will be permanently removed.`}
confirmText="Delete Project"
confirmVariant="destructive"
onConfirm={() => deleteProject(project.id)}
>
{#snippet trigger({ props })}
<Button {...props} variant="destructive" size="sm">
<TrashIcon class="mr-2 h-4 w-4" />
Delete
</Button>
{/snippet}
</AlertDialog>Unsaved Changes
<AlertDialog
title="Unsaved Changes"
description="You have unsaved changes. Do you want to leave without saving?"
cancelText="Stay"
confirmText="Leave"
confirmVariant="destructive"
onConfirm={navigateAway}
>
{#snippet trigger({ props })}
<Button {...props} variant="outline">Cancel</Button>
{/snippet}
</AlertDialog>Subscription Cancellation
<AlertDialog
title="Cancel Subscription"
description="Your subscription will remain active until the end of the current billing period. You can resubscribe at any time."
cancelText="Keep Subscription"
confirmText="Cancel Subscription"
onConfirm={cancelSubscription}
>
{#snippet trigger({ props })}
<Button {...props} variant="ghost" class="text-destructive">Cancel Subscription</Button>
{/snippet}
</AlertDialog>Bulk Action
<AlertDialog
title={`Delete ${selectedItems.length} items?`}
description="This will permanently delete all selected items. This action cannot be undone."
confirmText={`Delete ${selectedItems.length} items`}
confirmVariant="destructive"
onConfirm={deleteSelectedItems}
>
{#snippet trigger({ props })}
<Button {...props} variant="destructive" disabled={selectedItems.length === 0}
>Delete Selected</Button
>
{/snippet}
</AlertDialog>Accessibility
- Modal traps focus when open
- Escape key closes dialog
- Cancel is focused by default
- Proper ARIA labels and roles
- Screen reader announcements
Related Components
- Dialog - General purpose modal
- Button - Trigger and action buttons
- DropdownMenu - Context menus