Reputation: 31625
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
.
Upvotes: 9
Views: 8009
Reputation: 81026
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>
);
}
Upvotes: 9
Reputation: 31625
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.
Upvotes: 4