react framer-motion 메뉴바

해적왕·2022년 8월 13일
0
post-custom-banner

import styled from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
import { FiHome, FiMapPin, FiFolder, FiLock } from 'react-icons/fi';

const icons = [
  {
    shape: <FiHome />,
  },
  {
    shape: <FiMapPin />,
  },
  {
    shape: <FiFolder />,
  },
  {
    shape: <FiLock />,
  },
]

const MenuBar = () => {
  const icon = icons.map((x) => {
    return x.shape;
  })
  const [selectedMenu, setSelectedMenu] = useState(icon[0]);

  return ( )
 } 
 
 export default MenuBar;

https://react-icons.github.io/react-icons/

리액트 아이콘을 사용했다.
배열을 미리 map으로 먼저 나눠 shape만 쓸 수 있게했다. 메뉴 바로 사용할 때 링크도 삽입하기 위함이다.

  return ( 
    <Container>
      <Nav>
        <ul>
          {icons.map((item) => {
            return (
              <li key={item.shape} onClick={() => setSelectedMenu(item.shape)}>
                {item.shape}
                {item.shape == selectedMenu ? (
                  <Underline layoutId="underline"
                  />
                ) : null}
              </li>
            )
          })}
        </ul>
      </Nav>
    </Container>
  )

styled-components 부분이다.

const Container = styled(motion.div)`
    margin:200px auto 0 auto;
    width:350px;
`
const Nav = styled.div`
    background: #fff;
    border:1px solid #eee;

  ul{
    display: flex
  }

  li{
    position:relative;
    width:100%;
    height:100%;
    cursor: pointer;
    display:inline-block;
    padding:30px;
    display:flex;
    align-items:center;
    justify-content:center;
  }
`

const Underline = styled(motion.div)`
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: #000;
    vertical-align:bottom;
`

return 안을 살펴보면 li가 클릭될 때 클릭 된 shape를 setSelectedMenu안에 담았다. 아이콘 모양과 seletedmenu모양이 같을 때 <UnderLine /> 이 생성된다.
그리고 <UnderLine /> 안에 layoutId 를 넣어주면 된다.

layoutId 를 가진 새 구성요소가 다른 구성요소가 제거될 때 추가되면 구성요소는 이전 구성요소에서 레이아웃 애니메이션을 수행한다.

이렇게 framer-motion 에서는 이동하는 바도 손쉽게 만들 수 있다.


다르게도 해봤다.

profile
프론트엔드
post-custom-banner

0개의 댓글