reactjscss-animationscss-transitionsreact-spring

React-spring transition. How to move form smoothly down so that div appears? No matter the height of the div


Basically I have a button on top of a form thats like "More info" and the info is just a div with text in it, I wanna press the button and have the form scoot down and the div to fade in above it. I figured out how to basically do it but it still doesnt work nicely. As in I hard coded how much the margin bottom should be etc and so it doesnt work when the div is resized or has more text in it.

const InfoDiv = styled(animated.div) `
    font-family: "Mulish", sans-serif;
    font-size: 14pt;
    font-weight: 400;
    padding: 10px 5px;
    line-height: 24px;

`;

function RiskCalculator() {
    const [show, setShow] = useState(false)
    const transitions = useTransition(show, null, {
        from: {opacity: 0, marginBottom: -115},
        enter: {opacity: 1, marginBottom: 0},
        leave: {opacity: 0, marginBottom: -115}

    })
    return (
        <MainContainer>
            <Heading>My Heading</Heading>
            <Seperator />
            <div>
                <Button onClick={() => setShow(!show)}>Info</Button>
            </div>
            
            {
                transitions.map(({ item, key, props }) =>
                item && <InfoDiv key={key} style={props}>Lorem ipsum dolor sit amet, consectetur 
                adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
                Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea 
                commodo consequat. Duis aute irure dolor in reprehenderit in 
                voluptate velit esse cillum dolore eu fugiat nulla pariatur. 
                Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit 
                anim id est laborum.</InfoDiv>
            )
            }
            <form>
                <div>
                    Hey there
                </div>
                <input type='text'/>
                <input/>
            </form>
            
        </MainContainer>
    );
}

As you can see i hard coded the 115 into the margin bottom stuff and it works just like i want it to but thats just because 115 is a good approximation of the height of my info div, whenever i resize my window or add more text, the height obviously changes and the transition doesn't work.

Am i going about this the wrong way or am i missing something


Solution

  • I want to expand on Peter Ambruzs's answer. I chose to go with animating the maxHeight, but it only worked nicely if I combined it with setting a fixed duration of the animation, otherwise I got the snap that Saif experienced. So for example, this would work better:

      const transitions = useTransition(isVisible, {
        from: { maxHeight: "0px" },
        enter: { maxHeight: "600px" },
        leave: { maxHeight: "0px" },
        config: { ...config.default, duration: 200 },
      });