Package Exports
- material-ui-popup-state
- material-ui-popup-state/hooks
- material-ui-popup-state/index
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (material-ui-popup-state) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
material-ui-popup-state
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.
Table of Contents
Installation
npm install --save material-ui-popup-state
Examples with React Hooks
Menu
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
Popover
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)
Popper
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)
React Hooks API
Bind Functions
material-ui-popup-state/hooks
exports several helper functions you can use to
connect components easily:
anchorRef
: creates aref
function to pass to theanchorEl
(by default, thecurrentTarget
of the mouse event that triggered the popup is used; only useanchorRef
if you want a different element to be the anchor).bindMenu
: creates props to control aMenu
component.bindPopover
: creates props to control aPopover
component.bindPopper
: creates props to control aPopper
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.
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
Props
variant
('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.
usePopupState
return value
An object with the following properties:
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 (thecurrentTarget
of the triggering mouse event is used by default unless you have calledsetAnchorEl
)popupId
: thepopupId
prop you passed toPopupState
variant
: thevariant
prop you passed toPopupState
Examples with Render Props
Menu
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
Popover
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)
Mouse Over Interaction
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)
Popper
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)
Render Props API
Bind Functions
material-ui-popup-state
exports several helper functions you can use to
connect components easily:
anchorRef
: creates aref
function to pass to theanchorEl
(by default, thecurrentTarget
of the mouse event that triggered the popup is used; only useanchorRef
if you want a different element to be the anchor).bindMenu
: creates props to control aMenu
component.bindPopover
: creates props to control aPopover
component.bindPopper
: creates props to control aPopper
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.
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
Props
variant
('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.
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 (thecurrentTarget
of the triggering mouse event is used by default unless you have calledsetAnchorEl
)popupId
: thepopupId
prop you passed toPopupState
variant
: thevariant
prop you passed toPopupState