Skip to content

Commit 0b2dd11

Browse files
committed
Add jump options interface and implement customizable scroll behavior in VTour component
1 parent 27a9ab4 commit 0b2dd11

5 files changed

Lines changed: 396 additions & 6 deletions

File tree

docs/guide/jump-options.md

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
# Jump Options
2+
3+
VueJS Tour now supports customizable scroll animation options via the [jump.js](https://github.com/callmecavs/jump.js) library.
4+
5+
## Available Options
6+
7+
```typescript
8+
interface JumpOptions {
9+
/** Duration of scroll animation in milliseconds (default: 500) */
10+
duration?: number;
11+
12+
/** Vertical offset in pixels from target element (default: -100) */
13+
offset?: number;
14+
15+
/** Callback function to execute after scroll completes */
16+
callback?: () => void;
17+
18+
/** Easing function name or custom function (default: 'easeInOutQuad') */
19+
easing?: (t: number, b: number, c: number, d: number) => number | string;
20+
21+
/** Whether to focus the element for accessibility (default: false) */
22+
a11y?: boolean;
23+
}
24+
```
25+
26+
## Global Configuration
27+
28+
Set default jump options for all steps in the tour:
29+
30+
```vue
31+
<template>
32+
<VTour
33+
:steps="steps"
34+
:jump-options="{
35+
duration: 1000,
36+
offset: -50,
37+
easing: 'easeInOutQuad',
38+
a11y: true,
39+
}"
40+
/>
41+
</template>
42+
```
43+
44+
## Per-Step Configuration
45+
46+
Override global options for specific steps:
47+
48+
```typescript
49+
const steps = [
50+
{
51+
target: '#step1',
52+
content: 'This step uses global jump options',
53+
},
54+
{
55+
target: '#step2',
56+
content: 'This step uses custom scroll duration',
57+
jumpOptions: {
58+
duration: 300, // Faster scroll
59+
offset: -200, // More space at top
60+
},
61+
},
62+
];
63+
```
64+
65+
## Custom Easing
66+
67+
Provide a custom easing function:
68+
69+
```vue
70+
<script setup lang="ts">
71+
import { VTour } from '@globalhive/vuejs-tour';
72+
73+
const customEasing = (t: number, b: number, c: number, d: number) => {
74+
// Linear easing
75+
return (c * t) / d + b;
76+
};
77+
78+
const jumpOptions = {
79+
duration: 800,
80+
easing: customEasing,
81+
};
82+
</script>
83+
84+
<template>
85+
<VTour :steps="steps" :jump-options="jumpOptions" />
86+
</template>
87+
```
88+
89+
## Disabling Scroll
90+
91+
You can disable scrolling globally or per-step using the existing `noScroll` prop:
92+
93+
```vue
94+
<!-- Disable scrolling for entire tour -->
95+
<VTour :steps="steps" :no-scroll="true" />
96+
```
97+
98+
```typescript
99+
// Disable scrolling for specific step
100+
const steps = [
101+
{
102+
target: '#step1',
103+
content: 'This step will not scroll',
104+
noScroll: true,
105+
},
106+
];
107+
```
108+
109+
## Priority
110+
111+
When multiple jump option sources are provided, they are merged with the following priority:
112+
113+
1. **Step-specific options** (highest priority)
114+
2. **Global prop options**
115+
3. **Default values** (lowest priority)
116+
117+
Example:
118+
119+
```typescript
120+
// Global defaults
121+
const globalJumpOptions = {
122+
duration: 1000,
123+
offset: -100,
124+
a11y: true,
125+
};
126+
127+
// Step overrides
128+
const steps = [
129+
{
130+
target: '#step1',
131+
content: 'Step 1',
132+
jumpOptions: {
133+
duration: 300, // Only override duration
134+
// offset: still -100 from global
135+
// a11y: still true from global
136+
},
137+
},
138+
];
139+
```
140+
141+
## Available Easing Functions
142+
143+
jump.js supports the following built-in easing function names:
144+
145+
- `'easeInQuad'`
146+
- `'easeOutQuad'`
147+
- `'easeInOutQuad'` (default)
148+
- `'easeInCubic'`
149+
- `'easeOutCubic'`
150+
- `'easeInOutCubic'`
151+
- `'easeInQuart'`
152+
- `'easeOutQuart'`
153+
- `'easeInOutQuart'`
154+
- `'easeInQuint'`
155+
- `'easeOutQuint'`
156+
- `'easeInOutQuint'`
157+
158+
Or provide your own custom easing function following the signature:
159+
160+
```typescript
161+
(t: number, b: number, c: number, d: number) => number;
162+
```
163+
164+
Where:
165+
166+
- `t` = current time
167+
- `b` = beginning value
168+
- `c` = change in value
169+
- `d` = duration

src/Types.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
import type { NanoPopPosition } from 'nanopop';
22

3+
/**
4+
* Scroll animation options for jump.js
5+
* @see https://github.com/callmecavs/jump.js
6+
*/
7+
export interface JumpOptions {
8+
/** Duration of scroll animation in milliseconds (default: 500) */
9+
readonly duration?: number;
10+
11+
/** Vertical offset in pixels from target element (default: -100) */
12+
readonly offset?: number;
13+
14+
/** Callback function to execute after scroll completes */
15+
readonly callback?: () => void;
16+
17+
/** Easing function name (default: 'easeInOutQuad') */
18+
readonly easing?: (
19+
t: number,
20+
b: number,
21+
c: number,
22+
d: number
23+
) => number | string;
24+
25+
/** Whether to focus the element for accessibility (default: false) */
26+
readonly a11y?: boolean;
27+
}
28+
329
/**
430
* Configuration for a single step in a tour
531
*/
@@ -27,6 +53,9 @@ export interface ITourStep {
2753

2854
/** Whether to disable auto-scrolling for this step */
2955
readonly noScroll?: boolean;
56+
57+
/** Custom scroll animation options for this step (overrides global jumpOptions) */
58+
readonly jumpOptions?: Partial<JumpOptions>;
3059
}
3160

3261
/**
@@ -89,6 +118,9 @@ export interface VTourProps {
89118

90119
/** Default tooltip placement when step doesn't specify one */
91120
readonly defaultPlacement?: NanoPopPosition;
121+
122+
/** Default scroll animation options (can be overridden per step) */
123+
readonly jumpOptions?: Partial<JumpOptions>;
92124
}
93125

94126
/**

src/components/VTour.vue

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,14 @@ const _Backdrop = ref<HTMLElement>();
8282
8383
// Constants for timing and positioning
8484
const TELEPORT_RENDER_DELAY = 100; // ms to wait for Vue Teleport to render DOM elements
85-
const SCROLL_DURATION = 500; // ms for smooth scroll animation
86-
const SCROLL_OFFSET = -100; // px offset from top when scrolling to element
85+
86+
// Default jump.js scroll options (can be overridden via props)
87+
const DEFAULT_JUMP_OPTIONS = {
88+
duration: 500,
89+
offset: -100,
90+
easing: 'easeInOutQuad' as const,
91+
a11y: false,
92+
};
8793
8894
// Helper to check if tour was completed and saved to localStorage
8995
const isTourCompleted = (): boolean => {
@@ -330,11 +336,16 @@ const updatePosition = async (): Promise<void> => {
330336
// Scroll to target first if needed
331337
if (!props.noScroll && !currentStepData.noScroll) {
332338
await new Promise<void>((resolve) => {
333-
jump(targetElement, {
334-
duration: SCROLL_DURATION,
335-
offset: SCROLL_OFFSET,
339+
// Merge default options with global and step-specific options
340+
// Priority: step options > global options > defaults
341+
const scrollOptions = {
342+
...DEFAULT_JUMP_OPTIONS,
343+
...props.jumpOptions,
344+
...currentStepData.jumpOptions,
336345
callback: () => resolve(),
337-
});
346+
} as any; // jump.js has incomplete type definitions
347+
348+
jump(targetElement, scrollOptions);
338349
});
339350
}
340351

src/vuejs-tour.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ export type {
1010
VTourExposedMethods,
1111
ButtonLabels,
1212
SaveToLocalStorage,
13+
JumpOptions,
1314
} from './Types';
1415

1516
// Re-export NanoPopPosition from nanopop for user convenience

0 commit comments

Comments
 (0)