diff --git a/src/components/common/BottomSheet/BasicModal.jsx b/src/components/common/BottomSheet/BasicModal.jsx index 3031dd0..31838d2 100644 --- a/src/components/common/BottomSheet/BasicModal.jsx +++ b/src/components/common/BottomSheet/BasicModal.jsx @@ -2,8 +2,15 @@ import React from 'react'; import styled from 'styled-components'; const BasicModalWrapper = styled.div` - height: 192px; - margin: 0 16px; + padding: 16px; + max-height: 548px; + overflow-y: scroll; + -ms-overflow-style: none; + scrollbar-width: none; + + &::-webkit-scrollbar { + display: none; + } `; export default function BasicModal({ children }) { diff --git a/src/components/common/BottomSheet/BottomSheet.jsx b/src/components/common/BottomSheet/BottomSheet.jsx index a88e06c..9e2d2e2 100644 --- a/src/components/common/BottomSheet/BottomSheet.jsx +++ b/src/components/common/BottomSheet/BottomSheet.jsx @@ -1,51 +1,38 @@ -import React, { useState, useEffect, useRef } from 'react'; -import { BottomSheetDim, ModalBox, HeaderModal } from './BottomSheetStyle'; -import ListModal from './ListModal'; -import BasicModal from './BasicModal'; +import React, { useState, useEffect } from 'react'; +import { BottomSheetDim, BottomSheetWrapper, ModalBox, ModalHandle } from './BottomSheetStyle'; -// type: basic, list -function BottomSheet({ type = 'basic', isShow, setIsShow, children }) { - const [animate, setAnimate] = useState(false); - const [localVisible, setLocalVisible] = useState(isShow); - const wrapperRef = useRef(null); - const modalBoxRef = useRef(null); +export default function BottomSheet({ isShow, onClick, children }) { + const [isVisible, setIsVisible] = useState(false); useEffect(() => { - setLocalVisible(isShow); - }, [isShow]); + let modalTimer; - useEffect(() => { - if (localVisible && !isShow) { - setAnimate(true); - setTimeout(() => setAnimate(false), 250); + if (isShow) { + setIsVisible(true); + } else { + modalTimer = setTimeout(() => setIsVisible(false), 250); } // 0.25초뒤에 없어짐 - setLocalVisible(isShow); - }, [localVisible, isShow]); - - // Dim 클릭했을 때, ModalBox부분을 제외한 영역이어야 동작하도록 - const handleDimClick = (e) => { - if (wrapperRef.current && modalBoxRef.current && !modalBoxRef.current.contains(e.target)) { - setIsShow(false); - } - }; - // ModalBox의 HeaderModal을 클릭했을 때 동작 - const handleHeaderModalClick = () => { - setIsShow(false); - }; + return () => { + if (modalTimer !== undefined) { + clearTimeout(modalTimer); + } + }; + }, [isShow]); - if (!localVisible && !animate) return null; + if (!isVisible) { + return null; + } return ( <> - - - - {type === 'list' ? : {children}} + + + {children} + - + + ); } - -export default BottomSheet; diff --git a/src/components/common/BottomSheet/BottomSheetStyle.jsx b/src/components/common/BottomSheet/BottomSheetStyle.jsx index 8c7c45e..7197e71 100644 --- a/src/components/common/BottomSheet/BottomSheetStyle.jsx +++ b/src/components/common/BottomSheet/BottomSheetStyle.jsx @@ -1,4 +1,4 @@ -import styled, { css, keyframes } from 'styled-components'; +import styled, { keyframes } from 'styled-components'; const fadeIn = keyframes` from { @@ -23,13 +23,13 @@ const slideUp = keyframes` } to { - transform: translateY(calc(100% - ${({ LEN }) => (LEN < 425 ? LEN : 425)}px)); + transform: translateY(0); } `; const slideDown = keyframes` from { - transform: translateY(calc(100% - ${({ LEN }) => (LEN < 425 ? LEN : 425)}px)); + transform: translateY(0); } to { @@ -38,55 +38,39 @@ const slideDown = keyframes` `; export const BottomSheetDim = styled.div` - position: absolute; + position: fixed; top: 0; - - width: 100%; + width: clamp(390px, 100%, 720px); height: 100vh; - + margin: 0 auto; background-color: rgba(0, 0, 0, 0.3); - transition: background-color 0.25s ease-out; - - display: flex; - flex-direction: column; - justify-content: space-between; - - animation: ${fadeIn} 0.25s ease-out forwards; - - ${(props) => - props.disappear && - css` - animation-name: ${fadeOut}; - `} + animation: ${(p) => (p.isShow ? fadeIn : fadeOut)} 0.3s ease-out; + transition: background-color 0.3s ease-out; `; -export const ModalBox = styled.div` - width: inherit; - height: ${({ LEN }) => (LEN < 425 ? LEN : 425)}px; - border-radius: 1rem 1rem 0 0; - +export const BottomSheetWrapper = styled.article` + width: 100%; position: absolute; bottom: 0; +`; +export const ModalBox = styled.div` + position: relative; + bottom: 0; + z-index: 50; + border-radius: 20px 20px 0 0; + padding-top: 48px; display: flex; flex-direction: column; - background-color: ${({ theme }) => theme.colors.white}; - animation: ${slideUp} 0.25s ease-out forwards; - - ${(props) => - props.disappear && - css` - animation-name: ${slideDown}; - animation-timing-function: ease-in; - `} + animation: ${(p) => (p.isShow ? slideUp : slideDown)} 0.3s ease-out; `; -export const HeaderModal = styled.button` +export const ModalHandle = styled.button` width: 100%; height: 48px; - - position: relative; + position: absolute; + top: 0; &::before { content: ''; @@ -94,10 +78,8 @@ export const HeaderModal = styled.button` top: 50%; left: 50%; transform: translate(-50%, -50%); - width: 50px; height: 4px; - background-color: ${({ theme }) => theme.colors.gray100}; } `; diff --git a/src/components/common/BottomSheet/ListModal.jsx b/src/components/common/BottomSheet/ListModal.jsx index 4e14496..2a17847 100644 --- a/src/components/common/BottomSheet/ListModal.jsx +++ b/src/components/common/BottomSheet/ListModal.jsx @@ -2,34 +2,35 @@ import React from 'react'; import styled from 'styled-components'; const BottomSheetListWrapper = styled.ul` - max-height: 425px; - overflow-y: scroll; - ::-webkit-scrollbar { - width: 0; - background: transparent; - } + margin-bottom: 10px; `; const ListItem = styled.li` - height: 48px; - display: flex; - align-items: center; - padding: 0 24px; + height: 46px; + padding: 14px 26px; font-size: ${({ theme }) => theme.fontSize.sm}; + cursor: pointer; `; -const LEN = 0; - -export default function ListModal({ items }) { - const LEN = items.length * 48; +const TYPES = { + profile: ['설정 및 개인정보', '로그아웃'], + myPost: ['삭제', '수정'], + userPost: ['신고하기'], + chat: ['채팅방 나가기'], + myComment: ['삭제'], + userComment: ['신고하기'], +}; +export default function ListModal({ type, onClick }) { return ( - {items.map((item, index) => ( - {item} + {TYPES[type].map((item, index) => ( + + + ))} ); } - -export { LEN }; diff --git a/src/layout/BasicLayout.jsx b/src/layout/BasicLayout.jsx index bd3742f..7c8edaa 100644 --- a/src/layout/BasicLayout.jsx +++ b/src/layout/BasicLayout.jsx @@ -10,6 +10,7 @@ const LayoutWrapper = styled.div` margin: 0 auto; position: relative; background-color: #fff; + overflow-y: hidden; `; const LayoutMain = styled.div`