react-native-tourguide
Version:
Make an interactive step by step tour guide for your react-native app (a rewrite of react-native-copilot)
317 lines (261 loc) โข 8.55 kB
Markdown
<h1 align="center">react-native-tourguide</h1>
<p align="center">
A flexible <strong>tourguide</strong> for your react native app!
<br/><small>๐ Webable ๐</small>
<br/><small>(a rewriting of react-native-copilot)</small>
</p>
<div align="center">
<p align="center">
<a href="https://www.npmjs.com/package/react-native-tourguide">
<img alt="npm downloads" src="https://img.shields.io/npm/dm/react-native-tourguide"/>
</a>
<a href="https://www.npmjs.com/package/react-native-tourguide">
<img src="https://img.shields.io/npm/v/react-native-tourguide.svg" alt="NPM Version" />
</a>
<a href="http://reactnative.gallery/xcarpentier/react-native-tourguide">
<img src="https://img.shields.io/badge/reactnative.gallery-%F0%9F%8E%AC-green.svg"/></a>
</a>
<a href="#hire-an-expert">
<img src="https://img.shields.io/badge/%F0%9F%92%AA-hire%20an%20expert-brightgreen"/>
</a>
</p>
</div>
```
yarn add react-native-tourguide
```
```
yarn add 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 'react-native-tourguide'
// Add <TourGuideProvider/> at the root of you app!
function App() {
return (
<TourGuideProvider {...{ borderRadius: 16 }}>
<AppContent />
</TourGuideProvider>
)
}
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 (
<View style={styles.container}>
{/*
Use TourGuideZone only to wrap your component
*/}
<TourGuideZone
zone={2}
text={'A react-native-copilot remastered! ๐'}
borderRadius={16}
>
<Text style={styles.title}>
{'Welcome to the demo of\n"react-native-tourguide"'}
</Text>
</TourGuideZone>
<View style={styles.middleView}>
<TouchableOpacity style={styles.button} onPress={() => start()}>
<Text style={styles.buttonText}>START THE TUTORIAL!</Text>
</TouchableOpacity>
<TourGuideZone zone={3} shape={'rectangle_and_keep'}>
<TouchableOpacity style={styles.button} onPress={() => start(4)}>
<Text style={styles.buttonText}>Step 4</Text>
</TouchableOpacity>
</TourGuideZone>
<TouchableOpacity style={styles.button} onPress={() => start(2)}>
<Text style={styles.buttonText}>Step 2</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={stop}>
<Text style={styles.buttonText}>Stop</Text>
</TouchableOpacity>
<TourGuideZone
zone={1}
shape='circle'
text={'With animated SVG morphing with awesome flubber ๐ฎ๐ฏ'}
>
<Image source={{ uri }} style={styles.profilePhoto} />
</TourGuideZone>
</View>
<View style={styles.row}>
<TourGuideZone zone={4} shape={'circle'}>
<Ionicons name='ios-contact' {...iconProps} />
</TourGuideZone>
<Ionicons name='ios-chatbubbles' {...iconProps} />
<Ionicons name='ios-globe' {...iconProps} />
<TourGuideZone zone={5}>
<Ionicons name='ios-navigate' {...iconProps} />
</TourGuideZone>
<TourGuideZone zone={6} shape={'circle'}>
<Ionicons name='ios-rainy' {...iconProps} />
</TourGuideZone>
<TourGuideZoneByPosition
zone={7}
shape={'circle'}
isTourGuide
bottom={30}
left={35}
width={300}
height={300}
/>
</View>
</View>
)
}
```
`TourGuide` props:
```ts
interface TourGuideZoneProps {
zone: number // A positive number indicating the order of the step in the entire walkthrough.
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
startAtMount?: boolean // start at mount
keepTooltipPosition?: boolean
tooltipBottomOffset?: number
children: React.ReactNode
}
type Shape = 'circle' | 'rectangle' | 'circle_and_keep' | 'rectangle_and_keep'
export interface TourGuideProviderProps {
tooltipComponent?: React.ComponentType<TooltipProps>
tooltipStyle?: StyleProp<ViewStyle>
labels?: Labels
androidStatusBarVisible?: boolean
backdropColor?: string
verticalOffset?: number
wrapperStyle?: StyleProp<ViewStyle>
maskOffset?: number
borderRadius?: number
animationDuration?: number
children: React.ReactNode
dismissOnPress: 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](https://github.com/xcarpentier/react-native-tourguide/blob/master/App.tsx).
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](https://github.com/xcarpentier/react-native-tourguide/blob/master/src/components/Tooltip.tsx).
```js
const TooltipComponent = ({
isFirstStep,
isLastStep,
handleNext,
handlePrev,
handleStop,
currentStep,
}) => (
// ...
);
<TourGuideProvider {...{tooltipComponent: TooltipComponent}}>
// ...
</TourGuideProvider>
```
You can customize tooltips style:
```tsx
const style = {
backgroundColor: '#9FA8DA',
borderRadius: 10,
paddingTop: 5,
}
<TourGuideProvider {...{ tooltipStyle: style }}>
// ...
</TourGuideProvider>
```
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
<TourGuideProvider {...{ backdropColor: 'rgba(50, 50, 100, 0.9)' }}>
// ...
</TourGuideProvider>
```
You can localize labels:
```tsx
<TourGuideProvider
{...{
labels: {
previous: 'Vorheriger',
next: 'Nรคchster',
skip: 'รberspringen',
finish: 'Beenden',
},
}}
>
// ...
</TourGuideProvider>
```
Along with `start()`, `useTourGuideController` passes `copilotEvents` function to the component to help you with tracking of tutorial progress. It utilizes [mitt](https://github.com/developit/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`](https://github.com/mohebifar/react-native-copilot/blob/master/src/types.js#L2) instance as event handler argument.
Issues and Pull Requests are always welcome.