Security News
NIST Misses 2024 Deadline to Clear NVD Backlog
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.
material-ui-popup-state
Advanced tools
easiest way to create menus, popovers, and poppers with material-ui
The material-ui-popup-state npm package provides utilities to manage the state of Material-UI popups such as menus, popovers, and tooltips. It simplifies the process of handling open/close state, anchor elements, and other common popup behaviors.
Menu Popup
This feature allows you to create a menu popup that can be triggered by a button. The PopupState component manages the state of the popup, and the bindTrigger and bindMenu functions are used to bind the popup state to the button and menu components respectively.
```jsx
import React from 'react';
import { Button, Menu, MenuItem } from '@material-ui/core';
import PopupState, { bindTrigger, bindMenu } from 'material-ui-popup-state';
function MenuPopup() {
return (
<PopupState variant="popover" popupId="demoMenu">
{(popupState) => (
<React.Fragment>
<Button variant="contained" color="primary" {...bindTrigger(popupState)}>
Open Menu
</Button>
<Menu {...bindMenu(popupState)}>
<MenuItem onClick={popupState.close}>Option 1</MenuItem>
<MenuItem onClick={popupState.close}>Option 2</MenuItem>
<MenuItem onClick={popupState.close}>Option 3</MenuItem>
</Menu>
</React.Fragment>
)}
</PopupState>
);
}
export default MenuPopup;
```
Popover Popup
This feature allows you to create a popover popup that can be triggered by a button. The PopupState component manages the state of the popover, and the bindTrigger and bindPopover functions are used to bind the popup state to the button and popover components respectively.
```jsx
import React from 'react';
import { Button, Popover, Typography } from '@material-ui/core';
import PopupState, { bindTrigger, bindPopover } from 'material-ui-popup-state';
function PopoverPopup() {
return (
<PopupState variant="popover" popupId="demoPopover">
{(popupState) => (
<React.Fragment>
<Button variant="contained" color="primary" {...bindTrigger(popupState)}>
Open Popover
</Button>
<Popover
{...bindPopover(popupState)}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
transformOrigin={{ vertical: 'top', horizontal: 'center' }}
>
<Typography>The content of the Popover.</Typography>
</Popover>
</React.Fragment>
)}
</PopupState>
);
}
export default PopoverPopup;
```
Tooltip Popup
This feature allows you to create a tooltip popup that can be triggered by hovering or focusing on a button. The PopupState component manages the state of the tooltip, and the bindTrigger and bindTooltip functions are used to bind the popup state to the button and tooltip components respectively.
```jsx
import React from 'react';
import { Button, Tooltip } from '@material-ui/core';
import PopupState, { bindTrigger, bindTooltip } from 'material-ui-popup-state';
function TooltipPopup() {
return (
<PopupState variant="tooltip" popupId="demoTooltip">
{(popupState) => (
<Tooltip {...bindTooltip(popupState)} title="Tooltip text">
<Button variant="contained" color="primary" {...bindTrigger(popupState)}>
Hover or Focus
</Button>
</Tooltip>
)}
</PopupState>
);
}
export default TooltipPopup;
```
react-popper is a popular library for positioning tooltips, popovers, and other elements. It provides a powerful and flexible API for managing the positioning of elements, but it requires more manual setup compared to material-ui-popup-state.
react-overlays provides a set of components for managing overlays, including modals, tooltips, and popovers. It offers more control and customization options but may require more boilerplate code compared to material-ui-popup-state.
react-bootstrap is a complete UI library that includes components for modals, tooltips, and popovers. It is more comprehensive and provides a wider range of components, but it is tied to the Bootstrap framework, unlike material-ui-popup-state which is designed specifically for Material-UI.
Takes care of the boilerplate for common Menu, Popover and Popper use cases.
Provides a Custom React Hook that keeps track of the local state for a single popup, and functions to connect trigger, toggle, and popover/menu/popper components to the state.
Also provides a Render Props Component that keeps track of the local state for a single popup, and passes the state and mutation functions to a child render function.
npm install --save material-ui-popup-state
import * as React from 'react'
import Button from '@material-ui/core/Button'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import {
usePopupState,
bindTrigger,
bindMenu,
} from 'material-ui-popup-state/hooks'
const MenuPopupState = () => {
const popupState = usePopupState({ variant: 'popover', popupId: 'demoMenu' })
return (
<div>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Menu
</Button>
<Menu {...bindMenu(popupState)}>
<MenuItem onClick={popupState.close}>Cake</MenuItem>
<MenuItem onClick={popupState.close}>Death</MenuItem>
</Menu>
</div>
)
}
export default MenuPopupState
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import Popover from '@material-ui/core/Popover'
import {
usePopupState,
bindTrigger,
bindPopover,
} from 'material-ui-popup-state/hooks'
const styles = theme => ({
typography: {
margin: theme.spacing.unit * 2,
},
})
const PopoverPopupState = ({ classes }) => {
const popupState = usePopupState({
variant: 'popover',
popupId: 'demoPopover',
})
return (
<div>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Popover
</Button>
<Popover
{...bindPopover(popupState)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<Typography className={classes.typography}>
The content of the Popover.
</Typography>
</Popover>
</div>
)
}
PopoverPopupState.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(PopoverPopupState)
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import Popper from '@material-ui/core/Popper'
import {
usePopupState,
bindToggle,
bindPopper,
} from 'material-ui-popup-state/hooks'
import Fade from '@material-ui/core/Fade'
import Paper from '@material-ui/core/Paper'
const styles = theme => ({
typography: {
padding: theme.spacing.unit * 2,
},
})
const PopperPopupState = ({ classes }) => {
const popupState = usePopupState({ variant: 'popper', popupId: 'demoPopper' })
return (
<div>
<Button variant="contained" {...bindToggle(popupState)}>
Toggle Popper
</Button>
<Popper {...bindPopper(popupState)} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<Paper>
<Typography className={classes.typography}>
The content of the Popper.
</Typography>
</Paper>
</Fade>
)}
</Popper>
</div>
)
}
PopperPopupState.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(PopperPopupState)
material-ui-popup-state/hooks
exports several helper functions you can use to
connect components easily:
anchorRef
: creates a ref
function to pass to the anchorEl
(by default, the currentTarget
of the mouse event that triggered the popup
is used; only use anchorRef
if you want a different element to be the anchor).bindMenu
: creates props to control a Menu
component.bindPopover
: creates props to control a Popover
component.bindPopper
: creates props to control a Popper
component.bindTrigger
: creates props for a component that opens the popup when clicked.bindToggle
: creates props for a component that toggles the popup when clicked.bindHover
: creates props for a component that opens the popup while hovered.bindFocus
: creates props for a component that opens the popup while hovered.To use one of these functions, you should call it with the object
returned by usePopupState
and spread the return value into the desired
element:
import * as React from 'react'
import Button from '@material-ui/core/Button'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import {
usePopupState,
bindTrigger,
bindMenu,
} from 'material-ui-popup-state/hooks'
const MenuPopupState = () => {
const popupState = usePopupState({ variant: 'popover', popupId: 'demoMenu' })
return (
<div>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Menu
</Button>
<Menu {...bindMenu(popupState)}>
<MenuItem onClick={popupState.close}>Cake</MenuItem>
<MenuItem onClick={popupState.close}>Death</MenuItem>
</Menu>
</div>
)
}
export default MenuPopupState
usePopupState
This is a Custom Hook that uses useState
internally, therefore the Rules of Hooks apply to usePopupState
.
usePopupState
Propsvariant
('popover'
or 'popper'
, required)Use 'popover'
if your popup is a Popover
or Menu
; use 'popper'
if your
popup is a Popper
.
Right now this only affects whether bindTrigger
/bindToggle
/bindHover
return
an aria-controls
prop or an aria-describedby
prop.
popupId
(string
, optional but strongly encouraged)The id
for the popup component. It will be passed to the child props so that
the trigger component may declare the same id in an ARIA prop.
disableAutoFocus
(boolean
, optional)If true
, will not steal focus when the popup is opened. (And bindPopover
/bindMenu
) will inject disableAutoFocus
, disableEnforceFocus
, and disableRestoreFocus
).
usePopupState
return valueAn object with the following properties:
open([eventOrAnchorEl])
: opens the popup. You must pass in an anchor element or an event with a currentTarget
, otherwise the popup will not position properly and you will get a warning; Material-UI needs an anchor element to position the popup.close()
: closes the popuptoggle([eventOrAnchorEl])
: opens the popup if it is closed, or closes the popup if it is open. If the popup is currently closed, you must pass an anchor element or an event with a currentTarget
, otherwise the popup will not position properly and you will get a warning; Material-UI needs an anchor element to position the popup.setOpen(open, [eventOrAnchorEl])
: sets whether the popup is open. If open
is truthy, you must pass in an anchor element or an event with a currentTarget
, otherwise the popup will not position properly and you will get a warning; Material-UI needs an anchor element to position the popup.isOpen
: true
/false
if the popup is open/closedanchorEl
: the current anchor elementsetAnchorEl
: sets the anchor element (the currentTarget
of the triggering
mouse event is used by default unless you have called setAnchorEl
)popupId
: the popupId
prop you passed to PopupState
variant
: the variant
prop you passed to PopupState
import * as React from 'react'
import Button from '@material-ui/core/Button'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import PopupState, { bindTrigger, bindMenu } from 'material-ui-popup-state'
const MenuPopupState = () => (
<PopupState variant="popover" popupId="demoMenu">
{popupState => (
<React.Fragment>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Menu
</Button>
<Menu {...bindMenu(popupState)}>
<MenuItem onClick={popupState.close}>Cake</MenuItem>
<MenuItem onClick={popupState.close}>Death</MenuItem>
</Menu>
</React.Fragment>
)}
}
</PopupState>
)
export default MenuPopupState
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import Popover from '@material-ui/core/Popover'
import PopupState, { bindTrigger, bindPopover } from 'material-ui-popup-state'
const styles = theme => ({
typography: {
margin: theme.spacing.unit * 2,
},
})
const PopoverPopupState = ({ classes }) => (
<PopupState variant="popover" popupId="demoPopover">
{popupState => (
<div>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Popover
</Button>
<Popover
{...bindPopover(popupState)}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
>
<Typography className={classes.typography}>
The content of the Popover.
</Typography>
</Popover>
</div>
)}
</PopupState>
)
PopoverPopupState.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(PopoverPopupState)
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import Popover from '@material-ui/core/Popover'
import PopupState, { bindHover, bindPopover } from 'material-ui-popup-state'
const styles = theme => ({
popover: {
pointerEvents: 'none',
},
paper: {
padding: theme.spacing.unit,
},
})
const HoverPopoverPopupState = ({ classes }) => (
<PopupState variant="popover" popupId="demoPopover">
{popupState => (
<div>
<Typography {...bindHover(popupState)}>
Hover with a Popover.
</Typography>
<Popover
{...bindPopover(popupState)}
className={classes.popover}
classes={{
paper: classes.paper,
}}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'center',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'center',
}}
disableRestoreFocus
>
<Typography>The content of the Popover.</Typography>
</Popover>
</div>
)}
</PopupState>
)
HoverPopoverPopupState.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(HoverPopoverPopupState)
import React from 'react'
import PropTypes from 'prop-types'
import { withStyles } from '@material-ui/core/styles'
import Typography from '@material-ui/core/Typography'
import Button from '@material-ui/core/Button'
import Popper from '@material-ui/core/Popper'
import PopupState, { bindToggle, bindPopper } from 'material-ui-popup-state'
import Fade from '@material-ui/core/Fade'
import Paper from '@material-ui/core/Paper'
const styles = theme => ({
typography: {
padding: theme.spacing.unit * 2,
},
})
const PopperPopupState = ({ classes }) => (
<PopupState variant="popper" popupId="demoPopper">
{popupState => (
<div>
<Button variant="contained" {...bindToggle(popupState)}>
Toggle Popper
</Button>
<Popper {...bindPopper(popupState)} transition>
{({ TransitionProps }) => (
<Fade {...TransitionProps} timeout={350}>
<Paper>
<Typography className={classes.typography}>
The content of the Popper.
</Typography>
</Paper>
</Fade>
)}
</Popper>
</div>
)}
</PopupState>
)
PopperPopupState.propTypes = {
classes: PropTypes.object.isRequired,
}
export default withStyles(styles)(PopperPopupState)
material-ui-popup-state
exports several helper functions you can use to
connect components easily:
anchorRef
: creates a ref
function to pass to the anchorEl
(by default, the currentTarget
of the mouse event that triggered the popup
is used; only use anchorRef
if you want a different element to be the anchor).bindMenu
: creates props to control a Menu
component.bindPopover
: creates props to control a Popover
component.bindPopper
: creates props to control a Popper
component.bindTrigger
: creates props for a component that opens the popup when clicked.bindToggle
: creates props for a component that toggles the popup when clicked.bindHover
: creates props for a component that opens the popup while hovered.bindFocus
: creates props for a component that opens the popup while hovered.To use one of these functions, you should call it with the props PopupState
passed to your child function, and spread the return value into the desired
element:
import * as React from 'react'
import Button from '@material-ui/core/Button'
import Menu from '@material-ui/core/Menu'
import MenuItem from '@material-ui/core/MenuItem'
import PopupState, { bindTrigger, bindMenu } from 'material-ui-popup-state'
const MenuPopupState = () => (
<PopupState variant="popover" popupId="demoMenu">
{popupState => (
<React.Fragment>
<Button variant="contained" {...bindTrigger(popupState)}>
Open Menu
</Button>
<Menu {...bindMenu(popupState)}>
<MenuItem onClick={popupState.close}>Cake</MenuItem>
<MenuItem onClick={popupState.close}>Death</MenuItem>
</Menu>
</React.Fragment>
)}
</PopupState>
)
export default MenuPopupState
PopupState
Propsvariant
('popover'
or 'popper'
, required)Use 'popover'
if your popup is a Popover
or Menu
; use 'popper'
if your
popup is a Popper
.
Right now this only affects whether bindTrigger
/bindToggle
/bindHover
return
an aria-controls
prop or an aria-describedby
prop.
popupId
(string
, optional but strongly encouraged)The id
for the popup component. It will be passed to the child props so that
the trigger component may declare the same id in an ARIA prop.
disableAutoFocus
(boolean
, optional)If true
, will not steal focus when the popup is opened. (And bindPopover
/bindMenu
) will inject disableAutoFocus
, disableEnforceFocus
, and disableRestoreFocus
).
children
((popupState: InjectedProps) => ?React.Node
, required)The render function. It will be called with an object containing the following
props (exported as the InjectedProps
type):
open([eventOrAnchorEl])
: opens the popupclose()
: closes the popuptoggle([eventOrAnchorEl])
: opens the popup if it is closed, or closes the popup if it is open.setOpen(open, [eventOrAnchorEl])
: sets whether the popup is open.isOpen
: true
/false
if the popup is open/closedanchorEl
: the current anchor elementsetAnchorEl
: sets the anchor element (the currentTarget
of the triggering
mouse event is used by default unless you have called setAnchorEl
)popupId
: the popupId
prop you passed to PopupState
variant
: the variant
prop you passed to PopupState
FAQs
easiest way to create menus, popovers, and poppers with material-ui
The npm package material-ui-popup-state receives a total of 188,138 weekly downloads. As such, material-ui-popup-state popularity was classified as popular.
We found that material-ui-popup-state demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
NIST has failed to meet its self-imposed deadline of clearing the NVD's backlog by the end of the fiscal year. Meanwhile, CVE's awaiting analysis have increased by 33% since June.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.