Skip to main content

Overlays

The contentComponent you pass to useWalkthroughStep (or the WalkthroughStep component) is what gets rendered on top of the mask while the step is active. It receives ContentComponentProps, which provides the current step (including its mask) and the walkthrough context ctx (with next, previous, goTo, and stop).

You are free to render anything you like, the library just provides the context and the mask position.

A minimal content component

A content component is a plain React component. It receives ContentComponentProps (ctx (the walkthrough context) and step (the current step)), plus whatever extra props the step configured through contentComponentProps.

import type { ContentComponentProps } from "rn-interactive-walkthrough";
import { View, Text, Button } from "react-native";

interface WelcomeMessageProps extends ContentComponentProps {
title: string;
}

const WelcomeMessage = ({ title, ctx }: WelcomeMessageProps) => {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>{title}</Text>
<Button title="Next" onPress={ctx.next} />
</View>
);
};
<WalkthroughStep
number={1}
contentComponent={WelcomeMessage}
contentComponentProps={{
title: "Let's take a quick tour!",
}}
>
...
</WalkthroughStep>

The generic on useWalkthroughStep<P> (and the equivalent WalkthroughStepProps<P>) ties contentComponent and contentComponentProps to the same P, so your extra props stay fully type-safe.

Full-screen overlays

Set fullScreen: true to blank out the entire screen and render your overlay on top of it. This is great for welcome screens and introductions.

const { onLayout } = useWalkthroughStep({
number: 1,
fullScreen: true,
contentComponent: WelcomeMessage,
contentComponentProps: {
title: "Let's take a quick tour!",
},
});

Overlays positioned relative to a mask

For non-full-screen steps, destructure step to position your tooltip relative to the highlighted area. The mask provides x, y, width, and height in absolute screen coordinates.

import type { ContentComponentProps } from "rn-interactive-walkthrough";

interface WalkthroughTooltipProps extends ContentComponentProps {
title: string;
body: string;
}

const WalkthroughTooltip = ({ title, body, step }: WalkthroughTooltipProps) => {
const mask = step.computedMask ?? step.mask;
return (
<View
style={{
position: "absolute",
top: mask.y + mask.height + 16,
left: 50,
}}
>
<Text>{title}</Text>
<Text>{body}</Text>
</View>
);
};
const { onLayout } = useWalkthroughStep({
number: 2,
contentComponent: WalkthroughTooltip,
contentComponentProps: {
title: "Nearby users",
body: "These are all your friends nearby!",
},
});

step.mask is the raw measured rectangle; step.computedMask is the mask after layoutAdjustments have been applied. The library renders the computed mask, so position against step.computedMask ?? step.mask to stay in sync.

Because the overlay is just a React component, you can render it as a callout with an arrow, a modal, a bottom sheet, or whatever fits your design. Navigation functions like next and previous are available on ctx, so add them to your component whenever you need buttons.

Making the mask pressable

By default the highlighted area is blocked from receiving touches, so tapping it does nothing. Pass maskAllowInteraction: true to let the user press whatever is under the mask.

const { onLayout } = useWalkthroughStep({
number: 2,
maskAllowInteraction: true,
contentComponent: WalkthroughTooltip,
});

Press handlers

You can also attach your own press handlers to the mask and the backdrop:

  • onPressMask: called when the user taps the highlighted area
  • onPressBackdrop: called when the user taps anywhere outside the mask

Both receive the walkthrough context, so you can do things like advance or stop the tour.

const { onLayout } = useWalkthroughStep({
number: 2,
onPressMask: (ctx) => ctx?.next(),
onPressBackdrop: (ctx) => ctx?.stop(),
contentComponent: WalkthroughTooltip,
});

Passing props to a content component

Extra props are passed to your content component via contentComponentProps, and you add them to your component's props by extending ContentComponentProps. The examples above show this pattern with title and body.

You can also set a contentComponent on the WalkthroughProvider to use the same component for every step. This lets you avoid specifying the component on each useWalkthroughStep.

const App = () => {
return (
<WalkthroughProvider contentComponent={WalkthroughTooltip}>
{/* Your app */}
</WalkthroughProvider>
);
};

When using a provider-level content component, pass its props type as the generic to useWalkthroughStep so that contentComponentProps is typed correctly:

const { onLayout } = useWalkthroughStep<WalkthroughTooltipProps>({
number: 2,
contentComponentProps: {
title: "Nearby users",
body: "These are all your friends nearby!",
},
});

The provider's contentComponent is only a default. You can always override it for an individual step:

const { onLayout } = useWalkthroughStep({
number: 3,
contentComponent: WelcomeMessage,
contentComponentProps: {
title: "Let's take a quick tour!",
},
});

This allows you to use one shared content component by default while still customizing individual steps when needed.