Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use two transitions with material ui?

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.

like image 681
Vencovsky Avatar asked Dec 04 '19 03:12

Vencovsky


People also ask

How do you add transitions in MUI?

create(props, options) => transition.

Can I use framer motion with material UI?

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).

What is fade in material UI?

<Fade> in material-ui just disables the visibility of the component .


2 Answers

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>
  );
}

Edit Material demo

like image 72
Ryan Cogswell Avatar answered Oct 29 '22 12:10

Ryan Cogswell


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.

like image 22
Vencovsky Avatar answered Oct 29 '22 14:10

Vencovsky