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.