chore(FE-188): update Modal component

This commit is contained in:
ValdiANS
2025-11-04 15:46:30 +07:00
parent a12ae51f3a
commit 9daa6aaf8c
+38 -23
View File
@@ -1,6 +1,13 @@
'use client'; 'use client';
import { ReactNode, RefObject, useCallback, useRef, useState } from 'react'; import {
ReactNode,
RefObject,
useCallback,
useEffect,
useRef,
useState,
} from 'react';
import { cn } from '@/lib/helper'; import { cn } from '@/lib/helper';
export const useModal = () => { export const useModal = () => {
@@ -8,31 +15,35 @@ export const useModal = () => {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const openModal = useCallback(() => { const openModal = useCallback(() => {
if (!ref.current) return;
ref.current.showModal();
setOpen(true); setOpen(true);
ref.current?.showModal();
}, []); }, []);
const closeModal = useCallback(() => { const closeModal = useCallback(() => {
if (!ref.current) return;
ref.current.close();
setOpen(false); setOpen(false);
ref.current?.close();
}, []); }, []);
const toggle = useCallback(() => { const toggle = useCallback(() => {
if (open) { open ? closeModal() : openModal();
closeModal();
} else {
openModal();
}
}, [open, closeModal, openModal]); }, [open, closeModal, openModal]);
if (ref.current) { // Gunakan useEffect agar event listener tidak didaftarkan berulang kali
ref.current.addEventListener('close', () => { useEffect(() => {
closeModal(); 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 { interface ModalProps {
@@ -46,15 +57,19 @@ interface ModalProps {
} }
const Modal = ({ ref, children, closeOnBackdrop, className }: ModalProps) => { const Modal = ({ ref, children, closeOnBackdrop, className }: ModalProps) => {
return ( const handleBackdropClick = (e: React.MouseEvent<HTMLDialogElement>) => {
<dialog ref={ref} className={cn('modal', className?.modal)}> if (closeOnBackdrop && e.target === ref.current) {
<div className={cn('modal-box', className?.modalBox)}>{children}</div> ref.current?.close();
}
};
{closeOnBackdrop && ( return (
<form method='dialog' className='modal-backdrop'> <dialog
<button>close</button> ref={ref}
</form> className={cn('modal', className?.modal)}
)} onClick={handleBackdropClick}
>
<div className={cn('modal-box', className?.modalBox)}>{children}</div>
</dialog> </dialog>
); );
}; };