Make an interactive step by step tour guide for your react-native app (a rewrite of react-native-copilot)
npm install rn-tourguide
A flexible tourguide for your react native app!
๐ Webable ๐
(a rewriting of react-native-copilot)

```
yarn add rn-tourguide
``
yarn add react-native-svg
react-native link react-native-svg
If you are using Expo:
``
expo install react-native-svg
`tsx
import {
TourGuideProvider, // Main provider
TourGuideZone, // Main wrapper of highlight component
TourGuideZoneByPosition, // Component to use mask on overlay (ie, position absolute)
useTourGuideController, // hook to start, etc.
} from 'rn-tourguide'
// Add
function App() {
return (
)
}
const AppContent = () => {
const iconProps = { size: 40, color: '#888' }
// Use Hooks to control!
const {
canStart, // a boolean indicate if you can start tour guide
start, // a function to start the tourguide
stop, // a function to stopping it
eventEmitter, // an object for listening some events
} = useTourGuideController()
// Can start at mount ๐
// you need to wait until everything is registered ๐
React.useEffect(() => {
if (canStart) {
// ๐ test if you can start otherwise nothing will happen
start()
}
}, [canStart]) // ๐ don't miss it!
const handleOnStart = () => console.log('start')
const handleOnStop = () => console.log('stop')
const handleOnStepChange = () => console.log(stepChange)
React.useEffect(() => {
eventEmitter.on('start', handleOnStart)
eventEmitter.on('stop', handleOnStop)
eventEmitter.on('stepChange', handleOnStepChange)
return () => {
eventEmitter.off('start', handleOnStart)
eventEmitter.off('stop', handleOnStop)
eventEmitter.off('stepChange', handleOnStepChange)
}
}, [])
return (
{/*
Use TourGuideZone only to wrap your component
*/}
text={'A react-native-copilot remastered! ๐'}
borderRadius={16}
>
{'Welcome to the demo of\n"rn-tourguide"'}
shape='circle'
text={'With animated SVG morphing with awesome flubber ๐ฎ๐ฏ'}
>
shape={'circle'}
isTourGuide
bottom={30}
left={35}
width={300}
height={300}
/>
)
}
`
TourGuide props:
`ts
interface TourGuideZoneProps {
zone: number // A positive number indicating the order of the step in the entire walkthrough.
tourKey?: string // A string indicating which tour the zone belongs to
isTourGuide?: boolean // return children without wrapping id false
text?: string // text in tooltip
shape?: Shape // which shape
maskOffset?: number // offset around zone
borderRadius?: number // round corner when rectangle
keepTooltipPosition?: boolean
tooltipBottomOffset?: number
children: React.ReactNode
}
type Shape = 'circle' | 'rectangle' | 'circle_and_keep' | 'rectangle_and_keep'
export interface TourGuideProviderProps {
tooltipComponent?: React.ComponentType
tooltipStyle?: StyleProp
labels?: Labels
startAtMount?: boolean | string // start at mount, boolean for single tours, string for multiple tours
androidStatusBarVisible?: boolean
backdropColor?: string
verticalOffset?: number
wrapperStyle?: StyleProp
maskOffset?: number
borderRadius?: number
animationDuration?: number
children: React.ReactNode
dismissOnPress?: boolean
preventOutsideInteraction?:boolean
}
interface TooltipProps {
isFirstStep?: boolean
isLastStep?: boolean
currentStep: Step
labels?: Labels
handleNext?(): void
handlePrev?(): void
handleStop?(): void
}
interface Labels {
skip?: string
previous?: string
next?: string
finish?: string
}
`
In order to start the tutorial, you can call the start function from useTourGuideController hook:
`js
function HomeScreen() {
const { start } = useTourGuideController()
React.useEffect(() => {
start()
}, [])
render() {
// ...
}
}
export default HomeScreen
`
If you are looking for a working example, please check out this link.
If you'd like to have multiple tours (different pages, differnt user types, etc) you can pass in a tourKey to useTourGuideController to create a tour that is keyed to that tourKey. Important If you use a keyed tour, in order for the TourGuideZone components to register correctly you _must_ do one of two things. Either (1) pass along the tourKey to the TourGuideZone components, or (2) extract the TourGuideZone components from the hook itself
(1) If you want to pass along the tourKey
`ts
import { TourGuideZone, useTourGuideController } from 'rn-tourguide'
const {
canStart, // <-- These are all keyed to the tourKey
start, // <-- These are all keyed to the tourKey
stop, // <-- These are all keyed to the tourKey
eventEmitter, // <-- These are all keyed to the tourKey
tourKey, // <-- Extract the tourKey
} = useTourGuideController('results')
return (
zone={2}
text='Check on your results'
>
{/* Children /}
)
`
Or (2) if you want to extract the components directly from the hook
`ts
import { useTourGuideController } from 'rn-tourguide'
const { canStart, start, stop, TourGuideZone } =
useTourGuideController('results')
return (
text='Check on your results'
>
{/* Children /}
)
`
If you use multiple tours and would like to use the startAtMount prop on the TourGuideProvider component, then pass in the string of the tour you'd like to start
You can customize the tooltip by passing a component to the copilot HOC maker. If you are looking for an example tooltip component, take a look at the default tooltip implementation.
`js
const TooltipComponent = ({
isFirstStep,
isLastStep,
handleNext,
handlePrev,
handleStop,
currentStep,
}) => (
// ...
);
// ...
`
You can customize tooltips style:
`tsx
const style = {
backgroundColor: '#9FA8DA',
borderRadius: 10,
paddingTop: 5,
}
// ...
`
You can customize the mask color - default is rgba(0, 0, 0, 0.4), by passing a color string to the copilot HOC maker.
`tsx`
// ...
You can localize labels:
`tsx`
labels: {
previous: 'Vorheriger',
next: 'Nรคchster',
skip: 'รberspringen',
finish: 'Beenden',
},
}}
>
// ...
Along with start(), useTourGuideController passes copilotEvents function to the component to help you with tracking of tutorial progress. It utilizes mitt under the hood, you can see how full API there.
List of available events is:
- start โ Copilot tutorial has started.stop
- โ Copilot tutorial has ended or skipped.stepChange
- โ Next step is triggered. Passes Step instance as event handler argument.
Sometimes you need to prevent users to interact with app while tour is shown, in such case preventOutsideInteraction prop is up for you.
`default: false`
`jsx``
Issues and Pull Requests are always welcome.
Looking for a ReactNative freelance expert with more than 14 years experience? Contact me from myย website!
- MIT ยฉ 2020 Xavier CARPENTIER SAS, https://xaviercarpentier.com.
- MIT ยฉ 2017 OK GROW!, https://www.okgrow.com.