Files
real-time-fund/app/components/ConfirmModal.jsx
2026-03-02 19:40:08 +08:00

60 lines
1.8 KiB
JavaScript

'use client';
import { motion } from 'framer-motion';
import { createPortal } from 'react-dom';
import { TrashIcon } from './Icons';
export default function ConfirmModal({ title, message, onConfirm, onCancel, confirmText = "确定删除" }) {
const content = (
<motion.div
className="modal-overlay"
role="dialog"
aria-modal="true"
onClick={(e) => {
e.stopPropagation();
onCancel();
}}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
style={{ zIndex: 10002 }}
>
<motion.div
initial={{ opacity: 0, scale: 0.95, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 20 }}
className="glass card modal"
style={{ maxWidth: '400px' }}
onClick={(e) => e.stopPropagation()}
>
<div className="title" style={{ marginBottom: 12 }}>
<TrashIcon width="20" height="20" className="danger" />
<span>{title}</span>
</div>
<p className="muted" style={{ marginBottom: 24, fontSize: '14px', lineHeight: '1.6' }}>
{message}
</p>
<div className="row" style={{ gap: 12 }}>
<button
className="button secondary"
onClick={onCancel}
style={{ flex: 1, background: 'rgba(255,255,255,0.05)', color: 'var(--text)' }}
>
取消
</button>
<button
className="button danger"
onClick={onConfirm}
style={{ flex: 1 }}
autoFocus
>
{confirmText}
</button>
</div>
</motion.div>
</motion.div>
);
if (typeof document === 'undefined') return null;
return createPortal(content, document.body);
}