Files
llink/js/desktop/src/components/confirm-destructive-overlay.tsx
T

82 lines
2.2 KiB
TypeScript

import { useEffect } from 'react';
import { createPortal } from 'react-dom';
import { Button } from '@/components/ui/button';
import { KeyHint } from '@/components/key-hint';
interface ConfirmDestructiveOverlayProps {
title: string;
description: React.ReactNode;
confirmLabel: string;
pendingLabel?: string;
isPending: boolean;
onConfirm: () => void;
onClose: () => void;
}
export function ConfirmDestructiveOverlay({
title,
description,
confirmLabel,
pendingLabel = 'Working…',
isPending,
onConfirm,
onClose,
}: ConfirmDestructiveOverlayProps) {
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
e.preventDefault();
e.stopPropagation();
onClose();
}
};
window.addEventListener('keydown', handler, { capture: true });
return () =>
window.removeEventListener('keydown', handler, { capture: true });
}, [onClose]);
return createPortal(
<div className="fixed inset-0 z-[100]">
<div
className="absolute inset-0 bg-black/60 backdrop-blur-sm"
onClick={onClose}
/>
<div className="absolute left-1/2 top-1/2 w-full max-w-sm -translate-x-1/2 -translate-y-1/2 rounded-2xl border border-white/10 bg-white/5 p-6 shadow-2xl backdrop-blur-xl">
<div className="mb-3 flex items-center justify-between">
<h2 className="text-sm font-semibold text-white/70">{title}</h2>
<KeyHint
keys="Esc"
onClick={onClose}
title="Close (or press Esc)"
className="text-xs text-white/30"
>
to close
</KeyHint>
</div>
<div className="text-sm text-white/60">{description}</div>
<div className="mt-5 flex items-center justify-end gap-2">
<Button
variant="ghost"
size="sm"
onClick={onClose}
disabled={isPending}
>
Cancel
</Button>
<Button
variant="destructive"
size="sm"
onClick={onConfirm}
disabled={isPending}
>
{isPending ? pendingLabel : confirmLabel}
</Button>
</div>
</div>
</div>,
document.body,
);
}