v-tutorial 0.0.0-stage β†’ 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,352 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ # 🎯 v-tutorial
4
+
5
+ **100% Interactive, Mobile-First (Bootstrap-Style) & Headless-Ready Guided Tours for Vue 3**
6
+
7
+ [![NPM Version](https://img.shields.io/npm/v/v-tutorial?color=42b883&label=npm)](https://www.npmjs.com/package/v-tutorial)
8
+ [![Vue 3](https://img.shields.io/badge/Vue-3.x-42b883?logo=vue.js)](https://vuejs.org/)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Strict-3178c6?logo=typescript)](https://www.typescriptlang.org/)
10
+ [![Zero Dependencies](https://img.shields.io/badge/Dependencies-Zero-success)](#)
11
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
12
+
13
+ 🌎 **English** | πŸ‡§πŸ‡· **[Leia em PortuguΓͺs (Portuguese Version)](./README.pt-BR.md)**
14
+
15
+ </div>
16
+
17
+
18
+ <img width="1000" height="562" alt="v-tutorial" src="https://github.com/user-attachments/assets/ec106114-4da2-4358-9159-fde748cc29ff" />
19
+
20
+ ---
21
+
22
+ ## πŸš€ Live Demo & Showcase Project
23
+
24
+ Want to test `v-tutorial` in action or see how a real multi-route Vue 3 + TypeScript application is structured? Check out **OdontoTec**, my complete interactive showcase project:
25
+
26
+ * 🌐 **Try the Live Demo (GitHub Pages):** [https://marlon-bento.github.io/v-tutorial-showcase/](https://marlon-bento.github.io/v-tutorial-showcase/)
27
+ * πŸ“‚ **Explore the Example Repository:** [https://github.com/marlon-bento/v-tutorial-showcase](https://github.com/marlon-bento/v-tutorial-showcase)
28
+
29
+ ---
30
+
31
+ ## πŸ“‹ Table of Contents
32
+
33
+ 1. [Why `v-tutorial`? (+ Comparison Table)](#1-why-v-tutorial)
34
+ 2. [Modular Architecture](#2-modular-architecture)
35
+ 3. [Installation & Quick Setup](#3-installation--quick-setup)
36
+ 4. [Step Modes (`info`, `wait-click`, `optional-click`)](#4-step-modes-info-wait-click-optional-click)
37
+ 5. [Bootstrap-Style Mobile-First Responsiveness (`xs` to `xxl`)](#5-bootstrap-style-mobile-first-responsiveness-xs-to-xxl)
38
+ 6. [Declarative Usage (`<TutorialProvider>` + `<VTutorialStep>`)](#6-declarative-usage-tutorialprovider--vtutorialstep)
39
+ 7. [Connecting Remote Components (`registerAction` & `v-tutorial`)](#7-connecting-remote-components-registeraction--v-tutorial)
40
+ 8. [Styling, Dark Mode & CSS Variables](#8-styling-dark-mode--css-variables)
41
+ 9. [Headless UI Mode & Scoped Slots](#9-headless-ui-mode--scoped-slots)
42
+ 10. [Complete API Reference](#10-complete-api-reference)
43
+
44
+ ---
45
+
46
+ ## 1. Why `v-tutorial`?
47
+
48
+ Most guided tour libraries (`Driver.js`, `Shepherd.js`, `Intro.js`) were built for static websites or passive `"Next -> Next -> Finish"` reading flows. When used inside modern **Vue 3 SPAs** with dynamic routes, `Teleport` modals, and distinct Mobile/Desktop DOM trees, they break `z-index` stacking contexts, cover mandatory buttons on mobile screens, and fail when a user clicks **"Previous"**.
49
+
50
+ | Feature | `v-tutorial` | Driver.js | Shepherd.js | Intro.js |
51
+ | :--- | :---: | :---: | :---: | :---: |
52
+ | **4-Shield Real Click (`wait-click`)** *(No `z-index` hacks)* | βœ… | ❌ | ❌ | ❌ |
53
+ | **Bootstrap-Style Mobile-First Breakpoints (`xs`..`xxl`)** | βœ… | ❌ | ❌ | ❌ |
54
+ | **Anti-Collision Mobile Sheets (`bottom-sheet` / `top-sheet`)** | βœ… | ❌ | ❌ | ❌ |
55
+ | **Declarative Vue Router Rollback (`route` / `rollback-route`)** | βœ… | ❌ | ❌ | ❌ |
56
+ | **Remote Component State Rollback (`registerAction`)** | βœ… | ❌ | ❌ | ❌ |
57
+ | **Declarative `<VTutorialStep>` Template API + Slots** | βœ… | ❌ | ❌ | ❌ |
58
+ | **Headless UI Mode (`:unstyled="true"` + 8 Scoped Slots)** | βœ… | ❌ | ⚠️ Partial | ❌ |
59
+ | **External Dependencies** | **0** | 0 | Floating UI | 0 |
60
+
61
+ ### Core Highlights
62
+
63
+ * πŸ›‘οΈ **4-Shield Click Architecture (`wait-click`):** Instead of cloning DOM nodes or hacking `z-index`, `v-tutorial` surrounds the target element with 4 invisible click shields. The rest of the screen is blocked while **your real button remains 100% interactive** in its native DOM context.
64
+ * πŸ“± **Bootstrap-Style Mobile-First Cascade (`xs` -> `sm` -> `md` -> `lg` -> `xl` -> `xxl`):** Define base props for mobile (`xs`) and override `target`, `placement`, `enterActions`, or `disabled` at any breakpoint (`md`, `lg`, etc.). Rules cascade upward automatically just like Bootstrap's grid.
65
+ * 🧲 **Anti-Collision Mobile Sheets (`bottom-sheet` & `top-sheet`):** On mobile viewports, floating cards automatically dock as a clean bottom or top sheet. If a sheet would overlap the highlighted button, the anti-collision engine automatically flips it to the opposite free side.
66
+ * βͺ **Declarative State & Route Rollback:** If Step 2 opens a sidebar, Step 3 navigates to `/report`, and the user clicks **"Previous"**, `v-tutorial` automatically rolls back the route and UI state (`rollback-route`, `:rollback-actions`).
67
+ * ⚑ **0% Idle CPU Tracking:** Uses `ResizeObserver` + short `requestAnimationFrame` bursts only during CSS transitions (`transitionrun`), dropping to 0% CPU usage once the layout settles.
68
+
69
+ ---
70
+
71
+ ## 2. Modular Architecture
72
+
73
+ The library is split into focused, single-responsibility modules inside `src/`:
74
+
75
+ | File | Responsibility |
76
+ | :--- | :--- |
77
+ | `types.ts` | TypeScript interfaces for steps, responsive breakpoints, action maps, and contexts. |
78
+ | `responsive.ts` | Bootstrap 5 breakpoint detection (`xs` to `xxl`) and Mobile-First property cascading. |
79
+ | `domResolver.ts` | Visible DOM element resolution, multi-target bounding box calculation, and smooth auto-scrolling. |
80
+ | `positioning.ts` | Card & caret arrow coordinate math, auto-flipping, and mobile sheet anti-collision engine. |
81
+ | `useTutorial.ts` | Reactive state machine, step queue, registered actions, and global click capture. |
82
+ | `TutorialProvider.vue` | Root visual/Headless provider rendering shields, spotlight ring, arrow, and card slots. |
83
+ | `TutorialStep.vue` | Declarative `<VTutorialStep>` component with slot teleportation and reactive prop syncing. |
84
+
85
+ ---
86
+
87
+ ## 3. Installation & Quick Setup
88
+
89
+ Install the package via NPM, PNPM, or Yarn:
90
+
91
+ ```bash
92
+ npm install v-tutorial
93
+ ```
94
+
95
+ Register `TutorialPlugin` and import the stylesheet in your `main.ts`:
96
+
97
+ ```ts
98
+ // main.ts
99
+ import { createApp } from 'vue'
100
+ import App from './App.vue'
101
+ import router from './router'
102
+ import { TutorialPlugin } from 'v-tutorial'
103
+ import 'v-tutorial/style.css'
104
+
105
+ const app = createApp(App)
106
+
107
+ app.use(router)
108
+ app.use(TutorialPlugin, {
109
+ storageKey: 'my-app-tutorial-completed',
110
+ autoScroll: true,
111
+ scrollBehavior: 'smooth',
112
+ spotlightPadding: 6,
113
+ cardWidth: 370,
114
+ showArrow: true,
115
+ mobileSheetOnAuto: true,
116
+ router, // Optional: Enables declarative route="" and rollback-route="" on steps
117
+ })
118
+
119
+ app.mount('#app')
120
+ ```
121
+
122
+ ---
123
+
124
+ ## 4. Step Modes (`info`, `wait-click`, `optional-click`)
125
+
126
+ | Mode | "Next" Button | Clicking Target Element | Best Use Case |
127
+ | :--- | :---: | :---: | :--- |
128
+ | `'info'` *(default)* | **Visible** | Optional (does not auto-advance) | Welcome screens, general explanations, or panel overviews. |
129
+ | `'wait-click'` | **Hidden** *(shows "Waiting click...")* | **Required to advance** | Hands-on training where the user **must click the real button** (e.g., opening a menu or system). |
130
+ | `'optional-click'` | **Visible** | **Also advances the step** | When the user can either test the button (e.g., pin a favorite) or click "Next" to skip. |
131
+
132
+ ---
133
+
134
+ ## 5. Bootstrap-Style Mobile-First Responsiveness (`xs` to `xxl`)
135
+
136
+ Just like Bootstrap 5, `v-tutorial` is **Mobile-First**. Base props on `<VTutorialStep>` apply from `xs` (`0px`) upward, and any breakpoint override cascades to larger screens until overridden again:
137
+
138
+ | Breakpoint | Default Min-Width | Shorthand Props |
139
+ | :--- | :---: | :--- |
140
+ | `xs` *(base)* | `0px` | `target`, `placement` |
141
+ | `sm` | `576px` | `target-sm`, `placement-sm` |
142
+ | `md` | `768px` | `target-md`, `placement-md` |
143
+ | `lg` | `992px` | `target-lg`, `placement-lg` |
144
+ | `xl` | `1200px` | `target-xl`, `placement-xl` |
145
+ | `xxl` | `1400px` | `target-xxl`, `placement-xxl` |
146
+
147
+ ### 5.1. Using Shorthand Responsive Props (`target-md`, `placement-md`)
148
+ If your app renders `.mobile-system-link` on phones (`xs`/`sm`) and `.desktop-system-link` on desktops (`md` and up):
149
+
150
+ ```vue
151
+ <VTutorialStep
152
+ id="select-system"
153
+ target=".mobile-system-link"
154
+ target-md=".desktop-system-link"
155
+ placement="bottom-sheet"
156
+ placement-md="right"
157
+ title="Open a System"
158
+ mode="wait-click"
159
+ >
160
+ <p class="mb-0">Click on the highlighted system to open it.</p>
161
+ </VTutorialStep>
162
+ ```
163
+
164
+ ### 5.2. Mobile-Only or Desktop-Only Steps (`disabled: true` per Breakpoint)
165
+ Want a step that teaches mobile users how to pull open the mobile drawer (`.mobile-drawer-tab`), but automatically skips itself on desktop (`md` and up)? Use the `:breakpoints` prop:
166
+
167
+ ```vue
168
+ <!-- Runs on xs and sm (< 768px), automatically skipped on md, lg, xl, xxl (>= 768px) -->
169
+ <VTutorialStep
170
+ id="open-mobile-drawer"
171
+ target=".mobile-drawer-tab"
172
+ placement="bottom-sheet"
173
+ title="Mobile Menu Tab"
174
+ mode="wait-click"
175
+ :breakpoints="{
176
+ md: { disabled: true }
177
+ }"
178
+ >
179
+ <p class="mb-0">Tap the side pull-tab to open the mobile menu.</p>
180
+ </VTutorialStep>
181
+ ```
182
+
183
+ ---
184
+
185
+ ## 6. Declarative Usage (`<TutorialProvider>` + `<VTutorialStep>`)
186
+
187
+ Build complete multi-route interactive onboarding flows directly in your template:
188
+
189
+ ```vue
190
+ <template>
191
+ <TutorialProvider :auto-start="true">
192
+ <VTutorialStep
193
+ id="welcome"
194
+ title="Welcome!"
195
+ mode="info"
196
+ placement="center"
197
+ route="/"
198
+ :enter-actions="{ closeThemeModal: true, closeUserMenu: true, setSidebarExpanded: false }"
199
+ >
200
+ <p class="mb-0">This training is <strong>100% interactive</strong>.</p>
201
+ </VTutorialStep>
202
+
203
+ <VTutorialStep
204
+ id="click-report"
205
+ target=".report-link"
206
+ placement="bottom-sheet"
207
+ placement-md="right"
208
+ title="Report an Issue"
209
+ mode="wait-click"
210
+ rollback-route="/"
211
+ :enter-actions="{ setSidebarExpanded: true, openUserMenu: true }"
212
+ :rollback-actions="{ setSidebarExpanded: true, openUserMenu: true }"
213
+ >
214
+ <p class="mb-0">Click on <strong>"Report issue or suggestion"</strong>.</p>
215
+ </VTutorialStep>
216
+ </TutorialProvider>
217
+ </template>
218
+ ```
219
+
220
+ ---
221
+
222
+ ## 7. Connecting Remote Components (`registerAction` & `v-tutorial`)
223
+
224
+ ### 7.1. Exposing Component State (`registerAction`)
225
+ Any component can register actions that steps can trigger via `enterActions`, `rollbackActions`, or `leaveActions`:
226
+
227
+ ```ts
228
+ // Inside UserInfo.vue
229
+ import { useTutorial } from 'v-tutorial'
230
+
231
+ const { registerAction } = useTutorial()
232
+
233
+ registerAction('openUserMenu', () => {
234
+ if (isMobile.value) {
235
+ isOpen.value = true
236
+ } else {
237
+ isDesktopModalOpen.value = true
238
+ }
239
+ })
240
+
241
+ registerAction('closeUserMenu', () => {
242
+ isOpen.value = false
243
+ isDesktopModalOpen.value = false
244
+ })
245
+ ```
246
+
247
+ ### 7.2. Restarting the Tutorial from a Settings Modal
248
+ Call `restartTutorial()` from any component to clear the completion flag in `localStorage` and immediately launch Step 1:
249
+
250
+ ```ts
251
+ import { useTutorial } from 'v-tutorial'
252
+
253
+ const { restartTutorial } = useTutorial()
254
+
255
+ async function handleRestartClick() {
256
+ closeSettingsModal()
257
+ await restartTutorial()
258
+ }
259
+ ```
260
+
261
+ ---
262
+
263
+ ## 8. Styling, Dark Mode & CSS Variables
264
+
265
+ `v-tutorial` inherits **Tabler / Bootstrap** variables (`--tblr-primary`, `--tblr-bg-surface`) automatically and adapts to Dark Mode (`[data-bs-theme="dark"]` or `.dark`). Override `--v-tutorial-*` variables to customize:
266
+
267
+ ```css
268
+ :root {
269
+ --v-tutorial-primary: #10b981;
270
+ --v-tutorial-bg: #ffffff;
271
+ --v-tutorial-bg-secondary: #f8fafc;
272
+ --v-tutorial-text: #0f172a;
273
+ --v-tutorial-muted: #64748b;
274
+ --v-tutorial-border: rgba(15, 23, 42, 0.12);
275
+ --v-tutorial-danger: #ef4444;
276
+ --v-tutorial-backdrop: rgba(10, 14, 23, 0.72);
277
+ --v-tutorial-radius: 16px;
278
+ --v-tutorial-z-index: 10040;
279
+ }
280
+ ```
281
+
282
+ ---
283
+
284
+ ## 9. Headless UI Mode & Scoped Slots
285
+
286
+ Set `:unstyled="true"` or override any Scoped Slot on `<TutorialProvider>` (`#card`, `#header`, `#body`, `#hint`, `#progress`, `#footer`, `#exit-button`, `#spotlight`):
287
+
288
+ ```vue
289
+ <TutorialProvider>
290
+ <template #card="{ step, stepIndex, totalSteps, activeBreakpoint, nextStep, prevStep, endTutorial }">
291
+ <div class="custom-card p-4">
292
+ <small>Breakpoint: {{ activeBreakpoint }} | Step {{ stepIndex + 1 }}/{{ totalSteps }}</small>
293
+ <h4>{{ step?.title }}</h4>
294
+ <div v-html="step?.content"></div>
295
+ <button v-if="stepIndex > 0" @click="prevStep">Back</button>
296
+ <button v-if="step?.mode !== 'wait-click'" @click="nextStep">Next</button>
297
+ <button @click="endTutorial(true)">Skip</button>
298
+ </div>
299
+ </template>
300
+ </TutorialProvider>
301
+ ```
302
+
303
+ ---
304
+
305
+ ## 10. Complete API Reference
306
+
307
+ ### `<VTutorialStep>` Props / `TutorialStep` Properties
308
+
309
+ | Property | Type | Default | Description |
310
+ | :--- | :--- | :---: | :--- |
311
+ | `id` | `string` | Auto-generated | Unique step identifier. |
312
+ | `target` | `string \| string[]` | `undefined` | Base (`xs`) selector, `v-tutorial` ID, or array of selectors. |
313
+ | `targetSm`..`targetXxl` | `string \| string[]` | `undefined` | Mobile-First target overrides for `sm`, `md`, `lg`, `xl`, `xxl`. |
314
+ | `placement` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right' \| 'center' \| 'bottom-sheet' \| 'top-sheet'` | `'auto'` | Base (`xs`) card placement with automatic collision prevention. |
315
+ | `placementSm`..`placementXxl` | `TutorialPlacement` | `undefined` | Mobile-First placement overrides for `sm`, `md`, `lg`, `xl`, `xxl`. |
316
+ | `breakpoints` | `Partial<Record<TutorialBreakpointName, TutorialStepResponsiveOverride>>` | `undefined` | Full Mobile-First override object per breakpoint (`disabled`, `enterActions`, `title`, etc.). |
317
+ | `disabled` | `boolean` | `false` | Skips this step when `true` in the active breakpoint. |
318
+ | `title` | `string` | **Required** | Step header title. |
319
+ | `mode` | `'info' \| 'wait-click' \| 'optional-click'` | `'info'` | Step interaction behavior. |
320
+ | `hintText` | `string` | `undefined` | Text shown in the pulsing interactive banner. |
321
+ | `route` | `string` | `undefined` | Navigates to this route before entering the step. |
322
+ | `rollbackRoute` | `string` | `undefined` | Navigates to this route when returning via "Previous". |
323
+ | `enterActions` | `Record<string, any> \| string[]` | `undefined` | Registered actions executed when entering the step. |
324
+ | `rollbackActions` | `Record<string, any> \| string[]` | `undefined` | Registered actions executed when returning via "Previous". |
325
+ | `leaveActions` | `Record<string, any> \| string[]` | `undefined` | Registered actions executed when leaving the step. |
326
+ | `afterClickDelay` | `number` | `280` | Delay in `ms` after clicking the target before advancing. |
327
+ | `preventNativeClick` | `boolean` | `false` | Blocks the native click handler of the target during the tour. |
328
+
329
+ ### `useTutorial()` Return Values
330
+
331
+ | Property / Method | Type | Description |
332
+ | :--- | :--- | :--- |
333
+ | `isActive` | `Ref<boolean>` | Whether the tutorial is currently running. |
334
+ | `activeBreakpoint` | `ComputedRef<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl'>` | Current Bootstrap-style breakpoint name. |
335
+ | `isMobileViewport` | `ComputedRef<boolean>` | `true` when viewport width is below `md` (`< 768px`). |
336
+ | `currentStep` | `ComputedRef<TutorialStep \| null>` | Active step resolved for the current breakpoint. |
337
+ | `currentStepIndex` | `Ref<number>` | 0-based index of the active step. |
338
+ | `totalSteps` | `ComputedRef<number>` | Total enabled steps for the current breakpoint. |
339
+ | `progress` | `ComputedRef<number>` | Completion percentage (`0` to `100`). |
340
+ | `startTutorial(steps?, force?)` | `Promise<void>` | Starts the tour (`force = true` ignores `localStorage`). |
341
+ | `restartTutorial()` | `Promise<void>` | Clears `localStorage` flag and restarts from Step 1. |
342
+ | `nextStep()` / `prevStep()` | `Promise<void>` | Navigates forward or backward (with automatic rollback). |
343
+ | `goToStep(indexOrId)` | `Promise<void>` | Jumps directly to a specific step index or `id`. |
344
+ | `endTutorial(markCompleted?)` | `void` | Closes the tutorial immediately. |
345
+ | `registerAction(name, fn)` | `void` | Registers a named action callable by any step. |
346
+ | `onFinish` / `onStop` / `onStepChange` | `(cb) => () => void` | Lifecycle event listeners (auto-disposed on component unmount). |
347
+
348
+ ---
349
+
350
+ ## πŸ“„ License
351
+
352
+ Distributed under the **MIT License**. Created by [MΓ‘rlon Bento Azevedo](https://github.com/marlon-bento).