question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Wrapping motion component with chakra is removing transition prop

See original GitHub issue

Bug report

Describe the bug

When wrapping motion component inside chakra factory component, i lose access to transition prop.

To reproduce

const MotionBox = chakra(motion.div) this will create a div that holds chakra props and framer motion props, except that the transition prop coming from framer-motion is not available

Expected behavior

I expect to have access to transition attribute, specially in cased where framer-motion is providing animation, such as using AnimateSharedLayout where i am only required to provide layoutId and framer-motion will handle mount and unmount animation on my component.

System information

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:22 (8 by maintainers)

github_iconTop GitHub Comments

7reactions
TimKolbergercommented, Nov 20, 2020

You have to provide types for the forwardRef component. Please see: https://codesandbox.io/s/chakra-ui-motion-box-sbk9e?file=/src/App.tsx

const MotionBox = motion.custom(
  forwardRef<MotionProps & ChakraProps, "div">(({ layoutId, ...rest }, ref) => (
    <chakra.div ref={ref} {...(rest as ChakraProps)} />
  ))
);
4reactions
TimKolbergercommented, Dec 22, 2020

There are two ways to compose a component which accepts motion and chakra props.

use chakra() factory

const MotionBox = chakra(motion.div)

The drawback is, that the prop transition is consumed by the chakra styled system and not passed to the motion component. If you don’t need to use this prop, you are good to go with this solution.

props flow

  1. Use the MotionBox
    <MotionBox 
      px="8"
      mt="4"
      animate={{
        scale: [1, 2, 2, 1, 1],
      }}
      transition={{
        duration: 2,
        ease: "easeInOut",
      }} 
    />
    
  2. chakra extracts all style props (px,mt and transition…), creates a className and passes className on in addition to any non chakra style props
    <motion.div className="xyz" animate={{ scale: [1, 2, 2, 1, 1] }}/>
    
    animate is not a chakra style prop so it will be passed on. transition is a chakra style prop so it won’t be passed to the motion component -> bad if you need it

use motion.custom

const MotionBox = motion.custom(chakra.div)

This implementation passes every internal motion prop to the passed component. In our case chakra.div. This API is provided by framer-motion, not chakra-ui. We cannot fix anything there, because the implementation lives in the framer-motion source code. And I think this behaviour is intended to be able to reuse the motion props in the custom component - most of the times you won’t need it, but someone somewhere will.

We are on our own and need to filter every motion prop to prevent passing it to the DOM element. framer-motion exposes a function called isValidMotionProp which we can use to filter the mix of motion and chakra props.

import {
  forwardRef,
  ChakraProps,
  chakra,
} from "@chakra-ui/react";
import {
  motion,
  MotionProps,
  isValidMotionProp
} from "framer-motion";

const MotionBox = motion.custom(
  forwardRef<MotionProps & ChakraProps, "div">(
    (props, ref) => {
      const chakraProps = Object.fromEntries(
        Object.entries(props).filter(
          ([key]) => !isValidMotionProp(key)
        )
      );

      return <chakra.div ref={ref} {...chakraProps} />;
    }
  )
);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Transitions - Chakra UI
Common props from framer's motion elements; in prop used to trigger the transition; unmountOnExit prop used to unmount the component when it is...
Read more >
Advanced techniques in Chakra UI - LogRocket Blog
Chakra Factory enables third-party components to receive Chakra's style props. This reduces the need to create custom component wrappers ...
Read more >
Animated List with React, Chakra Ui and Framer Motion
A walkthrough of creating an animated list with React, Framer Motion and Chakra Ui. Project repo - https://github.com/Buupu/ motion -list.
Read more >
Transition - Chakra UI - YouTube
" Chakra UI is a simple, modular and accessible component library that gives you the building blocks you need to build your React ......
Read more >
Examples | Framer for Developers
By wrapping motion components with AnimatePresence , they gain the use of an exit property that can define either a set of values...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found