Comparison with other React FLIP libraries
| Feature | react-flip-move |
react-overdrive |
react-flip-toolkit |
|---|---|---|---|
| Animate position | ✅ | ✅ | ✅ |
| Animate scale | ❌ | ✅ | ✅ |
| Animate opacity | ❌ | ✅ | ✅ |
| Animate parent's size without warping children | ❌ | ❌ | ✅ |
| Use real FLIP instead of cloning & crossfading | ✅ | ❌ | ✅ |
| Use springs for animations | ❌ | ❌ | ✅ |
| Support spring-based stagger effects | ❌ | ❌ | ✅ |
| Usable with frameworks other than React | ❌ | ❌ | ✅ |
npm install react-flip-toolkit or yarn add react-flip-toolkit
Wrap all animated children with a single Flipper component that has a flipKey prop that changes every time animations should happen.
Wrap elements that should be animated with Flipped components that have a flipId prop matching them across renders.
Flipper
Flipped
SpringMemoizationwill-change:transformFork this example on Code Sandbox
import React, { useState } from 'react'
import { Flipper, Flipped } from 'react-flip-toolkit'
const AnimatedSquare = () => {
const [fullScreen, setFullScreen] = useState(false)
const toggleFullScreen = () => setFullScreen(prevState => !prevState)
return (
<Flipper flipKey={fullScreen}>
<Flipped flipId="square">
</Flipped>
</Flipper>
)
}
Fork this example on Code Sandbox
import React, { useState } from 'react'
import { Flipper, Flipped } from 'react-flip-toolkit'
const Square = ({ toggleFullScreen }) => (
<Flipped flipId="square">
</Flipped>
)
const FullScreenSquare = ({ toggleFullScreen }) => (
<Flipped flipId="square">
</Flipped>
)
const AnimatedSquare = () => {
const [fullScreen, setFullScreen] = useState(false)
const toggleFullScreen = () => setFullScreen(prevState => !prevState)
return (
<Flipper flipKey={fullScreen}>
{fullScreen ? (
<FullScreenSquare toggleFullScreen={toggleFullScreen} />
) : (
<Square toggleFullScreen={toggleFullScreen} />
)}
</Flipper>
)
}
Fork this example on Code Sandbox
import React, { useState } from 'react'
import { Flipper, Flipped } from 'react-flip-toolkit'
import shuffle from 'lodash.shuffle'
const ListShuffler = () => {
const [data, setData] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
const shuffleList = () => setData(shuffle(data))
return (
<Flipper flipKey={data.join('')}>
<button onClick={shuffleList}> shuffle</button>
<ul className="list">
{data.map(d => (
<Flipped key={d} flipId={d}>
<li>{d}</li>
</Flipped>
))}
</ul>
</Flipper>
)
}
Add some interest to a dynamic list of cards by animating changes to cards' sizes and positions.
Fork this example on Code Sandbox
The react-flip-toolkit library offers spring-driven stagger configurations so that you can achieve complex sequenced effects.
For the most basic stagger effect, you can simply add a stagger boolean prop to your Flipped element:
<Flipped flipId={`element-${i}`} stagger>
<AnimatedListItem/>
</Flipped>
Fork this example on Code Sandbox
react-flip-toolkit uses springs for animations. To customize the spring, you can pass in a preset name:
// spring preset can be one of: "stiff", "noWobble", "gentle", "veryGentle", or "wobbly"
<Flipper flipKey='foo' spring='wobbly'>
{/* Flipped components go here...*/}
</Flipper>
or a custom spring config:
<Flipper flipKey='foo' spring={{ stiffness: 280, damping: 22 }} >
{/* Flipped components go here...*/}
</Flipper>
View all spring options in the interactive explorer
Interesting animations often involve scale transforms in addition to simple translate transforms. The problem with scale animations has to do with children — if you scale a div up 2x, you will warp any children it has by scaling them up too, creating a weird-looking animation. That's why this library allows you to wrap the child with a Flipped component that has an inverseFlipId to counteract the transforms of the parent:
<Flipped flipId={id}>
<Flipped inverseFlipId={id} scale>
some text that will not be warped
</Flipped>
</Flipped>
By default, both the scale and the translation transforms of the parent will be counteracted (this allows children components to make their own FLIP animations without being affected by the parent).
But for many use cases, you'll want to additionally specify the scale prop to limit the adjustment to the scale and allow the positioning to move with the parent.
Note: the DOM element with the inverse transform should lie flush against its parent container for the most seamless animation.
That means any layout styles — padding, flexbox, etc—should be applied to the inverted container (the element wrapped with a Flipped component with an inverseFlipId) rather than the parent Flipped container.
react-flip-toolkit works great with client-side routers to provide route-driven transitions:
<Route
render={({ location, search }) => {
return (
<Flipper
flipKey={`${location.pathname}-${location.search}`}
>
{/* Child routes that contain Flipped components go here...*/}
</Flipper>
)
}}
/>
FlipperThe parent wrapper component that contains all the elements to be animated. You'll often need only one of these per page, but sometimes it will be more convenient to have multiple Flipper regions of your page concerned with different transitions.
<Flipper flipKey={someKeyThatChanges}>{/* children */}</Flipper>
| prop | default | type | details |
|---|---|---|---|
| flipKey (required) | - | string, number, bool |
Changing this tells react-flip-toolkit to transition child elements wrapped in Flipped components. |
| children (required) | - | node |
One or more element children |
| spring | noWobble |
string or object |
Pro |
$ claude mcp add react-flip-toolkit \
-- python -m otcore.mcp_server <graph>