5 글 보임 - 1 에서 5 까지 (총 5 중에서)
-
글쓴이글
-
2023년 2월 19일 16:56 #69080
정중식참가자Header.jsx
import { Item, List, Login, Logo, Menu, MenuItem, MenuList, StyleHeader, } from './styles/Header.styled';
import { useNavigate } from 'react-router-dom'; import { FiSearch } from 'react-icons/fi'; import { useEffect, useRef, useState } from 'react'; import { Button } from './styles/Button.styled';
const Header = () => { const [isOpen, setIsOpen] = useState(false); const menuRef = useRef(); const navigate = useNavigate();
const handleIsOpen = () => { if (isOpen) { setIsOpen(false); } else { setIsOpen(true); } };
useEffect(() => { if (menuRef.current) { if (isOpen) { menuRef.current.classList.remove('close'); menuRef.current.classList.add('open'); } if (!isOpen) { menuRef.current.classList.remove('open'); menuRef.current.classList.add('close'); } } }, [isOpen]);
return ( <StyleHeader> <Logo onClick={() => navigate('/')}> <h1>NewJeans</h1> </Logo>
<List> <Item color='#FFBFBF'> <span>하니</span> </Item> <Item color='#f7e600'> <span>민지</span> </Item> <Item color='#F7FCFF'> <span>해린</span> </Item> <Item color='#D0FC5C'> <span>다니엘</span> </Item> <Item color='#9EE0FF'> <span>혜인</span> </Item> </List>
<Login> <div className='user-wrap' onClick={() => handleIsOpen()}> Login </div> <FiSearch className='search-icon' /> </Login> {isOpen && ( <Menu ref={menuRef}> <MenuList> <MenuItem> <span className='name'>정중식, welcome! </span> </MenuItem>
<MenuItem> <Button backgroundColor='#00AE68' shadowColor='#007503'> 카드작성 </Button> </MenuItem> <MenuItem> <Button backgroundColor='#FFAA40'>마이페이지</Button> </MenuItem> <MenuItem> <Button backgroundColor='tomato'>로그아웃</Button> </MenuItem> </MenuList> </Menu> )} </StyleHeader> ); };
export default Header;
Header.styled.js
import styled, { keyframes } from 'styled-components';
export const menuOpenFrames = keyframes` 0% { height: 0px; } 50% { height: 250px; } 100% { height: 300px; } `; export const menuCloseFrames = keyframes` 0% { height: 300px; } 50% { height: 250px; } 100% { height: 0px; } `;
export const StyleHeader = styled.header` position: relative; display: flex; align-items: center; justify-content: space-between; background: #f9f5f2; height: 60px; padding-left: 10px; padding-right: 10px; `;
export const Logo = styled.div` height: 100%; font-size: 3rem; font-weight: bold; letter-spacing: -3px; cursor: pointer; `;
export const List = styled.ul` width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; padding-right: 50px; font-size: 25px; `;
export const Item = styled.li` margin-right: 10px;</pre> <pre> span { display: flex; align-items: center; cursor: pointer;</pre> <pre> &:hover { font-weight: bold; transition-duration: 0.3s; } }</pre> <pre> & span::before { content: ''; display: block; width: 20px; height: 20px; background: ${(props) => props.color}; border-radius: 50%; margin-right: 5px; } `;
export const Login = styled.div` display: flex; text-align: center; font-size: 25px; cursor: pointer;</pre> <pre> .user-wrap { margin-right: 7px; transition: 0.3s; &:hover { transform: scale(1.2); } }</pre> <pre> .search-icon { transition: 0.3s; &:hover { transform: scale(1.2); } } `;
export const Menu = styled.div` position: absolute; top: 60px; left: 0; width: 100%; z-index: 2; background: #f9f5f2;</pre> <pre> &.open { animation: ${menuOpenFrames} 0.3s linear forwards; }</pre> <pre> &.close { animation: ${menuCloseFrames} 0.3s linear forwards; } `;
export const MenuList = styled.ul` display: flex; flex-direction: column; padding: 2rem; font-size: 25px; `; export const MenuItem = styled.li` display: flex; margin-top: 10px;</pre> <pre> &:first-child { margin-top: 0; }</pre> <pre> & span::before { content: ''; display: block; width: 15px; height: 15px; background: gray; border-radius: 50%; margin-right: 5px; }</pre> <pre> span { display: flex; align-items: center; letter-spacing: -0.3px; font-size: 1.56rem; } `;
클릭시 잘 나타나기는합니다만, 다시 클릭해서 탭을 닫으면 close애니메이션이 적용이안됩니다..
혹시 뭐때문에그런거고 어떤식으로 해주면좋을까요?...
2023년 2월 19일 20:49 #69107
정중식참가자효율적이진않은것같지만 구현했습니다. 아무래도 isMenu &&(...) 이런식으로 하면 처음 useEffect()에서 if(isMenu)부분은 동작하지만, 요소가 바로 사라져버려서 close 클래스가 안붙는거같아서.. 그냥 미리 요소들을 배치시켜놓고 숨겨놓은다음에 클릭시 보이게끔해줬습니다. 괜찮은가요? ㅠ
const [isMenu, setIsMenu] = useState(''); const handleIsOpen = () => { if (isMenu) { setIsMenu(''); } else { setIsMenu(1); } }; useEffect(() => { if (menuRef.current) { if (isMenu) { menuRef.current.classList.remove('close'); menuRef.current.classList.add('open'); } if (!isMenu) { menuRef.current.classList.remove('open'); menuRef.current.classList.add('close'); } } }, [isMenu]);
<Menu ref={menuRef} visible={isMenu.toString()}> <MenuList visible={isMenu.toString()}> <MenuItem> <span className='name'>정중식, welcome! </span> </MenuItem>
<MenuItem> <Button backgroundColor='#00AE68' shadowColor='#007503'> 카드작성 </Button> </MenuItem> <MenuItem> <Button backgroundColor='#FFAA40'>마이페이지</Button> </MenuItem> <MenuItem> <Button backgroundColor='tomato'>로그아웃</Button> </MenuItem> </MenuList> </Menu>
2023년 2월 19일 21:07 #69109
정중식참가자아
<Menu className={isMenu ? 'open' : 'close'}>
좀 매끄럽지않아서 고민중이였는데 ..
ㅡ. ㅡ 완벽히 구현성공했습니다. 하루온종일 붙잡고있었는데 이렇게쉽게 풀어버릴수가..
2023년 2월 19일 21:23 #69112
정중식참가자선생님 정말 죄송합니다. 한번만 더 코드 봐주실수 있으실까요? 문제가, 메뉴를 닫으면 스르륵 닫혀야하는데 아무래도 조건문때문에 닫힐때 애니메이션이 발동되기도전에 요소가 사라져버려서 타임아웃을줬습니다.
import { Item, List, Login, Logo, Menu, MenuItem, MenuList, StyleHeader, } from './styles/Header.styled';
import { useNavigate } from 'react-router-dom'; import { FiSearch } from 'react-icons/fi'; import { useState } from 'react'; import { Button } from './styles/Button.styled';
const Header = () => { const [isMenu, setIsMenu] = useState(false); const [isOpen, setIsOpen] = useState(false);
const navigate = useNavigate();
const handleMenu = () => { setIsMenu(!isMenu);
if (isOpen) { setTimeout(() => { setIsOpen(false); }, 300); } else { setIsOpen(true); } };
return ( <StyleHeader> <Logo onClick={() => navigate('/')}> <h1>NewJeans</h1> </Logo>
<List> <Item color='#FFBFBF'> <span>하니</span> </Item> <Item color='#f7e600'> <span>민지</span> </Item> <Item color='#F7FCFF'> <span>해린</span> </Item> <Item color='#D0FC5C'> <span>다니엘</span> </Item> <Item color='#9EE0FF'> <span>혜인</span> </Item> </List>
<Login> <div className='user-wrap' onClick={() => handleMenu()}> Login </div> <FiSearch className='search-icon' /> </Login>
{isOpen && ( <Menu className={isMenu ? 'open' : 'close'}> <MenuList className={isMenu ? 'show' : 'hide'}> <MenuItem> <span className='name'>정중식, welcome! </span> </MenuItem>
<MenuItem> <Button backgroundColor='#00AE68' shadowColor='#007503'> 카드작성 </Button> </MenuItem> <MenuItem> <Button backgroundColor='#FFAA40'>마이페이지</Button> </MenuItem> <MenuItem> <Button backgroundColor='tomato'>로그아웃</Button> </MenuItem> </MenuList> </Menu> )} </StyleHeader> ); };
export default Header;
선생님이 보기에 어떤가요?
-
글쓴이글
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
- 답변은 로그인 후 가능합니다.