@reactour/tour
examples
Basic example
This is the minimal example
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps}> <Main /> </TourProvider> ) }
Mask click
Example to show the customizable behavior of the Mask click event. Try clicking the Mask and the Tour will proceed to the next step.
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} onClickMask={({ setCurrentStep, currentStep, steps, setIsOpen }) => { if (steps) { if (currentStep === steps.length - 1) { setIsOpen(false) } setCurrentStep((s) => (s === steps.length - 1 ? 0 : s + 1)) } }}> <Main /> </TourProvider> ) }
Close click
Example to show the customizable behavior of the Close click event. Try clicking the 'x' and the Tour will proceed to the next step.
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} onClickClose={({ setCurrentStep, currentStep, steps, setIsOpen }) => { if (steps) { if (currentStep === steps.length - 1) { setIsOpen(false) } setCurrentStep((s) => (s === steps.length - 1 ? 0 : s + 1)) } }}> <Main /> </TourProvider> ) }
Disable Keyboard
Example to show how to disable keyboard behavior.
import { TourProvider } from '@reactour/tour' import { useState } from 'react' import { steps } from './steps.js' import Main from './Main.js' export default function App () { const [disableKeyboardNavigation, setDisable] = useState([ 'esc', ]) function onChange(event) { let updatedList = [...disableKeyboardNavigation]; if (event.target.checked) { updatedList = [...disableKeyboardNavigation, event.target.value]; } else { updatedList.splice(disableKeyboardNavigation.indexOf(event.target.value), 1); } setDisable(updatedList); } return ( <> <pre className="demo-selectors"> <code>Disabled keys: <label> <input type="checkbox" name="dk" value="left" onChange={onChange} checked={disableKeyboardNavigation.includes("left")} /> left </label> <label> <input type="checkbox" name="dk" value="right" onChange={onChange} checked={disableKeyboardNavigation.includes("right")} /> right </label> <label> <input type="checkbox" name="dk" value="esc" onChange={onChange} checked={disableKeyboardNavigation.includes("esc")} /> esc </label> </code> </pre> <TourProvider steps={steps} disableKeyboardNavigation={disableKeyboardNavigation} > <Main /> </TourProvider> </> ) }
Scroll Smooth
Use smooth scroll between steps if they aren't visible in viewport
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} scrollSmooth> <Main /> </TourProvider> ) }
Padding
Custom wrapper, mask and popover paddings
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} padding={{ mask: 14, popover: [5, 10], wrapper: 20 }} > <Main /> </TourProvider> ) }
Prev and Next buttons
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} prevButton={({ currentStep, setCurrentStep, steps }) => { const first = currentStep === 0 return ( <button onClick={() => { if (first) { setCurrentStep((s) => steps.length - 1) } else { setCurrentStep((s) => s - 1) } }} > Back </button> ) }} nextButton={({ Button, currentStep, stepsLength, setIsOpen, setCurrentStep, steps, }) => { const last = currentStep === stepsLength - 1 return ( <Button onClick={() => { if (last) { setIsOpen(false) } else { setCurrentStep((s) => (s === steps?.length - 1 ? 0 : s + 1)) } }} > {last ? 'Close!' : null} </Button> ) }} > <Main /> </TourProvider> ) }
Custom handlers
Control currentStep externally. Useful when using global state.
import { useState } from 'react' import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { const [currentStep, setCurrentStep] = useState(0) console.log(currentStep) return ( <TourProvider steps={steps} currentStep={currentStep} setCurrentStep={() => { if (currentStep === steps.length - 1) { setCurrentStep(0) } else { setCurrentStep(currentStep + 1) } }} > <Main /> </TourProvider> ) }
RTL
RTL mode
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} rtl> <Main /> </TourProvider> ) }
Custom styles
Custom Tour, Mask and Popover components and parts styles
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { const radius = 10 return ( <TourProvider steps={steps} styles={{ popover: (base) => ({ ...base, '--reactour-accent': '#ef5a3d', borderRadius: radius, }), maskArea: (base) => ({ ...base, rx: radius }), maskWrapper: (base) => ({ ...base, color: '#ef5a3d' }), badge: (base) => ({ ...base, left: 'auto', right: '-0.8125em' }), controls: (base) => ({ ...base, marginTop: 100 }), close: (base) => ({ ...base, right: 'auto', left: 8, top: 8 }), }} > <Main /> </TourProvider> ) }
Disable Scroll
In this example, we are using afterOpen prop to lock the Y scroll and re-enable it through beforeClose prop.
import { TourProvider } from '@reactour/tour' import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock' import { steps } from './steps.js' import Main from './Main.js' export default function App () { const disableBody = (target) => disableBodyScroll(target) const enableBody = (target) => enableBodyScroll(target) return ( <TourProvider steps={steps} afterOpen={disableBody} beforeClose={enableBody}> <Main /> </TourProvider> ) }
Custom Badge
Create a custom Badge content
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} badgeContent={({ totalSteps, currentStep }) => currentStep + 1 + "/" + totalSteps} > <Main /> </TourProvider> ) }
Disable dots navigation
Disable navigating through click in dots buttons
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} disableDotsNavigation> <Main /> </TourProvider> ) }
Disable interaction
Disable highlighted area interaction. This example shows how to disable the default behavior and how to add an extra functionality when clicking this area. Try to select the highlighted text.
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} onClickHighlighted={(e) => { e.stopPropagation() console.log('No interaction') }} disableInteraction > <Main /> </TourProvider> ) }
Toggle navigation parts
Toggle Navigation parts as you want: badge, close button, prev & next buttons, dots or whole navigation zone.
import { TourProvider } from '@reactour/tour' import { useState } from 'react' import { steps } from './steps.js' import Main from './Main.js' export default function App () { const [enabledParts, setEnabled] = useState([ 'badge','close','nav','buttons','dots' ]) function onChange(event) { let updatedList = [...enabledParts]; if (event.target.checked) { updatedList = [...enabledParts, event.target.value]; } else { updatedList.splice(enabledParts.indexOf(event.target.value), 1); } setEnabled(updatedList); } return ( <> <pre className="demo-selectors column"> <code>Enabled parts: <label> <input type="checkbox" name="dk" value="badge" onChange={onChange} checked={enabledParts.includes("badge")} /> badge </label> <label> <input type="checkbox" name="dk" value="close" onChange={onChange} checked={enabledParts.includes("close")} /> close button </label> <label> <input type="checkbox" name="dk" value="nav" onChange={onChange} checked={enabledParts.includes("nav")} /> navigation </label> <label> <input type="checkbox" name="dk" value="buttons" onChange={onChange} checked={enabledParts.includes("buttons")} /> prev & next buttons </label> <label> <input type="checkbox" name="dk" value="dots" onChange={onChange} checked={enabledParts.includes("dots")} /> dots </label> </code> </pre> <TourProvider steps={steps} showBadge={enabledParts.includes('badge')} showCloseButton={enabledParts.includes('close')} showNavigation={enabledParts.includes('nav')} showPrevNextButtons={enabledParts.includes('buttons')} showDots={enabledParts.includes('dots')} > <Main /> </TourProvider> </> ) }
Starts at
Start Tour at specific step. Keep in mind that the number is zero based, so 2 is the third step.
import { TourProvider } from '@reactour/tour' import { steps } from './steps.js' import Main from './Main.js' export default function App () { return ( <TourProvider steps={steps} startAt={2}> <Main /> </TourProvider> ) }