I am passing a open prop to styled component to create animations for the hamburger icon. This is the code
const StyledBurger = styled.button`
display: flex;
flex-direction: column;
justify-content: center;
border: 0;
background-color: ${colors.cobaltBlue};
border-radius: 2.7px;
cursor: pointer;
div {
width: 27px;
height: 3px;
margin: 1.5px;
transition: all 0.2s linear;
border-radius: 1.4px;
background-color: ${colors.white};
:first-child {
${({ open }) => open && firstOpenAnimation};
}
:nth-child(2) {
opacity: ${({ open }) => (open ? '0' : '1')};
}
:nth-child(3) {
${({ open }) => open && seconOpenAnimation}
}
}
`;
const firstOpenKeyframe = keyframes`
50% {
transform: translateY(6px) rotate(0);
}
100% {
transform: translateY(6px) rotate(45deg);
}
`;
const secondOpenKeyframe = keyframes`
50% {
transform: translateY(-6px) rotate(0);
}
100% {
transform: translateY(-6px) rotate(-45deg);
}
`;
const firstCloseKeyFrame = keyframes`
50% {
transform:translateY(0) rotate(-45deg);
}
100% {
transform:translateY(-6px) rotate(-45deg) ;
}
`;
const firstOpenAnimation = css`
animation: 0.3s linear ${firstOpenKeyframe} forwards;
`;
const seconOpenAnimation = css`
animation: 0.3s linear ${secondOpenKeyframe} forwards;
`;
const firstCloseAnimation = css`
animation: 0.3s linear ${firstCloseKeyFrame} forwards;
`;
export default StyledBurger;
Basically what I want is if the menu is not open to reverse the animation that was created after the first click. I tried doing a conditional render of animation keyframe based on the prop open but what happens is when the page loads it immediately creates the animation of not is opened because it satisfies false. What can I do to fix this and create the opposite animation when unClicked
Make few corrections and it should all work properly.
${({ open }) => (open ? firstOpenAnimation : firstCloseAnimation)}
.working copy of your code is here
Working code snippet
const StyledBurger = styled.button`
display: flex;
flex-direction: column;
justify-content: center;
border: 0;
background-color: red;
border-radius: 2.7px;
cursor: pointer;
height: 30px;
div {
width: 27px;
height: 3px;
margin: 1.5px;
transition: all 0.2s linear;
border-radius: 1.4px;
background-color: white;
:first-child {
${({ open }) =>
open !== null && (open ? firstOpenAnimation : firstCloseAnimation)}
}
:nth-child(2) {
opacity: ${({ open }) => (open ? "0" : "1")};
}
:nth-child(3) {
${({ open }) =>
open !== null && (open ? seconOpenAnimation : secondCloseAnimation)}
}
}
`;
const firstOpenKeyframe = keyframes`
50% {
transform: translateY(6px) rotate(0);
}
100% {
transform: translateY(6px) rotate(45deg);
}
`;
const secondOpenKeyframe = keyframes`
50% {
transform: translateY(-6px) rotate(0);
}
100% {
transform: translateY(-6px) rotate(-45deg);
}
`;
const firstCloseKeyFrame = keyframes`
50% {
transform:translateY(0) rotate(-45deg);
}
100% {
transform:translateY(0) rotate(0) ;
}
`;
const secondCloseKeyFrame = keyframes`
50% {
transform:translateY(0) rotate(-45deg);
}
100% {
transform:translateY(0) rotate(0) ;
}
`;
const firstOpenAnimation = css`
animation: 0.3s linear ${firstOpenKeyframe} forwards;
`;
const seconOpenAnimation = css`
animation: 0.3s linear ${secondOpenKeyframe} forwards;
`;
const secondCloseAnimation = css`
animation: 0.3s linear ${secondCloseKeyFrame} forwards;
`;
const firstCloseAnimation = css`
animation: 0.3s linear ${firstCloseKeyFrame} forwards;
`;
export default function App() {
const [open, setOpen] = useState(null);
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<StyledBurger onClick={() => setOpen(prev => !prev)} open={open}>
<div />
<div />
<div />
</StyledBurger>
</div>
);
}