Now for the fun part.

Let’s create a components folder, with a child directory that will store our popover component.

import React, { useState } from 'react';

import { makeStyles } from '@material-ui/core/styles';

import Backdrop from '@material-ui/core/Backdrop';

import Popover from '@material-ui/core/Popover';

import Typography from '@material-ui/core/Typography';

import Button from '@material-ui/core/Button';

import Grid from '@material-ui/core/Grid';

import Divider from '@material-ui/core/Divider';

import useLocalStorage from 'hooks/useLocalStorage'; const useStyles = makeStyles(theme => ({

backdrop: {

zIndex: theme.zIndex.drawer + 1,

color: '#fff',

},

typography: {

padding: theme.spacing(2),

color: theme.palette.primary.contrastText,

},

grid: {

padding: theme.spacing(),

background: theme.palette.primary.main,

},

})); interface Props {

id: string;

anchorEl: Element;

text: string;

onClose: Function;

} const WhatsNew: React.FC<Props> = ({ anchorEl, text, onClose, id }) => {

const classes = useStyles();

const [open, setOpen] = useState(true);

const [gotIt, setGotIt] = useLocalStorage(`whats-new-${id}`, false);



const handleClose = () => {

setOpen(false);

onClose();

}; if (gotIt) {

return <></>;

}



return (

<Backdrop className={classes.backdrop} open={open} onClick={handleClose}>

<Popover

id={'new-menu'}

open={open}

anchorEl={anchorEl}

onClose={handleClose}

anchorOrigin={{

vertical: 'bottom',

horizontal: 'center',

}}

transformOrigin={{

vertical: 'top',

horizontal: 'center',

}}

>

<Grid

container

justify="flex-end"

direction="column"

className={classes.grid}

>

<Grid item>

<Typography className={classes.typography}>What's New</Typography>

<Divider />

</Grid>

<Grid item>

<Typography className={classes.typography}>{text}</Typography>

</Grid>

<Grid item container justify="flex-end">

<Button variant="contained" onClick={() => setGotIt(true)}>

GOT IT

</Button>

</Grid>

</Grid>

</Popover>

</Backdrop>

);

}; export default WhatsNew;

First, let’s look at what typescript props we want to pass in to make this reusable.

interface Props {

id: string;

anchorEl: Element;

text: string;

onClose: Function;

}

id — This is needed so we can keep an id, that will be used in local storage when they click on the GOT IT button. anchorEl — This is needed to tell the Material UI Popover what element in the document to appear next to, giving the user an idea of where to look for the new feature. text — This is a brief description of what is new, and how to use the new feature. onClose — This is a callback function, when the user clicks GOT IT, we need to set the anchorEl value to null and hide the popover.

Next, let’s look at the state within our component.

const [open, setOpen] = useState(true);



const [gotIt, setGotIt] = useLocalStorage(`whats-new-${id}`, false);

We keep a state on whether or not the popover is open and showing, and a local storage boolean on whether or not the user has clicked, GOT IT, or not.

Now we can write code to not show the popover if they have already clicked GOT IT.

if (gotIt) {

return <></>;

}

Material UI provides two components that we will use to accomplish our goal.

Backdrop — This component will show a darkened backdrop. This is useful because it will direct the attention away from the app and highlight the new feature.

Popover — This component will render a box that is next to our anchor element, highlighting the new feature.

Within the popover component, we can show the description of the new feature and a button for the user to click, to tell the app they now know of the new feature.

Mission accomplished!