70 lines
1.8 KiB
TypeScript
70 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import React, { useEffect } from "react";
|
|
|
|
interface PopupProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
show?: boolean;
|
|
title?: string;
|
|
children: React.ReactNode;
|
|
onClickClose?: React.MouseEventHandler<HTMLButtonElement>;
|
|
onClickOk?: React.MouseEventHandler<HTMLButtonElement>;
|
|
}
|
|
|
|
const Popup: React.FC<PopupProps> = ({
|
|
show = false,
|
|
title,
|
|
children,
|
|
onClickClose,
|
|
onClickOk,
|
|
...props
|
|
}) => {
|
|
useEffect(() => {
|
|
const handleKeyDown = (event: KeyboardEvent) => {
|
|
if (event.key === "Escape" && onClickClose) {
|
|
onClickClose(event as unknown as React.MouseEvent<HTMLButtonElement>);
|
|
}
|
|
if (event.key === "Enter") {
|
|
if (onClickOk) {
|
|
onClickOk(event as unknown as React.MouseEvent<HTMLButtonElement>);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (show) {
|
|
window.addEventListener("keydown", handleKeyDown);
|
|
}
|
|
|
|
return () => {
|
|
window.removeEventListener("keydown", handleKeyDown);
|
|
};
|
|
}, [show, onClickClose]);
|
|
|
|
if (!show) return null;
|
|
|
|
return (
|
|
<>
|
|
<div className="fixed top-0 left-0 w-full h-full bg-black opacity-75 z-10"></div>
|
|
<div className="fixed top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 z-20">
|
|
<div className="bg-base-100 p-8 rounded-lg">
|
|
{title && (
|
|
<h2 className="text-xl font-bold mb-4 text-base-content">
|
|
{title}
|
|
</h2>
|
|
)}
|
|
{children}
|
|
<div className="flex justify-between">
|
|
<button onClick={onClickClose} className="btn btn-sm">
|
|
Close
|
|
</button>
|
|
<button onClick={onClickOk} className="btn btn-sm btn-success">
|
|
Ok
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Popup;
|