Search code examples
cssreactjsstyled-componentsreact-animations

How to make slideIn AND slideOut with styled-components with react-animations


I'm working on building a component that displays none or block depending on it's isActive prop.

I've managed to make it slideInDown using react-animations with styled-components like this.

import styled, { keyframes } from 'styled-components';
import { ifProp } from 'styled-tools';
import { slideInDown } from 'react-animations';

const slideInAnimation = keyframes`${slideInDown}`;

const MyComponent = styled.div`
  animation: 0.4s ${slideInAnimation};
  display: ${ifProp('isActive', 'block', 'none')};
`;

I need to make it slideOutUp now. However, I'm not sure how to implement both slideInDown and slideOutUp animations together.

How would I accomplish that?

Note: that works. But I don't know how to make it both slide in and out. I tried something like this below but that didn't work.

import styled, { keyframes } from 'styled-components';
import { ifProp } from 'styled-tools';
import { slideInDown, slideOutUp } from 'react-animations';

const slideInAnimation = keyframes`${slideInDown}`;
const slideOutAnimation = keyframes`${slideOutUp}`;

const MyComponent = styled.div`
  animation: 0.4s ${slideInAnimation}, 0.4s ${slideOutAnimation};
  display: ${ifProp('isActive', 'block', 'none')};
`;

Solution

  • I went through the react-animations library, what I figured out is slideOutUp sets visibility: 'hidden.'

    const slideOutUp: Animation = {
      from: {
        transform: translate3d(0, 0, 0)
      },
      to: {
        visibility: 'hidden',
        transform: translate3d(0, '-100%', 0)
      }
    };
    

    You can use animation-fill-mode: forwards, which helps in retaining the style after the animation ends.

    You can do something like this (it works):

    const MyComponent = styled.div`
      animation: ${ifProp(
        "isActive",
        `0.4s ${slideInAnimation}`,
        `0.4s ${slideOutAnimation} forwards`
      )};
    `;
    

    Here is the working example, for testing purpose onClick event I am setting {isActive: false}

    https://codesandbox.io/s/949ql6p6no