Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 48 additions & 11 deletions package/src/lib/components/tour-overlay/TourOverlay.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ import {
import {
Animated,
type ColorValue,
Dimensions,
type LayoutRectangle,
Modal,
Platform,
StatusBar,
View,
} from "react-native";
import { Defs, Mask, Rect, Svg } from "react-native-svg";
Expand Down Expand Up @@ -83,6 +85,32 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,

const arrowRef = useRef<View>(null);

// Get actual screen dimensions for edge-to-edge support
const screenDimensions = useMemo(() => {
const { width, height } = Dimensions.get('screen');
const statusBarHeight = Platform.OS === 'android' ? StatusBar.currentHeight || 0 : 0;

// For Android edge-to-edge, use full screen dimensions
return {
width,
height: Platform.OS === 'android' ? height : height,
viewBoxWidth: width,
viewBoxHeight: Platform.OS === 'android' ? height : height,
statusBarHeight,
};
}, []);

// Adjust spot position for status bar offset when using statusBarTranslucent
const adjustedSpot = useMemo(() => {
if (Platform.OS === 'android' && screenDimensions.statusBarHeight > 0) {
return {
...spot,
y: spot.y + screenDimensions.statusBarHeight,
};
}
return spot;
}, [spot, screenDimensions.statusBarHeight]);

const floating = useMemo((): TooltipProps => ({
arrow: tourStep.arrow ?? tooltipProps.arrow,
flip: tourStep.flip ?? tooltipProps.flip,
Expand Down Expand Up @@ -150,7 +178,7 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,
}, [tourStep, onBackdropPress, current, goTo, next, previous, start, stop, pause, resume]);

useEffect(() => {
const { height, width } = spot;
const { height, width } = adjustedSpot;

if ([height, width].every(value => value > 0)) {
Animated.timing(tooltipOpacity.current, {
Expand All @@ -161,7 +189,7 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,
})
.start();
}
}, [spot, useNativeDriver]);
}, [adjustedSpot, useNativeDriver]);

useImperativeHandle<TourOverlayRef, TourOverlayRef>(ref, () => ({
hideTooltip: () => {
Expand All @@ -187,22 +215,31 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,
supportedOrientations={["portrait", "landscape", "landscape-left", "landscape-right", "portrait-upside-down"]}
transparent={true}
visible={current !== undefined}
statusBarTranslucent
>
<View testID="Overlay View" style={Css.overlayView}>
<Svg
<View
testID="Overlay View"
style={[
Css.overlayView,
{
height: screenDimensions.height,
width: screenDimensions.width,
}
]}
> <Svg
testID="Spot Svg"
height={vh(100)}
width={vw(100)}
viewBox={`0 0 ${vw(100)} ${vh(100)}`}
height={screenDimensions.height}
width={screenDimensions.width}
viewBox={`0 0 ${screenDimensions.viewBoxWidth} ${screenDimensions.viewBoxHeight}`}
onPress={handleBackdropPress}
shouldRasterizeIOS={true}
renderToHardwareTextureAndroid={true}
>
<Defs>
<Mask id="mask" x={0} y={0} height="100%" width="100%">
<Rect height={vh(100)} width={vw(100)} fill="#fff" />
<Rect height={screenDimensions.height} width={screenDimensions.width} fill="#fff" />
<ShapeMask
spot={spot}
spot={adjustedSpot}
setReference={refs.setReference}
motion={stepMotion}
padding={shapeOptions.padding}
Expand All @@ -211,8 +248,8 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,
</Mask>
</Defs>
<Rect
height={vh(100)}
width={vw(100)}
height={screenDimensions.height}
width={screenDimensions.width}
fill={color}
mask="url(#mask)"
opacity={backdropOpacity}
Expand Down
9 changes: 6 additions & 3 deletions package/src/lib/components/tour-overlay/TourOverlay.styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dimensions } from "react-native";
import { Platform, StyleSheet, type ViewStyle } from "react-native";

import { vh, vw } from "../../../helpers/responsive";

import type { Optional } from "../../../helpers/common";
import type { ArrowOptions } from "../../SpotlightTour.context";
Expand All @@ -20,8 +20,11 @@ export const DEFAULT_ARROW: Required<ArrowOptions> = {

export const Css = StyleSheet.create({
overlayView: {
height: vh(100),
width: vw(100),
position: "absolute",
top: 0,
left: 0,
height: Dimensions.get("screen").height,
width: Dimensions.get("screen").width,
},
tooltipArrow: {
backgroundColor: "transparent",
Expand Down