feat(ui): custom confirmation dialog replacing native window.confirm
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 51s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 51s
Single reusable dialog with a promise-based API: confirmAction({...})
returns Promise<boolean>. Supports title, optional message body,
confirm/cancel labels, and a 'destructive' flag that paints the confirm
button red.
Accessibility: Escape cancels, Enter confirms, confirm button auto-focus,
role=dialog + aria-labelledby, backdrop click = cancel.
Rolled out to: recipe delete, domain remove, profile delete, wishlist
remove. Native confirm() is gone from the codebase.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
41
src/lib/client/confirm.svelte.ts
Normal file
41
src/lib/client/confirm.svelte.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export type ConfirmOptions = {
|
||||
title: string;
|
||||
message?: string;
|
||||
confirmLabel?: string;
|
||||
cancelLabel?: string;
|
||||
destructive?: boolean;
|
||||
};
|
||||
|
||||
type PendingRequest = ConfirmOptions & {
|
||||
resolve: (result: boolean) => void;
|
||||
};
|
||||
|
||||
class ConfirmStore {
|
||||
pending = $state<PendingRequest | null>(null);
|
||||
|
||||
ask(options: ConfirmOptions): Promise<boolean> {
|
||||
// If another dialog is already open, close it as cancelled so we don't stack.
|
||||
if (this.pending) this.pending.resolve(false);
|
||||
return new Promise<boolean>((resolve) => {
|
||||
this.pending = { ...options, resolve };
|
||||
});
|
||||
}
|
||||
|
||||
answer(result: boolean): void {
|
||||
if (!this.pending) return;
|
||||
const p = this.pending;
|
||||
this.pending = null;
|
||||
p.resolve(result);
|
||||
}
|
||||
}
|
||||
|
||||
export const confirmStore = new ConfirmStore();
|
||||
|
||||
/**
|
||||
* Show a modal confirmation dialog. Resolves to true on confirm, false on cancel/Escape.
|
||||
* Safe on the server: falls back to the native confirm() only in the browser.
|
||||
*/
|
||||
export function confirmAction(options: ConfirmOptions): Promise<boolean> {
|
||||
if (typeof window === 'undefined') return Promise.resolve(false);
|
||||
return confirmStore.ask(options);
|
||||
}
|
||||
Reference in New Issue
Block a user