Просмотр исходного кода

feat: add confirmation component

Thomas Zhang 3 месяцев назад
Родитель
Сommit
7fed59f272

+ 62 - 0
src/lib/components/common/confirmation/confirmation.svelte

@@ -0,0 +1,62 @@
+<script lang="ts">
+	import type { Snippet } from 'svelte';
+
+	import * as AlertDialog from '$lib/components/controls/alert-dialog';
+
+	type Props = {
+		open: boolean;
+		title: string;
+		description: Snippet;
+		confirmLabel?: string;
+		confirmingLabel?: string;
+		variant?: 'destructive' | 'default';
+		onconfirm: () => Promise<void>;
+	};
+
+	let {
+		open = $bindable(),
+		title,
+		description,
+		confirmLabel = 'Confirm',
+		confirmingLabel = 'Confirming…',
+		variant = 'default',
+		onconfirm,
+	}: Props = $props();
+
+	let confirming = $state(false);
+
+	const handleConfirm = async () => {
+		confirming = true;
+		try {
+			await onconfirm();
+		} finally {
+			confirming = false;
+		}
+	};
+
+	const actionClass = $derived(
+		variant === 'destructive'
+			? 'bg-red-500 text-white hover:bg-red-600 disabled:opacity-50'
+			: undefined,
+	);
+</script>
+
+<AlertDialog.Root bind:open>
+	<AlertDialog.Portal>
+		<AlertDialog.Overlay />
+		<AlertDialog.Content>
+			<AlertDialog.Header>
+				<AlertDialog.Title>{title}</AlertDialog.Title>
+				<AlertDialog.Description>
+					{@render description()}
+				</AlertDialog.Description>
+			</AlertDialog.Header>
+			<AlertDialog.Footer>
+				<AlertDialog.Cancel>Cancel</AlertDialog.Cancel>
+				<AlertDialog.Action class={actionClass} disabled={confirming} onclick={handleConfirm}>
+					{confirming ? confirmingLabel : confirmLabel}
+				</AlertDialog.Action>
+			</AlertDialog.Footer>
+		</AlertDialog.Content>
+	</AlertDialog.Portal>
+</AlertDialog.Root>

+ 3 - 0
src/lib/components/common/confirmation/index.ts

@@ -0,0 +1,3 @@
+import ConfirmDialog from './confirmation.svelte';
+
+export { ConfirmDialog };