Chakra UI + Framer Motion
This example shows how to add some interesting motion interaction or animation to your Chakra UI websites or apps with Framer Motion.
Usage
There are two ways to use as props and chakra factory.
chakra factory
The chakra factory function can be used to represent animation and interaction
using framer motion props, as in the example below.
import { chakra } from "@chakra-ui/react";
import { motion, isValidMotionProp } from "framer-motion";
const ChakraBox = chakra(motion.div, {
shouldForwardProp: isValidMotionProp,
});
Let's see an example using the chakra factory function!
import { Container, chakra, shouldForwardProp } from '@chakra-ui/react'; import { motion, isValidMotionProp } from 'framer-motion'; const ChakraBox = chakra(motion.div, { /** * Allow motion props and non-Chakra props to be forwarded. */ shouldForwardProp: (prop) => isValidMotionProp(prop) || shouldForwardProp(prop), }); const FramerWithChakraFactory =() => { return ( <Container h="100vh" display="flex" alignItems="center" justifyContent="center"> <ChakraBox animate={{ scale: [1, 2, 2, 1, 1], rotate: [0, 0, 270, 270, 0], borderRadius: ["20%", "20%", "50%", "50%", "20%"], }} // @ts-ignore no problem in operation, although type error appears. transition={{ duration: 3, ease: "easeInOut", repeat: Infinity, repeatType: "loop", }} padding="2" bgGradient="linear(to-l, #7928CA, #FF0080)" display="flex" justifyContent="center" alignItems="center" width="100px" height="100px" > I'm Dizzy! </ChakraBox> </Container> ) } export default FramerWithChakraFactory
shouldForwardPropis needed to allow framer props to be used instead of the matching props from Chakra. If you do not include "children" somehow (for example by using ourshouldForwardProp), then you will not be able to use child components. Either way, all other Chakra props can still be used.
as prop
You can also use as prop to add animations and interactions.
It is important to note that if there are props with the same name as the
chakraprops, they take precedence over theframer motionprops. For example, atransitionwill take precedence over aframer motionprop and theframer motionfeature will not work.
import { Box } from "@chakra-ui/react";
import { motion } from "framer-motion";
function Example() {
return (
<Box
as={motion.div}
height="40px"
width="40px"
bg="orange.400"
drag="x"
dragConstraints={{ left: -100, right: 100 }}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
transition="0.5s linear"
// does not work: transition={{ transition: "0.5", ease: "linear" }}
/>
);
}
Let's look at an example of as prop!
import { Box, Container, keyframes } from '@chakra-ui/react'; import { motion } from 'framer-motion'; const animationKeyframes = keyframes` 0% { transform: scale(1) rotate(0); border-radius: 20%; } 25% { transform: scale(2) rotate(0); border-radius: 20%; } 50% { transform: scale(2) rotate(270deg); border-radius: 50%; } 75% { transform: scale(1) rotate(270deg); border-radius: 50%; } 100% { transform: scale(1) rotate(0); border-radius: 20%; } `; const animation = `${animationKeyframes} 2s ease-in-out infinite`; const FramerWithAsProp = () => { return ( <Container h="100vh" display="flex" alignItems="center" justifyContent="center"> <Box as={motion.div} animation={animation} padding="2" bgGradient="linear(to-l, #7928CA, #FF0080)" width="12" height="12" display="flex" /> </Container> ) }; export default FramerWithAsProp;