Overlays
Recipe: confirm removal, then notify
Complete child page component. Removal changes local state only. The snippet avoids an undefined external dialog component.
<script lang="ts">
import { Button, Card, getModalManager, getToastManager } from '@atom-forge/ui';
const modal = getModalManager();
const toast = getToastManager();
const titleId = $props.id();
let removed = $state(false);
let deciding = $state(false);
async function remove() {
if (deciding || removed) return;
deciding = true;
try {
const confirmed = await modal.openSnippet(confirmRemoval, {}, { key: 'remove-record' });
if (confirmed !== true) return;
removed = true;
toast.show('Removed from this local view.', { type: 'success' });
} finally {
deciding = false;
}
}
</script>
{#snippet confirmRemoval()}
<Card role="dialog" aria-modal="true" aria-labelledby={titleId} class="p-6 flex flex-col gap-4 w-80">
<h2 id={titleId}>Remove this record?</h2>
<p>This demo changes only the local view.</p>
<div class="flex justify-end gap-2">
<Button type="button" ghost label="Cancel" onclick={() => modal.close(false)}/>
<Button type="button" destructive label="Remove" onclick={() => modal.close(true)}/>
</div>
</Card>
{/snippet}
<Button type="button" destructive label="Remove record" disabled={deciding || removed} onclick={remove}/>
<p role="status">{removed ? 'Record removed from this local view.' : 'Record is present.'}</p>
Only true authorizes the local mutation. Backdrop/Escape dismissal, navigation, or duplicate-key suppression can resolve with undefined. modal.close targets the last modal of that kind; do not treat it as a handle for an arbitrary earlier dialog. For a reusable dialog component, use modal.open(Component, props, options) instead.
Application responsibilities
- Replace the local mutation with authorized persistence, handle failures, and keep pending state until work completes. A confirmation is not validation or authorization.
- The recipe supplies dialog naming and persistent status text, but does not implement focus trapping, initial focus, focus restoration, or a body scroll lock. Implement these before using it as a production modal. The renderer does not supply them automatically.
- Popup content owns keyboard dismissal and focus. Capture the actual anchor element before awaiting; an event's
currentTarget is only available during dispatch.
- Modal, Drawer, and Popup close on route navigation; Toast survives. Do not infer that closing cancels an in-flight application request.
- Toast has no built-in live-region role. Keep important feedback accessible independently; toast actions dismiss immediately without awaiting async callbacks.
- Tooltip has no focus trigger or automatic accessible description association. Keep essential instructions visible without hover.
Overlays
Recipe: confirm removal, then notify
Complete child page component. Removal changes local state only. The snippet avoids an undefined external dialog component.
<script lang="ts"> import { Button, Card, getModalManager, getToastManager } from '@atom-forge/ui'; const modal = getModalManager(); const toast = getToastManager(); const titleId = $props.id(); let removed = $state(false); let deciding = $state(false); async function remove() { if (deciding || removed) return; deciding = true; try { const confirmed = await modal.openSnippet(confirmRemoval, {}, { key: 'remove-record' }); if (confirmed !== true) return; removed = true; toast.show('Removed from this local view.', { type: 'success' }); } finally { deciding = false; } } </script> {#snippet confirmRemoval()} <Card role="dialog" aria-modal="true" aria-labelledby={titleId} class="p-6 flex flex-col gap-4 w-80"> <h2 id={titleId}>Remove this record?</h2> <p>This demo changes only the local view.</p> <div class="flex justify-end gap-2"> <Button type="button" ghost label="Cancel" onclick={() => modal.close(false)}/> <Button type="button" destructive label="Remove" onclick={() => modal.close(true)}/> </div> </Card> {/snippet} <Button type="button" destructive label="Remove record" disabled={deciding || removed} onclick={remove}/> <p role="status">{removed ? 'Record removed from this local view.' : 'Record is present.'}</p>Only
trueauthorizes the local mutation. Backdrop/Escape dismissal, navigation, or duplicate-key suppression can resolve withundefined.modal.closetargets the last modal of that kind; do not treat it as a handle for an arbitrary earlier dialog. For a reusable dialog component, usemodal.open(Component, props, options)instead.Application responsibilities
currentTargetis only available during dispatch.