반응형
이전 글
이번에는 접었다 폈다 하는 효과까지해서 트리 메뉴를 완성해보려고 한다.
routes/Directory/Child.tsx
import { useState } from 'react'
import { DownArrow } from 'assets/svgs'
import * as Styled from './index.styles'
const Child = ({ child }: Props) => {
const [isOpened, setIsOpened] = useState(true)
const handleClick = () => {
setIsOpened((prev) => !prev)
}
// ...
return (
<>
<li>
<Styled.ChildButton type='button' onClick={handleClick}>
{child.name}
<Styled.ButtonArrow isOpened={isOpened}>
<DownArrow width={18} height={18} fill='#666666' />
</Styled.ButtonArrow>
</Styled.ChildButton>
</li>
<li>
<Styled.ChildContainer isOpened={isOpened}>
{child.type === 'folder' && child.children?.map((c) => <Child key={`${c.id}`} child={c} />)}
</Styled.ChildContainer>
</li>
</>
)
}
먼저 메뉴가 열렸을 때, 닫혔을 때 상태 관리를 위해 isOpened 상태를 만들어준다. 메뉴 이름을 버튼으로 감싸준 후, 버튼을 클릭할 때마다 isOpened 상태가 바뀔 수 있도록 해준다.
버튼과 ul에 isOpened를 넘겨주어 css를 통해 접었다 펴지는 효과를 구현해줄 것이다.
routes/Directory/index.styles.ts
import styled, { css } from 'styled-components'
interface IChildContainer {
isOpened?: boolean
}
interface IButtonArrow {
isOpened: boolean
}
export const Directory = styled.section`
padding: 15px 0;
font-size: 16px;
`
export const ChildContainer = styled.ul<IChildContainer>`
overflow: hidden;
margin-left: 10px;
padding-left: 5px;
border-left: 1px solid #eeeeee;
${({ isOpened }) => {
if (isOpened !== undefined && !isOpened) {
return css`
height: 0px;
`
}
return css`
height: 100%;
`
}}
li {
cursor: pointer;
font-size: 16px;
line-height: 20px;
}
`
export const ChildButton = styled.button`
display: flex;
align-items: center;
font-size: 16px;
`
export const ButtonArrow = styled.span<IButtonArrow>`
display: flex;
align-items: center;
transform: ${({ isOpened }) => (isOpened ? 'scaleY(1)' : 'scaleY(-1)')};
`
Child 컴포넌트를 감싸는 ChildContainer를 만들어주고 overflow:hidden으로 지정해준다.
isOpened가 true일 경우에는 height가 100%, false일 경우는 height가 0px이 되도록 해서 접었다 펴지는 효과를 만들어주었다.
그리고 버튼 안에 있는 화살표 아이콘을 isOpened가 바뀔 때마다 상하반전이 되도록 해준다.
반응형
'FE > React' 카테고리의 다른 글
[React] geoLocation API로 현재 위치를 알아보자 (0) | 2023.02.02 |
---|---|
react-datepicker 적용하기(+ 커스텀) (0) | 2023.01.10 |
[React] 재귀 컴포넌트로 트리 메뉴 만들기(1) (0) | 2022.12.20 |
[React] Storybook 사용해보기 (0) | 2022.12.02 |
React Infinite Carousel 만들기(TS) (1) | 2022.11.24 |