diff --git a/android/app/build.gradle b/android/app/build.gradle
index d86629608ad8..64bf1a1e2277 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -106,8 +106,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
- versionCode 1001031903
- versionName "1.3.19-3"
+ versionCode 1001031904
+ versionName "1.3.19-4"
}
splits {
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index 355af22635c2..20ec4f624b3d 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -30,7 +30,7 @@
CFBundleVersion
- 1.3.19.3
+ 1.3.19.4
ITSAppUsesNonExemptEncryption
LSApplicationQueriesSchemes
diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist
index db5615f313ec..5577345e1c83 100644
--- a/ios/NewExpensifyTests/Info.plist
+++ b/ios/NewExpensifyTests/Info.plist
@@ -19,6 +19,6 @@
CFBundleSignature
????
CFBundleVersion
- 1.3.19.3
+ 1.3.19.4
diff --git a/package-lock.json b/package-lock.json
index 3367524ac4a7..adf0670c37c5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "new.expensify",
- "version": "1.3.19-3",
+ "version": "1.3.19-4",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "new.expensify",
- "version": "1.3.19-3",
+ "version": "1.3.19-4",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 6dffeecf2af4..c0819e274327 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
- "version": "1.3.19-3",
+ "version": "1.3.19-4",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
diff --git a/src/components/AvatarCropModal/Slider.js b/src/components/AvatarCropModal/Slider.js
index cfa02a114eca..2877b3a9c917 100644
--- a/src/components/AvatarCropModal/Slider.js
+++ b/src/components/AvatarCropModal/Slider.js
@@ -49,7 +49,10 @@ const Slider = (props) => {
>
{tooltipIsVisible && (
-
+
)}
diff --git a/src/components/EmojiPicker/CategoryShortcutButton.js b/src/components/EmojiPicker/CategoryShortcutButton.js
index 738fa67ca274..567521637f19 100644
--- a/src/components/EmojiPicker/CategoryShortcutButton.js
+++ b/src/components/EmojiPicker/CategoryShortcutButton.js
@@ -33,7 +33,10 @@ class CategoryShortcutButton extends PureComponent {
render() {
return (
-
+
this.setState({isHighlighted: true})}
diff --git a/src/components/Hoverable/index.js b/src/components/Hoverable/index.js
index d6dd14679ecd..c3b26d674f86 100644
--- a/src/components/Hoverable/index.js
+++ b/src/components/Hoverable/index.js
@@ -82,6 +82,11 @@ class Hoverable extends Component {
const {ref} = child;
if (_.isFunction(ref)) {
ref(el);
+ return;
+ }
+
+ if (_.isObject(ref)) {
+ ref.current = el;
}
},
onMouseEnter: (el) => {
diff --git a/src/components/Tooltip/index.js b/src/components/Tooltip/index.js
index 5ec44447cf2d..5403cf3055b1 100644
--- a/src/components/Tooltip/index.js
+++ b/src/components/Tooltip/index.js
@@ -120,18 +120,6 @@ class Tooltip extends PureComponent {
throw Error('Children is not a valid element.');
}
- const target = React.cloneElement(React.Children.only(this.props.children), {
- ref: (el) => {
- this.wrapperView = el;
-
- // Call the original ref, if any
- const {ref} = this.props.children;
- if (_.isFunction(ref)) {
- ref(el);
- }
- },
- });
-
return (
<>
{this.state.isRendered && (
@@ -161,7 +149,7 @@ class Tooltip extends PureComponent {
onHoverIn={this.showTooltip}
onHoverOut={this.hideTooltip}
>
- {target}
+ {React.Children.only(this.props.children)}
>
diff --git a/src/styles/getTooltipStyles.js b/src/styles/getTooltipStyles.js
index 88c9845349ee..6d2e667016df 100644
--- a/src/styles/getTooltipStyles.js
+++ b/src/styles/getTooltipStyles.js
@@ -57,14 +57,17 @@ function computeHorizontalShift(windowWidth, xOffset, componentWidth, tooltipWid
* @param {Number} yOffset - The distance between the top edge of the window
* and the top edge of the wrapped component.
* @param {Element} [tooltip] - The reference to the tooltip's root element
+ * @param {Number} tooltipTargetHeight - The height of the tooltip's target
* @returns {Boolean}
*/
-function isOverlappingAtTop(xOffset, yOffset, tooltip) {
+function isOverlappingAtTop(xOffset, yOffset, tooltip, tooltipTargetHeight) {
if (typeof document.elementFromPoint !== 'function') {
return false;
}
- const element = document.elementFromPoint(xOffset, yOffset);
+ // Use the vertical center of the target to prevent wrong element returned by elementFromPoint in case the target has a border radius.
+ const centerY = yOffset + tooltipTargetHeight / 2;
+ const element = document.elementFromPoint(xOffset, centerY);
const tooltipRef = (tooltip && tooltip.current) || tooltip;
// Ensure it's not the already rendered element of this very tooltip, so the tooltip doesn't try to "avoid" itself
@@ -141,7 +144,7 @@ export default function getTooltipStyles(
// If either a tooltip will try to render within GUTTER_WIDTH logical pixels of the top of the screen,
// Or the wrapped component is overlapping at top-left with another element
// we'll display it beneath its wrapped component rather than above it as usual.
- shouldShowBelow = yOffset - tooltipHeight < GUTTER_WIDTH || isOverlappingAtTop(xOffset, yOffset, tooltip);
+ shouldShowBelow = yOffset - tooltipHeight < GUTTER_WIDTH || isOverlappingAtTop(xOffset, yOffset, tooltip, tooltipTargetHeight);
// When the tooltip size is ready, we can start animating the scale.
scale = currentSize;