Skip to main content

Tour

Source@dopt/vue

Overview

The tour component is powered by a tour block and is great way to guide your user through new, undiscovered, or updated product features.

A tour block is comprised of items, which are the ordered set of steps in the tour.

The tour component exposes two composables to easily build product tours.

Composables

With our Vue SDK, you can use tours and tour items headlessly by importing the useTour or useTourItem composable from @dopt/vue.

useTour

  • useTour(id: string): Tour

A Vue composable for accessing and updating a tour's state.

<script>
import { useTour } from '@dopt/vue';
const {
id,
items,
active,
completed,
dismissed,
complete,
dismiss,
filter,
count,
size,
} = useTour('onboarding-tour.tour-component');
</script>
<template>
<div>
<div id="states">
<div>tour.active: {{ active }}</div>
<div>tour.completed: {{ completed }}</div>
<div>tour.dismissed: {{ dismissed }}</div>
</div>
<div id="actions">
<button v-on:click="() => complete()">Complete</button>
<button v-on:click="() => dismiss()">Dismiss</button>
</div>
<div id="children">
tour.items: {{ items.map(item => item.id).join(' ') }}
</div>
<div id="filtering">
<div id="active-items">
{{ filter('active').map(item => item.id).join(' ') }}
</div>
<div id="not-active-items">
{{ filter('not-active').map(item => item.id).join(' ') }}
</div>
<div id="completed-items">
{{ filter('completed').map(item => item.id).join(' ') }}
</div>
<div id="not-completed-items">
{{ filter('not-completed').map(item => item.id).join(' ') }}
</div>
</div>
<div id="metadata">
<div>tour.size: {{ size }}</div>
</div>
</div>
</template>

useTourItem

A Vue composable for accessing and updating a tour item's state and content.

<script>
import { useTourItem } from '@dopt/vue';
import RichText from '@dopt/html-rich-text';
const {
id,
tour,
index,
title,
body,
nextLabel,
backLabel,
active,
completed,
next,
back,
} = useTourItem('onboarding-tour.step-1');
</script>
<template>
<div>
<div id="states">
<div>tourItem.active: {{ active }}</div>
<div>tourItem.completed: {{ completed }}</div>
</div>
<div id="actions">
<button v-on:click="() => next()">{{ nextLabel }}</button>
<button v-on:click="() => back()">{{ backLabel }}</button>
</div>
<div id="content">
<div>tourItem.title: {{ title }}</div>
<div>
tourItem.body: <div v-html="RichText({ content: body })"></div>
</div>
<div>tourItem.nextLabel: {{ nextLabel }}</div>
<div>tourItem.backLabel: {{ backLabel }}</div>
</div>
<div id="parent">
<div>tourItem.tour: {{ tour()?.id?.value }}</div>
</div>
<div id="metadata">
<div>tourItem.index: {{ tourItem.index }}</div>
</div>
</div>
</template>

Types

Tour

A stateful container for tour items.

interface Tour {
id: Ref<string>;

items: () => TourItem[];

active: Ref<boolean>;

completed: Ref<boolean>;
dismissed: Ref<boolean>;

field: <V>(name: string) => undefined | null | V;

complete: () => void;
dismiss: () => void;

size: Ref<number>;

filter(on: FilterableField): TourItem[];
count(where: CountableField): number;
}

TourItem

A child of the tour. Includes state accessors and methods for updating state along with content configured in Dopt.

interface TourItem {
id: Ref<string>;

tour: () => Tour | undefined;

index: Ref<number | null | undefined>;

title: Ref<string | null | undefined>;
body: Ref<Children | null | undefined>;

nextLabel: Ref<string | null | undefined>;
backLabel: Ref<string | null | undefined>;

active: Ref<boolean>;

completed: Ref<boolean>;

field: <V>(name: string) => undefined | null | V;

next: () => void;
back: () => void;
}

FilterableField

type FilterableField = 'completed' | 'not-completed' | 'active' | 'not-active';

CountableField

type CountableField = FilterableField;