Tour
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
- useTourItem(
id
): TourItem
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;