## File: README.md

[](http://badge.fury.io/js/shepherd.js)


[](https://app.fossa.com/projects/git%2Bgithub.com%shipshapecode%2Fshepherd?ref=badge_shield)

[](https://github.com/shipshapecode/shepherd/actions/workflows/test.yml)
[](https://qlty.sh/gh/shipshapecode/projects/shepherd)
[](https://qlty.sh/gh/shipshapecode/projects/shepherd)
[](https://stackshare.io/shepherd-js)  

[Shepherd](https://shepherdjs.dev/) is an open source, fully featured, digital adoption platform (DAP) and user on-boarding service.

Supported Browsers
----------------------------------------------------------

| [](http://godban.github.io/browsers-support-badges/)Edge | [](http://godban.github.io/browsers-support-badges/)Firefox | [](http://godban.github.io/browsers-support-badges/)Chrome | [](http://godban.github.io/browsers-support-badges/)Safari |
| --------- | --------- | --------- | --------- |
| Edge| last 2 versions| last 2 versions| last 2 versions

# Shepherd

Shepherd makes it simple to create custom user on-boarding tours, trainings and announcements to drive user adoption. 

Shepherd enables you to guide users through a custom tour or journey within your app or website. Highly customizable with minimal styles, Shepherd allows for powerful customization while being easy to use. Various frameworks supported including React, Ember, Angular, Vue.js, ES Modules, or plain JavaScript. 

# Demo
See Shepherd Live on our website by clicking on the image:
<a href="https://shepherdjs.dev">
  
</a>

# Using Shepherd

### Shepherd Open Source Library

The Shepherd Standalone Library has been open source since the very beginning. Check out our tutorials here:

#### [React Shepherd Wrapper](packages/react)
#### [Angular Shepherd Wrapper](https://github.com/shipshapecode/angular-shepherd)
#### [Vue Shepherd Wrapper](https://github.com/shipshapecode/vue-shepherd)
#### [Ember Shepherd Wrapper](https://github.com/RobbieTheWagner/ember-shepherd)


# White Glove Services

If you have an idea or project in mind and would like to engage our team to build a custom tour, training or on-boarding experience, [get in touch](mailto:ahoy@shipshape.io)! 


## Resources

- [Website](https://shepherdjs.dev/)
- [Documentation](https://docs.shepherdjs.dev/)
- [Demo](https://shepherdjs.dev/)
- [Discord](https://discord.gg/EGcDW5NSud)


## Contributing

We encourage contributions of all kinds. If you would like to contribute in some way, please review our [guidelines for contributing](CONTRIBUTING.md).
Our release process is mostly automated. For more details, see [RELEASE.md](RELEASE.md).


## Projects Already Using Shepherd

### Rails gems

### [abraham](https://github.com/actmd/abraham)

Rails engine that generates and tracks Shepherd tours within an application

### Websites and Apps

### [SimplePlanner](https://simpleplanner.io)

[SimplePlanner](https://simpleplanner.io) uses Shepherd to help new users get familiar with its collaborative scheduling approach. 
You do need to sign up via OAuth or email to see the scheduling tour. 
Check out the [Envato Tuts+ Startup Series on its codebase](https://code.tutsplus.com/series/building-your-startup-with-php--cms-742) which describes how Simple Planner was built.

### [LogSeq](https://logseq.com/) 

[LogSeq](https://logseq.com/) uses Shepherd to guide users through initial setup steps.

### [Snapsure](https://snapsure.app)

[Snapsure](https://snapsure.app) uses Shepherd to help photographers learn how to set up alerts for their desired picture-perfect weather conditions.

### [Drupal](https://www.drupal.org/docs/8/core/modules/tour/overview)

The [Drupal](https://www.drupal.org/docs/8/core/modules/tour/overview) CMS uses Shepherd to offer tours of it's core modules, and allows developers to add Tours to their custom and contributed modules.

### [Budibase Shepherd Tour Plugin](https://github.com/JayP718/tour_shepherd_bb_plugin)

[Budibase](https://budibase.com/) is an open source application which allows you develop low code applications rapidly and efficiently.This [Budibase](https://budibase.com/) Shepherd tour plugin allows you to create interative walkthroughs for your application.


### Your Project Here

If you have a cool open-source library built on Shepherd, PR this doc.


## License

Shepherd.js is dual-licensed under AGPL-3.0 and a Commercial License.

- **Free for open source and non-commercial use** under AGPL-3.0
- **Commercial license required** for commercial products and revenue-generating companies

See [LICENSE.md](LICENSE.md) for complete details or visit [shepherdjs.dev/pricing](https://shepherdjs.dev/pricing) to purchase a commercial license.

[](https://app.fossa.com/projects/git%2Bgithub.com%2Fshipshapecode%2Fshepherd?ref=badge_large)

---

## File: docs-src/src/content/docs/recipes/cookbook.md

---
title: Cookbook
---

### Disable Scroll

Previously, disabling scrolling was built into Shepherd, but it was buggy
and bulky, so we opted to remove [body-scroll-lock](https://github.com/willmcpo/body-scroll-lock)
as a dependency, in favor of users installing it directly in their apps. To disable scrolling,
you can install `body-scroll-lock` and run `bodyScrollLock.disableBodyScroll();` before
starting the tour, then `bodyScrollLock.clearAllBodyScrollLocks();` after stopping the tour.

### Highlighting multiple elements

Highlighting multiple elements is supported by Shepherd out of the box. You can pass an array of selectors to the `extraHighlights` option in the step configuration. This will highlight all the elements in the array as well as the target element defined in the `attachTo` option.

```javascript
const tour = new Shepherd.Tour({
  steps: [
    {
      text: 'This is a step with multiple highlights',
      attachTo: {
        element: '.target-element',
        on: 'bottom'
      },
      extraHighlights: ['.example-selector', '.example-selector-2']
    }
  ]
});
```

If an element to be highlighted is contained by another element that is also being highlighted, the contained element will not be highlighted. This is to prevent the contained element from being obscured by the containing element.

Highlighted elements do not have to share a scroll container with the `attachTo` target. Each one is clipped vertically by the scroll containers that actually crop it, so only the part of it that is scrolled into view is cut out of the overlay. An element whose position takes it outside those containers — `fixed`, or `absolute` against a containing block above them, as a dropdown usually is — is cut out in full, wherever it is painted. Clipping is vertical only: an element scrolled out of view horizontally is still cut out in full.

### Offsets

By default, FloatingUI instances are placed directly next to their target. However, if you need to apply some margin
between them or if you need to fine tune the position according to some custom logic, you can use an offset middleware.

For example:

```js
import { offset } from '@floating-ui/dom';

const tour = new Shepherd.Tour({
  steps: [
    {
      ...
      floatingUIOptions: {
        middleware: [offset({ mainAxis: 0, crossAxis: 12 })]
      }
      ...
    }
  ]
});
```

### Progress Indicator

Using the already exposed API, you could add a progress indicator of your choosing
for each step to let your users know how far into a tour they may be.

The example below uses the [Step](https://docs.shepherdjs.dev/api/step/classes/step/) `options`
object and adds to `when` on the `show` event. Within that, we create an element
to render in the header with text of what step out of all potential steps is now
being show.

```javascript
when: {
  show() {
    const currentStep = Shepherd.activeTour?.getCurrentStep();
    const currentStepElement = currentStep?.getElement();
    const header = currentStepElement?.querySelector('.shepherd-header');
    const progress = document.createElement('span');
    progress.style['margin-right'] = '315px';
    progress.innerText = `${Shepherd.activeTour?.steps.indexOf(currentStep) + 1}/${Shepherd.activeTour?.steps.length}`;
    header?.insertBefore(progress, currentStepElement.querySelector('.shepherd-cancel-icon'));
  }
}
```

Another example, for anyone who wants to add progress indicators to the footer. Add the `shepherd-progress` className and some extra styles.

```javascript
when: {
  show() {
    const currentStep = Shepherd.activeTour?.getCurrentStep();
    const currentStepElement = currentStep?.getElement();
    const footer = currentStepElement?.querySelector('.shepherd-footer');
    const progress = document.createElement('span');
    progress.className = 'shepherd-progress';
    progress.innerText = `${Shepherd.activeTour?.steps.indexOf(currentStep) + 1} of ${Shepherd.activeTour?.steps.length}`;
    footer?.insertBefore(progress, currentStepElement.querySelector('.shepherd-button:last-child'));
  }
}
```

```scss
.shepherd-footer {
  align-items: center;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
  display: flex;
  justify-content: space-between;
  padding: 0 0.75rem 0.75rem;

  .shepherd-button:last-child {
    margin-right: 0;
  }

  .shepherd-progress {
    font-size: 0.8rem;
  }
}
```

---

## File: docs-src/src/content/docs/recipes/react.md

---
title: React Usage
---

## Use in React
We've published a React package for years that really just exports the default Shepherd class and gives you some syntactical sugar for setting up Shepherd in a React app. This adds another layer from the root API and provides opinionated patterns. It's mainly a wrapper around the Shepherd library that exposes the tour object and methods to the context object that can be passed into props for dynamic interactivity. We think there's more than one way to create solutions and instead just prefer to provide a couple of examples on how you can do this. 

### Custom hooks pattern
You can just create a hook that will let you setup and share a Tour instance and swap them out as needed.

```javascript
export const useShepherdTour = ({ tourOptions, steps }) => {
  const tourObject = useMemo(() => {
    const tourInstance = new Shepherd.Tour(tourOptions);

    tourInstance.addSteps(steps);

    return tourInstance;
  }, [tourOptions, steps]);

  return tourObject;
};
```

### Context/Provider pattern

```javascript
// App imports above, this is either in a root App.js/ts file or somewhere in your app
const ShepherdTourContext = React.createContext();
const ShepherdTourContextConsumer = ShepherdTourContext.Consumer;
const shepherdTourInstance = new Shepherd.Tour();

return (
  <ShepherdTourContext.Provider value={shepherdTourInstance}>
    { ... }
  </ShepherdTourContext.Provider>
);

// elsewhere in your app within a component
const tour = useContext(ShepherdTourContext);

return (
  
    <HomePage>
      
        Start Tour
      
    </HomePage>
  
);
```

---

## File: docs-src/src/content/docs/guides/analytics.mdx

---
title: Analytics
---

With Shepherd, you can track the progress of your users through your app journey. e.g., This can be useful for understanding how users are interacting with your site, and where they might be getting stuck. 

## Tracking
Events occur at each step of the journey, and can be tracked using the `on` method of a `Tour` instance. The most obvious way to track is with the following events: `active`, `cancel`, `complete`, `show`.

### Active
This event triggers when the tour itself becomes active. This means that the tour is ready and not necessarily that the first step is shown.

### Cancel
At any point, if the user cancels the tour, this event will trigger.

### Complete
When the user completes the tour, this event will trigger. This means that the user has gone through all the steps in the tour.

### Show
This event triggers when a step is shown to the user.


## Exposing the Analytics
In order to start tracking, just tell Shepherd what you want to do when one of the events is fired.

```javascript
const shepherd = new Shepherd.Tour();
const trackedEvents = ['active', 'cancel', 'complete', 'show'];

shepherd.on('start', (eventOptions) => { ... });
shepherd.start(); //the above will fire and run the function
```

---

## File: docs-src/src/content/docs/guides/install.mdx

---
title: Installation
---

import { Tabs, TabItem } from '@astrojs/starlight/components';

:::note[License Information]
Shepherd.js is **free for open source and non-commercial use** under AGPL-3.0. Commercial projects require a commercial license. [Learn more about licensing →](/guides/license/)
:::

## Install Directly

<Tabs>
  <TabItem label="npm">
  ```bash 
  npm install shepherd.js --save 
  ```
  </TabItem>
  <TabItem label="yarn">
  ```bash 
  yarn add shepherd.js 
  ```
  </TabItem>
  <TabItem label="pnpm">
  ```bash 
  pnpm add shepherd.js 
  ```
  </TabItem>
  <TabItem label="bun">
  ```bash 
  bun add shepherd.js 
  ```
  </TabItem>
</Tabs>

### styles

Don't forget to add your styles

```javascript
import 'shepherd.js/dist/css/shepherd.css';
```

### GitHub Releases

Whenever we release a new version, the contents of the `dist` are uploaded
to the release in GitHub. You can find those assets [here](https://github.com/shipshapecode/shepherd/releases).

### jsDelivr CDN

You can use jsDelivr to pull down any release from npm. For example, you could include v10.0.1 with styles in your app
with:

```html
<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/shepherd.js@17.0.0/dist/js/shepherd.mjs"
></script>
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/shepherd.js@17.0.0/dist/css/shepherd.css"
/>
```

## JS Framework Wrappers

We strive to make it easy to use Shepherd in all the major frameworks, and have written wrappers to facilitate this.

- [angular-shepherd](https://github.com/shipshapecode/angular-shepherd)
- [ember-shepherd](https://github.com/shipshapecode/ember-shepherd)
- [react-shepherd](https://github.com/shipshapecode/shepherd/tree/main/packages/react)
- [vue-shepherd](https://github.com/shipshapecode/vue-shepherd)

---

## File: docs-src/src/content/docs/guides/styling.md

---
title: Styling
---

### Default Styles

Shepherd ships with some default styles, but we try to keep it minimal, so you do not have a ton to override.
You can also opt out of styles entirely, by not including the `shepherd.css` file.

### Custom Classes

If you'd like to change styles within your own CSS, you can pass custom class names to the tour instance &mdash;
or, as part of the options for each step &mdash; and use them as hooks for your own styling rules.

```javascript
let tour = new Shepherd.Tour({
  defaultStepOptions: {
    classes: 'shepherd-theme-custom'
  }
});
```

### Adding a prefix to the default `shepherd-*` classes

If you have a situation where you are running two Shepherd instances on a page, and they need to be styled
differently, you may want to prefix the class names. This is now possible with the `classPrefix` option.

```js
const tour = new Shepherd.Tour({
  classPrefix: 'my-tour-'
});
```

---

## File: docs-src/src/content/docs/guides/usage.md

---
title: Usage
---

### Rollup/Webpack Based Builds

The latest versions of Rollup and Webpack support ES6 imports. Shepherd ships as
an ES module which should allow you to import using standard ES import syntax.

i.e.

```js
import Shepherd from 'shepherd.js';
```

First create a new `Tour` instance for your tour:

```javascript
const tour = new Shepherd.Tour({
  useModalOverlay: true,
  defaultStepOptions: {
    classes: 'shadow-md bg-purple-dark',
    scrollTo: true
  }
});
```

The `defaultStepOptions` option allows you to specify any options which should
be applied to all this tour's steps by default.

Next, add your steps:

```javascript
tour.addStep({
  id: 'example-step',
  text: 'This step is attached to the bottom of the `.example-css-selector` element.',
  attachTo: {
    element: '.example-css-selector',
    on: 'bottom'
  },
  classes: 'example-step-extra-class',
  buttons: [
    {
      text: 'Next',
      action: tour.next
    }
  ]
});
```

Finally, to start the tour, just call `start` on your `Tour` instance:

```javascript
tour.start();
```

If you need to remove a step from your tour, call `removeStep` on your `Tour`
instance. If the step currently being displayed is the one you're removing, and
there are steps left in the tour, then the first one will be shown, otherwise,
the tour will be cancelled.

```javascript
tour.removeStep('example-step');
```

### API

#### Global Shepherd Object

Shepherd exposes a single object onto the window, `Shepherd`.

That global object fires several events to let you link up actions with events
occurring in _any_ tour:

##### Methods

- `Shepherd.on(eventName, handler, [context])`: Bind an event
- `Shepherd.off(eventName, [handler])`: Unbind an event
- `Shepherd.once(eventName, handler, [context])`: Bind just the next instance of
  an event

##### Events

The global Shepherd fires the following events whenever a `Tour` instance fires
them. It adds to the object passed to the event handlers a `tour` key pointing
to the instance which fired the event:

- `complete`
- `cancel`
- `hide`
- `show`
- `start`
- `active`
- `inactive`

For multiple events, you can use something like:

```javascript
['complete', 'cancel'].forEach((event) =>
  shepherd.on(event, () => {
    // some code here
  })
);
```

##### Current Tour

The global `Shepherd` includes a property which is always set to the currently
active tour, or null if there is no active tour:

- `Shepherd.activeTour`

#### Tour Instances

##### Creation

You create a `Tour` object for each tour you'd like to create.

Tour's constructor accepts a hash of options:

```javascript
const myTour = new Shepherd.Tour(options);
```

##### Tour Options

- `classPrefix`: The prefix to add to the `shepherd-enabled` and
  `shepherd-target` class names as well as the `data-shepherd-step-id`.
- `confirmCancel`:
  - If true, will issue a `window.confirm` before cancelling
  - If it is a function(support Async Function), it will be called and wait for
    the return value, and will only be cancelled if the value returned is true
- `confirmCancelMessage`: The message to display in the confirm dialog
- `defaultStepOptions`: Default options for Steps created through `addStep`
- `exitOnEsc`: Exiting the tour with the escape key will be enabled unless this
  is explicitly set to `false`.
- `keyboardNavigation`: Navigating the tour via left and right arrow keys will
  be enabled unless this is explicitly set to `false`.
- `stepsContainer` An optional container element for the steps. If not set, the
  steps will be appended to `document.body`.
- `modalContainer` An optional container element for the modal. If not set, the
  modal will be appended to `document.body`.
- `steps`: An array of step options objects or Step instances to initialize the
  tour with.
- `tourName`: An optional "name" for the tour. This will be appended to the the
  tour's dynamically generated `id` property.
- `useModalOverlay`: Whether or not steps should be placed above a darkened
  modal overlay. If true, the overlay will create an opening around the target
  element so that it can remain interactive.

##### Tour Methods

- `addStep(options)`: Creates a new Step object with options, and returns the
  `Step` instance it created. If the options hash doesn't include an `id`, one
  will be generated. You can also pass an existing `Step` instance rather than
  `options`, but note that Shepherd does not support a Step being attached to
  multiple Tours.
- `addSteps([Steps])`: Add multiple steps to the tour
- `getById(id)`: Return a step with a specific id
- `isActive()`: Check if the tour is active
- `next()`: Advance to the next step, in the order they were added
- `back()`: Show the previous step, in the order they were added
- `cancel()`: Trigger cancel on the current step, hiding it without advancing
- `complete()`: Calls \_done() triggering the `complete` event
- `hide()`: Hide the current step
- `show([id])`: Show the step specified by id (if it's a string), or index (if
  it's a number) provided. Defaults to the first step.
- `start()`: Show the first step and begin the tour
- `getCurrentStep()`: Returns the currently shown step
- `removeStep(id)`: Removes the step from the tour
- `on(eventName, handler, [context])`: Bind an event
- `off(eventName, [handler])`: Unbind an event
- `once(eventName, handler, [context])`: Bind just the next instance of an event

`start()` always returns a promise, and `show()`, `next()`, and `back()` return
one while a step is waiting on its `attachTo.element` (see `waitForElement`
below). Await them if you need to know the step is on screen — otherwise they
can be called and ignored, as before.

##### Tour Events

- `complete`: Triggered when the last step is advanced
- `cancel`
- `hide`
- `show`: Triggered with a hash of the `step` and the `previous` step
- `start`

Steps are instances of the Step object. They are generally created by the
`Tour::addStep` method, which returns the `Step` instance it created.

#### Steps

##### Step Options

- `text`: The text in the body of the step. It can be one of three types:
  - HTML string
  - `HTMLElement` object
  - `Function` to be executed when the step is built. It must return one the two
    options above.
- `title`: The step's title. It becomes an `h3` at the top of the step.
- `attachTo`: The element the step should be attached to on the page. An object
  with properties `element` and `on`.
  - `element`: An element selector string, a DOM element, or a function
    (returning a selector, a DOM element, `null` or `undefined`).
  - `on`: The optional direction to place the Floating UI tooltip relative to
    the element.
    - Possible string values: 'auto', 'auto-start', 'auto-end', 'top',
      'top-start', 'top-end', 'bottom', 'bottom-start', 'bottom-end', 'right',
      'right-start', 'right-end', 'left', 'left-start', 'left-end'

```js
const new Step(tour, {
  attachTo: { element: '.some .selector-path', on: 'left' },
  ...moreOptions
});
```

If you don’t specify an `attachTo` the element will appear in the middle of the
screen. The same will happen if your `attachTo.element` callback returns `null`,
`undefined`, or a selector that does not exist in the DOM. The `waitForElement`
and `skipMissingElement` options described below let you change this behavior
for elements that are missing or rendered late.

If you omit the `on` portion of `attachTo`, the element will still be
highlighted, but the tooltip will appear in the middle of the screen, without an
arrow pointing to the target.

If the element to highlight does not yet exist while instantiating tour steps,
you may use lazy evaluation by supplying a function to `attachTo.element`. The
function will be called in the `before-show` phase.

- `beforeShowPromise`: A function that returns a promise. When the promise
  resolves, the rest of the `show` code for the step will execute. For example:
  ```javascript
  beforeShowPromise: function() {
    return new Promise(function(resolve) {
      $('#my-bootstrap-modal').on('shown.bs.modal', function () {
        resolve();
      });
    });
  },
  ```
- `canClickTarget` A boolean, that when set to false, will set
  `pointer-events: none` on the target
- `cancelIcon` Options for the cancel icon
  - `attrs` Additional HTML attributes to apply to the cancel icon button
    element. This is useful for adding data attributes for testing or analytics.
    Note: These attributes cannot override critical properties like `type`,
    `onclick`, `class`, or `aria-label`.

  ```javascript
  cancelIcon: {
    enabled: true,
    label: 'Close Tour',
    attrs: {
      'data-test': 'close-tour-button',
      'data-analytics-id': 'tour-close'
    }
  }
  ```

  - `enabled` Should a cancel "✕" be shown in the header of the step?
  - `label` The label to add for `aria-label`

- `classes`: A string of extra classes to add to the step's content element.
- `data`: Arbitrary, JSON-serializable data to associate with the step. Shepherd
  does not use it internally; read it back from `step.options.data` in your
  event handlers and button actions. Useful for analytics ids or other metadata,
  e.g. on generated tour definitions.
- `buttons`: An array of buttons to add to the step. These will be rendered in a
  footer below the main body text. Each button in the array is an object of the
  format:
  - `attrs`: Additional HTML attributes to apply to the button element. Useful
    for adding data attributes for testing or analytics.
  - `label`: The label to add for `aria-label`. It can also be a function that
    returns a string (useful with i18n solutions).
  - `disabled`: A boolean that controls the `disabled` attribute. It can also be
    a function that returns a boolean.
  - `classes`: Extra classes to apply to the `<a>`
  - `secondary`: A boolean, that when true, adds a `shepherd-button-secondary`
    class to the button
  - `text`: The HTML text of the button. It can also be a function that returns
    a string (useful with i18n solutions).
  - `action`: A function executed when the button is clicked on. It is
    automatically bound to the `tour` the step is associated with, so things
    like `this.next` will work inside the action. You can use action to skip
    steps or navigate to specific steps, with something like:
  ```javascript
    action() {
      return this.show('some_step_name');
    }
  ```
- `extraHighlights`: An array of extra element selectors to highlight when the
  overlay is shown The tooltip won’t be fixed to these elements, but they will
  be highlighted just like the attachTo element. They do not have to share a
  scroll container with the attachTo element: each one is clipped vertically by
  the scroll containers that actually crop it, so only the part of it that is
  scrolled into view is cut out of the overlay. An element positioned outside
  those containers — `fixed`, or `absolute` against a containing block above
  them — is cut out in full, matching where it is painted.
- `advanceOn`: An action on the page which should advance shepherd to the next
  step. It should be an object with a string `selector` and an `event` name. For
  example: `{selector: '.some-element', event: 'click'}`. It doesn't have to be
  an event inside the tour, it can be any event fired on any element on the
  page. You can also always manually advance the Tour by calling
  `myTour.next()`.
- `highlightClass`: An extra class to apply to the `attachTo` element when it is
  highlighted (that is, when its step is active). You can then target that
  selector in your CSS.
- `id`: The string to use as the `id` for the step. If an id is not passed one
  will be generated.
- `modalOverlayOpeningPadding`: An amount of padding to add around the modal
  overlay opening
- `modalOverlayOpeningRadius`: An amount of border radius to add around the
  modal overlay opening. It can be either a number or an object with properties
  `{ topLeft, bottomLeft, bottomRight, topRight }`
- `floatingUIOptions`: Extra options to pass to
  [Floating UI](https://floating-ui.com/docs/getting-started)
- `showOn`: A function that, when it returns true, will show the step. If it
  returns false, the step will be skipped.
- `skipMissingElement`: A boolean. When true, a step whose `attachTo.element`
  cannot be found in the DOM is skipped (like `showOn` returning false) instead
  of being shown centered. If all remaining steps are skipped, the tour
  completes going forward, or cancels going backward. It can also be set on
  `defaultStepOptions` to apply to every step. Steps without an `attachTo`
  element are never skipped, since they are intentionally centered.
- `waitForElement`: The maximum amount of time, in milliseconds, to wait for the
  `attachTo.element` to appear in the DOM before showing the step. The DOM is
  watched with a `MutationObserver`, falling back to polling where
  `MutationObserver` is unavailable, so the step attaches as soon as the element
  appears. If the timeout expires, the step falls back to its default behavior:
  skipped when `skipMissingElement` is true, otherwise shown centered. It can
  also be set on `defaultStepOptions` to apply to every step. Useful for targets
  that are rendered asynchronously.

  Both options look the target up before the step's own `beforeShowPromise` and
  `before-show` handlers run, so they cannot see an element that those handlers
  create — keep using `beforeShowPromise` for targets the step itself renders.
  Both are plain JSON values, so a tour definition using them stays
  serializable.

- `scrollTo`: Should the element be scrolled to when this step is shown? If
  true, uses the default `scrollIntoView`, if an object, passes that object as
  the params to `scrollIntoView` i.e. `{behavior: 'smooth', block: 'center'}`
- `scrollToHandler`: A function that lets you override the default `scrollTo`
  behavior and define a custom action to do the scrolling, and possibly other
  logic.
- `when`: You can define show, hide, etc events inside when. For example:

```javascript
when: {
  show: function() {
    window.scrollTo(0, 0);
  }
}
```

##### Step Methods

- `show()`: Show this step
- `hide()`: Hide this step. The step's element stays in the DOM, so the step can
  be shown again later.
- `cancel()`: Hide this step and trigger the `cancel` event
- `complete()`: Hide this step and trigger the `complete` event
- `scrollTo()`: Scroll to this step's element
- `isOpen()`: Returns true if the step is currently shown
- `destroy()`: Permanently tear the step down — removes its element from the
  DOM, destroys the Floating UI instance, and triggers the `destroy` event
- `updateStepOptions(options)`: Merge new options into the step and re-render
  its element in place
- `getElement()`: Returns the step's element — `undefined` if the step has never
  been shown, `null` if it has been destroyed
- `getTarget()`: Returns the step's resolved `attachTo` element
- `on(eventName, handler, [context])`: Bind an event
- `off(eventName, [handler])`: Unbind an event
- `once(eventName, handler, [context])`: Bind just the next instance of an event

##### Step Events

- `before-show`: Triggered at the start of every `show()`, before the step's
  element is created
- `show`: Triggered at the end of every `show()`, once the element is in the DOM
  and positioned
- `before-hide`: Triggered at the start of every `hide()`
- `hide`: Triggered at the end of every `hide()`
- `complete`: Triggered by `step.complete()`
- `cancel`: Triggered by `step.cancel()`
- `destroy`: Triggered when the step is disposed of for good — by
  `step.destroy()`, by `tour.removeStep(id)`, or for every step in the tour when
  the tour completes or is cancelled

Please note that `complete` and `cancel` are only ever triggered if you call the
associated methods in your code.

##### Step Lifecycle

| What happens                                       | Events, in order                 |
| -------------------------------------------------- | -------------------------------- |
| A step is shown for the first time                 | `before-show`, `show`            |
| Advancing away with `next()`, `back()`, `show(id)` | `before-hide`, `hide`            |
| The same step is shown again later                 | `before-show`, `show`            |
| `tour.removeStep(id)` on the step that is open     | `before-hide`, `hide`, `destroy` |
| `tour.complete()` or `tour.cancel()`               | `destroy`, once for every step   |

Shepherd rebuilds a step's element from scratch on every `show()`, but that is
an implementation detail — recreating the element does **not** emit `destroy`.
The event fires only when the step is actually being thrown away, so use it to
release anything you allocated for the step, and `before-hide` / `hide` for work
that should run every time the step goes away.

`destroy()` is not guarded against running more than once, so calling it
yourself and then completing the tour will emit `destroy` twice. Keep your
teardown idempotent if you do both.

> **Behavior change** — `destroy` used to also fire every time an already-shown
> step was shown again, in between `before-show` and `show`, because the element
> is recreated on each show. Recreating the element no longer triggers
> `destroy`. See [#3443](https://github.com/shipshapecode/shepherd/issues/3443).

### Advancing on Actions

You can use the `advanceOn` option, or the Next button, to advance steps. If you
would like however to have a step advance on a complex user action, you can do
the following:

```javascript
const myStep = myTour.addStep(options);

yourApp.on('some-event', () => {
  if (myStep.isOpen()) {
    Shepherd.activeTour.next();
  }
});
```

### 🔼 Displaying Arrows

By default, Shepherd will generate and position an "arrow" element that points
to the target of a step. This is done by setting the `arrow` option to `true` on
each ``Step.options` &mdash; but you can disable the arrow manually by setting
it to false:

```js
myTour.addStep({
  id: 'Step 1',
  arrow: false
});
```

You can also provide an options object, to configure the arrow's
[padding](https://floating-ui.com/docs/arrow#padding). The padding is the
closest the arrow will get to the edge of the step.

```js
myTour.addStep({
  id: 'Step 1',
  arrow: { padding: 10 }
});
```

Furthermore, while Shepherd provides some basic arrow styling, you can style it
as you wish by targeting the `.shepherd-arrow` element.

---

## File: docs-src/src/content/docs/api/README.md

---
editUrl: false
next: false
prev: false
title: "shepherd.js"
---

## Modules

- [evented](/api/evented/readme/)
- [shepherd](/api/shepherd/readme/)
- [step](/api/step/readme/)
- [tour](/api/tour/readme/)

---

## File: docs-src/README.md

# Starlight Starter Kit: Basics

[](https://starlight.astro.build)

```
npm create astro@latest -- --template starlight
```

[](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
[](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs)

> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!

## 🚀 Project Structure

Inside of your Astro + Starlight project, you'll see the following folders and files:

```
.
├── public/
├── src/
│   ├── assets/
│   ├── content/
│   │   ├── docs/
│   │   └── config.ts
│   └── env.d.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json
```

Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name.

Images can be added to `src/assets/` and embedded in Markdown with a relative link.

Static assets, like favicons, can be placed in the `public/` directory.

## 🧞 Commands

All commands are run from the root of the project, from a terminal:

| Command                   | Action                                           |
| :------------------------ | :----------------------------------------------- |
| `npm install`             | Installs dependencies                            |
| `npm run dev`             | Starts local dev server at `localhost:4321`      |
| `npm run build`           | Build your production site to `./dist/`          |
| `npm run preview`         | Preview your build locally, before deploying     |
| `npm run astro ...`       | Run CLI commands like `astro add`, `astro check` |
| `npm run astro -- --help` | Get help using the Astro CLI                     |

## 👀 Want to learn more?

Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat).