Home > Enterprise >  React / Framer Motion - why are my child elements not staggered?
React / Framer Motion - why are my child elements not staggered?

Time:12-03

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:

enter image description here

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.

  • Related