/reactour

Tourist Guide into your React Components

Primary LanguageJavaScriptMIT LicenseMIT

Reactour

Tourist Guide into your React Components

Demo

Edit 6z56m8x18k


⚠️ The master branch is currently in development. Please use the v1 branch to follow the current versions published.


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 styled-components@^4 and react@^16.3 due to the use of createRef, so:

npm i -S styled-components@^4.0.0
# or
yarn add styled-components@^4.0.0

Usage

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

import React, { useState } from 'react'
import Tour from 'reactour'

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

const App = () => {
  const [isTourOpen, setIsTourOpen] = useState(false);

  return (
    <>
      { /* other stuff */}
      <Tour
        steps={steps}
        isOpen={isTourOpen}
        onRequestClose={() => setIsTourOpen(false)}
      />
    </>
  )
};

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

accessibilityOptions

Configure accessibility related accessibility options

Type: object

Default:

    // attribute to associate the dialog with a title for screen readers
    ariaLabelledBy: null,
    // aria-label attribute for the close button
    closeButtonAriaLabel: 'Close',
    // Show/Hide Navigation Dots for screen reader software
    showNavigationScreenReaders: true,

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

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

disableFocusLock

Disable the ability to set a focus on Input in the Highlighted element

Type: bool

Default: true

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

Default: 0

steps

Array of elements to highlight 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,
})),
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',
  },
  // ...
]

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

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}
/>