Skip to content

Commit b80cb44

Browse files
committed
fix : android issue
1 parent e76274d commit b80cb44

File tree

1 file changed

+50
-43
lines changed

1 file changed

+50
-43
lines changed

src/HighLightToolTip.tsx

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import {
88
type LayoutRectangle,
99
Dimensions,
1010
Platform,
11-
type LayoutChangeEvent,
1211
InteractionManager,
1312
} from 'react-native';
1413

@@ -45,52 +44,55 @@ export const HighlightToolTip: React.FC<HighlightOverlayProps> = ({
4544
androidOffsetY = 0,
4645
}) => {
4746
const [hole, setHole] = useState<LayoutRectangle | null>(null);
48-
const [tooltipLayout, setTooltipLayout] = useState<{
49-
width: number;
50-
height: number;
51-
} | null>(null);
5247
const { width: screenWidth, height: screenHeight } = Dimensions.get('window');
5348

5449
useEffect(() => {
5550
const task = InteractionManager.runAfterInteractions(() => {
56-
if (targetRef.current) {
57-
const handle = findNodeHandle(targetRef.current);
58-
if (handle) {
59-
UIManager.measureInWindow(
60-
handle,
61-
(x: number, y: number, width: number, height: number) => {
62-
const isAndroid = Platform.OS === 'android';
63-
setHole({
64-
x,
65-
y: isAndroid ? y + androidOffsetY : y,
66-
width,
67-
height,
68-
});
51+
if (!targetRef.current) {
52+
return;
53+
}
54+
const handle = findNodeHandle(targetRef.current);
55+
if (handle) {
56+
UIManager.measureInWindow(
57+
handle,
58+
(x: number, y: number, width: number, height: number) => {
59+
if ([x, y, width, height].some((val) => isNaN(val))) {
60+
console.warn(
61+
'HighlightToolTip: Failed to measure target component.'
62+
);
63+
return;
6964
}
70-
);
71-
}
65+
66+
const isAndroid = Platform.OS === 'android';
67+
setHole({
68+
x,
69+
y: isAndroid ? y + androidOffsetY : y,
70+
width,
71+
height,
72+
});
73+
}
74+
);
7275
}
7376
});
7477

75-
return () => task.cancel();
78+
return () => {
79+
task.cancel();
80+
};
7681
}, [targetRef, androidOffsetY]);
7782

78-
const onTooltipLayout = (event: LayoutChangeEvent) => {
79-
const { width, height } = event.nativeEvent.layout;
80-
if (tooltipLayout?.width !== width || tooltipLayout?.height !== height) {
81-
setTooltipLayout({ width, height });
82-
}
83-
};
84-
8583
const getTooltipPosition = () => {
86-
if (!hole || !tooltipLayout) {
87-
return { top: 0, left: 0, opacity: 0 };
88-
}
84+
if (!hole) return { top: 0, left: 0 };
8985

9086
const { x: offsetX = 0, y: offsetY = 0 } = offset;
91-
const margin = allowOverlap ? -4 : 24;
92-
const { width: tooltipWidth, height: tooltipHeight } = tooltipLayout;
87+
// Adjust margin based on allowOverlap - use larger margin to prevent overlap
88+
const margin = allowOverlap ? -4 : 24; // Negative margin when overlap is allowed, otherwise larger margin
89+
90+
// Calculate tooltip size dynamically based on screen size
91+
const maxTooltipWidth = Math.min(screenWidth * 0.8, 320); // Max 80% of screen width or 320px
92+
const tooltipWidth = maxTooltipWidth;
93+
const tooltipHeight = 120; // Adjust to actual height + extra space
9394

95+
// Calculate initial position
9496
let calculatedPosition = { top: 0, left: 0 };
9597

9698
switch (tooltipPosition) {
@@ -167,26 +169,39 @@ export const HighlightToolTip: React.FC<HighlightOverlayProps> = ({
167169
};
168170
}
169171

172+
// Check screen boundaries and auto-adjust
170173
let { top, left } = calculatedPosition;
174+
175+
// Fixed margin for screen boundary adjustment (always positive)
171176
const boundaryMargin = 16;
172177

178+
// Left boundary check
173179
if (left < boundaryMargin) {
174180
left = boundaryMargin;
175181
}
176182

183+
// Right boundary check - ensure tooltip doesn't extend beyond screen
177184
if (left + tooltipWidth > screenWidth - boundaryMargin) {
178185
left = screenWidth - tooltipWidth - boundaryMargin;
186+
// If still not enough space, adjust tooltip width
187+
if (left < boundaryMargin) {
188+
left = boundaryMargin;
189+
}
179190
}
180191

192+
// Top boundary check
181193
if (top < boundaryMargin) {
194+
// If it goes above, move to bottom - maintain allowOverlap setting
182195
if (tooltipPosition.includes('top')) {
183196
top = hole.y + hole.height + (allowOverlap ? -4 : 24);
184197
} else {
185198
top = boundaryMargin;
186199
}
187200
}
188201

202+
// Bottom boundary check
189203
if (top + tooltipHeight > screenHeight - boundaryMargin) {
204+
// If it goes below, move to top - maintain allowOverlap setting
190205
if (tooltipPosition.includes('bottom')) {
191206
top = hole.y - tooltipHeight - (allowOverlap ? -4 : 24);
192207
} else {
@@ -197,17 +212,11 @@ export const HighlightToolTip: React.FC<HighlightOverlayProps> = ({
197212
return {
198213
top: top + offsetY,
199214
left: left + offsetX,
200-
opacity: 1,
201-
maxWidth: screenWidth * 0.9,
215+
maxWidth: tooltipWidth,
202216
};
203217
};
204218

205-
const isHoleLayoutInvalid =
206-
!hole || [hole.x, hole.y, hole.width, hole.height].some(isNaN);
207-
208-
if (isHoleLayoutInvalid) {
209-
return null;
210-
}
219+
if (!hole) return null;
211220

212221
const tooltipStyle = getTooltipPosition();
213222

@@ -265,12 +274,10 @@ export const HighlightToolTip: React.FC<HighlightOverlayProps> = ({
265274

266275
{/* Tooltip */}
267276
<View
268-
onLayout={onTooltipLayout}
269277
style={{
270278
position: 'absolute',
271279
top: tooltipStyle.top,
272280
left: tooltipStyle.left,
273-
opacity: tooltipStyle.opacity,
274281
maxWidth: tooltipStyle.maxWidth,
275282
}}
276283
>

0 commit comments

Comments
 (0)