[React] navigation tab 컴포넌트

DONNIE·2023년 7월 14일
0

React

목록 보기
20/26

네비게이션으로 즐겨찾기 메뉴 보여주기
스뭇드하게 보여야해서 scss 파일도 올린다.ㅋ

  • Tab.js

const Tab = () => {

    const modalRef = useRef(null);
    const [openTab, setOpenTab] = useState(false);
    const [favModal, setFavModal] = useState(false);

	// tab 버튼 클릭시 토글 여닫기
    const handleTab = () =>{
        setOpenTab(!openTab)
    }
    // 외부 클릭시 tab 창 닫힘
    const handleOutsideClick = (e) => {
        if (modalRef.current && !modalRef.current.contains(e.target)) {
         setOpenTab(false)
        }
      }; 
    useEffect(() => {
        document.addEventListener("mousedown", handleOutsideClick);
        return () => {
          document.removeEventListener("mousedown", handleOutsideClick);
        };
      }, []);

      useEffect(()=>{
        if(favModal) {
            setOpenTab(false);
        }
      },[favModal])
    return (
        <>
        <Style open={openTab}>
            <div className={ `${openTab ? 'modal' : 'cursor-btn'}`} >
            <div className={`navigation-container ${openTab ? 'open' : 'closed'} `} ref={modalRef}>
                <div className="nav-top"><h1>Bookmark</h1></div>
                <div className="nav-middle">
                    <ul className="bookmark-list">
                        {
                            userPreference!==null &&
                            menu.map((item,idx)=>{
                               return(
                                    <Fragment key={generateRandomString(idx)}>
                                    {
                                        item.isHave &&
                                        <li > <div> · {item.label}</div>
                                            <ul>
                                                {
                                                    item.lowerMenu.map((i,index)=>{
                                                        return (
                                                            <Fragment key={generateRandomString(index)}>
                                                           { i.isFavorite &&  <li className="cursor-btn" onClick={()=>{onClickLink(i.path)}}>{i.label}</li>}
                                                            </Fragment>
                                                        )
                                                    })
                                                }
                                            </ul>
                                        </li>
                                    }
                                    </Fragment>
                               )
                            })
                        }
                    </ul>
                </div>
                <div className="nav-bottom custom-flex-item custom-align-item custom-justify-center cursor-btn" onClick={()=>setFavModal(true)}><img src={Setting} alt="nav-setting"/><p className="custom-stress-txt " >Setting</p></div>
            <div className={`tab-container custom-flex-item custom-justify-center custom-align-item  ${openTab ? 'open' : 'closed'}`} onClick={handleTab}>
                {!openTab ? ' My Favorite Quick' : <img src={Close} />}
            </div>
            </div>
            </div>

            {
                favModal
                &&
                <Favorite onClose={()=>setFavModal(false)} menu={menu} home={userPreference?.myHome}/>
            }
        </Style>
        </>
    )
}
export default Tab

const Style = styled.div`
.tab-container {
    background: ${(props)=> props.open? 'white' :'#BB0841'};
    box-shadow: ${(props)=> props.open? 'none' :'1px 1px 10px 0px rgba(187, 8, 65, 0.36);'}; 
}
`
  • tab.scss
@import '../variables.scss';
.tab-container {
    
    position: absolute;
    left: 257px;
    width: 257px;
     color: white;
    top: 50%; width: 32px; 
    height: 120px;font-size: 14px; letter-spacing: 0.14px;
    writing-mode: vertical-lr;  border-radius: 0px 4px 4px 0px;
}
.navigation-container {
    width: 257px; display : flex; flex-direction : column;
    height: 100vh; 
    position: fixed;
    top: 0;
    left: -200px;
    transition: left 0.3s ease; background : white; padding: 25px 30px; // 애니메이션
    h1 {
        font-size: 20px; font-weight: 700; letter-spacing: 0.2px;
    }
  }
  .tab-container .open {
    left: 400px; 
  }
  .navigation-container.open {
    left: 0; 
  }
  
  .navigation-container.closed {
    left: -257px;
  }
  .nav-middle {
     padding-top: 20px;
    .bookmark-list{
     
      & > li {
        width: 201px;  padding: 20px 15px; border-radius: 4px; border: 1px solid #CCC;
       background: #FBFBFB; margin-bottom: 10px;
      }
      & > li > div {
        font-size: 16px; font-weight: 600; letter-spacing: 0.4px;
      }
      & > li ul li {
        font-size: 12px; font-weight: 400; letter-spacing: 0.12px;  padding: 10px 0 0 8px;
      }
    }
    
  }
  .nav-bottom {
    margin-top: auto; background-color: #F0F0F0;
    width: 84px; height: 28px; border-radius: 100px;

    img {
        margin-right: 5px;
    }
    p {
        font-size: 12px; font-weight: 600; line-height: 14px; letter-spacing: 0.01em;
    }
  }
profile
후론트엔드 개발자

0개의 댓글