네비게이션으로 즐겨찾기 메뉴 보여주기
스뭇드하게 보여야해서 scss 파일도 올린다.ㅋ
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);'};
}
`
@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;
}
}