-
-
+ return (
+
+
-
-
- {
- items.map((item) => {
- return (
-
- );
- })
- }
+
+ {
+ items.map((item) => {
+ return (
+
+ );
+ })
+ }
+
-
+ );
+ }
}
-
+ />
);
}
}
diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js
index a127feaed..74a0d53f8 100644
--- a/frontend/src/Components/Form/EnhancedSelectInput.js
+++ b/frontend/src/Components/Form/EnhancedSelectInput.js
@@ -87,6 +87,9 @@ class EnhancedSelectInput extends Component {
constructor(props, context) {
super(props, context);
+ this._buttonRef = {};
+ this._optionsRef = {};
+
this.state = {
isOpen: false,
selectedIndex: getSelectedIndex(props),
@@ -106,14 +109,6 @@ class EnhancedSelectInput extends Component {
//
// Control
- _setButtonRef = (ref) => {
- this._buttonRef = ref;
- }
-
- _setOptionsRef = (ref) => {
- this._optionsRef = ref;
- }
-
_addListener() {
window.addEventListener('click', this.onWindowClick);
}
@@ -126,8 +121,8 @@ class EnhancedSelectInput extends Component {
// Listeners
onWindowClick = (event) => {
- const button = ReactDOM.findDOMNode(this._buttonRef);
- const options = ReactDOM.findDOMNode(this._optionsRef);
+ const button = ReactDOM.findDOMNode(this._buttonRef.current);
+ const options = ReactDOM.findDOMNode(this._optionsRef.current);
if (!button || this.state.isMobile) {
return;
@@ -276,75 +271,91 @@ class EnhancedSelectInput extends Component {
element: styles.tether
}}
{...tetherOptions}
- >
-
-
-
- {selectedOption ? selectedOption.value : null}
-
+ renderTarget={
+ (ref) => {
+ this._buttonRef = ref;
-
-
-
-
-
+ return (
+
+
+
+
+ {selectedOption ? selectedOption.value : null}
+
- {
- isOpen && !isMobile &&
-
-
- {
- values.map((v, index) => {
- return (
-
- {v.value}
-
- );
- })
- }
-
-
+
+
+
+
+
+
+ );
+ }
}
-
+ renderElement={
+ (ref) => {
+ this._optionsRef = ref;
+
+ if (!isOpen || isMobile) {
+ return;
+ }
+
+ return (
+
+
+ {
+ values.map((v, index) => {
+ return (
+
+ {v.value}
+
+ );
+ })
+ }
+
+
+ );
+ }
+ }
+ />
{
isMobile &&
diff --git a/frontend/src/Components/Menu/Menu.js b/frontend/src/Components/Menu/Menu.js
index da778bb7a..946b7e0ec 100644
--- a/frontend/src/Components/Menu/Menu.js
+++ b/frontend/src/Components/Menu/Menu.js
@@ -38,6 +38,9 @@ class Menu extends Component {
constructor(props, context) {
super(props, context);
+ this._menuRef = {};
+ this._menuContentRef = {};
+
this.state = {
isMenuOpen: false,
maxHeight: 0
@@ -60,7 +63,7 @@ class Menu extends Component {
return;
}
- const menu = ReactDOM.findDOMNode(this.refs.menu);
+ const menu = ReactDOM.findDOMNode(this._menuRef.current);
if (!menu) {
return;
@@ -73,9 +76,13 @@ class Menu extends Component {
}
setMaxHeight() {
- this.setState({
- maxHeight: this.getMaxHeight()
- });
+ const maxHeight = this.getMaxHeight();
+
+ if (maxHeight !== this.state.maxHeight) {
+ this.setState({
+ maxHeight
+ });
+ }
}
_addListener() {
@@ -99,10 +106,10 @@ class Menu extends Component {
// Listeners
onWindowClick = (event) => {
- const menu = ReactDOM.findDOMNode(this.refs.menu);
- const menuContent = ReactDOM.findDOMNode(this.refs.menuContent);
+ const menu = ReactDOM.findDOMNode(this._menuRef.current);
+ const menuContent = ReactDOM.findDOMNode(this._menuContentRef.current);
- if (!menu) {
+ if (!menu || !menuContent) {
return;
}
@@ -116,7 +123,17 @@ class Menu extends Component {
this.setMaxHeight();
}
- onWindowScroll = () => {
+ onWindowScroll = (event) => {
+ if (!this._menuContentRef.current) {
+ return;
+ }
+
+ const menuContent = ReactDOM.findDOMNode(this._menuContentRef.current);
+
+ if (menuContent && menuContent.contains(event.target)) {
+ return;
+ }
+
this.setMaxHeight();
}
@@ -158,35 +175,46 @@ class Menu extends Component {
}
);
- const content = React.cloneElement(
- childrenArray[1],
- {
- ref: 'menuContent',
- alignMenu,
- maxHeight,
- isOpen: isMenuOpen
- }
- );
-
return (
-
- {button}
-
+ renderTarget={
+ (ref) => {
+ this._menuRef = ref;
- {
- isMenuOpen &&
- content
+ return (
+
+ {button}
+
+ );
+ }
}
-
+ renderElement={
+ (ref) => {
+ this._menuContentRef = ref;
+
+ if (!isMenuOpen) {
+ return null;
+ }
+
+ return React.cloneElement(
+ childrenArray[1],
+ {
+ ref,
+ alignMenu,
+ maxHeight,
+ isOpen: isMenuOpen
+ }
+ );
+ }
+ }
+ />
);
}
}
diff --git a/frontend/src/Components/Tooltip/Popover.js b/frontend/src/Components/Tooltip/Popover.js
index c958fce1b..567815654 100644
--- a/frontend/src/Components/Tooltip/Popover.js
+++ b/frontend/src/Components/Tooltip/Popover.js
@@ -105,42 +105,53 @@ class Popover extends Component {
element: styles.tether
}}
{...tetherOptions[position]}
- >
-
- {anchor}
-
-
- {
- this.state.isOpen &&
-
(
+
-
-
+ {anchor}
+
+ )
+ }
+ renderElement={
+ (ref) => {
+ if (!this.state.isOpen) {
+ return null;
+ }
-
- {title}
-
+ return (
+
+
+
-
- {body}
+
+ {title}
+
+
+
+ {body}
+
-
+ );
+ }
}
-
+ />
);
}
}
diff --git a/frontend/src/Components/Tooltip/Tooltip.js b/frontend/src/Components/Tooltip/Tooltip.js
index 43caf87e8..40293081c 100644
--- a/frontend/src/Components/Tooltip/Tooltip.js
+++ b/frontend/src/Components/Tooltip/Tooltip.js
@@ -105,44 +105,55 @@ class Tooltip extends Component {
element: styles.tether
}}
{...tetherOptions[position]}
- >
-
- {anchor}
-
-
- {
- this.state.isOpen &&
-
(
+
+ {anchor}
+
+ )
+ }
+ renderElement={
+ (ref) => {
+ if (!this.state.isOpen) {
+ return;
+ }
+
+ return (
+ >
+
-
- {tooltip}
+
+ {tooltip}
+
-
+ );
+ }
}
-
+ />
);
}
}
diff --git a/package.json b/package.json
index 2af318098..bfe56581d 100644
--- a/package.json
+++ b/package.json
@@ -101,7 +101,7 @@
"react-router-dom": "4.3.1",
"react-slider": "0.11.2",
"react-tabs": "3.0.0",
- "react-tether": "1.0.1",
+ "react-tether": "2.0.0",
"react-text-truncate": "0.14.0",
"react-virtualized": "9.21.0",
"redux": "4.0.1",
diff --git a/yarn.lock b/yarn.lock
index 0116c2e18..cbb53cf77 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6940,13 +6940,13 @@ react-tabs@3.0.0:
classnames "^2.2.0"
prop-types "^15.5.0"
-react-tether@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/react-tether/-/react-tether-1.0.1.tgz#6e5173764d4f9b8bef6d1b20ff51972909674942"
- integrity sha512-OsgGk2hmsIpnpMl1Uq9aYKopG4V7bDuz2msNYPaRosF0CBbpa1YVF9P1qJ8MRsf1Zj/oK/I2uH++S+ffqxL98A==
+react-tether@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/react-tether/-/react-tether-2.0.0.tgz#84928b9636f1fe0a6874d1e450e7822e87f8cb07"
+ integrity sha512-iJnqTQV42Pf7w4xrg3g1gxSxbBCXleDt8AzlSoAqRINqB+mhcJUeegpB8SFMJ/nKT7lSfMkx3GvUfYY+9sPBGw==
dependencies:
- prop-types "^15.5.8"
- tether "^1.4.3"
+ prop-types "^15.6.2"
+ tether "^1.4.5"
react-text-truncate@0.14.0:
version "0.14.0"
@@ -8243,7 +8243,7 @@ terser@^3.16.1:
source-map "~0.6.1"
source-map-support "~0.5.9"
-tether@^1.4.3:
+tether@^1.4.5:
version "1.4.5"
resolved "https://registry.yarnpkg.com/tether/-/tether-1.4.5.tgz#8efd7b35572767ba502259ba9b1cc167fcf6f2c1"
integrity sha512-fysT1Gug2wbRi7a6waeu39yVDwiNtvwj5m9eRD+qZDSHKNghLo6KqP/U3yM2ap6TNUL2skjXGJaJJTJqoC31vw==