Giter Site home page Giter Site logo

steffeydev / react-native-popover-view Goto Github PK

View Code? Open in Web Editor NEW
531.0 4.0 85.0 13.68 MB

A well-tested, adaptable, lightweight <Popover> component for react-native

License: MIT License

TypeScript 100.00%
react-native popover modal view component tablet react-navigation

react-native-popover-view's Introduction

react-native-popover-view

npm version npm version npm licence

A well-tested, adaptable, lightweight <Popover> component for react-native with no dependencies. Tested and working on iOS and Android. May work on Web, but not officially supported.

It is written entirely in TypeScript and uses React Native's native driver for responsive animations, even when the JS thread is busy.

Demo Video

Open the snack to play with all the features!


Looking for maintainers

I no longer have any React Native apps that I actively maintain, and so am thus detached from the community and need to focus my attention elsewhere. If you actively use this project and are interested in maintaining it, please reach out and let me know!

Table of Contents
  • Simple: By default the popover will float in the center of the screen, but if you choose to anchor it to a view (like a Touchable) or to a point on the screen, it will automatically find the best placement to accommodate the popover content.
  • Customizable: Tweak everything, including the popover and arrow style, placement heuristics, animation configuration, and more.
  • Adaptable: Popover adapts to changing content size, screen size, and orientation, and will move to accomidate the on-screen keyboard for text input into the popover.
npm i react-native-popover-view

or

yarn add react-native-popover-view

Showing popover from an element

For the simplest usage, just pass your Touchable into the from prop. The Popover will automatically be shown when the Touchable is pressed.

import React from 'react';
import Popover from 'react-native-popover-view';

function App() {
  return (
    <Popover
      from={(
        <TouchableOpacity>
          <Text>Press here to open popover!</Text>
        </TouchableOpacity>
      )}>
      <Text>This is the contents of the popover</Text>
    </Popover>
  );
}

Note that if you pass an onPress or ref prop to the Touchable it will be overwritten.

Showing popover from an element (advanced)

For more advanced usage, pass in a function that returns any React element. You control which element the popover anchors on (using the sourceRef) and when the popover will be shown (using the showPopover callback). In this example, the Popover will appear to originate from the text inside the popover, and will only be shown when the Touchable is held down.

import React from 'react';
import Popover from 'react-native-popover-view';

function App() {
  return (
    <Popover
      from={(sourceRef, showPopover) => (
        <View>
          <TouchableOpacity onLongPress={showPopover}>
            <Text ref={sourceRef}>Press here to open popover!</Text>
          </TouchableOpacity>
        </View>
      )}>
      <Text>This is the contents of the popover</Text>
    </Popover>
  );
}

Showing popover from an element (allow manual dismiss)

You can control visibility yourself instead of letting the Popover manage it automatically by using the isVisible and onRequestClose prop. This would allow you to manually dismiss the Popover. onRequestClose is called when the user taps outside the Popover. If you want to force the user to tap a button inside the Popover to dismiss, you could omit onRequestClose and change the state manually.

import React, { useState, useEffect } from 'react';
import Popover from 'react-native-popover-view';

function App() {
  const [showPopover, setShowPopover] = useState(false);

  useEffect(() => {
    setTimeout(() => setShowPopover(false), 2000);
  }, []);

  return (
    <Popover
      isVisible={showPopover}
      onRequestClose={() => setShowPopover(false)}
      from={(
        <TouchableOpacity onPress={() => setShowPopover(true)}>
          <Text>Press here to open popover!</Text>
        </TouchableOpacity>
      )}>
      <Text>This popover will be dismissed automatically after 2 seconds</Text>
    </Popover>
  );
}

Showing popover from a reference to an element

If you need even more control (e.g. having the Popover and Touchable in complete different parts of the node hierarchy), you can just pass in a normal ref.

import React, { useRef, useState } from 'react';
import Popover from 'react-native-popover-view';

function App() {
  const touchable = useRef();
  const [showPopover, setShowPopover] = useState(false);

  return (
    <>
      <TouchableOpacity ref={touchable} onPress={() => setShowPopover(true)}>
        <Text>Press here to open popover!</Text>
      </TouchableOpacity>
      <Popover from={touchable} isVisible={showPopover} onRequestClose={() => setShowPopover(false)}>
        <Text>This is the contents of the popover</Text>
      </Popover>
    </>
  );
}

Showing popover from a predetermined position

If you already know the exact location of the place you want the Popover to anchor, you can create a Rect(x, y, width, height) object, and show from that Rect. Note that Rect(x, y, 0, 0) is equivalent to showing from the point (x, y).

import React, { useState } from 'react';
import Popover, { Rect } from 'react-native-popover-view';

function App() {
  const [showPopover, setShowPopover] = useState(false);

  return (
    <>
      <TouchableOpacity onPress={() => setShowPopover(true)}>
        <Text>Press here to open popover!</Text>
      </TouchableOpacity>
      <Popover from={new Rect(5, 100, 20, 40)} isVisible={showPopover} onRequestClose={() => setShowPopover(false)}>
        <Text>This is the contents of the popover</Text>
      </Popover>
    </>
  );
}

Showing popover without anchor

If you just want the popover to be floating on the screen, not anchored to anything, you can omit the from prop altogether.

import React, { useState } from 'react';
import Popover from 'react-native-popover-view';

function App() {
  const [showPopover, setShowPopover] = useState(false);

  return (
    <>
      <TouchableOpacity onPress={() => setShowPopover(true)}>
        <Text>Press here to open popover!</Text>
      </TouchableOpacity>
      <Popover isVisible={showPopover} onRequestClose={() => setShowPopover(false)}>
        <Text>This popover will stay centered on the screen, even when the device is rotated!</Text>
      </Popover>
    </>
  );
}

Showing popover in a specific direction

Normally, the Popover will automatically pick the direction it pops out based on where it would fit best on the screen, even showing centered and unanchored if the contents would be compressed otherwise. If you would like to force a direction, you can pass in the placement prop.

import React from 'react';
import Popover, { PopoverPlacement } from 'react-native-popover-view';

function App() {
  return (
    <Popover
      placement={PopoverPlacement.BOTTOM}
      from={(
        <TouchableOpacity>
          <Text>Press here to open popover!</Text>
        </TouchableOpacity>
      )}>
      <Text>This is the contents of the popover</Text>
    </Popover>
  );
}

Showing popover as a tooltip

Normally, the popover creates a background that dims the content behind it. You can also show a tooltip without fading the background. Read more about the available modes below. Note that when using TOOLTIP mode, you must control the visiblity manually (onRequestClose will never be called).

import React, { useRef, useState } from 'react';
import Popover, { PopoverMode, PopoverPlacement } from 'react-native-popover-view';

function App() {
  const [showPopover, setShowPopover] = useState(false);

  return (
    <Popover
      mode={PopoverMode.TOOLTIP}
      placement={PopoverPlacement.TOP}
      isVisible={showPopover}
      from={(
        <TouchableOpacity onPress={() => setShowPopover(true)}>
          <Text>Press here to open popover!</Text>
        </TouchableOpacity>
      )}>
      <>
        <Text>This is the contents of the popover</Text>
        <TouchableOpacity onPress={() => setShowPopover(false)}>
          <Text>Dismiss</Text>
        </TouchableOpacity>
      </>
    </Popover>
  );
}

Using class components

If you are not using functional components and hooks yet, you can still use class components in almost every case outlined above. Here is an example of using a class component and a ref, which is slightly different when using class components.

import React, { createRef } from 'react';
import Popover from 'react-native-popover-view';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.touchable = createRef();
    this.state = {
      showPopover: false
    }
  }

  render() {
    return (
      <>
        <TouchableOpacity ref={this.touchable} onPress={() => this.setState({ showPopover: true })}>
          <Text>Press here to open popover!</Text>
        </TouchableOpacity>
        <Popover
          from={this.touchable}
          isVisible={this.state.showPopover}
          onRequestClose={() => this.setState({ showPopover: false })}>
          <Text>This is the contents of the popover</Text>
        </Popover>
      </>
    );
  }
}

All props are optional

Prop Type Default Description
from multiple null Popover source. See From section below.
isVisible bool false Show/Hide the popover. Required if from is not a Touchable or function that uses showPopover call (see examples). If supplied, takes precedence regardless of from.
mode string 'rn-modal' One of: 'rn-modal', 'js-modal', 'tooltip'. See Mode section below for details.
placement string OR string list 'auto' How to position the popover, one of 'top', 'bottom', 'left', 'right', 'floating', or 'auto'. When 'auto' is specified, it will try to determine the best placement so that the popover is fully visible within displayArea. If an array of options is passed in, it will pick the first option that can accommodate the content.
offset number 0 The amount to shift the popover away from the source. Does not apply if the popover is centered.
popoverStyle object The style of the popover itself. You can override the borderRadius, backgroundColor, or any other style prop for a View.
popoverShift object How much to shift the popover in each direction, as a multiplier. Object of shape { x: -1 to 1, y: -1 to 1 }, where both x and y are optional. -1 shifts the popover all the way to the left/top and 1 shifts it to the right/bottom. Currently only applies when placement is floating, but this will apply to all placements in a future version.
backgroundStyle object The style of the background view. Default is a black background with 0.5 opacity.
arrowSize object { width: 16, height: 8 } The size of the arrow, as an object with width & height properties. The width of the arrow is the size of the arrow on the edge that touches the popover (base of isosceles triangle), while the height covers the distance from the popover to the source view, regardless of the placement of the popover. You can use { width: 0, height: 0 } to hide the arrow completely.
arrowShift number 0 How much to shift the arrow to either side, as a multiplier. -1 will shift it all the way to the left (or top) corner of the source view, while 1 will shift all the way to the right (or bottom) corner. A value of 0.5 or -0.8 will shift it partly to one side.
onOpenStart function Callback to be fired when the open animation starts (before animation)
onOpenComplete function Callback to be fired when the open animation ends (after animation)
onRequestClose function Callback to be fired when the user taps outside the popover (on the background) or taps the system back button on Android
onCloseStart function Callback to be fired when the popover starts closing (before animation)
onCloseComplete function Callback to be fired when the popover is finished closing (after animation)
onPositionChange function Callback to be fired when the popover position finishes moving position (after animation)
animationConfig object An object containing any configuration options that can be passed to Animated.timing (e.g. { duration: 600, easing: Easing.inOut(Easing.quad) }). The configuration options you pass will override the defaults for all animations.
displayArea rect Area where the popover is allowed to be displayed. By default, this will be automatically calculated to be the size of the display, or the size of the parent component if mode is not 'rn-modal'.
displayAreaInsets object Insets to apply to the display area. The Popover will not be allowed to go beyond the display area minus the insets.
statusBarTranslucent bool For 'rn-modal' mode on Android only. Determines whether the background should go under the status bar. Passed through to RN Modal component, see their docs as well.
verticalOffset number 0 The amount to vertically shift the popover on the screen, for use in correcting an occasional issue on Android. In certain Android configurations, you may need to apply a verticalOffset of -StatusBar.currentHeight for the popover to originate from the correct place. For shifting the popover in other situations, the offset prop should be used.
debug bool false Set this to true to turn on debug logging to the console. This is useful for figuring out why a Popover isn't showing.

The from prop can be:

  • A React element. If that element has an onPress prop, that prop will be be used to open the Popover.
  • A ref object created using useRef in function components or createRef in class components.
  • A function that takes two ordered argument, a ref and a showPopover callback, and returns a React element. Pass the ref argument to ref prop of the element that will be the source of the Popover (the view that the arrow will point to), and call showPopover callback to trigger the popover (or pass to the onPress prop or similar of a component). You can also ignore the showPopover argument and control visibility using the isVisible prop.
  • A point: { x: number, y: number }. In React Native coordinate system, (0, 0) is the top left of the screen.
  • A rectangle: { x: number, y: number, width: number, height: number }. The popover arrow will be pinned to the edges of the rectangle.

If no from is provided, the popover will float in the center of the screen.

The Popover can show in three modes:

  • Popover.MODE.RN_MODAL ('rn-modal')
  • Popover.MODE.JS_MODAL ('js-modal')
  • Popover.MODE.TOOLTIP ('tooltip')

RN Modal (Default)

Shows the popover full screen in a React Native Modal Component. The upside is that it is guaranteed to show on top of all other views, regardless of where the Popover component is placed in the view hierarchy. The downside is that you can only have one Modal shown at any one time, so this won't work for nested popovers or if you use a Modal for other reasons. Taps to the area outside the popover will trigger the onRequestClose callback.

JS Modal

Use this if you want to show nested Popovers, or are showing the Popover from a view that is already inside a native modal. Unlike with Tooltip, taps to the area outside the popover will trigger the onRequestClose callback.

Tooltip

Shows the Popover without taking over the screen, no background is faded in and taps to the area around the popover fall are not blocked. The onRequestClose callback will never be called, so the Popover will have to be dismissed some other way.

Tips for using JS Modal and Tooltip

Both JS Modal and Tooltip modes render the Popover into the react component tree instead of in a dedicated native modal. Because of this, you must place the Popover component at the proper place in the component hiearchy for it to show, potentially in a different place than the Touchable that the Popover is anchored to.

The key thing to consider is that the Popover will only be able to render in the space of its immediate parent. If the parent of the Popover is a view with the same dimensions of the Touchable, the Popover will not be able to show. If you can't see the Popover when using these modes, try moving the Popover to the root view, or as close to the root view as possible, so that the Popover's immediate parent fills the screen. If you render the Touchable inside a ScrollView, the Popover should be an immediate child of the ScrollView.

Some devices have notches or other screen features that create zones where you might want to avoid showing a Popover. To do so, follow the instructions to setup react-native-safe-area-context, then use the provided hooks to pass the safe area insets straight to the displayAreaInsets prop:

import { useSafeAreaInsets } from 'react-native-safe-area-context';
import Popover from 'react-native-popover-view';

function PopoverSafeWrapper(props) {
  const insets = useSafeAreaInsets();
  return (
    <Popover {...props} displayAreaInsets={insets} />
  );
}

In all cases, start by passing the debug={true} prop to the Popover, to see if the debug output can help you figure out the issue.

Show from a ref not working

If on an Android device, try adding these props to the component whose ref you passed in to from:

  • renderToHardwareTextureAndroid={true}
  • collapsable={false}

See facebook/react-native#3282 and #28 for more info.

Android vertical positioning incorrect

Depending on how your app is configured, you may need to use the following verticalOffset prop to correctly position the popover on Android:

import { Platform, StatusBar, ... } from 'react-native';

...

  <Popover
    {...otherProps}
    verticalOffset={Platform.OS === 'android' ? -StatusBar.currentHeight : 0 }
  />

Error when passing a functional component to the from prop

When passing a function component to the Popover from prop, you may see the following error:

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

This is because the Popover component uses ref to find the position of the from component on the screen, so that it can position the Popover correctly. Functional components don't have a ref like class components did, and thus causes this error.

As the error suggests, modifying your functional component to use React.forwardRef will fix this error. You should forward the ref to the underlying component that represents the bounds from which you want the Popover to show (usually the topmost component).

4.x to 5.0

  • New Props: offset & popoverShift
  • Breaking: Replaces arrowStyle with arrowSize. The only known customization of the arrow was the width, height, and backgroundColor. In version 5.0, arrowSize prop allows customization of width and height (with some tweaks, explained in prop table), and the arrow will inherit the backgroundColor from popoverStyle. To hide arrow, instead of passing backgroundColor: 'transparent', pass an arrowSize of { width: 0, height: 0 }, and then use the offset prop to move popover away from source if desired. The shadow props passed to popoverStyle will apply to the arrow as well.
  • Under-the-hood changes: Refactoring and optimizations may cause slight changes to content handling and placement, review and test your popovers after upgrade to make sure they still look as expected.
  • Simplification: Using a shadow no longer requires popoverStyle to contain overflow: visible (#15)
  • Deprecation: Rect is deprecated and will be removed in the future. Instead of using new Rect(x, y, width, height), just pass in an object of the form { x: number, y: number, width: number, height: number }.

3.x to 4.0

Removed internal safe area view; if you want the Popover to avoid showing behind notches on some devices, follow the instructions: Usage with Safe Area Context.

2.x to 3.0

  • fromRect and fromView have been consolidated into a single from prop, where you can pass a Rect or a Ref. All Refs passed in must now be a RefObject created from React.createRef or React.useRef. All Rects passed in must be an actual Rect object (e.g. from={new Rect(x, y, width, height)}).
  • from prop now supports additional modes, including passing in a React element for simpler usage. See new examples and usage notes above.
  • fromDynamicRect has been removed.

1.x to 2.0

  • onClose has been renamed to onRequestClose (for clarity and consistency with normal RN Modals)
  • New mode prop replaces showInModal. Replace showInModal={false} with mode={Popover.MODE.JS_MODAL}
  • doneClosingCallback has been renamed onCloseComplete
  • New backgroundStyle prop replaces showBackground. Replace showBackground={false} with backgroundStyle={{ backgroundColor: 'transparent' }}
  • Fix in version 2.0 means that verticalOffset may no longer be needed, so if you are using it be sure to test

1.0 to 1.1

This version moved the react-navigation portion of this project to it's own repository: react-navigation-popover. To use with react-navigation, install that npm package change import { createPopoverStackNavigator } from 'react-native-popover-view' to import createPopoverStackNavigator from 'react-navigation-popover'.

0.7 to 1.0

The only breaking change in version 1.0 was renaming PopoverStackNavigator to createPopoverStackNavigator, to match the react-navigation other navigation functions.

0.5 to 0.6

Version 0.6 brought some large changes, increasing efficiency, stability, and flexibility. For React Navigation users, there is a new prop, showInPopover, that you might want to pass to createPopoverStackNavigator if you want to customize when to show stack views in a Popover. This replaces PopoverNavigation.shouldShowInPopover. See the new setup instructions below for details.

Pull requests are welcome; if you find that you are having to bend over backwards to make this work for you, feel free to open an issue or PR! Of course, try to keep the same coding style if possible and I'll try to get back to you as soon as I can.

Use yarn build to build the dist folder (compile TypeScript to JavaScript), and use yarn watch to continuously build on save.

This is a fork of react-native-popover, originally created by Jean Regisser [email protected] (https://github.com/jeanregisser) but since abandoned.

I have rebuilt most of the library from the ground up for improved handling of changing screen sizes on tablets (split-screen mode), a redesigned automatic placement algorithm, TypeScript, and ES6 compatibility.

Similar forks exist on Github (such as react-native-modal-popover), but this is the first to be published on NPM as far as I know.


MIT Licensed

react-native-popover-view's People

Contributors

asmundg avatar awinograd avatar dependabot[bot] avatar drewvolz avatar hawkrives avatar jeanregisser avatar jesuscc1993 avatar jjshammas avatar kev71187 avatar kurtfurbush avatar lachlanroche avatar nicomontanari avatar ph1p avatar rajrohityadav avatar rohansi avatar rxliuli avatar seanroberts avatar steffeydev avatar trent-evernote avatar zhigang1992 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-native-popover-view's Issues

Does not function on certain devices

Hello!

It works perfectly in the iOS simulator; however, I have tested on a physical device (both iPhone and iPad) and it does not render.

In fact, trying to present the popover actually crashes the app with no error... it just freezes. I really liked this library but this is a deal-breaker. I am building with Xcode 9.4.1

RTL support not provided. PopOver view does not display when app switched to RTL

Describe the bug
What is it that you are seeing? Please be detailed in your description so that I can help fix your issue as quickly as possible.

Device/Setup Info:

  • Device: [e.g. iPhone 6]
  • OS: [e.g. iOS 8.1]
  • react-native version: [e.g. 0.57.1]
  • react-native-popover-view version: [e.g. 1.0.7]

Screenshots
If there is a visual issue, add screenshots or a video so that I can see what is going on.

Debug Output
Pass the debug={true} prop into the Popover, and then paste the contents of the log here.

Arrow Style | how to add arrow style to mode={ 'rn-modal'}

Hi,

Can you please suggest me how to add arrow style for rn-modal

<Popover
                        isVisible={this.state.isVisible}
                        mode={
                            'rn-modal'}
                        onRequestClose={() => this.closePopover()}>
                        <View style={{
                            backgroundColor: '#2f2f2f',
                            padding: 20,
                            width: normalize(260),
                        }}>

                         <Text>text</Tex>
                        </View>
                    </Popover>

I just want to say this is an awesome component

I have had 0 issues using it, it worked flawlessly, the documentation is clear and concise, the usage is obvious, and within minutes I had popups working in my app.

This is seriously the best RN component I've ever used.

isVisible:true not popup when open the app by default

Open app and refresh ctrl+R (working)

setDefaultDisplayArea - newDisplayArea: {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 measureContent - Showing Popover - requestedContentSize: {"height":55.42856979370117,"width":151.42857360839844,"y":0,"x":0} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 computeGeometry - displayArea: {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 computeGeometry - fromRect: {"x":350,"y":20.571428298950195,"width":40.85714340209961,"height":40.85714340209961} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 computeGeometry - displayArea: {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 computeGeometry - fromRect: {"x":350,"y":20.571428298950195,"width":40.85714340209961,"height":40.85714340209961} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 measureContent - Showing Popover - geom: {"popoverOrigin":{"x":190.57142639160156,"y":13.285715103149414},"anchorPoint":{"x":350,"y":41},"placement":"left","forcedContentSize":{"height":639.4285888671875,"width":332},"viewLargerThanDisplayArea":{"height":false,"width":false}} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 measureContent - Showing Popover - Animating In blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - fromRect: {"x":350,"y":20.571428298950195,"width":40.85714340209961,"height":40.85714340209961} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - getDisplayArea(): {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - displayAreaStore: {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:26989 Running application "BoostMerchantApp" with appParams: {"rootTag":61}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF

Close app and open again (not working)
setDefaultDisplayArea - newDisplayArea: {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 measureContent - Waiting for resize to finish blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - fromRect: {"x":350,"y":20.571428298950195,"width":40.85714340209961,"height":40.85714340209961} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - getDisplayArea(): {"x":10,"y":10,"width":391.4285583496094,"height":639.4285888671875} blob:http://localhost:8081/3a732971-c4ed-43dd-a0b0-e8e189bfa30e:142043 setDefaultDisplayArea (inside calculateRect callback) - displayAreaStore: undefined

Popover does not show if isVisible is initially true

I pasted the "Standalone" example into my project. At the top of the file:

import Popover from 'react-native-popover-view'

In render:

<Popover
      isVisible={this.state.isVisible}>
      <Text>Hello, world.</Text>
</Popover>

It simply does not work... there are no errors but nothing shows up. I am using an iOS simulator (yes, this.state.isVisible is true). Is there some other setup required or what? I thought the width and size props were optional.

Popover is shown under text elements

Describe the bug
I am using the component with tooltip mode. It is shown under text. z index won't help. Does anyone know what I might be doing wrong?
Thank you!

Screenshots
image

Custom Arrow Color

Thanks for the great work.

It'd be great if it could change the arrow color of the popover.
What do you think about accepting style prop?

Bug in calculating size

Describe the bug
There are two bugs that cause the initial calculation of the popover to frequently be incorrect and cause incorrect animate slide in effects.

Device/Setup Info:

  • Device: iPad Air Simulator
  • OS: iOS 13.3
  • react-native version: 0.61
  • react-native-popover-view version: 2.04

Screenshots
bug-popover-gif

onClose working in 2.0.4 but onRequestClose dont

I had version 1.0.18 so i uninstalled and installed newest version 2.0.4, and onRequestClose wasn't working but onClose(deprecated) was working. How can i solve this?
The "Example" folder shows the use of onClose still

When click on button for multiple times popover is opening and screen got strucked?

Here is my sample code you can look into it.

showPopover() {
   this.setState({isVisible: true});
 }

 closePopover() {
    this.setState({isVisible: false});
 }

 render() {
    return (

   <View>        
    <TouchableHighlight ref={ref => this.touchable = ref} style={styles.button} onPress={() => this.showPopover()}> <Text>Press me</Text> </TouchableHighlight> 
    <Popover
      isVisible={this.state.isVisible}
      fromView={this.touchable}
      onClose={() => this.closePopover()}>
      <Text>I'm the content of this popover!</Text>
    </Popover>
  </view>

 );
}

Element from which popover was opened above modal

Hi, is it possible to make the clicked element that was used to trigger the popover visibility appear "above" the modal background of the popover? At the same level as the popover.
I tried messing around with z-indexes but with no luck.

Thank you.

Android devices positioning popover in center of screen

So I've got a bit of a weird bug going on that I can't quite seem to figure out. On iOS devices, this popover appears correctly at the top of the view. But on android devices, it gets shoved into the middle, and the arrow is dead center on the screen:

img_0335

However, this popover which is attached to an absolutely positioned element on the screen shows up correctly on both devices?

img_0336

Sorry about the cropping, its not an open project. Happy to provide as much information as I can, just not sure exactly where to start in terms of providing helpful content.

sound during popover

hi, thanks for this library.
Do you support with option to have a sound when the popover show? if not can you please tell me how can I do that?

Thanks

mode={'tooltip'} not opens popover

I want to open pop over without dim effect, I have tried to use mode = {'tooltip} but after using mode popover is not opening. It's working fine with 'rn-modal' .

<Popover isVisible={this.state.modalVisible} mode={"tooltip"} popoverStyle={{ backgroundColor: 'transparent' }} onRequestClose={() => this.setState({ modalVisible: false, selectedItem: "" }) } >

Incorrect popover origin when size changes during animate in

Describe the bug
If the popover size gets bigger as the view is animating in (for example, if content is loaded async and then re-rendered just before or during animation), the popover appears to be originating from a location that is below the actual fromRect.

Device/Setup Info:

  • Device: iPad Pro 12.9"
  • OS: iOS 12
  • react-native version: 0.57
  • react-native-popover-view version: 1.0.16

Screenshots
See CC Orlando App - Bible Tab - Top right button

Debug Output

measureContent - Showing Popover - Animating In
getTranslateOrigin - popoverOrigin: {"x":908,"y":30}
getTranslateOrigin - popoverSize: {"width":380,"height":911}
getTranslateOrigin - anchorPoint: {"x":1296,"y":42}
getTranslateOrigin - shift: {"hoizontal":198,"vertical":-443.5}
measureContent - new requestedContentSize: {"y":0,"width":380,"x":0,"height":984} (used to be {"y":0,"width":380,"x":0,"height":911})
handleGeomChange - requestedContentSize: : {"y":0,"width":380,"x":0,"height":984}
computeGeometry - displayArea: {"x":10,"y":30,"width":1346,"height":984}
computeGeometry - fromRect: {"x":1296,"y":22,"width":70,"height":40}
computeGeometry - displayArea: {"x":10,"y":30,"width":1346,"height":984}
computeGeometry - fromRect: {"x":1296,"y":22,"width":70,"height":40}

error: bundling failed: Error: Unable to resolve module `../../react-navigation/src/views/StackView/StackView`

Thanks for all the work put into this repo. It works really well. However I tried upgrading to react-navigation v2.12.1 and I keep getting this error:

error: bundling failed: Error: Unable to resolve module ../../react-navigation/src/views/StackView/StackView from /.../node_modules/react-native-popover-view/src/PopoverStackNavigator.js: The module ../../react-navigation/src/views/StackView/StackView could not be found from /..../node_modules/react-native-popover-view/src/PopoverStackNavigator.js. Indeed, none of these files exist:

I am not using this library for react navigation integration, I just want the component. Is there a way to turn off this react-navigation integration option? It is causing more headaches than it solves.

I'm using v1.0.5 of this repo.

Can't display a dialog after popover did close (iOS only)

Describe the bug
In popoverDoneClosing I want to open the Alert dialog. On iOS, the alert closes straight after it showed and after that the app freezes. You can't tap anything, my guess is that popover modal doesn't close properly and overlays the entire screen (like in #16). If you wrap Alert in setTimeout with 0 (zero) interval you may get this behavior after the second hit. You can try it out in this Expo Snack: https://snack.expo.io/HJFjG-G9V With 100 interval, it's pretty much ok, but it still freezes occasionally.
Expected bevavior: I call Alert in popoverDoneClosing and it displays without closing and freezing the app, without the need to set a timeout.

Device/Setup Info:

  • Device: any iPhone
  • OS: iOS 12.2
  • react-native version: 0.58.5
  • react-native-popover-view version: 1.0.19

Debug Output
This bug does not reproduce when Remote Debug is enabled.

Shadow style not displaying

Running on React Native 0.55.4

I noticed that the default styles for the popover include a box shadow around the view. Unfortunately, this doesn't seem to be displaying.

It seems that the issue might be a conflict with Animated.View and the boxShadow styles. If I manually hack it so that the styles get applied to a regular View child below the Animated.View, the shadow displays as expected.

Multiple Popovers opening in sequence, second not opening when triggered by button in first

Sorry for my bad English.
I want to use react-native-popover-view as a guide for new user. If user read the first guide and they click "Ok" it will open the second guide. My code is below.
Thank you for your help !
"react-native-popover-view": "version": "1.0.9",
"react-native": "version": "0.57.4",

export default class App extends Component<Props> {
  componentDidMount() {
    this.setState({ isVisible: true });
  }
  state = {
    isVisible: false,
    isVisible2: false
  };

  showPopover() {
    this.setState({ isVisible: true });
  }
  showPopover2() {
    this.setState({ isVisible2: true });
    this.setState({ isVisible: false });
  }

  closePopover() {
    this.setState({ isVisible: false });
  }
  render() {
    return (
      <View style={styles.container}>
        <Popover
          isVisible={this.state.isVisible}
          fromView={this.touchable}
          onClose={() => this.closePopover()}
        >
          <Text style={styles.test}>The first guide</Text>
          <TouchableHighlight
            style={styles.button}
            onPress={() => this.showPopover2()}
          >
            <Text>go to second</Text>
          </TouchableHighlight>
        </Popover>
        <Popover
          isVisible={this.state.isVisible2}
          fromView={this.touchable2}
          onClose={() => this.closePopover()}
        >
          <Text style={styles.test}>The second guide</Text>
          <TouchableHighlight
            style={styles.button}
            onPress={() => this.showPopover()}
          >
            <Text>Press me</Text>
          </TouchableHighlight>
        </Popover>

        <TouchableHighlight
          ref={ref => (this.touchable = ref)}
          style={styles.button}
          onPress={() => this.showPopover()}
        >
          <Text>Press me</Text>
        </TouchableHighlight>
        <Text
          ref2={ref2 => (this.touchable2 = ref2)}
          tyle={styles.instructions}
        >
          text 1
        </Text>
      </View>
    );
  }
}

Subtract verticalOffset from popover height to preserve margins on popover

Hi,
verticalOffset still required on Android on version 2.x when running on expo, and may update the popover height according the vertical offset too (for better experience on large popovers like the image attached)

here snippet and screenshots, thanks and awesome work !!!

btw: on iOS works as expected.

<TouchableOpacity
  ref={ref => (this._controls_button_ref = ref)}
  style={{
    position: 'absolute',
    top: 0,
    right: 0
  }}
  onPress={this._showControls}
>
  <Text>Button</Text>
</TouchableOpacity>
<Popover
  isVisible={showControls}
  fromView={this._controls_button_ref}
  onRequestClose={this._onPressCancel}
  verticalOffset={
    Platform.OS === 'android' ? -Constants.statusBarHeight : 0
  }
>
  <View>Stuff here</View>
</Popover>

telegram-cloud-photo-size-1-5154761118516881495-y

Add parameters to control animations

I have different situations where the default animation is acting strange. I'd like the ability to adjust duration, easing, or turn it off altogether.

animationConfig not valid in typescript 3.6.3

Setting animationConfig to {duration: 100} results in a TS error. Maybe something changed on the RN side of the type definitions?

No overload matches this call.
  Overload 1 of 2, '(props: Readonly<PopoverViewProps>): Popover', gave the following error.
    Property 'toValue' is missing in type '{ duration: number; }' but required in type 'TimingAnimationConfig'.
  Overload 2 of 2, '(props: PopoverViewProps, context?: any): Popover', gave the following error.
    Property 'toValue' is missing in type '{ duration: number; }' but required in type 'TimingAnimationConfig'.
  • react-native version: 0.60.5
  • react-native-popover-view version: 2.0.5
  • typescript version: 3.6.3

edit: small additional unrelated TS issue, Popover.MODE constants aren't in the .d.ts file resulting in TS errors when they are referenced.

Error while wrapping the PopOver inside a Text element

<Text> <Text style={styles.sectionTitle} onPress={() => this.setState({isVisible: true})} ref={(ref) => (this.touchable = ref)}> Click here to show PopOver </Text> <View style={styles.popover}> <Popover isVisible={this.state.isVisible} fromView={this.touchable} placement={'bottom'} onRequestClose={() => this.closePopover()}> <Text>ReactNativePopOverViewSuccessfull</Text> </Popover> </View> </Text>

code shown above is from my poc . In my actual project all of my components are dynamically created and i need to show popover to a particular text component, so i tried wrapping up the popover inside the text component but it fires error while clicking the text component

Device/Setup Info:

  • OS: Android 10
  • react-native version: 0.61.5
  • react-native-popover-view version: 2.1.0

Screenshots
1589542419685

Getting a TypeError crash

Hi,

I keep running in the same crash, takes a few seconds to popup but it always does.

Can't quite work out what's causing it.

I'm running it with Expo (v28).

simulator screen shot - iphone 8 - 2018-08-08 at 13 17 43

Not sure what else to provide. Let me know what could help?

Ben

Make style attributes accept an array

It would be cool if the popoverStyle prop (and all other style props, would accept an array as all other RN elements with style prop do. The background here is to apply different styles through a hook (e.g. react-navigations useTheme hook).

const { colors } = useTheme()
<View style={[styles.modal, { backgroundColor: colors.background }]}>

Android Support

Thank you for this beautiful work
I know that this library have problems with android
I tryed this library on my project (android) and i noticed that the pop over is displayed only if i rotate the display after call the show pop over function
Maybe this can help you to fix
When do you think this library will support android?

Not working in RTL direction

I am showing popup but when i switched to arabic language. application direction get changed as below :

if(language == "arabic"){
I18nManager.allowRTL(true);
}

After allowing RTL when i tried to show popup screen stuck.

Broken on RN 0.57.0

I think this may be related to #16 . Ever since I updated to react-native 0.57, whenever I try to open the popover the entire app just "freezes". I suspect that there is some sort of invisible overlay blocking all user interaction because I can still shake to refresh and access dev menu.

Dependency Error

So I just started trying to use this, and immediately got an error:

Unable to resolve ../../react-navigation/src/navigators/createKeyboardAwareNavigator" from ".//node_modules/react-native-popover-view/src/PopoverStackNavigator.js`: The module `../../react-navigation/src/navigators/createKeyboardAwareNavigator` could not be found"

Not sure what I did wrong here.

Update react

Event componentWillRecieveProps will deprecate after updating react.
Use getDerivedStateFromProps() and componentDidUpdate() instead componentWillReceiveProps();

Android Support

It's promising but the demo app didn't work on Android at all.
Any plan to support Android?

Popovers don't fade under status bar + modal shifts around

Describe the bug
My app is set up to render under a translucent status bar but modals always avoid it. I'm using the rn-modal mode and it works alright but I can see the status bar area does not fade and the popover shifts around vertically after animating in sometimes. I suspect this is due to the status bar differences.

I see there is a statusBarTranslucent prop for Modal but there is no way for me to pass that in. I have tried the other modes but they do not work for my use case.

Device/Setup Info:

  • Device: Moto e5 cruise, Samsung Galaxy S7 edge, Samsung Galaxy S10+
  • OS: Android 8 to 10
  • react-native version: 0.61 (Expo SDK 37)
  • react-native-popover-view version: 2.0.7

Debug Output

componentWillReceiveProps - Awaiting popover show
setDefaultDisplayArea - newDisplayArea: {"x":10,"y":34,"width":340,"height":524}
setDefaultDisplayArea - displayAreaOffset: {"x":0,"y":0}
setDefaultDisplayArea (inside calculateRect callback) - fromRect
setDefaultDisplayArea (inside calculateRect callback) - getDisplayArea(): {"x":10,"y":34,"width":340,"height":524}
setDefaultDisplayArea (inside calculateRect callback) - displayAreaStore: {"x":10,"y":10,"width":340,"height":548}
setDefaultDisplayArea (inside calculateRect callback) - Triggering state update
handleGeomChange - requestedContentSize: : {"y":0,"height":290,"width":178.5,"x":0}
computeGeometry - displayArea: {"x":10,"y":34,"width":340,"height":524}
computeGeometry - fromRect: {}
handleGeomChange - Triggering popover move to: {"x":90.75,"y":151}
setDefaultDisplayArea - newDisplayArea: {"x":10,"y":10,"width":340,"height":548}
setDefaultDisplayArea - displayAreaOffset: {"x":0,"y":0}
setDefaultDisplayArea (inside calculateRect callback) - fromRect
setDefaultDisplayArea (inside calculateRect callback) - getDisplayArea(): {"x":10,"y":10,"width":340,"height":548}
setDefaultDisplayArea (inside calculateRect callback) - displayAreaStore: {"x":10,"y":34,"width":340,"height":524}
setDefaultDisplayArea (inside calculateRect callback) - Triggering state update
handleGeomChange - requestedContentSize: : {"y":0,"height":290,"width":178.5,"x":0}
computeGeometry - displayArea: {"x":10,"y":10,"width":340,"height":548}
computeGeometry - fromRect: {}
handleGeomChange - Triggering popover move to: {"x":90.75,"y":139}
measureContent - Showing Popover - requestedContentSize: {"y":0,"height":290,"width":178.5,"x":0}
computeGeometry - displayArea: {"x":10,"y":10,"width":340,"height":548}
computeGeometry - fromRect: {}
measureContent - Showing Popover - geom: {"popoverOrigin":{"x":90.75,"y":139},"anchorPoint":{"x":180,"y":284},"forcedContentSize":{"width":340,"height":548},"viewLargerThanDisplayArea":{"width":false,"height":false},"showArrow":false}
measureContent - Showing Popover - Animating In
getTranslateOrigin - popoverOrigin: {"x":90.75,"y":139}
getTranslateOrigin - popoverSize: {"width":178.5,"height":290}
getTranslateOrigin - anchorPoint: {"x":180,"y":284}
getTranslateOrigin - shift: {"hoizontal":0,"vertical":0}
animateIn - onOpenComplete - Calculated Popover Rect: {"x":91,"y":139,"width":178.5,"height":290}

This is the output from when the popover moved after animating in. We can see it started at Y=151 but then moved to Y=139. The status bar height is 24 and this is a difference of 12. This makes sense because the modal is set to be centered.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.