I have a list of items. When the order changes I want them to animate to their new position.
Before:
<ul>
<li>One</li>
<li>Two</li>
</ul>
After:
<ul>
<li>Two</li>
<li>One</li>
</ul>
Are there any libraries that can do this? Ive tired React Transition Group, React Pose and React Spring but none seem to support it, instead they focus on animations when items enter and leave the DOM. Im a bit surprised I haven't found anything as it seems like a common use case to me.
https://reactcommunity.org/react-transition-group/
https://popmotion.io/pose/
https://www.react-spring.io/
To animate list reordering with React, we can use the react-flip-move package. Then we add the FlipMove component and wrap it around the array of items we want to animate when reordering by writing: We have the Num component with a ref passed from App with forwardRef . Next, in App , we create the nums state with an array of items.
Animating items out of an array in React can be trickier than you’d think. If you have tried to roll your own solution yet, you have likely been frustrated by the fact that, once your state has been updated with an item removed, it’s gone (and hard to hold on to for the sake of animation!).
By convention, react-transition-group will use the following styles: Since we’re currently only worried about animating the exit of an item from our list, we can actually get by with only using the .item-exit-active class: Here, we’re saying that, when the transition is active, set the opacity to 0 but with a 700ms ease-out transition.
For React and Ionic React. React Listview item selection example. Select a single item or enable multiple selection for batch operations. For React and Ionic React. React Listview reorder demo. Grab and sort from drag handle on the left or right side, or tap/click and hold to sort. For React and Ionic React.
In react-spring there is an example about it. But it is quite complicated, there is a lot happening. I created a simplified version from it.
You have an array of names. You define a y value based on the index. And you can move the elements with translate property. The position is set to absolute.
With one click you can shuffle the array. With another click you can remove elements. In react transition, you can define the entering and leaving animation. The leaving animation called when you remove an element.
import { render } from 'react-dom';
import React, { useState } from 'react';
import { useTransition, animated } from 'react-spring';
import shuffle from 'lodash/shuffle';
import './styles.css';
let data = [
{
name: 'Rare Wind'
},
{
name: 'Saint Petersburg'
},
{
name: 'Deep Blue'
},
{
name: 'Ripe Malinka'
},
{
name: 'Near Moon'
},
{
name: 'Wild Apple'
}
];
function App() {
const [rows, set] = useState(data);
let height = 20;
const transitions = useTransition(
rows.map((data, i) => ({ ...data, height, y: i * height })),
d => d.name,
{
from: { position: 'absolute', height: 20, opacity: 0 },
leave: { height: 0, opacity: 0 },
enter: ({ y, height }) => ({ y, height, opacity: 1 }),
update: ({ y, height }) => ({ y, height })
}
);
return (
<div class="list" style={{ height }}>
<button onClick={() => set(shuffle(rows))}>click</button>
<button onClick={() => set(rows.slice(1))}>remove first</button>
{transitions.map(({ item, props: { y, ...rest }, key }, index) => (
<animated.div
key={key}
class="card"
style={{
zIndex: data.length - index,
transform: y.interpolate(y => `translate3d(0,${y}px,0)`),
...rest
}}
>
<div class="cell">
<div class="details">{item.name}</div>
</div>
</animated.div>
))}
</div>
);
}
const rootElement = document.getElementById('root');
render(<App />, rootElement);
Here is the sandbox: https://codesandbox.io/s/animated-list-order-example-with-react-spring-teypu
Edit: I added add element as well, because it is a nicer example this way. :)
Update: This sandbox is from necrifede who updated my example to version 9.: https://codesandbox.io/s/animated-list-order-example-with-react-spring-forked-nhwqk9?file=/src/index.js
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With