diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index a84c1827..958d88dd 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -1,6 +1,13 @@ 'use client'; -import { ReactNode, RefObject, useCallback, useRef, useState } from 'react'; +import { + ReactNode, + RefObject, + useCallback, + useEffect, + useRef, + useState, +} from 'react'; import { cn } from '@/lib/helper'; export const useModal = () => { @@ -8,31 +15,35 @@ export const useModal = () => { const [open, setOpen] = useState(false); const openModal = useCallback(() => { + if (!ref.current) return; + ref.current.showModal(); setOpen(true); - - ref.current?.showModal(); }, []); const closeModal = useCallback(() => { + if (!ref.current) return; + ref.current.close(); setOpen(false); - ref.current?.close(); }, []); const toggle = useCallback(() => { - if (open) { - closeModal(); - } else { - openModal(); - } + open ? closeModal() : openModal(); }, [open, closeModal, openModal]); - if (ref.current) { - ref.current.addEventListener('close', () => { - closeModal(); - }); - } + // Gunakan useEffect agar event listener tidak didaftarkan berulang kali + useEffect(() => { + const dialog = ref.current; + if (!dialog) return; - return { ref, open, setOpen, openModal, closeModal, toggle } as const; + const handleClose = () => setOpen(false); + dialog.addEventListener('close', handleClose); + + return () => { + dialog.removeEventListener('close', handleClose); + }; + }, []); + + return { ref, open, openModal, closeModal, toggle } as const; }; interface ModalProps { @@ -46,15 +57,19 @@ interface ModalProps { } const Modal = ({ ref, children, closeOnBackdrop, className }: ModalProps) => { - return ( - -
{children}
+ const handleBackdropClick = (e: React.MouseEvent) => { + if (closeOnBackdrop && e.target === ref.current) { + ref.current?.close(); + } + }; - {closeOnBackdrop && ( -
- -
- )} + return ( + +
{children}
); };