Chakra UI + Framer Motion
If you'd like to add some interesting motion interaction or animation to your Chakra UI websites or apps, here's a quick tip:
If you're using a version of framer motion
less than v 3.10.0
:
import { Box, forwardRef } from "@chakra-ui/react"import { motion, isValidMotionProp } from "framer-motion"// 1. Create a custom motion component from Boxconst MotionBox = motion.custom(forwardRef((props, ref) => {const chakraProps = Object.fromEntries(// do not pass framer props to DOM elementObject.entries(props).filter(([key]) => !isValidMotionProp(key)),)return <Box ref={ref} {...chakraProps} />}),)// 2. You'll get access to `motion` and `chakra` props in `MotionBox`function Example() {return (<MotionBoxboxSize="40px"bg="red.300"drag="x"dragConstraints={{ left: -100, right: 100 }}whileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}/>)}
If you're using the latest verion of framer motion
, which is >= v 3.10.0
. In
this version, framer-motion
automatically filters out motion-related props
forwarded to the provided component.
Reference
import { Box, forwardRef } from "@chakra-ui/react"import { motion } from "framer-motion"const MotionBox = motion(Box)function Example() {return (<MotionBoxheight="40px"bg="red.300"drag="x"dragConstraints={{ left: -100, right: 100 }}whileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}/>)}
For TypeScript users, here's what you need to do:
import React from "react"import { HTMLChakraProps, chakra } from "@chakra-ui/react"import { motion, HTMLMotionProps } from "framer-motion"type Merge<P, T> = Omit<P, keyof T> & T;type MotionBoxProps = Merge<HTMLChakraProps<"div">, HTMLMotionProps<"div">>;export const MotionBox: React.FC<MotionBoxProps> = motion(chakra.div);function Example() {return (<MotionBoxheight="40px"bg="red.300"drag="x"dragConstraints={{ left: -100, right: 100 }}whileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}/>)}