useClickOutside 훅
import { RefObject, useEffect } from 'react';
interface UseClickOutsideProps {
ref: RefObject<HTMLElement>;
handler: () => void;
enabled?: boolean;
}
export function useClickOutside({ ref, handler, enabled = true }: UseClickOutsideProps) {
useEffect(() => {
if (!enabled) return;
const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
handler();
}
};
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, [ref, handler, enabled]);
}
사용하는 측
useClickOutside({
ref: dialogRef,
handler: closeDialog,
enabled: open,
});
// ..
<motion.div
layoutId={`card-container-${id}`}
ref={dialogRef}
transition={{
layout: { duration: 0.3, ease: "easeOut" }
}}
>
여기서 중요한 것은, layoutId에 동일한 props를 전달하여 같은 요소라는 것을 motion에게 알려주는 것이다.
화면 기록 2025-01-05 오후 4.15.45.mov
화면 기록 2025-01-05 오후 4.16.02.mov