A flexible and customizable tour guide library for web applications, built with TypeScript and Vue.js reactivity system.
- π― Highly customizable tour steps and popover templates
- π¨ Flexible positioning and styling options
- π Support for entry/leave hooks for each step
- π Customizable overlay and highlighting
- π Configurable offsets and padding
- π― Multiple placement options
- πͺ Written in TypeScript with full type support
npm install tour-master
import { Tour } from 'tour-master';
const tour = new Tour({
steps: [
{
element: '#step1', // Can be string ID, HTMLElement, or function
stages: [ // Optional custom highlight areas
{
x: 0,
y: 0,
width: 100,
height: 100,
},
],
},
{
element: document.getElementById('step2'),
placement: 'top', // Control popover placement
entry: async (action) => {
// Do something when entering this step
},
leave: async (action) => {
// Do something when leaving this step
},
},
],
popoverTemplate: (pre, next, finish, currentStep, currentStepIndex, stepTotal) => {
// Return a function that creates and returns your popover element
return (bindArrowEl) => {
const el = document.createElement('div');
// ... configure your popover
return el;
};
},
// Optional configurations
popoverOffset: 8,
popoverPadding: 5,
zIndex: 1000,
overlayOpacity: 0.5,
});
// Start the tour
tour.start();
interface TourConfig<T = undefined> {
steps: Array<TourStep & T>
popoverTemplate: PopoverTemplate<T>
popoverArrowPositioned?: PopoverArrowPositionedHandler
popoverOffset?: number
popoverPadding?: number
zIndex?: number
overlayOpacity?: number
}
interface TourStep {
element: string | HTMLElement | (() => HTMLElement)
stages?: StageDefinition[] | (() => StageDefinition[])
entry?: (action: 'pre' | 'next') => void | Promise<void>
leave?: (action: 'pre' | 'next' | 'finish') => void | Promise<void>
placement?: Placement
}
You can create custom popover templates using vanilla JavaScript or any framework. Here's an example with Vue:
import { defineComponent, h, render } from 'vue';
const tour = new Tour({
// ... other config
popoverTemplate: (pre, next, finish, currentStep, currentStepIndex, stepTotal) => {
return (bindArrowEl) => {
const component = defineComponent({
setup() {
return () => h('div', { class: 'tour-popover' }, [
h('div', { class: 'content' }, currentStep.content),
h('div', { class: 'actions' }, [
h('button', { onClick: pre }, 'Previous'),
h('button', { onClick: next }, 'Next'),
h('button', { onClick: finish }, 'Finish'),
]),
]);
},
});
const container = document.createElement('div');
render(component, container);
return container.firstElementChild as HTMLElement;
};
},
});
You can define custom highlight areas for each step:
const tour = new Tour({
steps: [
{
element: '#step1',
stages: () => [{
x: 100,
y: 100,
width: 200,
height: 50,
}],
},
],
});
Each step supports entry and leave hooks:
const tour = new Tour({
steps: [
{
element: '#step2',
entry: async (action) => {
// action will be 'pre' or 'next'
await someAsyncOperation();
},
leave: async (action) => {
// action will be 'pre', 'next', or 'finish'
await cleanup();
},
},
],
});
You can chain multiple tours together:
const tourScheduler = new TourScheduler({
tours: new Map([
['tour1', tour1],
['tour2', tour2],
]),
stateHandler() {
// Logic to determine which tour to show
return 'tour1'; // or 'tour2'
},
});
Check the playground
directory in the repository for complete working examples including:
- Multiple sequential tours
- Custom popover styling
- Tour transitions
MIT