diff --git a/Example/android/build.gradle b/Example/android/build.gradle
index eed9972..f96eb32 100644
--- a/Example/android/build.gradle
+++ b/Example/android/build.gradle
@@ -2,10 +2,11 @@
buildscript {
repositories {
- jcenter()
+ google()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.3'
+ classpath("com.android.tools.build:gradle:4.2.2")
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -15,7 +16,7 @@ buildscript {
allprojects {
repositories {
mavenLocal()
- jcenter()
+ mavenCentral()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
diff --git a/lib/Popover.js b/lib/Popover.js
index b624755..3549639 100644
--- a/lib/Popover.js
+++ b/lib/Popover.js
@@ -1,107 +1,108 @@
import React, { PureComponent } from 'react';
-import { findNodeHandle, Text, ViewPropTypes } from 'react-native';
+import { findNodeHandle } from 'react-native';
import PropTypes from 'prop-types';
import { v4 as uuidv4 } from 'uuid';
class Popover extends PureComponent {
static contextTypes = {
- registerPopover: PropTypes.func,
- unregisterPopover: PropTypes.func,
+ registerPopover: PropTypes.func,
+ unregisterPopover: PropTypes.func,
};
static propTypes = {
- children: PropTypes.node,
- isVisible: PropTypes.bool,
- arrowColor: PropTypes.string,
- arrowWidth: PropTypes.number,
- arrowHeight: PropTypes.number,
- placement: PropTypes.oneOf(['left', 'right', 'top', 'bottom', 'auto']),
- pointerEvents: PropTypes.string,
- offset: PropTypes.shape({
- x: PropTypes.number.isRequired,
- y: PropTypes.number.isRequired,
- }),
+ children: PropTypes.node,
+ isVisible: PropTypes.bool,
+ arrowColor: PropTypes.string,
+ arrowWidth: PropTypes.number,
+ arrowHeight: PropTypes.number,
+ placement: PropTypes.oneOf(['left', 'right', 'top', 'bottom', 'auto']),
+ pointerEvents: PropTypes.string,
+ offset: PropTypes.shape({
+ x: PropTypes.number.isRequired,
+ y: PropTypes.number.isRequired,
+ }),
};
static defaultProps = {
- children: null,
- isVisible: true,
- arrowColor: 'white',
- arrowWidth: 15,
- arrowHeight: 10,
- placement: 'auto',
- pointerEvents: 'box-none',
- offset: {
- x: 0,
- y: 0,
- },
+ children: null,
+ isVisible: true,
+ arrowColor: 'white',
+ arrowWidth: 15,
+ arrowHeight: 10,
+ placement: 'auto',
+ pointerEvents: 'box-none',
+ offset: {
+ x: 0,
+ y: 0,
+ },
};
constructor(props) {
- super(props);
- this._id = uuidv4();
+ super(props);
+ this._id = uuidv4();
}
componentDidMount() {
- if (!this.props.isVisible) {
- return;
- }
- this.registerSelf();
+ if (!this.props.isVisible) {
+ return;
+ }
+ this.registerSelf();
}
componentDidUpdate(prevProps) {
- if (prevProps.isVisible !== this.props.isVisible || prevProps.placement !== this.props.placement) {
- if (this.props.isVisible) {
- this.registerSelf();
- } else {
- this.unregisterSelf();
+ if (prevProps.isVisible !== this.props.isVisible || prevProps.placement !== this.props.placement) {
+ if (this.props.isVisible) {
+ this.registerSelf();
+ } else {
+ this.unregisterSelf();
+ }
}
- }
}
componentWillUnmount() {
- this.unregisterSelf();
+ this.unregisterSelf();
}
- setElementRef = x => {
- this._element = x;
+ setElementRef = (x) => {
+ this._element = x;
};
registerSelf() {
- // delay to the next tick to guarantee layout
- setTimeout(() => {
- if (this._element !== null) {
- const {
- arrowColor,
- arrowWidth,
- arrowHeight,
- placement,
- component,
- pointerEvents,
- offset,
- } = this.props;
- this.context.registerPopover(this._id, findNodeHandle(this._element), {
- arrowColor,
- arrowWidth,
- arrowHeight,
- placement,
- component,
- pointerEvents,
- offset,
- });
- }
- });
+ // delay to the next tick to guarantee layout
+ setTimeout(() => {
+ if (this._element !== null) {
+ const {
+ arrowColor,
+ arrowWidth,
+ arrowHeight,
+ placement,
+ component,
+ pointerEvents,
+ offset,
+ } = this.props;
+ this.context.registerPopover(this._id, findNodeHandle(this._element), {
+ arrowColor,
+ arrowWidth,
+ arrowHeight,
+ placement,
+ component,
+ pointerEvents,
+ offset,
+ });
+ }
+ });
}
unregisterSelf() {
- this.context.unregisterPopover(this._id);
+ this.context.unregisterPopover(this._id);
}
render() {
- const child = React.Children.only(this.props.children);
- return React.cloneElement(child, {
- ref: this.setElementRef,
- });
+ const child = React.Children.only(this.props.children);
+ return React.cloneElement(child, {
+ ref: this.setElementRef,
+ collapsable: false, // to avoid crashes on Android
+ });
}
}
diff --git a/lib/PopoverContainer.js b/lib/PopoverContainer.js
index db1e930..7dbaa2f 100644
--- a/lib/PopoverContainer.js
+++ b/lib/PopoverContainer.js
@@ -1,95 +1,111 @@
import React, { Component } from 'react';
-import { PanResponder, findNodeHandle, UIManager, View } from 'react-native';
+import { UIManager, View } from 'react-native';
import PropTypes from 'prop-types';
import PopoverElement from './PopoverElement';
const addKey = (obj, key, value) => ({ ...obj, [key]: value });
const delKey = (obj, key) => {
- const copy = Object.assign({}, obj);
- delete copy[key];
- return copy;
+ const copy = Object.assign({}, obj);
+ delete copy[key];
+ return copy;
};
class PopoverContainer extends Component {
static propTypes = {
- children: PropTypes.node,
- padding: PropTypes.number,
+ children: PropTypes.node,
+ padding: PropTypes.number,
};
static defaultProps = {
- children: null,
- padding: 0,
+ children: null,
+ padding: 0,
};
static childContextTypes = {
- registerPopover: PropTypes.func,
- unregisterPopover: PropTypes.func,
+ registerPopover: PropTypes.func,
+ unregisterPopover: PropTypes.func,
};
state = {
- registry: {},
- containerSize: null,
+ registry: {},
+ containerSize: null,
};
getChildContext() {
- return {
- registerPopover: this.registerPopover,
- unregisterPopover: this.unregisterPopover,
- };
+ return {
+ registerPopover: this.registerPopover,
+ unregisterPopover: this.unregisterPopover,
+ };
}
onRootLayout = ({ nativeEvent: { layout: { width, height } } }) => {
- this.setState({ containerSize: { width, height } });
+ this.setState({ containerSize: { width, height } });
};
registerPopover = (id, element, props) => {
- if (this.state.containerSize === null) {
- setTimeout(() => this.registerPopover(id, element, props));
- return;
- }
- UIManager.measureLayout(
- element,
- findNodeHandle(this._root),
- err => {
- console.error(err);
- },
- (x, y, width, height) => {
- this.setState({
- registry: addKey(this.state.registry, id, {
- rect: { x, y, width, height },
- props,
- }),
- });
- },
- );
+ if (this.state.containerSize === null) {
+ setTimeout(() => this.registerPopover(id, element, props));
+ return;
+ }
+ UIManager.measureInWindow(
+ element,
+ (x, y, width, height) => {
+ this.setState({
+ registry: addKey(this.state.registry, id, {
+ rect: {
+ x, y, width, height,
+ },
+ props,
+ }),
+ });
+ },
+ );
+ /* TODO: investigate why the code bellow doesn't work
+ UIManager.measureLayout(
+ element,
+ findNodeHandle(this._root),
+ (err) => {
+ console.error(err);
+ },
+ (x, y, width, height) => {
+ this.setState({
+ registry: addKey(this.state.registry, id, {
+ rect: {
+ x, y, width, height,
+ },
+ props,
+ }),
+ });
+ },
+ );
+ */
};
- unregisterPopover = id => {
- this.setState({ registry: delKey(this.state.registry, id) });
+ unregisterPopover = (id) => {
+ this.setState(state => ({ registry: delKey(state.registry, id) }));
};
render() {
- return (
- {
- this._root = x;
- }}
- style={{ flex: 1 }}
- onLayout={this.onRootLayout}
- >
- {this.props.children}
- {Object.entries(this.state.registry).map(([id, { rect, props }]) =>
- ,
- )}
-
- );
+ return (
+ {
+ this._root = x;
+ }}
+ style={{ flex: 1 }}
+ onLayout={this.onRootLayout}
+ >
+ {this.props.children}
+ {Object.entries(this.state.registry).map(([id, { rect, props }]) =>
+ ())}
+
+ );
}
}
diff --git a/lib/PopoverElement.js b/lib/PopoverElement.js
index 99d139c..e982493 100644
--- a/lib/PopoverElement.js
+++ b/lib/PopoverElement.js
@@ -1,9 +1,8 @@
import React, { Component } from 'react';
-import { StyleSheet, View, ViewPropTypes } from 'react-native';
+import { StyleSheet, View } from 'react-native';
import PropTypes from 'prop-types';
import computeGeometry from './computeGeometry';
import {
- PLACEMENT_OPTIONS,
capitalizeFirstLetter,
findDirectionWithoutColor,
} from './utils';
@@ -95,6 +94,9 @@ class PopoverElement extends Component {
}
measureLayout = ({ nativeEvent: { layout: { width, height } } }) => {
+ if (width === this.state.width && height === this.state.height) {
+ return;
+ }
this.setState({ width, height }, () => this.computeStyles(this.props));
};