{"id":22382482,"url":"https://github.com/jcoreio/material-ui-popup-state","last_synced_at":"2026-04-11T00:22:05.932Z","repository":{"id":32826996,"uuid":"143743032","full_name":"jcoreio/material-ui-popup-state","owner":"jcoreio","description":"boilerplate for common Material-UI Menu, Popover and Popper use cases","archived":false,"fork":false,"pushed_at":"2025-04-01T23:05:25.000Z","size":5344,"stargazers_count":458,"open_issues_count":18,"forks_count":31,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-03T20:06:25.219Z","etag":null,"topics":["boilerplate","material-ui","menu","popover","popper","popup","render-props"],"latest_commit_sha":null,"homepage":"https://jcoreio.github.io/material-ui-popup-state/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jcoreio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-08-06T14:50:07.000Z","updated_at":"2025-04-01T23:05:29.000Z","dependencies_parsed_at":"2023-01-14T22:21:45.062Z","dependency_job_id":"9e602751-27aa-424f-9856-62fb47d51d59","html_url":"https://github.com/jcoreio/material-ui-popup-state","commit_stats":{"total_commits":435,"total_committers":10,"mean_commits":43.5,"dds":"0.19310344827586212","last_synced_commit":"51a2a4ddd240642716be14ebf15496c610c01dcf"},"previous_names":[],"tags_count":64,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcoreio%2Fmaterial-ui-popup-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcoreio%2Fmaterial-ui-popup-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcoreio%2Fmaterial-ui-popup-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcoreio%2Fmaterial-ui-popup-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcoreio","download_url":"https://codeload.github.com/jcoreio/material-ui-popup-state/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248337227,"owners_count":21086980,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boilerplate","material-ui","menu","popover","popper","popup","render-props"],"created_at":"2024-12-05T00:13:12.914Z","updated_at":"2026-04-11T00:22:05.881Z","avatar_url":"https://github.com/jcoreio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# material-ui-popup-state\n\n[![CircleCI](https://circleci.com/gh/jcoreio/material-ui-popup-state.svg?style=svg)](https://circleci.com/gh/jcoreio/material-ui-popup-state)\n[![Coverage Status](https://codecov.io/gh/jcoreio/material-ui-popup-state/branch/master/graph/badge.svg)](https://codecov.io/gh/jcoreio/material-ui-popup-state)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n[![npm version](https://badge.fury.io/js/material-ui-popup-state.svg)](https://badge.fury.io/js/material-ui-popup-state)\n\nTakes care of the boilerplate for common Menu, Popover and Popper use cases.\n\nProvides a [Custom React Hook](https://reactjs.org/docs/hooks-custom.html) that keeps track of the local state for a single popup, and functions to connect trigger, toggle, and\npopover/menu/popper components to the state.\n\nAlso provides a [Render Props Component](https://reactjs.org/docs/render-props.html) that\nkeeps track of the local state for a single popup, and passes the state and\nmutation functions to a child render function.\n\n# Requirements\n\nRequires MUI \u003e= 5.0.0 and React \u003e= 16.8.0.\nFor MUI v4 you'll need `material-ui-popup-state@^1.9.3`.\n\n# Table of Contents\n\n\u003c!-- toc --\u003e\n\n- [material-ui-popup-state](#material-ui-popup-state)\n- [Requirements](#requirements)\n- [Table of Contents](#table-of-contents)\n- [Installation](#installation)\n- [Examples with React Hooks](#examples-with-react-hooks)\n  - [Menu](#menu)\n  - [Popover](#popover)\n  - [Popper](#popper)\n- [React Hooks API](#react-hooks-api)\n  - [Bind Functions](#bind-functions)\n  - [`usePopupState`](#usepopupstate)\n  - [`usePopupState` Props](#usepopupstate-props)\n    - [`variant` (`'popover'`, `'popper'`, or `'dialog'`, **required**)](#variant-popover-popper-or-dialog-required)\n    - [`popupId` (`string`, **optional**)](#popupid-string-optional)\n    - [`disableAutoFocus` (`boolean`, **optional**)](#disableautofocus-boolean-optional)\n  - [`usePopupState` return value](#usepopupstate-return-value)\n- [Examples with Render Props](#examples-with-render-props)\n  - [Menu](#menu-1)\n  - [Popover](#popover-1)\n  - [Mouse Over Interaction](#mouse-over-interaction)\n  - [Popper](#popper-1)\n- [Render Props API](#render-props-api)\n  - [Bind Functions](#bind-functions-1)\n  - [`PopupState` Props](#popupstate-props)\n    - [`variant` (`'popover'`, `'popper'`, or `'dialog'`, **required**)](#variant-popover-popper-or-dialog-required-1)\n    - [`popupId` (`string`, **optional**)](#popupid-string-optional)\n    - [`disableAutoFocus` (`boolean`, **optional**)](#disableautofocus-boolean-optional-1)\n    - [`children` (`(popupState: InjectedProps) =\u003e ?React.Node`, **required**)](#children-popupstate-injectedprops--reactnode-required)\n- [Using `Popover` and `Menu` with `bindHover`](#using-popover-and-menu-with-bindhover)\n- [Chaining event handlers](#chaining-event-handlers)\n  - [Chaining event handlers manually](#chaining-event-handlers-manually)\n  - [Using `material-ui-popup-state/chainEventHandlers`](#using-material-ui-popup-statechaineventhandlers)\n\n\u003c!-- tocstop --\u003e\n\n# Installation\n\n```sh\nnpm install --save material-ui-popup-state\n```\n\n# Examples with React Hooks\n\n## Menu\n\n```js\nimport * as React from 'react'\nimport Button from '@mui/material/Button'\nimport Menu from '@mui/material/Menu'\nimport MenuItem from '@mui/material/MenuItem'\nimport {\n  usePopupState,\n  bindTrigger,\n  bindMenu,\n} from 'material-ui-popup-state/hooks'\n\nconst MenuPopupState = () =\u003e {\n  const popupState = usePopupState({ variant: 'popover', popupId: 'demoMenu' })\n  return (\n    \u003cdiv\u003e\n      \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n        Open Menu\n      \u003c/Button\u003e\n      \u003cMenu {...bindMenu(popupState)}\u003e\n        \u003cMenuItem onClick={popupState.close}\u003eCake\u003c/MenuItem\u003e\n        \u003cMenuItem onClick={popupState.close}\u003eDeath\u003c/MenuItem\u003e\n      \u003c/Menu\u003e\n    \u003c/div\u003e\n  )\n}\n\nexport default MenuPopupState\n```\n\n## Popover\n\n```js\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { withStyles } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport Button from '@mui/material/Button'\nimport Popover from '@mui/material/Popover'\nimport {\n  usePopupState,\n  bindTrigger,\n  bindPopover,\n} from 'material-ui-popup-state/hooks'\n\nconst styles = (theme) =\u003e ({\n  typography: {\n    margin: theme.spacing.unit * 2,\n  },\n})\n\nconst PopoverPopupState = ({ classes }) =\u003e {\n  const popupState = usePopupState({\n    variant: 'popover',\n    popupId: 'demoPopover',\n  })\n  return (\n    \u003cdiv\u003e\n      \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n        Open Popover\n      \u003c/Button\u003e\n      \u003cPopover\n        {...bindPopover(popupState)}\n        anchorOrigin={{\n          vertical: 'bottom',\n          horizontal: 'center',\n        }}\n        transformOrigin={{\n          vertical: 'top',\n          horizontal: 'center',\n        }}\n      \u003e\n        \u003cTypography className={classes.typography}\u003e\n          The content of the Popover.\n        \u003c/Typography\u003e\n      \u003c/Popover\u003e\n    \u003c/div\u003e\n  )\n}\n\nPopoverPopupState.propTypes = {\n  classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(PopoverPopupState)\n```\n\n## Popper\n\n```js\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { withStyles } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport Button from '@mui/material/Button'\nimport Popper from '@mui/material/Popper'\nimport {\n  usePopupState,\n  bindToggle,\n  bindPopper,\n} from 'material-ui-popup-state/hooks'\nimport Fade from '@mui/material/Fade'\nimport Paper from '@mui/material/Paper'\n\nconst styles = (theme) =\u003e ({\n  typography: {\n    padding: theme.spacing.unit * 2,\n  },\n})\n\nconst PopperPopupState = ({ classes }) =\u003e {\n  const popupState = usePopupState({ variant: 'popper', popupId: 'demoPopper' })\n  return (\n    \u003cdiv\u003e\n      \u003cButton variant=\"contained\" {...bindToggle(popupState)}\u003e\n        Toggle Popper\n      \u003c/Button\u003e\n      \u003cPopper {...bindPopper(popupState)} transition\u003e\n        {({ TransitionProps }) =\u003e (\n          \u003cFade {...TransitionProps} timeout={350}\u003e\n            \u003cPaper\u003e\n              \u003cTypography className={classes.typography}\u003e\n                The content of the Popper.\n              \u003c/Typography\u003e\n            \u003c/Paper\u003e\n          \u003c/Fade\u003e\n        )}\n      \u003c/Popper\u003e\n    \u003c/div\u003e\n  )\n}\n\nPopperPopupState.propTypes = {\n  classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(PopperPopupState)\n```\n\n# React Hooks API\n\n## Bind Functions\n\n`material-ui-popup-state/hooks` exports several helper functions you can use to\nconnect components easily:\n\n- `anchorRef`: creates a `ref` function to pass to the `anchorEl`\n  (by default, the `currentTarget` of the mouse event that triggered the popup\n  is used; only use `anchorRef` if you want a different element to be the anchor).\n- `bindMenu`: creates props to control a `Menu` component.\n- `bindPopover`: creates props to control a `Popover` component.\n- `bindPopper`: creates props to control a `Popper` component.\n- `bindDialog`: creates props to control a `Dialog` component.\n- `bindTrigger`: creates props for a component that opens the popup when clicked.\n- `bindContextMenu`: creates props for a component that opens the popup on when right clicked (`contextmenu` event).\n  **NOTE**: `bindPopover`/`bindMenu` will position the Popover/Menu to the `contextmenu` event location. To position\n  using the `contextmenu` target element instead, pass `anchorReference=\"anchorEl\"` after `{...bindPopover(popupState)}`/`{...bindMenu(popupState)}`.\n- `bindToggle`: creates props for a component that toggles the popup when clicked.\n- `bindHover`: creates props for a component that opens the popup while hovered.\n  **NOTE**: See [this guidance](#using-popover-and-menu-with-bindhover) if you are using `bindHover` with `Popover` or `Menu`.\n- `bindFocus`: creates props for a component that opens the popup while focus.\n- `bindDoubleClick`: creates props for a component that opens the popup while double click.\n\nTo use one of these functions, you should call it with the object\nreturned by `usePopupState` and spread the return value into the desired\nelement:\n\n```js\nimport * as React from 'react'\nimport Button from '@mui/material/Button'\nimport Menu from '@mui/material/Menu'\nimport MenuItem from '@mui/material/MenuItem'\nimport {\n  usePopupState,\n  bindTrigger,\n  bindMenu,\n} from 'material-ui-popup-state/hooks'\n\nconst MenuPopupState = () =\u003e {\n  const popupState = usePopupState({ variant: 'popover', popupId: 'demoMenu' })\n  return (\n    \u003cdiv\u003e\n      \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n        Open Menu\n      \u003c/Button\u003e\n      \u003cMenu {...bindMenu(popupState)}\u003e\n        \u003cMenuItem onClick={popupState.close}\u003eCake\u003c/MenuItem\u003e\n        \u003cMenuItem onClick={popupState.close}\u003eDeath\u003c/MenuItem\u003e\n      \u003c/Menu\u003e\n    \u003c/div\u003e\n  )\n}\n\nexport default MenuPopupState\n```\n\n## `usePopupState`\n\nThis is a [Custom Hook](https://reactjs.org/docs/hooks-custom.html) that uses `useState` internally, therefore the [Rules of Hooks](https://reactjs.org/docs/hooks-rules.html) apply to `usePopupState`.\n\n## `usePopupState` Props\n\n### `variant` (`'popover'`, `'popper'`, or `'dialog'`, **required**)\n\nUse `'popover'` if your popup is a `Popover` or `Menu`; use `'popper'` if your\npopup is a `Popper`.\n\nRight now this only affects whether `bindTrigger`/`bindToggle`/`bindHover` return\nan `aria-controls` prop or an `aria-describedby` prop.\n\n### `popupId` (`string`, **optional**)\n\nThe `id` for the popup component. It will be passed to the child props so that\nthe trigger component may declare the same id in an ARIA prop.\n\nDefaults to `React.useId()` if `React.useId` exists; in older versions of React\nyou will have to manually provide a `popupId`.\n\n### `disableAutoFocus` (`boolean`, **optional**)\n\nIf `true`, will not steal focus when the popup is opened. (And `bindPopover`/`bindMenu` will inject `disableAutoFocus`, `disableEnforceFocus`, and `disableRestoreFocus`).\n\nDefaults to `true` when the popup is opened by the `bindHover` or `bindFocus` element.\n\n## `usePopupState` return value\n\nAn object with the following properties:\n\n- `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; MUI needs an anchor element to position the popup.\n- `close()`: closes the popup\n- `toggle([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; MUI needs an anchor element to position the popup.\n- `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; MUI needs an anchor element to position the popup.\n- `isOpen`: `true`/`false` if the popup is open/closed\n- `anchorEl`: the current anchor element\n- `anchorPosition`: the current anchor position\n- `setAnchorEl`: sets the anchor element (the `currentTarget` of the triggering\n  mouse event is used by default unless you have called `setAnchorEl`)\n- `popupId`: the `popupId` prop you passed to `PopupState`\n- `variant`: the `variant` prop you passed to `PopupState`\n\n# Examples with Render Props\n\n## Menu\n\n```js\nimport * as React from 'react'\nimport Button from '@mui/material/Button'\nimport Menu from '@mui/material/Menu'\nimport MenuItem from '@mui/material/MenuItem'\nimport PopupState, { bindTrigger, bindMenu } from 'material-ui-popup-state'\n\nconst MenuPopupState = () =\u003e (\n  \u003cPopupState variant=\"popover\" popupId=\"demoMenu\"\u003e\n    {(popupState) =\u003e (\n      \u003cReact.Fragment\u003e\n        \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n          Open Menu\n        \u003c/Button\u003e\n        \u003cMenu {...bindMenu(popupState)}\u003e\n          \u003cMenuItem onClick={popupState.close}\u003eCake\u003c/MenuItem\u003e\n          \u003cMenuItem onClick={popupState.close}\u003eDeath\u003c/MenuItem\u003e\n        \u003c/Menu\u003e\n      \u003c/React.Fragment\u003e\n    )}\n  \u003c/PopupState\u003e\n)\n\nexport default MenuPopupState\n```\n\n## Popover\n\n```js\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { withStyles } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport Button from '@mui/material/Button'\nimport Popover from '@mui/material/Popover'\nimport PopupState, { bindTrigger, bindPopover } from 'material-ui-popup-state'\n\nconst styles = (theme) =\u003e ({\n  typography: {\n    margin: theme.spacing.unit * 2,\n  },\n})\n\nconst PopoverPopupState = ({ classes }) =\u003e (\n  \u003cPopupState variant=\"popover\" popupId=\"demoPopover\"\u003e\n    {(popupState) =\u003e (\n      \u003cdiv\u003e\n        \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n          Open Popover\n        \u003c/Button\u003e\n        \u003cPopover\n          {...bindPopover(popupState)}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        \u003e\n          \u003cTypography className={classes.typography}\u003e\n            The content of the Popover.\n          \u003c/Typography\u003e\n        \u003c/Popover\u003e\n      \u003c/div\u003e\n    )}\n  \u003c/PopupState\u003e\n)\n\nPopoverPopupState.propTypes = {\n  classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(PopoverPopupState)\n```\n\n## Mouse Over Interaction\n\n```js\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { withStyles } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport HoverPopover from 'material-ui-popup-state/HoverPopover'\nimport PopupState, { bindHover, bindPopover } from 'material-ui-popup-state'\n\nconst styles = (theme) =\u003e ({\n  popover: {\n    pointerEvents: 'none',\n  },\n  paper: {\n    padding: theme.spacing.unit,\n  },\n})\n\nconst HoverPopoverPopupState = ({ classes }) =\u003e (\n  \u003cPopupState variant=\"popover\" popupId=\"demoPopover\"\u003e\n    {(popupState) =\u003e (\n      \u003cdiv\u003e\n        \u003cTypography {...bindHover(popupState)}\u003e\n          Hover with a Popover.\n        \u003c/Typography\u003e\n        \u003cHoverPopover\n          {...bindPopover(popupState)}\n          className={classes.popover}\n          classes={{\n            paper: classes.paper,\n          }}\n          anchorOrigin={{\n            vertical: 'bottom',\n            horizontal: 'center',\n          }}\n          transformOrigin={{\n            vertical: 'top',\n            horizontal: 'center',\n          }}\n        \u003e\n          \u003cTypography\u003eThe content of the Popover.\u003c/Typography\u003e\n        \u003c/HoverPopover\u003e\n      \u003c/div\u003e\n    )}\n  \u003c/PopupState\u003e\n)\n\nHoverPopoverPopupState.propTypes = {\n  classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(HoverPopoverPopupState)\n```\n\n## Popper\n\n```js\nimport React from 'react'\nimport PropTypes from 'prop-types'\nimport { withStyles } from '@mui/material/styles'\nimport Typography from '@mui/material/Typography'\nimport Button from '@mui/material/Button'\nimport Popper from '@mui/material/Popper'\nimport PopupState, { bindToggle, bindPopper } from 'material-ui-popup-state'\nimport Fade from '@mui/material/Fade'\nimport Paper from '@mui/material/Paper'\n\nconst styles = (theme) =\u003e ({\n  typography: {\n    padding: theme.spacing.unit * 2,\n  },\n})\n\nconst PopperPopupState = ({ classes }) =\u003e (\n  \u003cPopupState variant=\"popper\" popupId=\"demoPopper\"\u003e\n    {(popupState) =\u003e (\n      \u003cdiv\u003e\n        \u003cButton variant=\"contained\" {...bindToggle(popupState)}\u003e\n          Toggle Popper\n        \u003c/Button\u003e\n        \u003cPopper {...bindPopper(popupState)} transition\u003e\n          {({ TransitionProps }) =\u003e (\n            \u003cFade {...TransitionProps} timeout={350}\u003e\n              \u003cPaper\u003e\n                \u003cTypography className={classes.typography}\u003e\n                  The content of the Popper.\n                \u003c/Typography\u003e\n              \u003c/Paper\u003e\n            \u003c/Fade\u003e\n          )}\n        \u003c/Popper\u003e\n      \u003c/div\u003e\n    )}\n  \u003c/PopupState\u003e\n)\n\nPopperPopupState.propTypes = {\n  classes: PropTypes.object.isRequired,\n}\n\nexport default withStyles(styles)(PopperPopupState)\n```\n\n# Render Props API\n\n## Bind Functions\n\n`material-ui-popup-state` exports several helper functions you can use to\nconnect components easily:\n\n- `anchorRef`: creates a `ref` function to pass to the `anchorEl`\n  (by default, the `currentTarget` of the mouse event that triggered the popup\n  is used; only use `anchorRef` if you want a different element to be the anchor).\n- `bindMenu`: creates props to control a `Menu` component.\n- `bindPopover`: creates props to control a `Popover` component.\n- `bindPopper`: creates props to control a `Popper` component.\n- `bindDialog`: creates props to control a `Dialog` component.\n- `bindTrigger`: creates props for a component that opens the popup when clicked.\n- `bindContextMenu`: creates props for a component that opens the popup on when right clicked (`contextmenu` event).\n  **NOTE**: `bindPopover`/`bindMenu` will position the Popover/Menu to the `contextmenu` event location. To position\n  using the `contextmenu` target element instead, pass `anchorReference=\"anchorEl\"` after `{...bindPopover(popupState)}`/`{...bindMenu(popupState)}`.\n- `bindToggle`: creates props for a component that toggles the popup when clicked.\n- `bindHover`: creates props for a component that opens the popup while hovered.\n  **NOTE**: See [this guidance](#using-popover-and-menu-with-bindhover) if you are using `bindHover` with `Popover` or `Menu`.\n- `bindFocus`: creates props for a component that opens the popup while hovered.\n\nTo use one of these functions, you should call it with the props `PopupState`\npassed to your child function, and spread the return value into the desired\nelement:\n\n```js\nimport * as React from 'react'\nimport Button from '@mui/material/Button'\nimport Menu from '@mui/material/Menu'\nimport MenuItem from '@mui/material/MenuItem'\nimport PopupState, { bindTrigger, bindMenu } from 'material-ui-popup-state'\n\nconst MenuPopupState = () =\u003e (\n  \u003cPopupState variant=\"popover\" popupId=\"demoMenu\"\u003e\n    {(popupState) =\u003e (\n      \u003cReact.Fragment\u003e\n        \u003cButton variant=\"contained\" {...bindTrigger(popupState)}\u003e\n          Open Menu\n        \u003c/Button\u003e\n        \u003cMenu {...bindMenu(popupState)}\u003e\n          \u003cMenuItem onClick={popupState.close}\u003eCake\u003c/MenuItem\u003e\n          \u003cMenuItem onClick={popupState.close}\u003eDeath\u003c/MenuItem\u003e\n        \u003c/Menu\u003e\n      \u003c/React.Fragment\u003e\n    )}\n  \u003c/PopupState\u003e\n)\n\nexport default MenuPopupState\n```\n\n## `PopupState` Props\n\n### `variant` (`'popover'`, `'popper'`, or `'dialog'`, **required**)\n\nUse `'popover'` if your popup is a `Popover` or `Menu`; use `'popper'` if your\npopup is a `Popper`.\n\nRight now this only affects whether `bindTrigger`/`bindToggle`/`bindHover` return\nan `aria-controls` prop or an `aria-describedby` prop.\n\n### `popupId` (`string`, **optional**)\n\nThe `id` for the popup component. It will be passed to the child props so that\nthe trigger component may declare the same id in an ARIA prop.\n\nDefaults to `React.useId()` if `React.useId` exists; in older versions of React\nyou will have to manually provide a `popupId`.\n\n### `disableAutoFocus` (`boolean`, **optional**)\n\nIf `true`, will not steal focus when the popup is opened. (And `bindPopover`/`bindMenu` will inject `disableAutoFocus`, `disableEnforceFocus`, and `disableRestoreFocus`).\n\nDefaults to `true` when the popup is opened by the `bindHover` or `bindFocus` element.\n\n### `children` (`(popupState: InjectedProps) =\u003e ?React.Node`, **required**)\n\nThe render function. It will be called with an object containing the following\nprops (exported as the `InjectedProps` type):\n\n- `open([eventOrAnchorEl])`: opens the popup\n- `close()`: closes the popup\n- `toggle([eventOrAnchorEl])`: opens the popup if it is closed, or closes the popup if it is open.\n- `setOpen(open, [eventOrAnchorEl])`: sets whether the popup is open.\n- `isOpen`: `true`/`false` if the popup is open/closed\n- `anchorEl`: the current anchor element\n- `anchorPosition`: the current anchor position\n- `setAnchorEl`: sets the anchor element (the `currentTarget` of the triggering\n  mouse event is used by default unless you have called `setAnchorEl`)\n- `popupId`: the `popupId` prop you passed to `PopupState`\n- `variant`: the `variant` prop you passed to `PopupState`\n\n# Using `Popover` and `Menu` with `bindHover`\n\nMUI's `Modal` (used by `Popover` and `Menu`) blocks pointer events to all other components, interfering with `bindHover`\n(the popover or menu will open when the mouse enters the `bindHover` element, but won't close when the mouse leaves). You can\nuse the following components to work around this:\n\n```js\nimport HoverMenu from 'material-ui-popup-state/HoverMenu'\nimport HoverPopover from 'material-ui-popup-state/HoverPopover'\n```\n\nThese are just wrapper components that pass inline styles to prevent `Modal` from blocking pointer events.\n\n# Chaining event handlers\n\nWhat if you need to perform additional actions in `onClick`, but it's being injected by `{...bindTrigger(popupState)}` etc?\n\nThere are two options:\n\n## Chaining event handlers manually\n\nThis is the most straightforward, explicit option.\n\n```tsx\nconst button = (\n  \u003cButton\n    {...bindTrigger(popupState)}\n    onClick={(e: React.MouseEvent) =\u003e {\n      bindTrigger(popupState).onClick(e)\n      performCustomAction(e)\n    }}\n  \u003e\n    Open Menu\n  \u003c/Button\u003e\n)\n```\n\n## Using `material-ui-popup-state/chainEventHandlers`\n\nIf you don't like the above option, you can use the provided `material-ui-popup-state/chainEventHandlers` helper:\n\n```tsx\nimport { chainEventHandlers } from 'material-ui-popup-state/chainEventHandlers'\n\nconst button = (\n  \u003cButton\n    {...chainEventHandlers(bindTrigger(popupState), {\n      onClick: (e: React.MouseEvent) =\u003e {\n        bindTrigger(popupState).onClick(e)\n        performCustomAction(e)\n      },\n    })}\n  \u003e\n    Open Menu\n  \u003c/Button\u003e\n)\n```\n\n`chainEventHandlers` accepts a variable number of props arguments and combines any function props of the same name\ninto a function that invokes the chained functions in sequence. For all other properties the behavior is like\n`Object.assign`.\n\n\u003e [!WARNING]  \n\u003e `chainEventHandlers` doesn't memoize the combined event handler functions, so they will cause components to\n\u003e rerender. If you need memoized functions, you will need to perform the memoization with your own code, for example\n\u003e using `React.useCallback` and [chaining event handlers manually](#chaining-event-handlers-manually).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcoreio%2Fmaterial-ui-popup-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcoreio%2Fmaterial-ui-popup-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcoreio%2Fmaterial-ui-popup-state/lists"}