diff --git a/native/tooltip/nux-tips-overlay.react.js b/native/tooltip/nux-tips-overlay.react.js
--- a/native/tooltip/nux-tips-overlay.react.js
+++ b/native/tooltip/nux-tips-overlay.react.js
@@ -23,6 +23,7 @@
} from '../types/layout-types.js';
import type { LayoutEvent } from '../types/react-native.js';
import { AnimatedView } from '../types/styles.js';
+import type { WritableAnimatedStyleObj } from '../types/styles.js';
const { Value } = Animated;
@@ -63,6 +64,20 @@
height: 10,
width: 10,
},
+ triangleDown: {
+ borderBottomColor: 'transparent',
+ borderBottomWidth: 0,
+ borderLeftColor: 'transparent',
+ borderLeftWidth: 10,
+ borderRightColor: 'transparent',
+ borderRightWidth: 10,
+ borderStyle: 'solid',
+ borderTopColor: 'tooltipBackground',
+ borderTopWidth: 10,
+ height: 10,
+ top: Platform.OS === 'android' ? -1 : 0,
+ width: 10,
+ },
tipText: {
color: 'panelForegroundLabel',
fontSize: 20,
@@ -73,6 +88,7 @@
export type NUXTipsOverlayParams = {
+initialCoordinates: LayoutCoordinates,
+verticalBounds: VerticalBounds,
+ +tooltipLocation: 'above' | 'below',
};
export type NUXTipsOverlayProps = {
@@ -81,7 +97,6 @@
};
const margin: number = 20;
-const tipContainerTranslateY = -80;
function opacityEnteringAnimation() {
'worklet';
@@ -159,34 +174,41 @@
[dimensions.width, initialCoordinates, tipHorizontalOffset],
);
+ const { tooltipLocation } = route.params;
+
const baseTipContainerStyle = React.useMemo(() => {
const { y, x, height, width } = initialCoordinates;
- const top =
- Math.min(y + height, verticalBounds.y + verticalBounds.height) + margin;
+ const style: WritableAnimatedStyleObj = {
+ position: 'absolute',
+ alignItems: 'center',
+ };
+
+ if (tooltipLocation === 'below') {
+ style.top =
+ Math.min(y + height, verticalBounds.y + verticalBounds.height) +
+ margin;
+ } else {
+ style.bottom =
+ dimensions.height - Math.max(y, verticalBounds.y) + margin;
+ }
const extraLeftSpace = x;
const extraRightSpace = dimensions.width - width - x;
if (extraLeftSpace < extraRightSpace) {
- return {
- top,
- position: 'absolute',
- alignItems: 'center',
- left: 0,
- minWidth: width + 2 * extraLeftSpace,
- };
+ style.left = 0;
+ style.minWidth = width + 2 * extraLeftSpace;
} else {
- return {
- top,
- position: 'absolute',
- alignItems: 'center',
- right: 0,
- minWidth: width + 2 * extraRightSpace,
- };
+ style.right = 0;
+ style.minWidth = width + 2 * extraRightSpace;
}
+
+ return style;
}, [
+ dimensions.height,
dimensions.width,
initialCoordinates,
+ tooltipLocation,
verticalBounds.height,
verticalBounds.y,
]);
@@ -232,7 +254,10 @@
initialCoordinates.width +
initialCoordinates.x) /
2;
- const initialY = tipContainerTranslateY;
+ const initialY =
+ tooltipLocation === 'below'
+ ? -values.targetHeight / 2
+ : values.targetHeight / 2;
return {
animations: {
@@ -253,7 +278,7 @@
},
};
},
- [initialCoordinates.width, initialCoordinates.x],
+ [initialCoordinates.width, initialCoordinates.x, tooltipLocation],
);
// prettier-ignore
@@ -266,7 +291,10 @@
initialCoordinates.width +
initialCoordinates.x) /
2;
- const toValueY = tipContainerTranslateY;
+ const toValueY =
+ tooltipLocation === 'below'
+ ? -values.currentHeight / 2
+ : values.currentHeight / 2;;
return {
animations: {
@@ -291,9 +319,17 @@
},
};
},
- [initialCoordinates.width, initialCoordinates.x],
+ [initialCoordinates.width, initialCoordinates.x, tooltipLocation],
);
+ let triangleDown = null;
+ let triangleUp = null;
+ if (tooltipLocation === 'above') {
+ triangleDown = ;
+ } else if (tooltipLocation === 'below') {
+ triangleUp = ;
+ }
+
return (
@@ -317,10 +353,11 @@
entering={tipContainerEnteringAnimation}
exiting={tipContainerExitingAnimation}
>
-
+ {triangleUp}
{tipText}
+ {triangleDown}