Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a loading button in MUI?

I am using react with MUI framework and I was wondering how can I create an loading button using this framework?

I am looking for something similar to this.

like image 506
Kevin Vugts Avatar asked Feb 05 '18 09:02

Kevin Vugts


People also ask

What is an Mui button?

The Material-UI (MUI) Button component merits a detailed exploration of all of its functionality. Its broad use across many UIs makes a deep knowledge of it’s props highly valuable.

Is it possible to use ripple and focus in Mui V5?

I tested ripple, focus, and disabled and they worked great. Regardless, the variant functionality in MUI v5 gives a great way to package up Button styling. If you create a new variant and you are using TypeScript, be sure to extend the Button Variant typing with the below code:

When to use material UI in authentication flow?

When a user submits a login form in the authentication flow it's desirable to give the user feedback that the request is in flight. Material UI is an implementation of Google's material design in React. Material UI has some fancy buttons.

What's new in Mui V5?

Another great new feature in MUI v5 is the ability to override the default values of props for a component across your theme. The defaultProps syntax is similar to variants and styleOverrides.


1 Answers

To the best of my knowledge, there is no single component that accomplishes this out of the box in material-ui. However, you can implement your own easily using CircularProgress.

Assuming you are using material-ui v1, here's a rough example. First, I create a LoadingButton that accepts a loading prop - if that prop is true, I display a CircularProgress indicator. It also accepts a done prop - if that's true, the button clears the progress indicator and becomes a checkmark to show success.

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Button from 'material-ui/Button';
import { CircularProgress } from 'material-ui/Progress';
import Check from 'material-ui-icons/Check';

const styles = theme => ({
  button: {
    margin: theme.spacing.unit,
  },
});

const LoadingButton = (props) => {
  const { classes, loading, done, ...other } = props;

  if (done) {
    return (
      <Button className={classes.button} {...other} disabled>
        <Check />
      </Button>
    );
  }
  else if (loading) {
    return (
      <Button className={classes.button} {...other}>
        <CircularProgress />
      </Button>
    );
  } else {
    return (
      <Button className={classes.button} {...other} />
    );
  }
}

LoadingButton.defaultProps = {
  loading: false,
  done: false,
  };

LoadingButton.propTypes = {
  classes: PropTypes.object.isRequired,
  loading: PropTypes.bool,
  done: PropTypes.bool,
};

export default withStyles(styles)(LoadingButton);

You can use the LoadingButton as shown in the following example, which uses state to set the appropriate prop on the button.

import React from 'react';
import LoadingButton from './LoadingButton';

class ControlledButton extends React.Component {
  constructor(props) {
    super(props);

    this.state = { loading: false, finished: false };
  }

  render() {
    const { loading, finished } = this.state;

    const setLoading = !finished && loading;

    return (
      <div>
        <LoadingButton
          loading={setLoading}
          done={finished}
          onClick={() => {
            // Clicked, so show the progress dialog
            this.setState({ loading: true });

            // In a 1.5 seconds, end the progress to show that it's done
            setTimeout(() => { this.setState({ finished: true })}, 1500);
          }}
        >
          Click Me
        </LoadingButton>
      </div>
    );
  }
}

export default ControlledButton;

You can of course tweak the styling and functionality to meet your exact needs.

like image 87
Jules Dupont Avatar answered Oct 11 '22 18:10

Jules Dupont