README
Tourist Guide into your React Components
This documentation is for the latest release, which uses npm scoped package
@reactour
. The originalreactour
is now on branchv1
and its documentation can be found here.
Install
npm i -S @reactour/tour @emotion/react
# or
yarn add @reactour/tour @emotion/react
From
v2.3.0
@emotion/react
is a Peer Dependency
Usage
Add the TourProvider
at the root of your Application, passing the steps
of the elements to highlight during the Tour.
// ...
import { TourProvider } from '@reactour/tour'
ReactDOM.render(
<TourProvider steps={steps}>
<App />
</TourProvider>,
document.getElementById('root')
)
const steps = [
{
selector: '.first-step',
content: 'This is my first Step',
},
// ...
]
Then somewhere down the Application tree, control the Tour using useTour
hook.
import { useTour } from '@reactour/tour'
function App() {
const { setIsOpen } = useTour()
return (
<>
<p className="first-step">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent at
finibus nulla, quis varius justo. Vestibulum lorem lorem, viverra porta
metus nec, porta luctus orci
</p>
<button onClick={() => setIsOpen(true)}>Open Tour</button>
</>
)
}
Examples
Playground
The Playground is the perfect place to play aroud with all @reactour
Components. Here is an online version.
Sandboxes
- Using React Router
- Using React Modal
- Using Semantic UI Modal
- Using React Bootstrap Modal
- Tour with data fetching
Feel free to make a PR proposing new sandboxes or demos to add in the playground.
TourProvider
steps?: StepType[]
Array of elements to highlight with special info and props.
StepType
selector: string | Element
A string containing one CSS Selector to match and highlight the at the time of this step.
content: string | ({ setCurrentStep, transition, isHighlightingObserved, currentStep, setIsOpen }) => void
The content to show inside the Popover at the time of this step. Using a function
have parameters to use inside content.
position?: 'top' | 'right' | 'bottom' | 'left' | 'center' | [number, number]
The preferred postion to position the Popover in relation with the highlighted element. Will be automatically calculated in case of unavailable space.
highlightedSelectors?: string[]
Array of CSS Selector to be included (by union) in the highlighted region of the Mask.
mutationObservables?: string[]
Array of CSS Selector that addition or removal will triggered a rerender of the Mask shape.
resizeObservables?: string[]
Array of CSS Selector that when resizeing each will triggered a rerender of the Mask shape.
navDotAriaLabel?: string
String to assign to aria-label
attribute of the Dot of this step.
stepInteraction?: boolean
Allow to reenable the interaction for this specific step, when disableInteraction
(from TourProvider) is true
.
action?: (elem: Element | null) => void
Action fired when the Tour arrives in this step.
disableActions?: boolean
Allow to disable all possible actions (interaction with Mask, Navigation Arrows, Navigation Dots, Close button and keyboard events) when the Tour is in this step.
padding?: Padding
Control padding spaces for this specific step.
bypassElem?: boolean
Excludes the main selector
when calculating highlited area if present highlightedSelectors
.
styles?: StylesObj & PopoverStylesObj & MaskStylesObj
Customize styles fro this specific step.
components?: PopoverComponentsType
Prop to customize granurally each Component inside the Popover.
Components available
key | props |
---|---|
Badge |
styles |
Close |
styles , onClick , disabled |
Content |
content ,setCurrentStep ,transition , isHighlightingObserved ,currentStep ,setIsOpen |
Navigation |
styles ,setCurrentStep , steps , currentStep , disableDots , nextButton , prevButton , setIsOpen , hideButtons , hideDots , disableAll , rtl , Arrow , |
Arrow |
styles , inverted , disabled |
Example
import { components } from '@reactour/tour'
function Badge({ children }) {
return (
<components.Badge
styles={{ badge: base => ({ ...base, backgroundColor: 'red' }) }}
>
👉 {children} 👈
</components.Badge>
)
}
function Close({ onClick }) {
return (
<button
onClick={onClick}
style={{ position: 'absolute', right: 0, top: 0 }}
>
x
</button>
)
}
const steps = [
/* ... */
]
export default function App() {
return (
<TourProvider steps={steps} components={{ Badge, Close }}>
{/* ... */}
</TourProvider>
)
}
styles?: StylesObj & PopoverStylesObj & MaskStylesObj
Prop to customize styles for the different parts of the Mask, Popover and Tour using a function that allows to extend the base styles an take advantage of some state props.
Style keys and props available
Refer to Mask docs and Popover docs for its specific Components
Tour Components
key | props |
---|---|
badge |
|
controls |
|
button |
disabled |
arrow |
disabled |
dot |
current , disabled , showNumber |
close |
disabled |
Example
const styles = {
maskWrapper: base => ({
...base,
color: 'red',
}),
highlightedArea: (base, { x, y }) => ({
...base,
x: x + 10,
y: y + 10,
}),
badge: base => ({ ...base, color: 'blue' }),
}
padding?: Padding
Type details
type Padding =
| number
| {
mask?: ComponentPadding
popover?: ComponentPadding
wrapper?: ComponentPadding
}
// x and y same value or [x, y] handled separated
type ComponentPadding = number | [number, number]
Extra space to add between the Mask and the Popover and the highlighted element. A single number coordinates both spaces. Otherwise, passing an Object
specifying the Component space.
position?: Position
Type details
type Position =
| 'top'
| 'right'
| 'bottom'
| 'left'
| 'center'
| [number, number]
| ((postionsProps: PositionProps) => Position)
type PositionProps = {
bottom: number
height: number
left: number
right: number
top: number
width: number
windowWidth: number
windowHeight: number
}
Set a global position for the Popover in all steps, fixed in case of [number, number]
, calculated in case of position string
setCurrentStep: Dispatch<React.SetStateAction<number>>
Function to control the Tour current step state.
currentStep: number
Custom Tour current step
state.
This option could be overrided on specific steps using stepInteraction
prop.
disableInteraction?: boolean
Disables the ability to click or interact in any way with the Highlighted element on every step.
This option could be overrided on specific steps using stepInteraction
prop.
disableFocusLock?: boolean
The Tour uses FocusScope in order to lock the focus
iteration inside the Popover when Tour is active. This prop allows to disable this behaviour.
disableDotsNavigation?: boolean
Disable interactivity with Dot navigation inside Popover.
disableKeyboardNavigation?: boolean | KeyboardParts[]
Type details
type KeyboardParts = 'esc' | 'left' | 'right'
Disable all keyboard navigation events when true
, disable only selected keys when array.
default: false
className?: string
Class assigned to Popover.
default: reactour__popover
maskClassName?: string
Class assigned to Mask.
default: reactour__mask
highlightedMaskClassName?: string
Class assigned to highlighted part of Mask. Useful when using disableInteraction
.
nextButton?: (props: BtnFnProps) => void
prevButton?: (props: BtnFnProps) => void
Type details
type BtnFnProps = {
Button: React.FC<NavButtonProps>
setCurrentStep: Dispatch<React.SetStateAction<number>>
stepsLength: number
currentStep: number
setIsOpen: Dispatch<React.SetStateAction<Boolean>>
}
type NavButtonProps = {
onClick?: () => void
kind?: 'next' | 'prev'
hideArrow?: boolean
}
Helper functions to customize the Next and Prev buttons inside Popover, with useful parameters. It is possible to use the base Button
and customize the props.
afterOpen?: (target: Element | null) => void
Action fired just after the Tour is open.
beforeClose?: (target: Element | null) => void
Action fired just before the Tour is closed.
onClickMask?: (clickProps: ClickProps) => void
Type details
type ClickProps = {
setIsOpen: Dispatch<React.SetStateAction<Boolean>>
setCurrentStep: Dispatch<React.SetStateAction<number>>
currentStep: number
steps: StepType[]
}
Function that overrides the default close behavior of the Mask click handler. Comes with useful parameters to play with.
onClickClose?: (clickProps: ClickProps) => void
Type details
type ClickProps = {
setIsOpen: Dispatch<React.SetStateAction<Boolean>>
setCurrentStep: Dispatch<React.SetStateAction<number>>
currentStep: number
}
Function that overrides the default close behavior of the Close icon click handler. Comes with useful parameters to play with.
onClickHighlighted?: MouseEventHandler<SVGRectElement>
Click handler for highlighted area. Only works when disableInteraction
is active. Useful in case is needed to avoid onClickMask
when clicking the highlighted element.
Example
<TourProvider
steps={steps}
disableInteraction
onClickHighlighted={e => {
e.stopPropagation()
console.log('No interaction at all')
}}
>
{/* ... */}
</TourProvider>
badgeContent?: (badgeProps: BadgeProps) => any
Type details
type BadgeProps = {
totalSteps: number
currentStep: number
transition: boolean
}
Function to customize the content of the Badge using helper parameters like the current and total steps and if the Tour is transitioning between steps.
showNavigation?: boolean
Show or hide the Navigation (Prev and Next buttons and Dots) inside Popover.
showPrevNextButtons?: boolean
Show or hide Prev and Next buttons inside Popover.
showCloseButton?: boolean
Show or hide the Close button inside Popover.
showBadge?: boolean
Show or hide the Badge inside Popover.
scrollSmooth?: boolean
Activate smooth
scroll behavior when steps are outside viewport.
default: false
inViewThreshold?: { x?: number, y?: number } | number
Tolerance in pixels to add when calculating if the step element is outside viewport to scroll into view.
accessibilityOptions?: A11yOptions
Type details
type A11yOptions = {
ariaLabelledBy: string
closeButtonAriaLabel: string
showNavigationScreenReaders: boolean
}
Configure generic accessibility related attributes like aria-labelledby, aria-label for Close button and if show or hide Dot navigation in screen readers.
rtl?: boolean
Option to navigate and show Navigation in right-to-left mode
ContentComponent?: ComponentType<PopoverContentProps>
Completelly custom component to rendere inside the Popover.
Type details
type PopoverContentProps = {
styles?: StylesObj & PopoverStylesObj & MaskStylesObj
badgeContent?: (badgeProps: BadgeProps) => any
components?: PopoverComponentsType
accessibilityOptions?: A11yOptions
disabledActions?: boolean
onClickClose?: (clickProps: ClickProps) => void
setCurrentStep: Dispatch<React.SetStateAction<number>>
currentStep: number
transition?: boolean
isHighlightingObserved?: boolean
setIsOpen: Dispatch<React.SetStateAction<Boolean>>
steps: StepType[]
showNavigation?: boolean
showPrevNextButtons?: boolean
showCloseButton?: boolean
showBadge?: boolean
nextButton?: (props: BtnFnProps) => void
prevButton?: (props: BtnFnProps) => void
disableDotsNavigation?: boolean
rtl?: boolean
}
Example
function ContentComponent(props) {
const isLastStep = props.currentStep === props.steps.length - 1
return (
<div style={{ border: '5px solid red', padding: 10, background: 'white' }}>
{props.steps[props.currentStep].content}
<button
onClick={() => {
if (isLastStep) {
props.setIsOpen(false)
} else {
props.setCurrentStep(s => s + 1)
}
}}
>
{isLastStep ? 'x' : '>'}
</button>
</div>
)
}
const steps = [
/* ... */
]
function App() {
return (
<TourProvider
steps={steps}
ContentComponent={ContentComponent}
styles={{ popover: base => ({ ...base, padding: 0 }) }}
>
{/* ... */}
</TourProvider>
)
}
useTour
Later in any Component down in the tree of TourProvider you can control the Tour in many ways
import { useTour } from '@reactour/tour'
function MyComponent() {
const { isOpen, currentStep, steps, setIsOpen, setCurrentStep } = useTour()
return (
<>
<h1>{isOpen ? 'Welcome to the tour!' : 'Thank you for participate!'}</h1>
<p>
Now you are visiting the place {currentStep + 1} of {steps.length}
</p>
<nav>
<button onClick={() => setIsOpen(o => !o)}>Toggle Tour</button>
<button onClick={() => setCurrentStep(3)}>
Take a fast way to 4th place
</button>
<button
onClick={() =>
setSteps([
{ selector: '.new-place-1', content: 'New place 1' },
{ selector: '.new-place-2', content: 'New place 2' },
])
setCurrentStep(1)
}
>
Switch to a new set of places, starting from the last one!
</button>
</nav>
</>
)
}
isOpen: Boolean
Is the Tour open or close
currentStep: number
The current step. zero based
steps: StepType[]
The Array
of steps set currently
setIsOpen: Dispatch<React.SetStateAction<Boolean>>
SetState
function open or close Tour
setSteps: Dispatch<React.SetStateAction<StepType[]>>
SetState
function to update the Array
of steps
withTour
In case you needed there is an enhacer that allows you to have all useTour
functionalities through a Higher Order Component.
import { Component } from 'react'
import { withTour } from '@reactour/tour'
class MyComponent extends Component {
render() {
return (
<>
<button onClick={() => this.props.setIsOpen(true)}>Start Tour</button>
<div>{/* ... */}</div>
</>
)
}
}
export defatult withTour(MyCompnent)