Categories
Material UI

Material UI — Links and Menus

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 add links and menus to Material UI.

Simple Links

We can add links with the Link component.

For instance, we can write:

import React from "react";
import Link from "@material-ui/core/Link";

export default function App() {
  const preventDefault = event => event.preventDefault();

  return (
    <div>
      <Link href="#" onClick={preventDefault}>
        Link
      </Link>
    </div>
  );
}

We add a link with the href to go the URL we want when we click it.

onClick lets us pass in a click handler to change the behavior of the link.

We can also change the color to change the color of the link.

For example, we can write:

import React from "react";
import Link from "@material-ui/core/Link";

export default function App() {
  const preventDefault = event => event.preventDefault();

  return (
    <div>
      <Link href="#" onClick={preventDefault} color="primary">
        Link
      </Link>
    </div>
  );
}

We set the color to primary to make it purple.

Also, we can pass a value to the variant prop to change the styles:

import React from "react";
import Link from "@material-ui/core/Link";
import Typography from "@material-ui/core/Typography";

export default function App() {
  const preventDefault = event => event.preventDefault();

  return (
    <div>
      <Typography>
        <Link href="#" onClick={preventDefault} variant="inherit">
          Link
        </Link>
      </Typography>
    </div>
  );
}

Menus

We can add a menu with the Menu component.

Inside it, we can add items with the MenuItem components.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";

export default function App() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  const handleClick = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };
  return (
    <div>
      <Button onClick={handleClick}>Open</Button>
      <Menu
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        <MenuItem onClick={handleClose}>home</MenuItem>
        <MenuItem onClick={handleClose}>profile</MenuItem>
        <MenuItem onClick={handleClose}>logout</MenuItem>
      </Menu>
    </div>
  );
}

to add a menu.

We have a Button that has the onClick prop set to the handleClick function.

It sets the anchor element to element so that we can open the menu.

We set the open prop of the menu to the anchor element.

The anchor element would be the button as indicated in the handleClick function.

This way, we can determine if the button is clicked and we can open the menu if it’s set.

To close the menu, we set the anchorEl to null so that open will have false passed in.

Selected Menus

We can keep a menu item selected.

To do that, we can set the selected prop to true if the item is selected.

For example, we can write:

import React from "react";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import Menu from "@material-ui/core/Menu";
import MenuItem from "@material-ui/core/MenuItem";

const options = ["apple", "orange", "grape"];

export default function App() {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [selectedIndex, setSelectedIndex] = React.useState(1);

  const handleClickListItem = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleMenuItemClick = (event, index) => {
    setSelectedIndex(index);
    setAnchorEl(null);
  };

  const handleClose = () => {
    setAnchorEl(null);
  };

  return (
    <div>
      <List component="nav">
        <ListItem button onClick={handleClickListItem}>
          open
        </ListItem>
      </List>
      <Menu
        anchorEl={anchorEl}
        keepMounted
        open={Boolean(anchorEl)}
        onClose={handleClose}
      >
        {options.map((option, index) => (
          <MenuItem
            key={option}
            selected={index === selectedIndex}
            onClick={event => handleMenuItemClick(event, index)}
          >
            {option}
          </MenuItem>
        ))}
      </Menu>
    </div>
  );
}

to add a menu.

We keep the index of the selected item with the selectedIndex .

It’s set when we click on the MenuItem .

We have the selected prop that has a boolean expression to compare the index of the item against the selectedIndex value to determine which value is selected.

Customized Menu

We can create our own menu with the Popper , Paper and ClickAwayListener components.

For example, we can write:

import React from "react";
import Button from "@material-ui/core/Button";
import ClickAwayListener from "@material-ui/core/ClickAwayListener";
import Grow from "@material-ui/core/Grow";
import Paper from "@material-ui/core/Paper";
import Popper from "@material-ui/core/Popper";
import MenuItem from "@material-ui/core/MenuItem";
import MenuList from "@material-ui/core/MenuList";

export default function App() {
  const [open, setOpen] = React.useState(false);
  const anchorRef = React.useRef(null);

const handleToggle = () => {
    setOpen(prevOpen => !prevOpen);
  };

const handleClose = event => {
    if (anchorRef.current && anchorRef.current.contains(event.target)) {
      return;
    }

setOpen(false);
  };

function handleListKeyDown(event) {
    if (event.key === "Tab") {
      event.preventDefault();
      setOpen(false);
    }
  }

  const prevOpen = React.useRef(open);
  React.useEffect(() => {
    if (prevOpen.current === true && open === false) {
      anchorRef.current.focus();
    }

  prevOpen.current = open;
  }, [open]);

  return (
    <div>
      <Button ref={anchorRef} onClick={handleToggle}>
        menu
      </Button>
      <Popper open={open} anchorEl={anchorRef.current} transition disablePortal>
        {({ TransitionProps, placement }) => (
          <Grow
            {...TransitionProps}
            style={{
              transformOrigin:
                placement === "bottom" ? "center top" : "center bottom"
            }}
          >
            <Paper>
              <ClickAwayListener onClickAway={handleClose}>
                <MenuList autoFocusItem={open} onKeyDown={handleListKeyDown}>
                  <MenuItem onClick={handleClose}>home</MenuItem>
                  <MenuItem onClick={handleClose}>profile</MenuItem>
                  <MenuItem onClick={handleClose}>logout</MenuItem>
                </MenuList>
              </ClickAwayListener>
            </Paper>
          </Grow>
        )}
      </Popper>
    </div>
  );
}

We add the Button to toggle the menu.

The Popper has the actual menu.

The Grow component adds the transition for the menu with the TransitionProps .

We can set the transformOrigin to set how the menu is placed.

Paper has holds the ClickAwayListener so that the menu is closed when we click outside the menu.

MenuList has the menu entries.

handleClose sets the open state to false to close the menu.

We also have the handleListKeyDown function to handle Tab key presses.

We close the menu when it’s pressed.

Conclusion

We can add links and menus easily with the Link and Menu components.

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 *