Back to Driver Js

Async Tour

apps/docs/src/content/guides/async-tour.mdx

1.8.04.7 KB
Original Source

import { CodeSample } from "../../components/CodeSample.tsx";

You can also have async steps in your tour. This is useful when you want to load some data from the server and then show the tour.

<CodeSample heading={'Asynchronous Tour'} tour={[ { element: '.line:nth-child(14)', popover: { title: 'First Step', description: 'You can add a function to override the default behavior of the next button i.e. to fetch some data from the server and then call moveNext()', } }, { element: '.line:nth-child(17)', popover: { title: 'Manually Handle Next', description: 'Here we are moving to the next step manually since driver.js does not know when the data is loaded dynamically.', } }, { popover: { title: 'Next Step is Async', description: 'This is the first step. Next element will be loaded dynamically.', }, }, { element: '.dynamic-el', popover: { title: 'Async Element', description: 'This element is loaded dynamically and will be removed as soon as we move away from this step' } }, { popover: { title: 'Last Step', description: 'This is the last step.' } } ]} id={"tour-example"} client:load>

js
import { driver } from "driver.js";
import "driver.js/dist/driver.css";

const driverObj = driver({
  showProgress: true,
  steps: [
    {
      popover: {
        title: 'First Step',
        description: 'This is the first step. Next element will be loaded dynamically.'
        // By passing onNextClick, you can override the default behavior of the next button.
        // This will prevent the driver from moving to the next step automatically.
        // You can then manually call driverObj.moveNext() to move to the next step.
        onNextClick: () => {
          // .. load element dynamically
          // .. and then call
          driverObj.moveNext();
        },
      },
    },
    {
      element: '.dynamic-el',
      popover: {
        title: 'Async Element',
        description: 'This element is loaded dynamically.'
      },
      // onDeselected is called when the element is deselected.
      // Here we are simply removing the element from the DOM.
      onDeselected: () => {
        // .. remove element
        document.querySelector(".dynamic-el")?.remove();
      }
    },
    { popover: { title: 'Last Step', description: 'This is the last step.' } }
  ]

});

driverObj.drive();

</CodeSample>

Note: By overriding onNextClick, and onPrevClick hooks you control the navigation of the driver. This means that user won't be able to navigate using the buttons and you will have to either call driverObj.moveNext() or driverObj.movePrevious() to navigate to the next/previous step.

You can use this to implement custom logic for navigating between steps. This is also useful when you are dealing with dynamic content and want to highlight the next/previous element based on some logic.

onNextClick and onPrevClick hooks can be configured at driver level as well as step level. When configured at the driver level, you control the navigation for all the steps. When configured at the step level, you control the navigation for that particular step only.

Waiting for Elements

When you know the next element is rendered on demand, you often don't need the manual onNextClick dance at all. Give the step a waitForElement timeout and the tour waits for the element to appear, staying on the current step in the meantime. Pair it with advanceOnClick when the highlighted element itself is what triggers the rendering, e.g. a button that opens a modal:

js
const driverObj = driver({
  steps: [
    {
      element: '#open-modal-btn',
      // Clicking the highlighted button acts like pressing next;
      // the button's own click still runs and opens the modal.
      advanceOnClick: true,
      popover: {
        title: 'Open the Modal',
        description: 'Click this button to continue.',
        showButtons: ['close'],
      },
    },
    {
      element: '#modal-confirm',
      // Wait up to 5 seconds for the modal to render before
      // treating the element as missing.
      waitForElement: 5000,
      popover: {
        title: 'Confirm',
        description: 'This step appeared once the modal rendered.',
      },
    },
  ],
});

driverObj.drive();

If the element never shows up, the wait times out into the usual missing-element behavior: the centered fallback popover, or a skip when skipMissingElement is set. Both options can also be set at the driver level to apply to every step.

See Interactive Tour for live demos of both options, and Multi-Page Tour for continuing a tour across page navigations.