Categories
Material UI

Material UI — Snack Bar Customization

Spread the love

Material UI is a Material Design library made for React.

It’s a set of React components that have Material Design styles.

In this article, we’ll look at how to customize snack bars with Material UI.

Consecutive Snack Bars

We can display multiple snack bars consecutively with some logic.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import Snackbar from "@material-ui/core/Snackbar";
import IconButton from "@material-ui/core/IconButton";
import CloseIcon from "@material-ui/icons/Close";

export default function App() {
  const [snackPack, setSnackPack] = React.useState([]);
  const [open, setOpen] = React.useState(false);
  const [messageInfo, setMessageInfo] = React.useState(undefined);

  React.useEffect(() => {
    if (snackPack.length && !messageInfo) {
      setMessageInfo({ ...snackPack[0] });
      setSnackPack(prev => prev.slice(1));
      setOpen(true);
    } else if (snackPack.length && messageInfo && open) {
      setOpen(false);
    }
  }, [snackPack, messageInfo, open]);

  const handleClick = message => () => {
    setSnackPack(prev => [...prev, { message, key: new Date().getTime() }]);
  };

  const handleClose = (event, reason) => {
    if (reason === "clickaway") {
      return;
    }
    setOpen(false);
  };

  const handleExited = () => {
    setMessageInfo(undefined);
  };

  return (
    <div>
      <Button onClick={handleClick("Message A")}>Show A</Button>
      <Button onClick={handleClick("Message B")}>Show B</Button>
      <Snackbar
        open={open}
        autoHideDuration={6000}
        onClose={handleClose}
        onExited={handleExited}
        message={messageInfo ? messageInfo.message : undefined}
        action={
          <React.Fragment>
            <Button color="secondary" size="small" onClick={handleClose}>
              foo
            </Button>
            <IconButton color="inherit" onClick={handleClose}>
              <CloseIcon />
            </IconButton>
          </React.Fragment>
        }
      />
    </div>
  );
}

The snackPack state has the items to display.

We set the message with setMessageInfo .

This is done in the useEffect callback.

When a button is clicked, then the old message is removed from the snackPack with setSnackPack and then we add the new one.

The handleClick function lets us change the message .

Now when we click the button, then old is gone and the new one is displayed.

Snack Bars and Floating Action Buttons

We should make the snack bar display above floating action buttons in mobile.

To do that, we can write:

import React from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import Fab from "@material-ui/core/Fab";
import AddIcon from "@material-ui/icons/Add";
import Snackbar from "@material-ui/core/Snackbar";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
  fab: {
    position: "absolute",
    bottom: theme.spacing(2),
    right: theme.spacing(2)
  },
  snackbar: {
    [theme.breakpoints.down("xs")]: {
      bottom: 90
    }
  }
}));

export default function App() {
  const classes = useStyles();

  return (
    <div>
      <AppBar position="static" color="primary">
        <Toolbar>
          <Typography variant="h6" color="inherit">
            App
          </Typography>
        </Toolbar>
      </AppBar>
      <Fab color="secondary" className={classes.fab}>
        <AddIcon />
      </Fab>
      <Snackbar
        open
        autoHideDuration={6000}
        message="hello"
        action={
          <Button color="inherit" size="small">
            ok
          </Button>
        }
        className={classes.snackbar}
      />
    </div>
  );
}

to move the snack bar above the floating action button with some styles.

We made the snack bar display at the bottom with the snackbar class set to bottom: 90 when the breakpoint is xs.

Also, we set the floating action button to have an absolute position with the fab class.

These are all in the makeStyles function.

Change Transition

We can add transition effects to our snack bar when it opens.

To do that, we pass in a value for the TransitionComponent .

For example, we write:

import React from "react";
import Button from "@material-ui/core/Button";
import Snackbar from "@material-ui/core/Snackbar";
import Grow from "@material-ui/core/Grow";

function GrowTransition(props) {
  return <Grow {...props} />;
}

export default function TransitionsSnackbar() {
  const [open, setOpen] = React.useState(false);

  const handleClick = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div>
      <Button onClick={handleClick}>Grow</Button>
      <Snackbar
        open={open}
        onClose={handleClose}
        TransitionComponent={GrowTransition}
        message="lorem ipsum"
      />
    </div>
  );
}

We created the GrowTransition component and pass that into the TransitionComponent prop.

Alternatives include the Fade and Slide transitions.

Control Slide Direction

We can also change the slide direction if we use the Slide transition effect.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import Snackbar from "@material-ui/core/Snackbar";
import Slide from "@material-ui/core/Slide";

function TransitionLeft(props) {
  return <Slide {...props} direction="left" />;
}

export default function TransitionsSnackbar() {
  const [open, setOpen] = React.useState(false);

  const handleClick = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div>
      <Button onClick={handleClick}>Slide</Button>
      <Snackbar
        open={open}
        onClose={handleClose}
        TransitionComponent={TransitionLeft}
        message="lorem ipsum"
      />
    </div>
  );
}

We have a Snackbar with the TransitionComponent set to TransitionLeft .

TransitionLeft has the Slide component to add the slide transition with the direction set to left to make it slide right to left.

Conclusion

We can add transitions to snack bars.

Also, we can display snack bars consecutively.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *