Gathering detailed insights and metrics for react-native-modal-popover
Gathering detailed insights and metrics for react-native-modal-popover
Gathering detailed insights and metrics for react-native-modal-popover
Gathering detailed insights and metrics for react-native-modal-popover
npm install react-native-modal-popover
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
323 Stars
60 Commits
45 Forks
4 Watching
3 Branches
5 Contributors
Updated on 14 Nov 2024
TypeScript (70.3%)
Java (13.51%)
Objective-C (9.79%)
JavaScript (3.17%)
Ruby (1.59%)
Starlark (1.31%)
Shell (0.32%)
Cumulative downloads
Total Downloads
Last day
6.7%
1,287
Compared to previous day
Last week
-7.7%
5,903
Compared to previous week
Last month
7.4%
26,924
Compared to previous month
Last year
37.6%
286,953
Compared to previous year
2
2
Pure JS popover component for react-native
The original react-native-popover is now outdated,
so I decided to publish my own module to avoid using github url in my package.json. Something got lost in
the process of rewriting, but now it uses Modal
and native animation drivers, and also has cool helper
to use with Touchables. Thanks to @jeanregisser and to the authors of hanging PRs for their code.
Previously (version 0.0.6
) this module required react version >16.2.0
to work (which corresponds to react-native version >0.52.0
).
Version 0.0.7
does not reqire React.Fragment
anymore, so you can use with reasonably old versions of react and react-native.
1yarn add react-native-modal-popover
This module exports two react components, Popover
and PopoverController
, and one react hook, usePopover
.
Popover
works pretty much like original Popover
, and PopoverController
is a convenience component that uses React Render Props pattern.
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
usePopover
is preferred modern way to have popover in your app.
1import React from 'react'; 2import { Button, StyleSheet, Text, View } from 'react-native'; 3import { Popover, usePopover } from 'react-native-modal-popover'; 4 5const styles = StyleSheet.create({ 6 app: { 7 ...StyleSheet.absoluteFillObject, 8 alignItems: 'center', 9 justifyContent: 'center', 10 backgroundColor: '#c2ffd2', 11 }, 12 content: { 13 padding: 16, 14 backgroundColor: 'pink', 15 borderRadius: 8, 16 }, 17 arrow: { 18 borderTopColor: 'pink', 19 }, 20 background: { 21 backgroundColor: 'rgba(0, 0, 255, 0.5)', 22 }, 23}); 24 25const App = () => { 26 const { 27 openPopover, 28 closePopover, 29 popoverVisible, 30 touchableRef, 31 popoverAnchorRect, 32 } = usePopover(); 33 return ( 34 <View style={styles.app}> 35 <Button title="Press me!" ref={touchableRef} onPress={openPopover} /> 36 <Popover 37 contentStyle={styles.content} 38 arrowStyle={styles.arrow} 39 backgroundStyle={styles.background} 40 visible={popoverVisible} 41 onClose={closePopover} 42 fromRect={popoverAnchorRect} 43 supportedOrientations={['portrait', 'landscape']}> 44 <Text>Hello from inside popover!</Text> 45 </Popover> 46 </View> 47 ); 48}; 49 50export default App;
Use PopoverController
if you cannot use hooks for some reason.
1import React from 'react'; 2import { Button, StyleSheet, Text, View } from 'react-native'; 3import { Popover, PopoverController } from 'react-native-modal-popover'; 4 5const styles = StyleSheet.create({ 6 app: { 7 ...StyleSheet.absoluteFillObject, 8 alignItems: 'center', 9 justifyContent: 'center', 10 backgroundColor: '#c2ffd2', 11 }, 12 content: { 13 padding: 16, 14 backgroundColor: 'pink', 15 borderRadius: 8, 16 }, 17 arrow: { 18 borderTopColor: 'pink', 19 }, 20 background: { 21 backgroundColor: 'rgba(0, 0, 255, 0.5)', 22 }, 23}); 24 25const App = () => ( 26 <View style={styles.app}> 27 <PopoverController> 28 {({ 29 openPopover, 30 closePopover, 31 popoverVisible, 32 setPopoverAnchor, 33 popoverAnchorRect, 34 }) => ( 35 <React.Fragment> 36 <Button 37 title="Press me!" 38 ref={setPopoverAnchor} 39 onPress={openPopover} 40 /> 41 <Popover 42 contentStyle={styles.content} 43 arrowStyle={styles.arrow} 44 backgroundStyle={styles.background} 45 visible={popoverVisible} 46 onClose={closePopover} 47 fromRect={popoverAnchorRect} 48 supportedOrientations={['portrait', 'landscape']}> 49 <Text>Hello from inside popover!</Text> 50 </Popover> 51 </React.Fragment> 52 )} 53 </PopoverController> 54 </View> 55); 56 57export default App;
Popover
Prop | Type | Optional | Default | Description |
---|---|---|---|---|
visible | bool | Yes | false | Show/Hide the popover |
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. | |
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. |
placement | string | Yes | 'auto' | How to position the popover - top | bottom | start | end | auto. When 'auto' is specified, it will determine the ideal placement so that the popover is fully visible within displayArea . |
onClose | function | Yes | Callback to be fired when the user closes the popover | |
onDismiss | function | Yes | Callback to be fired after the popup closes | |
backgroundStyle | ViewStyle | Yes | Custom style to be applied to background overlay | |
contentStyle | ViewStyle | Yes | Custom style to be applied to popover reactangle. Use it to set round corners, background color, etc. | |
arrowStyle | ViewStyle | Yes | Custom style to be applied to popover arrow. Use borderTopColor to match content backgroundColor | |
duration | number | Yes | 300 | Animation duration |
easing | (show: boolean) => (value: number) => number | Yes | show => 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 |
useNativeDriver | bool | Yes | false | Defines if animations should use native driver |
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. Set this to ['portrait', 'landscape'] if you want your popover to resprect screen orientation. | |
calculateStatusBar | bool | Yes | false | Defines if while use status bar height while calculating "Y" origin of anchor. |
PopoverController
and usePopover
hookPopoverController
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.
usePopover
returns object with same props as PopoverControllerRenderProps
, except that ref has different name: touchableRef
.
PopoverControllerRenderProps
:Prop | Type | Description |
---|---|---|
openPopover | () => void | Call this function when you want to open popover, e.g. pass to onPress of a Button |
closePopover | () => 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. |
popoverVisible | boolean | Pass this to visible prop of Popover component |
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. |
popoverAnchorRect | Rect | Pass this as fromRect prop of Popover component |
Rect
Rect is an object with the following properties: {x: number, y: number, width: number, height: number}
PopoverController
In this case you have to handle refs, measure UI handle and manage popover visibility manually:
1import React from 'react'; 2import { 3 findNodeHandle, 4 NativeModules, 5 StyleSheet, 6 Text, 7 View, 8} from 'react-native'; 9import Button from './Button'; 10import Popover from './popover'; 11 12const styles = StyleSheet.create({ 13 app: { 14 ...StyleSheet.absoluteFillObject, 15 padding: 10, 16 backgroundColor: '#c2ffd2', 17 alignItems: 'center', 18 }, 19}); 20 21export default class App2 extends React.Component { 22 state = { 23 showPopover: false, 24 popoverAnchor: { x: 0, y: 0, width: 0, height: 0 }, 25 }; 26 27 setButton = (e) => { 28 const handle = findNodeHandle(this.button); 29 if (handle) { 30 NativeModules.UIManager.measure(handle, (x0, y0, width, height, x, y) => { 31 this.setState({ popoverAnchor: { x, y, width, height } }); 32 }); 33 } 34 }; 35 36 openPopover = () => { 37 this.setState({ showPopover: true }); 38 }; 39 40 closePopover = () => this.setState({ showPopover: false }); 41 42 render() { 43 return ( 44 <View style={styles.app}> 45 <Button 46 ref={(r) => { 47 this.button = r; 48 }} 49 icon="arrow-up" 50 onPress={this.openPopover} 51 onLayout={this.setButton} 52 /> 53 <Popover 54 visible={this.state.showPopover} 55 fromRect={this.state.popoverAnchor} 56 onClose={this.closePopover} 57 placement="bottom"> 58 <Text>Hi</Text> 59 </Popover> 60 </View> 61 ); 62 } 63}
If you want to add some features, feel free to submit PR.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
Reason
binaries present in source code
Details
Reason
Found 4/25 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
30 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn Morereact-native-modal
An enhanced React Native modal
react-native-modal-datetime-picker
A react-native datetime-picker for Android and iOS
react-native-popover-view
A <Popover /> component for react-native iOS, Android, and Web
react-native-date-picker
A datetime picker for React Native. In-modal or inlined. Supports Android and iOS.