{"id":20698956,"url":"https://github.com/doomsower/react-native-modal-popover","last_synced_at":"2025-05-16T18:06:44.108Z","repository":{"id":22008623,"uuid":"94686578","full_name":"doomsower/react-native-modal-popover","owner":"doomsower","description":"React-Native pure JS popover that uses Modal","archived":false,"fork":false,"pushed_at":"2023-03-04T03:28:00.000Z","size":10762,"stargazers_count":322,"open_issues_count":25,"forks_count":45,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-08T20:58:13.645Z","etag":null,"topics":["modal","popover","react-native"],"latest_commit_sha":null,"homepage":null,"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/doomsower.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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":"2017-06-18T12:44:10.000Z","updated_at":"2025-03-28T18:47:33.000Z","dependencies_parsed_at":"2024-06-18T13:42:07.574Z","dependency_job_id":"6e8b4ba5-022a-47e8-9e1d-4eb81ab950b0","html_url":"https://github.com/doomsower/react-native-modal-popover","commit_stats":{"total_commits":55,"total_committers":7,"mean_commits":7.857142857142857,"dds":0.2909090909090909,"last_synced_commit":"09c997df686b5bb15b2bea2936865eabce0bb5e5"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doomsower%2Freact-native-modal-popover","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doomsower%2Freact-native-modal-popover/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doomsower%2Freact-native-modal-popover/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/doomsower%2Freact-native-modal-popover/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/doomsower","download_url":"https://codeload.github.com/doomsower/react-native-modal-popover/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254264767,"owners_count":22041794,"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":["modal","popover","react-native"],"created_at":"2024-11-17T00:27:31.233Z","updated_at":"2025-05-16T18:06:44.090Z","avatar_url":"https://github.com/doomsower.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-native-modal-popover\n\nPure JS popover component for react-native\n\n![Android](https://raw.githubusercontent.com/doomsower/react-native-modal-popover/master/gifs/android.gif)\n![iOS](https://raw.githubusercontent.com/doomsower/react-native-modal-popover/master/gifs/ios.gif)\n\n## About this module\n\nThe original [react-native-popover](https://github.com/jeanregisser/react-native-popover) is now outdated,\nso I decided to publish my own module to avoid using github url in my package.json. Something got lost in\nthe process of rewriting, but now it uses `Modal` and native animation drivers, and also has cool helper\nto use with Touchables. Thanks to @jeanregisser and to the authors of hanging PRs for their code.\n\n## Requirements\n\nPreviously (version `0.0.6`) this module required react version `\u003e16.2.0` to work (which corresponds to react-native version `\u003e0.52.0`).\n\nVersion `0.0.7` does not reqire `React.Fragment` anymore, so you can use with reasonably old versions of react and react-native.\n\n## Install\n\n```sh\nyarn add react-native-modal-popover\n```\n\n## Usage\n\nThis module exports two react components, `Popover` and `PopoverController`, and one react hook, `usePopover`.\n`Popover` works pretty much like original `Popover`, and `PopoverController` is a convenience component that uses [React Render Props](https://github.com/jaredpalmer/awesome-react-render-props) pattern.\n\n**Important** this example uses `React.Fragment` to wrap children, but if you use `react-native` version older than `0.52`, then you should reaplce `React.Fragment` with `View`\n\n### Using hook\n\n`usePopover` is preferred modern way to have popover in your app.\n\n```jsx\nimport React from 'react';\nimport { Button, StyleSheet, Text, View } from 'react-native';\nimport { Popover, usePopover } from 'react-native-modal-popover';\n\nconst styles = StyleSheet.create({\n  app: {\n    ...StyleSheet.absoluteFillObject,\n    alignItems: 'center',\n    justifyContent: 'center',\n    backgroundColor: '#c2ffd2',\n  },\n  content: {\n    padding: 16,\n    backgroundColor: 'pink',\n    borderRadius: 8,\n  },\n  arrow: {\n    borderTopColor: 'pink',\n  },\n  background: {\n    backgroundColor: 'rgba(0, 0, 255, 0.5)',\n  },\n});\n\nconst App = () =\u003e {\n  const {\n    openPopover,\n    closePopover,\n    popoverVisible,\n    touchableRef,\n    popoverAnchorRect,\n  } = usePopover();\n  return (\n    \u003cView style={styles.app}\u003e\n      \u003cButton title=\"Press me!\" ref={touchableRef} onPress={openPopover} /\u003e\n      \u003cPopover\n        contentStyle={styles.content}\n        arrowStyle={styles.arrow}\n        backgroundStyle={styles.background}\n        visible={popoverVisible}\n        onClose={closePopover}\n        fromRect={popoverAnchorRect}\n        supportedOrientations={['portrait', 'landscape']}\u003e\n        \u003cText\u003eHello from inside popover!\u003c/Text\u003e\n      \u003c/Popover\u003e\n    \u003c/View\u003e\n  );\n};\n\nexport default App;\n```\n\n### Using PopoverController\n\nUse `PopoverController` if you cannot use hooks for some reason.\n\n```jsx\nimport React from 'react';\nimport { Button, StyleSheet, Text, View } from 'react-native';\nimport { Popover, PopoverController } from 'react-native-modal-popover';\n\nconst styles = StyleSheet.create({\n  app: {\n    ...StyleSheet.absoluteFillObject,\n    alignItems: 'center',\n    justifyContent: 'center',\n    backgroundColor: '#c2ffd2',\n  },\n  content: {\n    padding: 16,\n    backgroundColor: 'pink',\n    borderRadius: 8,\n  },\n  arrow: {\n    borderTopColor: 'pink',\n  },\n  background: {\n    backgroundColor: 'rgba(0, 0, 255, 0.5)',\n  },\n});\n\nconst App = () =\u003e (\n  \u003cView style={styles.app}\u003e\n    \u003cPopoverController\u003e\n      {({\n        openPopover,\n        closePopover,\n        popoverVisible,\n        setPopoverAnchor,\n        popoverAnchorRect,\n      }) =\u003e (\n        \u003cReact.Fragment\u003e\n          \u003cButton\n            title=\"Press me!\"\n            ref={setPopoverAnchor}\n            onPress={openPopover}\n          /\u003e\n          \u003cPopover\n            contentStyle={styles.content}\n            arrowStyle={styles.arrow}\n            backgroundStyle={styles.background}\n            visible={popoverVisible}\n            onClose={closePopover}\n            fromRect={popoverAnchorRect}\n            supportedOrientations={['portrait', 'landscape']}\u003e\n            \u003cText\u003eHello from inside popover!\u003c/Text\u003e\n          \u003c/Popover\u003e\n        \u003c/React.Fragment\u003e\n      )}\n    \u003c/PopoverController\u003e\n  \u003c/View\u003e\n);\n\nexport default App;\n```\n\n## Props\n\n### `Popover`\n\n| Prop                  | Type                                                                                                | Optional | Default                                                                     | Description                                                                                                                                                                                                                                           |\n| --------------------- | --------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| visible               | bool                                                                                                | Yes      | false                                                                       | Show/Hide the popover                                                                                                                                                                                                                                 |\n| fromRect              | Rect                                                                                                | No\\*     |                                                                             | Rectangle at which to anchor the popover. **Optional** when used inside `PopoverTouchable`, **required** when used standalone. If you set this property, you should also change it when screen orientation changes.                                   |\n| displayArea           | Rect                                                                                                | Yes      | Screen - 10px padding                                                       | Area where the popover is allowed to be displayed. **Important note:** if you use non-default value here and you want to handle screen orientation changes, it is your responsibility to change this value when screen orientation changes.           |\n| placement             | string                                                                                              | Yes      | 'auto'                                                                      | How to position the popover - top \u0026#124; bottom \u0026#124; start \u0026#124; end \u0026#124; auto. When 'auto' is specified, it will determine the ideal placement so that the popover is fully visible within `displayArea`.                                       |\n| onClose               | function                                                                                            | Yes      |                                                                             | Callback to be fired when the user closes the popover                                                                                                                                                                                                 |\n| onDismiss             | function                                                                                            | Yes      |                                                                             | Callback to be fired after the popup closes                                                                                                                                                                                                           |\n| backgroundStyle       | ViewStyle                                                                                           | Yes      |                                                                             | Custom style to be applied to background overlay                                                                                                                                                                                                      |\n| contentStyle          | ViewStyle                                                                                           | Yes      |                                                                             | Custom style to be applied to popover reactangle. Use it to set round corners, background color, etc.                                                                                                                                                 |\n| arrowStyle            | ViewStyle                                                                                           | Yes      |                                                                             | Custom style to be applied to popover arrow. Use `borderTopColor` to match content backgroundColor                                                                                                                                                    |\n| duration              | number                                                                                              | Yes      | 300                                                                         | Animation duration                                                                                                                                                                                                                                    |\n| easing                | (show: boolean) =\u003e (value: number) =\u003e number                                                        | Yes      | show =\u003e show ? Easing.out(Easing.back(1.70158)) : Easing.inOut(Easing.quad) | Function that returns easing function for show or hide animation, depending on `show` argument                                                                                                                                                        |\n| useNativeDriver       | bool                                                                                                | Yes      | false                                                                       | Defines if animations should use native driver                                                                                                                                                                                                        |\n| supportedOrientations | array of enum('portrait', 'portrait-upside-down', 'landscape', 'landscape-left', 'landscape-right') | Yes      |                                                                             | This prop is passed to react-native `Modal`, see [react-native docs](https://facebook.github.io/react-native/docs/modal.html#supportedorientations). Set this to `['portrait', 'landscape']` if you want your popover to resprect screen orientation. |\n| calculateStatusBar    | bool                                                                                                | Yes      | false                                                                       | Defines if while use status bar height while calculating \"Y\" origin of anchor.                                                                                                                                                                        |\n\n### `PopoverController` and `usePopover` hook\n\n`PopoverController` accepts function as children. This function is called with one argument of type `PopoverControllerRenderProps` and returns react element. The children of this element are your UI handle to open popover (`Button`, `Toggle`, whatever) and `Popover` element itself. Pass properties to you handle and `Popover`, and `PopoverController` will make them work together behind the scenes. All the props are required to make controller work.\n\n`usePopover` returns object with same props as `PopoverControllerRenderProps`, except that ref has different name: `touchableRef`.\n\n#### `PopoverControllerRenderProps`:\n\n| Prop                                                                 | Type         | Description                                                                                                                                                                                                                                                          |\n| -------------------------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| openPopover                                                          | () =\u003e void   | Call this function when you want to open popover, e.g. pass to `onPress` of a `Button`                                                                                                                                                                               |\n| closePopover                                                         | () =\u003e void   | Call this function when you want to close popover. Typically you pass this as `onClose` prop of `Popover`, which will make popover close when tapped outside. If you have a button inside popover which should close the popover, pass this function to this button. |\n| popoverVisible                                                       | boolean      | Pass this to `visible` prop of `Popover` component                                                                                                                                                                                                                   |\n| setPopoverAnchor (`PopoverController`) / touchableRef (`usePopover`) | ref function | Pass this as `ref` to popover UI handle. This will bind popover display position to the position of this UI handle.                                                                                                                                                  |\n| popoverAnchorRect                                                    | Rect         | Pass this as `fromRect` prop of `Popover` component                                                                                                                                                                                                                  |\n\n### `Rect`\n\nRect is an object with the following properties: `{x: number, y: number, width: number, height: number}`\n\n## Using without `PopoverController`\n\nIn this case you have to handle refs, measure UI handle and manage popover visibility manually:\n\n```jsx\nimport React from 'react';\nimport {\n  findNodeHandle,\n  NativeModules,\n  StyleSheet,\n  Text,\n  View,\n} from 'react-native';\nimport Button from './Button';\nimport Popover from './popover';\n\nconst styles = StyleSheet.create({\n  app: {\n    ...StyleSheet.absoluteFillObject,\n    padding: 10,\n    backgroundColor: '#c2ffd2',\n    alignItems: 'center',\n  },\n});\n\nexport default class App2 extends React.Component {\n  state = {\n    showPopover: false,\n    popoverAnchor: { x: 0, y: 0, width: 0, height: 0 },\n  };\n\n  setButton = (e) =\u003e {\n    const handle = findNodeHandle(this.button);\n    if (handle) {\n      NativeModules.UIManager.measure(handle, (x0, y0, width, height, x, y) =\u003e {\n        this.setState({ popoverAnchor: { x, y, width, height } });\n      });\n    }\n  };\n\n  openPopover = () =\u003e {\n    this.setState({ showPopover: true });\n  };\n\n  closePopover = () =\u003e this.setState({ showPopover: false });\n\n  render() {\n    return (\n      \u003cView style={styles.app}\u003e\n        \u003cButton\n          ref={(r) =\u003e {\n            this.button = r;\n          }}\n          icon=\"arrow-up\"\n          onPress={this.openPopover}\n          onLayout={this.setButton}\n        /\u003e\n        \u003cPopover\n          visible={this.state.showPopover}\n          fromRect={this.state.popoverAnchor}\n          onClose={this.closePopover}\n          placement=\"bottom\"\u003e\n          \u003cText\u003eHi\u003c/Text\u003e\n        \u003c/Popover\u003e\n      \u003c/View\u003e\n    );\n  }\n}\n```\n\n## Contributing\n\nIf you want to add some features, feel free to submit PR.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoomsower%2Freact-native-modal-popover","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdoomsower%2Freact-native-modal-popover","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdoomsower%2Freact-native-modal-popover/lists"}