React Pose PoseGroup simply animates elements of a list when the list change with the flipMove option
https://codesandbox.io/s/inspiring-herschel-37bvs
How to do it with react-spring?
{items.map(item => (
<Item key={item} />
))}
I'd like to animate the list if an item is removed, and the animation smoothly fill the gap
Animating to position is a little more difficult in react-spring, as you have to manipulate the positions as styles. I like to use hook based animation so I converted the component to function. The best way to solve this problem is the useTransition function in react-spring. You can define from, enter and leave styles for it. And it will apply to each array item as they removed or added.
For the position I need the y position first as data then as a property. So I map the index as y, and I introduce it to the props as a variable to interpolate from.
const [items, setItems] = React.useState([0, 1, 2, 3]);
const transitions = useTransition(
items.map((item, i) => ({ label: item, y: i })),
item => item.label,
{
from: { opacity: 0 },
leave: { opacity: 0 },
enter: ({ y }) => ({ y, opacity: 1 }),
update: ({ y }) => ({ y })
}
);
Then you can use the transition object in the render part to map the items with styles from it. The trick here is the transform style. The y now change based on the array order. We can create a nice transform style based on it to move the items around.
<ul className="sidepanel">
{transitions.map(({ item, props, key }, index) => (
<animated.li
style={{
position: "absolute",
opacity: props.opacity,
transform: props.y.interpolate(
y => `translate3d(0,${y * 40}px,0)`
)
}}
className="item"
data-key={item.label % 5}
key={key}
onClick={() => {
setItems([0, 1, 3]);
}}
/>
))}
</ul>
Finally the example, I added an add an shuffle button. https://codesandbox.io/s/react-spring-position-animation-di9rb