What I'm trying to do is use Fade
and Slide
in the same component.
<Slide in={isValid} timeout={timeout} direction="left">
<Fade in={isValid} timeout={timeout}>
<Foo />
</Fade>
</Slide>
But it doesn't work.
When isValid
is true, it slides the component without the fade effect and when it's false, the component just blinks and disappears.
How can I make it work? I don't want to use makeStyle
.
create(props, options) => transition.
Material-UI has component prop option for this kind of requirement and should do better and more elegant approach than the wrapping-approach. Then, you can pass any props provided by framer-motion package to your Material-UI component as long as they're not conflicted (i'm not sure if any).
<Fade> in material-ui just disables the visibility of the component .
The Slide and the Fade components both change the style.transition
property, so if they act on the same element they clobber portions of the other's work.
The way to get this to work is for them to act on different elements. Introducing a div
between the two transitions gets the desired behavior.
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Switch from "@material-ui/core/Switch";
import Paper from "@material-ui/core/Paper";
import Fade from "@material-ui/core/Fade";
import Slide from "@material-ui/core/Slide";
import FormControlLabel from "@material-ui/core/FormControlLabel";
const useStyles = makeStyles(theme => ({
root: {
height: 180
},
container: {
display: "flex"
},
paper: {
margin: theme.spacing(1),
backgroundColor: "lightblue"
},
svg: {
width: 100,
height: 100
},
polygon: {
fill: theme.palette.primary.main,
stroke: theme.palette.divider,
strokeWidth: 1
}
}));
export default function SlideAndFade() {
const classes = useStyles();
const [checked, setChecked] = React.useState(false);
const handleChange = () => {
setChecked(prev => !prev);
};
return (
<div className={classes.root}>
<FormControlLabel
control={<Switch checked={checked} onChange={handleChange} />}
label="Show"
/>
<div className={classes.container}>
<Slide in={checked} timeout={1000}>
<div>
<Fade in={checked} timeout={1000}>
<Paper elevation={4} className={classes.paper}>
<svg className={classes.svg}>
<polygon
points="0,100 50,00, 100,100"
className={classes.polygon}
/>
</svg>
</Paper>
</Fade>
</div>
</Slide>
</div>
</div>
);
}
I realized that if you wrap the transition in a div
or other element to make it as a container, it will work.
<Slide in={isValid} timeout={timeout} direction="left">
<div> // adding this div will make it work
<Fade in={isValid} timeout={timeout}>
<Foo />
</Fade>
</div>
</Slide>
And then you can just create your own Fade
component that wraps a div
.
const MyFade = React.forwardRef(
({ children, in: In, timeout, ...otherProps }, ref) => {
return (
<div ref={ref} {...otherProps}>
<Fade in={In} timeout={timeout}>
{children}
</Fade>
</div>
);
}
);
Thanks to @Ryan Cogswe that also helped in this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With