import React, { useRef, useState, useEffect } from 'react'; import './Popconfirm.css'; /** * Kole UI Popconfirm(React) * 对齐 组件2.txt Popconfirm 规范:气泡确认、图标+描述+确认/取消,点击外部关闭 * * props: * - title : 确认描述文本 * - okText / cancelText * - placement : 'bottom' | 'top' * - visible / defaultVisible : 受控打开 * - onConfirm() / onCancel() * - children : 触发元素(如按钮) */ export default function Popconfirm({ title, okText = '确定', cancelText = '取消', placement = 'bottom', visible, defaultVisible = false, onConfirm, onCancel, children }) { const rootRef = useRef(null); const [innerOpen, setInnerOpen] = useState(defaultVisible); const open = visible !== undefined ? visible : innerOpen; const [style, setStyle] = useState({}); const syncPos = () => { if (!rootRef.current) return; const r = rootRef.current.getBoundingClientRect(); setStyle(placement === 'top' ? { left: r.left, bottom: window.innerHeight - r.top } : { left: r.left, top: r.bottom + 8 }); }; const setOpen = (v) => { if (visible === undefined) setInnerOpen(v); if (v) { syncPos(); document.addEventListener('click', onDocClick, true); window.addEventListener('resize', syncPos); } else { document.removeEventListener('click', onDocClick, true); window.removeEventListener('resize', syncPos); } }; const onDocClick = (e) => { if (rootRef.current && rootRef.current.contains(e.target)) return; setOpen(false); }; useEffect(() => { if (open) { syncPos(); document.addEventListener('click', onDocClick, true); window.addEventListener('resize', syncPos); } return () => { document.removeEventListener('click', onDocClick, true); window.removeEventListener('resize', syncPos); }; }, [open]); const confirm = () => { onConfirm && onConfirm(); setOpen(false); }; const cancel = () => { onCancel && onCancel(); setOpen(false); }; return ( setOpen(!open)}>{children} {open && (
! {title}
)}
); } /* 用法示例: import Popconfirm from './Popconfirm'; */