# reactour

> Tourist Guide into your React Components

Latest version **1.19.4** (published 2024-05-31) · MIT license · 0 weekly downloads

## Install

```sh
npm install reactour
pnpm add reactour
yarn add reactour
bun add reactour
```

## Health

**Score 33/100 (F)** — status: abandoned.

Positive: has types package; esm support; no vulnerabilities.

Warnings: low downloads.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 1.19.4 |
| Published | 2024-05-31 |
| First published | 2017-03-31 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | separate (@types/reactour) |
| Module format | ESM + CommonJS |
| Dependencies | 8 |
| Unpacked size | 117.6 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 4090 |
| Author | Lionel T |
| Maintainers | elrumordelaluz |
| Keywords | react, tour, intro, guide, introduction, step-by-step, guide, walkthrough, joyride, tourist-guide, product-intro, presentation |

## Links

- npm: https://www.npmjs.com/package/reactour
- Repository: https://github.com/elrumordelaluz/reactour.git#v1
- Homepage: https://github.com/elrumordelaluz/reactour/tree/v1
- Issues: https://github.com/elrumordelaluz/reactour/issues
- npm.io page: https://npm.io/package/reactour

## Dependencies (8)

- [classnames](https://npm.io/package/classnames.md) 2.3.1
- [prop-types](https://npm.io/package/prop-types.md) 15.7.2
- [scrollparent](https://npm.io/package/scrollparent.md) 2.0.1
- [scroll-smooth](https://npm.io/package/scroll-smooth.md) 1.1.1
- [lodash.debounce](https://npm.io/package/lodash.debounce.md) 4.0.8
- [react-focus-lock](https://npm.io/package/react-focus-lock.md) ^2.12.1
- [focus-outline-manager](https://npm.io/package/focus-outline-manager.md) ^1.0.2
- [@rooks/use-mutation-observer](https://npm.io/package/@rooks/use-mutation-observer.md) 4.11.2

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 1.19.4 (latest) — 2024-05-31
- 1.19.3 — 2024-04-04
- 1.19.2 — 2023-10-19
- 1.19.1 — 2023-09-12
- 1.19.0 — 2022-12-29
- 1.18.7 — 2022-01-25
- 1.18.6 — 2021-07-12
- 1.18.5 — 2021-07-07
- 1.18.4 — 2021-05-21
- 1.18.3 — 2021-03-12
- 1.18.2 — 2021-03-08
- 1.18.1 — 2021-02-11
- 1.18.0 — 2020-06-15
- 1.17.0 — 2020-04-07
- 1.16.4 — 2020-04-07
- … 52 more at https://npm.io/package/reactour/versions

## README

<p align="center">
  <img alt="Reactour" title="Reactour" src="/logo.svg" width="250">
</p>
<p align="center" style="margin-top: 40px">
  <strong>Tourist Guide</strong> into your React Components
</p>
<p align="center">
  <a href="https://elrumordelaluz.github.io/reactour/">Demo</a>
</p>
<p align="center">
  <a href="https://codesandbox.io/s/6z56m8x18k?module=%2FApp.js">
    <img src="https://codesandbox.io/static/img/play-codesandbox.svg" alt="Edit 6z56m8x18k">
  </a>
</p>

## Install

```zsh
npm i -S reactour
# or
yarn add reactour
```

<small>From `v1.9.1` [styled-components](https://www.styled-components.com/) it isn't bundled into the package and is required `styled-components@^4` and `react@^16.3` due to the use of [createRef](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs), so: </small>

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

## Sponsored by

#### Gold sponsors 🥇

<p>
  <a href="https://frigade.com/?source=reactour">
    <img alt="Frigade sponsor" title="Frigade sponsor" src="./sponsor-frigade.png" width="600">
  </a>
</p>
<p>
  Reactour is proud to be sponsored by  <a href="https://frigade.com/?source=reactour">Frigade</a>, a developer tool for building better product onboarding: guided tours, getting started checklists, announcements, and more.
</p>

#### Silver sponsors 🥈

<p>
  <a href="https://www.dopt.com/?source=reactour">
    <img alt="Dopt sponsor" title="Dopt sponsor" src="./sponsor-dopt.png" width="300">
  </a>
</p>
<p>
  <a href="https://www.dopt.com/?source=reactour">Dopt</a> gives developers UI components and SDKs to build seamless onboarding and education experiences in minutes.
</p>

## Usage

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

```js
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`

```js
// 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'])`

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

#### getCurrentStep

> Function triggered each time current step change

Type: `func`

```js
// 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`

```js
// 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`

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

#### onBeforeClose

> Do something before _Tour_ is closed

Type: `func`

```js
// 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

```js
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

```js
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

<p>
  <details>
    <summary>How is implemented the scroll lock behaviour in the <a href="https://github.com/elrumordelaluz/reactour/blob/master/src/demo/App.js">Demo</a>?</summary>
    <p>
      To guarantee a cross browser behaviour we use <a href="https://www.npmjs.com/package/body-scroll-lock">body-scroll-lock</a>. </p>
      <p>Import the library
        <pre lang=js>
import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'</pre>
    </p>
    <p>Create the event handlers
        <pre lang=js>
disableBody = target => disableBodyScroll(target)
enableBody = target => enableBodyScroll(target)</pre>
    </p>
    <p>Then assign them into the Tour props
        <pre lang=js>
&lt;Tour
  {...props}
  onAfterOpen={this.disableBody}
  onBeforeClose={this.enableBody}
/&gt;</pre>
    </p>
  </details>
</p>

---
_Source: https://npm.io/package/reactour · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
