118 lines
3.4 KiB
TypeScript
118 lines
3.4 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { MdClose, MdDelete } from 'react-icons/md';
|
|
import clsx from 'clsx';
|
|
|
|
interface ConfirmDeleteBtnProps {
|
|
onDelete: () => void;
|
|
size?: 'sm' | 'md' | 'lg';
|
|
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
className?: string;
|
|
}
|
|
|
|
const ConfirmDeleteBtn: React.FC<ConfirmDeleteBtnProps> = ({
|
|
onDelete,
|
|
size = 'sm',
|
|
position = 'top-right',
|
|
className
|
|
}) => {
|
|
const [showConfirm, setShowConfirm] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = () => setShowConfirm(false);
|
|
if (showConfirm) {
|
|
document.addEventListener('click', handleClickOutside);
|
|
return () => document.removeEventListener('click', handleClickOutside);
|
|
}
|
|
}, [showConfirm]);
|
|
|
|
const handleClick = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
setShowConfirm(true);
|
|
};
|
|
|
|
const handleConfirm = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
onDelete();
|
|
setShowConfirm(false);
|
|
};
|
|
|
|
const handleCancel = (e: React.MouseEvent) => {
|
|
e.stopPropagation();
|
|
setShowConfirm(false);
|
|
};
|
|
|
|
const sizeClasses = {
|
|
sm: 'p-0.5',
|
|
md: 'p-1',
|
|
lg: 'p-1.5'
|
|
};
|
|
|
|
const iconSizes = {
|
|
sm: 14,
|
|
md: 16,
|
|
lg: 18
|
|
};
|
|
|
|
const positionClasses = {
|
|
'top-right': '-right-1 -top-1',
|
|
'top-left': '-left-1 -top-1',
|
|
'bottom-right': '-right-1 -bottom-1',
|
|
'bottom-left': '-left-1 -bottom-1'
|
|
};
|
|
|
|
return (
|
|
<div
|
|
className={clsx(
|
|
"absolute",
|
|
positionClasses[position],
|
|
"z-10",
|
|
className
|
|
)}
|
|
onClick={e => e.stopPropagation()}
|
|
>
|
|
{!showConfirm && (
|
|
<button
|
|
onClick={handleClick}
|
|
className={clsx(
|
|
sizeClasses[size],
|
|
"rounded-full",
|
|
"bg-white/90 shadow-sm",
|
|
"text-gray-400 hover:text-red-600",
|
|
"transition-all duration-150",
|
|
"opacity-0 group-hover:opacity-100",
|
|
"hover:scale-110"
|
|
)}
|
|
title="Remove"
|
|
>
|
|
<MdClose size={iconSizes[size]} />
|
|
</button>
|
|
)}
|
|
|
|
{showConfirm && (
|
|
<div className={clsx(
|
|
"flex items-center gap-1",
|
|
"bg-white rounded-lg shadow-lg",
|
|
sizeClasses[size]
|
|
)}>
|
|
<button
|
|
onClick={handleConfirm}
|
|
className="p-1 rounded-md bg-red-50 text-red-600 hover:bg-red-100 transition-colors"
|
|
title="Confirm remove"
|
|
>
|
|
<MdDelete size={iconSizes[size]} />
|
|
</button>
|
|
<button
|
|
onClick={handleCancel}
|
|
className="p-1 rounded-md bg-gray-50 text-gray-600 hover:bg-gray-100 transition-colors"
|
|
title="Cancel"
|
|
>
|
|
<MdClose size={iconSizes[size]} />
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ConfirmDeleteBtn;
|
|
|