Navigation 부분 작성 중 발견한 문제로 css에서는 높이값이 지정되지 않았을 때 (height:auto) transition을 적용시킬 수 없다.
하지만 나는 navigation 부분은 list의 개수가 다르고, max-height:100vw 와 같은 코드를 적용시킬 수 없기 때문에 높이를 지정할 수 없었음!
이를 해결하기 위해서는 js로 style을 적용시켜야 하지만!! react는 이미 라이브러리가 만들어져 있다 😉
react-animate-height - how to use
[react-animate-height
Lightweight React component for animating height using CSS transitions.. Latest version: 3.0.4, last published: 15 days ago. Start using react-animate-height in your project by running `npm i react-animate-height`. There are 329 other projects in the npm r
www.npmjs.com](https://www.npmjs.com/package/react-animate-height)
npm에 나와있는 예시 코드대로 작성하니 무난하게 성공했음!
코드 핵심
import { useState } from "react";
import AnimateHeight from "react-animate-height";
import NavPartList from "./NavPartList";
const NavInnerButton = styled.button`
// 기타 style code
// arrow
& > div:first-child:after,
& > div:first-child::after {
display: block;
content: "";
position: absolute;
right: 0;
top: 10px;
width: 7px;
height: 7px;
border-top: 1px solid ${({ theme }) => theme.colors.pointGray};
border-left: 1px solid ${({ theme }) => theme.colors.pointGray};
transform: rotate(135deg);
transition: all 0.3s ease-in;
}
}
.sub_list_show {
width: 100%;
// arrow
& > div:first-child:after,
& > div:first-child::after {
transform: rotate(225deg);
}
}
`;
function NavInnerSub({ item }) {
const [height, setHeight] = useState(0);
const [more, setMore] = useState(false);
const onClickMore = () => {
setMore(!more);
setHeight(height === 0 ? "auto" : 0);
};
return (
<NavInnerButton
aria-expanded={height !== 0}
aria-controls="example-panel"
onClick={onClickMore}
>
<div className={more ? "sub_list sub_list_show" : "sub_list"}>
<NavPartList item={item} />
<AnimateHeight id="example-panel" duration={300} height={height}>
<ul>
<li></li>
</ul>
</AnimateHeight>
</div>
</NavInnerButton>
);
}
export default NavInnerSub;
적용 완료.gif
코드 전문보기
import { useState } from "react";
import { Link as RRDLink, useLocation } from "react-router-dom";
import styled from "styled-components";
import AnimateHeight from "react-animate-height";
import NavPartList from "./NavPartList";
const Link = ({ children, isActive, ...props }) => {
return <RRDLink {...props}>{children}</RRDLink>;
};
const NavInnerButton = styled.button`
width: 100%;
height: auto;
padding: 0;
padding-right: 25px;
margin-top: 25px;
margin-left: 30px;
text-decoration: none;
border: none;
background-color: transparent;
text-align: left;
cursor: pointer;
.sub_list {
ul {
width: 180px;
margin-left: 30px;
padding-bottom: 5px;
}
li {
width: 100%;
height: auto;
line-height: 41px;
}
// NavInner Name
& > div {
position: relative;
}
// arrow
& > div:first-child:after,
& > div:first-child::after {
display: block;
content: "";
position: absolute;
right: 0;
top: 10px;
width: 7px;
height: 7px;
border-top: 1px solid ${({ theme }) => theme.colors.pointGray};
border-left: 1px solid ${({ theme }) => theme.colors.pointGray};
transform: rotate(135deg);
transition: all 0.3s ease-in;
}
}
.sub_list_show {
width: 100%;
// arrow
& > div:first-child:after,
& > div:first-child::after {
transform: rotate(225deg);
}
}
`;
const StyledSubLink = styled(Link)`
text-decoration: none;
font-family: ${({ theme }) => theme.font.point};
font-size: 14px;
color: ${(props) => (props.isActive ? "#64C5B1" : "#101038")};
`;
function NavInnerSub({ item }) {
const { pathname } = useLocation();
const [height, setHeight] = useState(0);
const [more, setMore] = useState(false);
const onClickMore = () => {
setMore(!more);
setHeight(height === 0 ? "auto" : 0);
};
return (
<NavInnerButton
aria-expanded={height !== 0}
aria-controls="example-panel"
onClick={onClickMore}
>
<div className={more ? "sub_list sub_list_show" : "sub_list"}>
<NavPartList item={item} />
<AnimateHeight id="example-panel" duration={300} height={height}>
<ul>
{item.subNav.map((item, key) => (
<li key={key}>
<StyledSubLink to={item.url} isActive={pathname === item.url}>
{item.subName}
</StyledSubLink>
</li>
))}
</ul>
</AnimateHeight>
</div>
</NavInnerButton>
);
}
export default NavInnerSub;
'front > react' 카테고리의 다른 글
window사이즈를 확인하여 useSate 값을 변경해 navigation 상태관리하기 - matchMedia (0) | 2022.07.11 |
---|---|
컴포넌트 재사용을 위한 react component 전달 (0) | 2022.07.08 |
styled-components에서 기본 css3로 옮기기 - css3는 네스팅과 변수사용에 제한이 있다 (0) | 2022.07.08 |
react-router-dom의 NavLink처럼 Link to와 현재 url이 일치할 때 styled-components 사용 하기 및 onClick 이벤트가 발생하면 css의 style이 변하게 설정 (0) | 2022.07.04 |
[react] more button & 버튼 클릭하여 표시되는 list 개수 수정 (0) | 2022.06.29 |