🌜
🌞
reactour

reactour

v1.18.7

Tourist Guide into your React Components

npm install reactour

README

Reactour

Tourist Guide into your React Components

Demo

Edit 6z56m8x18k

Install

npm i -S reactour
# or
yarn add reactour

From v1.9.1 styled-components it isn't bundled into the package and is required [email protected]^4 and [email protected]^16.3 due to the use of createRef, so:

npm i -S [email protected]^4.0.0
# or
yarn add [email protected]^4.0.0

Usage

Add the Tour Component in your Application, passing the steps with the elements to highlight during the Tour.

import React from 'react'
import Tour from 'reactour'

class App extends Component {
  // ...

  render  (
    <>
      { /* other stuff */}
      <Tour
        steps={steps}
        isOpen={this.state.isTourOpen}
        onRequestClose={this.closeTour} />
    </>
  )
}

const steps = [
  {
    selector: '.first-step',
    content: 'This is my first Step',
  },
  // ...
]

Tour Props

accentColor

Change --reactour-accent (defaults to accentColor on IE) css custom prop to apply color in Helper, number, dots, etc

Type: string

Default: #007aff

badgeContent

Customize Badge content using current and total steps values

Type: func

// example
<Tour badgeContent={(curr, tot) => `${curr} of ${tot}`} />

children

Content to be rendered inside the Helper

Type: node | elem

className

Custom class name to add to the Helper

Type: string

closeButtonAriaLabel

aria-label attribute for the close button (for accessibility)

Type: string

Default: 'Close'

closeWithMask

Close the Tour by clicking the Mask

Type: bool

Default: true

disableDotsNavigation

Disable interactivity with Dots navigation in Helper

Type: bool

disableInteraction

Disable the ability to click or intercat in any way with the Highlighted element

Type: bool

disableKeyboardNavigation

Disable all keyboard navigation (next and prev step) when true, disable only selected keys when array

Type: bool | array(['esc', 'right', 'left'])

// example
<Tour disableKeyboardNavigation={['esc']} />

getCurrentStep

Function triggered each time current step change

Type: func

// example
<Tour
  getCurrentStep={(curr) => console.log(`The current step is ${curr + 1}`)}
/>

goToStep

Programmatically change current step after the first render, when the value changes

Type: number

highlightedMaskClassName

Custom class name to add to the element which is the overlay for the target element when disableInteraction

Type: string

inViewThreshold

Tolerance in pixels to add when calculating if an element is outside viewport to scroll into view

Type: number

isOpen

You know…

Type: bool

Required: true

lastStepNextButton

Change Next button in last step into a custom button to close the Tour

Type: node

// example
<Tour lastStepNextButton={<MyButton>Done! Let's start playing</MyButton>} />

maskClassName

Custom class name to add to the Mask

Type: string

maskSpace

Extra Space between in pixels between Highlighted element and Mask

Type: number

Default: 10

nextButton

Renders as next button navigation

Type: node

nextStep

Overrides default nextStep internal function

Type: func

onAfterOpen

Do something after Tour is opened

Type: func

// example
<Tour onAfterOpen={(target) => (document.body.style.overflowY = 'hidden')} />

onBeforeClose

Do something before Tour is closed

Type: func

// example
<Tour onBeforeClose={(target) => (document.body.style.overflowY = 'auto')} />

onRequestClose

Function to close the Tour

Type: func

Required: true

prevButton

Renders as prev button navigation

Type: node

prevStep

Overrides default prevStep internal function

Type: func

rounded

Beautify Helper and Mask with border-radius (in px)

Type: number

Default: 0

scrollDuration

Smooth scroll duration when positioning the target element (in ms)

Type: number

Default: 1

scrollOffset

Offset when positioning the target element after scroll to it

Type: number

Default: a calculation to the center of the viewport

showButtons

Show/Hide Helper Navigation buttons

Type: bool

Default: true

showCloseButton

Show/Hide Helper Close button

Type: bool

Default: true

showNavigation

Show/Hide Helper Navigation Dots

Type: bool

Default: true

showNavigationNumber

Show/Hide number when hovers on each Navigation Dot

Type: bool

Default: true

showNumber

Show/Hide Helper Number Badge

Type: bool

Default: true

startAt

Starting step when Tour is open the first time

Type: number

steps

Array of elements to highligt with special info and props

Type: shape

Required: true

Steps shape
steps: PropTypes.arrayOf(PropTypes.shape({
  'selector': PropTypes.string,
  'content': PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.element,
    PropTypes.func,
  ]).isRequired,
  'position':PropTypes.oneOfType([
    PropTypes.arrayOf(PropTypes.number),
    PropTypes.oneOf(['top', 'right', 'bottom', 'left', 'center']),
  ]),
  'action': PropTypes.func,
  'style': PropTypes.object,
  'stepInteraction': PropTypes.bool,
  'navDotAriaLabel': PropTypes.string,
  'observe': PropTypes.string,
  'highlightedSelectors': PropTypes.array,
  'mutationObservables': PropTypes.array,
  'resizeObservables': PropTypes.array,
})),
Steps example
const steps = [
  {
    selector: '[data-tour="my-first-step"]',
    content: ({ goTo, inDOM }) => (
      <div>
        Lorem ipsum <button onClick={() => goTo(4)}>Go to Step 5</button>
        <br />
        {inDOM && '🎉 Look at your step!'}
      </div>
    ),
    position: 'top',
    // you could do something like:
    // position: [160, 250],
    action: (node) => {
      // by using this, focus trap is temporary disabled
      node.focus()
      console.log('yup, the target element is also focused!')
    },
    style: {
      backgroundColor: '#bada55',
    },
    // Disable interaction for this specific step.
    // Could be enabled passing `true`
    // when `disableInteraction` prop is present in Tour
    stepInteraction: false,
    // Text read to screen reader software for this step's navigation dot
    navDotAriaLabel: 'Go to step 4',
    // Observe direct children DOM mutations of this node
    // If a child is added: the highlighted region is redrawn focused on it
    // If a child is removed: the highlighted region is redrawn focused on the step selector node
    observe: '[data-tour="observable-parent"]',
    // Array of selectors, each selected node will be included (by union)
    // in the highlighted region of the mask. You don't need to add the
    // step selector here as the default highlighted region is focused on it
    highlightedSelectors: ['[data-tour="highlighted-element"]'],
    // Array of selectors, addition/removal of a matching node will trigger a rerender
    // of the mask shape. Useful in combination with highlightedSelectors when highlighted
    // region of mask should be redrawn after a user action
    mutationObservables: ['[data-tour="mutable-element"]'],
    // Array of selectors, each selected node resize will triggered a rerender of the mask shape.
    // Useful in combination with highlightedSelectors when highlighted region of mask should
    // be redrawn after a user action. You should also add the selector in mutationObservables
    // if you want to track DOM addition/removal too
    resizeObservables: ['[data-tour="resizable-parent"]'],
  },
  // ...
]

update

Value to listen if a forced update is needed

Type: string

updateDelay

Delay time when forcing update. Useful when there are known animation/transitions

Type: number

Default: 1

disableFocusLock

Disable FocusLock component.

Type: bool

Default: false

FAQ

How is implemented the scroll lock behaviour in the Demo?

To guarantee a cross browser behaviour we use body-scroll-lock.

Import the library

import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'

Create the event handlers

disableBody = target => disableBodyScroll(target)
enableBody = target => enableBodyScroll(target)

Then assign them into the Tour props

<Tour
  {...props}
  onAfterOpen={this.disableBody}
  onBeforeClose={this.enableBody}
/>

Release Notes

1.18.0
By Lionel Tzatzkin • Published on June 15, 2020

Thanks to the awesome @qboot work on #266 now is possible to:

  • highlight multiple elements passing an Array of selectors into the new step prop highlightedSelectors
  • redraw the svg mask when node mutations happens passing selectors to mutationObservables
  • redraw the mask when node resizes happens, passing them to resizeObservables.

More details on readme

1.17.0
By Lionel Tzatzkin • Published on April 7, 2020
  • Add Round Mask #243
  • Add disableFocusLock #234
1.12.0
By Lionel Tzatzkin • Published on January 18, 2019

Now is possible to pass CustomHelper prop with a component that receive the following props to handle content, status and behaviour:

  • current (number)
  • content (string|func)
  • totalSteps (number)
  • gotoStep (func)
  • close (func)

Docs coming.

1.11.0
By Lionel Tzatzkin • Published on December 19, 2018

Add close function into content (when is a function) on each stepso now is possible to:


const steps = [
  {
    selector: '.step2',
    content: ({ close }) => (
      <>You can <button onClick={close}>close</button> the Tour from here</>
    ),
  },
  //...
]

thanks @gdsrosa

1.10.0
By Lionel Tzatzkin • Published on December 4, 2018

onAfterOpen and onBeforeClose will not apply styles to body to avoid scroll by default. Is up to the end user. Example in demo App.

1.7.1
By Lionel Tzatzkin • Published on April 18, 2018
  • Remove Controls Component when both flags showButtons and showNavigation are false
  • Pass startAt number as an argument to the internal open() method

Thanks @yossijacob for both contributions!

1.7.0
By Lionel Tzatzkin • Published on April 17, 2018

New props

  • goToStep: let you programmatically jump to a step
  • getCurrentStep: let you get the current step index each time it changes
  • prevStep and nextStep: let you override default next and prev internal functions
  • disableKeyboardNavigation
  • disableDotsNavigation
  • accentColor: let you customize the --reactour-accent css variable
  • rounded: apply rounded corners in Highlighted elem and Guide

Step changes

  • selector step property now it's optional (render the content centered)

Awesome changes

  • Refactor mask with dynamic svg shape
  • Add Code conventions

Props to @qboot for the really clean code and descriptions in the PRs full of useful stuff.

1.6.2
By Lionel Tzatzkin • Published on September 30, 2017

thanks to @iamdey

1.6.0
By Lionel Tzatzkin • Published on September 19, 2017

This new prop don't allow to interact with the highlighted elem. Also added the prop highlightedMaskClassName to customise this new layer.

Thanks to @msliva for the idea and congrats for the first PR 🎉

1.5.0
By Lionel Tzatzkin • Published on September 4, 2017

Allows to customize the content with two params current step and total step.

i.e

<Tour
   onRequestClose={closeTour}
   steps={[…]}
   isOpen={true}
   badgeContent={(cur, tot) => `${cur} of ${tot}`}
/>

or something more complex like

<Tour
   onRequestClose={closeTour}
   steps={[…]}
   isOpen={true}
   badgeContent={(cur, tot) => cur === 1 ? 'welcome!' : `${cur}/${tot}`}
/>

Thanks to @jovstern for the idea

General

License
MIT
Typescript Types
Tree-shakeable
Yes

Popularity

GitHub Stargazers
3,176
Community Interest
2,965
Number of Forks
305

Maintenance

Commits
11/2110/22060
Last Commit
Open Issues
16
Closed Issues
347
Open Pull Requests
1
Closed Pull Requests
54

Versions

Versions Released
11/2110/2201
Latest Version Released
Jan 25, 2022
Current Tags
latest1.18.7

Contributors

elrumordelaluz
elrumordelaluz
Commits: 265
qboot
qboot
Commits: 11
nelsonwong1012
nelsonwong1012
Commits: 9
ahmedbera
ahmedbera
Commits: 5
andzav
andzav
Commits: 5
frassinier
frassinier
Commits: 5
msliva
msliva
Commits: 4
yaodingyd
yaodingyd
Commits: 4
tarqu1n
tarqu1n
Commits: 4
belgac
belgac
Commits: 3
FullMoon04
FullMoon04
Commits: 3
yossijacob
yossijacob
Commits: 2
klepas
klepas
Commits: 2
iamdey
iamdey
Commits: 2
Justkant
Justkant
Commits: 1