Intro
드롭 다운(Drop Down), 토글 메뉴(Toggle Menu), 슬라이드 메뉴(Slide Menu), 아코디언 메뉴(Accodian Menu) 등 다양한 이름으로 불리우는 것 같다.
하늘색 부분의 영역을 클릭하면 On/ Off 된다.
특정 아이콘 or 버튼을 삽입하여 그 부분만 클릭시 메뉴를 움직이도록 만들 예정이다.
Code
- styled-components를 사용했다.
- 다른 페이지에서 사용하기 위해 슬라이드바를 컴포넌트 형식으로 따로 분리하여 파일을 작성했다.
- 원래 슬라이드바 왼쪽에 다른 컴포넌트가 있는 부분을 고려하여 margin, padding 등의 css를 작성했다.
때문에 작동원리, 애니메이션 부분만 참고하시길
// SlideBar.jsx
import React, { useState, useRef } from "react";
import styled from "styled-components";
const Container = styled.div`
display: flex;
`;
// direction(4) : ↑ → ↓ ←
const Content = styled.div`
// width를 하드코딩했는데 크기 기억하기
width: 405px;
height: 100% - 10px;
margin: 10px 10px 10px -20px;
border-top: 1px solid #7eb3ff;
border-bottom: 1px solid #7eb3ff;
box-shadow: 2px 0px 6px rgba(13, 19, 29, 0.25);
/* overflow: hidden; */
transition: width 0.2s ease-out; // 애니메이션 속성 설정해주기
`;
const Toggle = styled.div`
width: 40px;
height: 100% - 10px;
margin: 10px 10px 10px -10px;
background: skyblue;
border: 1px solid #7eb3ff;
box-shadow: 2px 0px 6px rgba(13, 19, 29, 0.25);
border-radius: 0px 10px 10px 0px;
`;
export default function SideBar() {
const [onOff, setOnOff] = useState(true);
const contentRef = useRef(null);
const handleOnOff = () => {
if (!contentRef || !contentRef.current) {
// useRef 변수가 비었을 때 그냥 리턴하도록 예외처리
return;
}
const style = contentRef.current.style;
if (!onOff) {
// 하드코딩했던 이전의 width 크기로 돌아가자
style.width = "405px";
} else if (onOff) {
style.width = "0px";
}
setOnOff((onOff) => !onOff);
};
return (
<Container>
<Content ref={contentRef}></Content>
<Toggle
className={`${onOff ? "open" : "close"}`}
onClick={() => handleOnOff()}
></Toggle>
</Container>
);
}
// App.jsx
import React from "react";
import styled from "styled-components";
import SideBar from "./SideBar";
const Container = styled.div`
display: flex;
height: 100%;
`;
export default function App() {
return (
<Container>
<SideBar />
</Container>
);
}
참고 자료
https://devbirdfeet.tistory.com/141
간단한 설명으로 이해하는데 정말 도움이 되었다.
받아오는 리스트의 크기만큼 스크롤 높이를 지정해준다.
code
// 클릭시 실행되는 함수
function foldList() {
if (!listRef || !listRef.current) { // useRef 변수가 비었을 때
return; // 그냥 리턴하도록 예외처리를 해주자
}
const style = listRef.current.style; // 접근할 DOM 요소의 스타일 속성을 미리 선언해둔다.
if (closeList) { // closeAllList 상태변수가 true 일 때
style.maxHeight = '0'; // maxHeight 는 0이 되고 접힌다.
} else if (!closeList) { // closeAllList 상태변수가 false 면
style.maxHeight =
`${listRef.current.scrollHeight}px`; // maxHeight = scroll 길이가 되고 메뉴가 열린다.
}
setCloseList(!closeList); // 클릭할 때마다 상태를 반대로 바꾼다.
}
애니메이션
.open img {
transform: rotate(180deg); // 화살표 아이콘 방향돌리기
}
.content {
overflow: hidden;
transition: max-height 0.3s ease-out; // 애니메이션 속성 설정해주기
}
'React' 카테고리의 다른 글
[React] useLocation을 활용해 사이드(메뉴)바를 현재 주소 기준으로 활성화하기 (0) | 2023.05.21 |
---|---|
[React] 드롭다운(Dropdown) 컴포넌트 만들기 (0) | 2023.05.20 |
[React] .env 환경변수 설정하기 (0) | 2023.03.06 |
[React] iframe 태그를 활용해 CodePen 코드 가져오기 (0) | 2022.11.02 |
[React] React Slick을 활용하여 캐러셀(Carousel) 만들기 (0) | 2022.10.05 |