I'm building a balance overview within a financial services application. The content is rendered by passing props into a single <BalanceEntry>
component and then mapping all available entries into the page.
Using Framer Motion, I want to stagger the entry animation of each rendered <BalanceEntry>
as a child by 0.2 seconds.
<div className="pt-16">
<motion.div
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, x: 1 }}
transition={{
delay: 0.3,
default: { ease: 'easeInOut' },
staggerChildren: 0.2,
}}
>
{TransactionData.map((item) => {
return (
<div key={item.id}>
<motion.div variants={BalanceEntryVariants}>
<BalanceEntry
transactionDate={item.transactionDate}
transactionType={item.transactionType}
transactionID={item.transactionID}
transactionAmount={item.transactionAmount}
transactionIcon={item.transactionIcon}
/>
</motion.div>
</div>
);
})}
</motion.div>
</div>
);
I have created two motion.divs based on multiple suggestions here on SO to achieve the staggering, but I still fail to have each BalanceEntry component animated with staggering, instead they are always animated as a group:
The variants are setup like this:
const BalanceEntryVariants = {
hidden: {
opacity: 0,
y: -20,
},
visible: {
opacity: 1,
x: 1,
transition: {
ease: 'easeInOut',
},
},
};
Where is my mistake to render each individual BalanceEntry staggered happening?
CodePudding user response:
It seems that this can be solved by defining a variant for the parent motion.div
as well, perhaps try something like:
const parent = {
visible: {
opacity: 1,
y: -20,
transition: {
when: 'beforeChildren',
staggerChildren: 0.2,
delay: 0.3,
},
},
hidden: {
opacity: 0,
x: 1,
transition: {
when: 'afterChildren',
},
},
};
Add the variant to parent motion.div
:
<motion.div initial="hidden" animate="visible" variants={parent}>
...
</motion.div>
Here is a minimized example running on: stackblitz
There might be other issues as well (not sure about the purpose of y: -20
and x: 1
), but hopefully this would still help.