feat: implement useOverlayDismiss hook for consistent modal dismissal behavior
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { XMarkIcon } from '@heroicons/react/24/outline';
|
||||
import { useOverlayDismiss } from '../../hooks/useOverlayDismiss';
|
||||
|
||||
type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
|
||||
|
||||
@@ -21,22 +22,13 @@ interface Props {
|
||||
}
|
||||
|
||||
export default function Modal({ open, title, size = 'md', onClose, children, footer }: Props) {
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); };
|
||||
document.addEventListener('keydown', onKey);
|
||||
return () => document.removeEventListener('keydown', onKey);
|
||||
}, [open, onClose]);
|
||||
const dismiss = useOverlayDismiss(onClose, open);
|
||||
|
||||
if (!open) return null;
|
||||
|
||||
return createPortal(
|
||||
<div className="overlay" onClick={onClose}>
|
||||
<div
|
||||
className="modal"
|
||||
style={{ maxWidth: sizeMap[size] }}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="overlay" {...dismiss}>
|
||||
<div className="modal" style={{ maxWidth: sizeMap[size] }}>
|
||||
<div className="modal-head">
|
||||
<h2>{title}</h2>
|
||||
<button type="button" className="mini-btn" onClick={onClose} aria-label="بستن">
|
||||
|
||||
Reference in New Issue
Block a user