From 5e9723ae018e90253539c83fb7309f47588fc91e Mon Sep 17 00:00:00 2001 From: zieun Date: Fri, 7 Jul 2023 19:58:20 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20BottomSheet=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=ED=9B=85=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/BottomSheet/hooks/index.ts | 1 + .../hooks/useModalControl/useModalControl.ts | 41 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/components/BottomSheet/hooks/index.ts create mode 100644 src/components/BottomSheet/hooks/useModalControl/useModalControl.ts diff --git a/src/components/BottomSheet/hooks/index.ts b/src/components/BottomSheet/hooks/index.ts new file mode 100644 index 00000000..bcd02033 --- /dev/null +++ b/src/components/BottomSheet/hooks/index.ts @@ -0,0 +1 @@ +export { default as useModalControl } from './useModalControl/useModalControl'; diff --git a/src/components/BottomSheet/hooks/useModalControl/useModalControl.ts b/src/components/BottomSheet/hooks/useModalControl/useModalControl.ts new file mode 100644 index 00000000..bf1c2593 --- /dev/null +++ b/src/components/BottomSheet/hooks/useModalControl/useModalControl.ts @@ -0,0 +1,41 @@ +import { useState, useEffect, useRef } from 'react'; +import { useClickOutside } from '@/hooks'; + +interface Props { + onClose: () => void; +} +const useModalControl = ({ onClose }: Props) => { + const [isOpen, setIsOpen] = useState(false); + const closeStatus = useRef(false); + const closeModalWithTransition = () => { + closeStatus.current = true; + setIsOpen(false); + }; + const openModalWithTransition = () => { + setIsOpen(true); + }; + const ref = useClickOutside({ + onClickOutside: () => { + closeModalWithTransition(); + }, + }); + const handleTransitionEnd = (event: TransitionEvent) => { + if (event.propertyName === 'transform' && closeStatus.current) { + onClose(); + } + }; + useEffect(() => { + openModalWithTransition(); + const element = ref.current; + if (!element) return; + element.addEventListener('transitionend', handleTransitionEnd); + return () => { + element.removeEventListener('transitionend', handleTransitionEnd); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return { ref, isOpen, closeModalWithTransition }; +}; + +export default useModalControl;