MUI & Motion-Framer
Have you ever wondered how to combine the power of the easy animations that Framer Motion offers with Material UI components? I want to show you how easy is to combine both technologies in a clean and simple way!
In order to do so, let's build a simple MUI Button, with a start icon that is going to animate between add and close with framer motion.
When browsing for solutions on google on how to combine Material UI with freamer motion, you'll find a lot of bad implementetions, like wrapping a component with motion, or using motion.div or motion.button surrounding the MUI component. In fact is way simpler than this!
Let's make a reusable button, that we can import in any other component to control and open-closed state on a form, using properly motion framer with it:
import { AddOutlined } from '@mui/icons-material';
import { Button, Typography } from '@mui/material';
import { motion } from 'framer-motion';
interface Props {
toggle: () => void;
on: boolean;
}
const AddButton = (props: Props) => {
const { toggle, on } = props;
return (
<Button
component={motion.button}
variant='contained'
startIcon={
<AddOutlined
component={motion.svg}
animate={{ rotate: on ? 45 : 0 }}
transition={{ duration: 0.3 }}
/>
}
onClick={toggle}
color={on ? 'error' : 'primary'}
>
<Typography
variant='button'
component={motion.p}
layout
transition={{ duration: 0.1 }}
>
{on ? 'Close' : 'Add'}
</Typography>
</Button>
);
};
export default AddButton;
In the MUI components, you can add the 'component' property, here is where you define that is going to render in the DOM as a framer motion component, in this case a motion.button, but it could be any motion value, like div or svg, use it depending on what component it is (an icon would be an svg, and a Box, Grid or Stack would be a div as examples). After doing that, you can add the framer motion animation props without TypesCript errors.
The toggle function it can be a simple function on the parent component, with a useState:
import {useState} from 'react';
import { Collapse } from '@mui/material'
const ParentComponent = () => {
const [open, setOpen] = useState<boolean>(false);
const toggleOpen = () => {
setOpen(prev => !prev);
}
return (
<>
<AddButton toggle={toggleOpen} on={open} />
<Collapse in={open}>
/* ... Rest of the code */
</Collapse>
</>
)
}
And as simple as this, we can use the motion animations.
I hope this helps you next time you have to combine MUI with Framer-Motion!
Don't we need to make any changes in the configuration files ? That's very helpful Thanks
Great Blog! I recently created an opensource animation component library using framer motion. The animations are heavily inspired by awwwards animations. Can I get some feedback on it? https://ui.gloz.tech