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.
@@ -0,0 +1,352 @@
1
+ <div align="center">
2
+
3
+ # 🎯 v-tutorial
4
+
5
+ **Tours Guiados e Treinamento 100% Interativo, Mobile-First (Estilo Bootstrap) e Headless-Ready para 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/Dependências-Zero-success)](#)
11
+ [![License: MIT](https://img.shields.io/badge/Licença-MIT-blue.svg)](https://opensource.org/licenses/MIT)
12
+
13
+ 🇧🇷 **Português** | 🌎 **[Read in English (English Version)](./README.md)**
14
+
15
+ </div>
16
+
17
+ <img width="1000" height="562" alt="v-tutorial" src="https://github.com/user-attachments/assets/ec106114-4da2-4358-9159-fde748cc29ff" />
18
+
19
+ ---
20
+
21
+ ## 🚀 Demonstração Online e Projeto de Exemplo
22
+
23
+ Quer testar o `v-tutorial` funcionando na prática ou consultar o código completo de uma aplicação Vue 3 + TypeScript com múltiplas rotas, modais e responsividade Mobile-First? Confira o **OdontoTec**, meu projeto oficial de demonstração:
24
+
25
+ * 🌐 **Testar Demonstração Online (GitHub Pages):** [https://marlon-bento.github.io/v-tutorial-showcase/](https://marlon-bento.github.io/v-tutorial-showcase/)
26
+ * 📂 **Ver Repositório do Projeto de Exemplo:** [https://github.com/marlon-bento/v-tutorial-showcase](https://github.com/marlon-bento/v-tutorial-showcase)
27
+
28
+ ---
29
+
30
+ ## 📋 Sumário
31
+
32
+ 1. [Por que usar o `v-tutorial`? (+ Tabela Comparativa)](#1-por-que-usar-o-v-tutorial)
33
+ 2. [Arquitetura Modular](#2-arquitetura-modular)
34
+ 3. [Instalação e Configuração Rápida](#3-instalação-e-configuração-rápida)
35
+ 4. [Modos de Passo (`info`, `wait-click`, `optional-click`)](#4-modos-de-passo-info-wait-click-optional-click)
36
+ 5. [Responsividade Mobile-First Estilo Bootstrap (`xs` até `xxl`)](#5-responsividade-mobile-first-estilo-bootstrap-xs-até-xxl)
37
+ 6. [Uso Declarativo (`<TutorialProvider>` + `<VTutorialStep>`)](#6-uso-declarativo-tutorialprovider--vtutorialstep)
38
+ 7. [Conectando Componentes Distintos (`registerAction` e `v-tutorial`)](#7-conectando-componentes-distintos-registeraction-e-v-tutorial)
39
+ 8. [Customização Visual, Dark Mode e Variáveis CSS](#8-customização-visual-dark-mode-e-variáveis-css)
40
+ 9. [Modo Headless UI e Scoped Slots](#9-modo-headless-ui-e-scoped-slots)
41
+ 10. [Referência Completa da API](#10-referência-completa-da-api)
42
+
43
+ ---
44
+
45
+ ## 1. Por que usar o `v-tutorial`?
46
+
47
+ A maioria das bibliotecas de tour (`Driver.js`, `Shepherd.js`, `Intro.js`) foi pensada para sites estáticos ou fluxos passivos de leitura (`"Próximo -> Próximo -> Concluir"`). Quando colocadas dentro de uma **SPA moderna em Vue 3** com rotas dinâmicas, modais via `Teleport` e árvores DOM diferentes para Mobile e Desktop, elas quebram o `z-index` da aplicação, cobrem botões obrigatórios no celular e falham quando o usuário clica em **"Anterior"**.
48
+
49
+ | Recurso | `v-tutorial` | Driver.js | Shepherd.js | Intro.js |
50
+ | :--- | :---: | :---: | :---: | :---: |
51
+ | **Clique Real com 4 Escudos (`wait-click`)** *(Sem hack de `z-index`)* | ✅ | ❌ | ❌ | ❌ |
52
+ | **Breakpoints Mobile-First Estilo Bootstrap (`xs`..`xxl`)** | ✅ | ❌ | ❌ | ❌ |
53
+ | **Gavetas Mobile Anti-Colisão (`bottom-sheet` / `top-sheet`)** | ✅ | ❌ | ❌ | ❌ |
54
+ | **Rollback Declarativo de Rotas (`route` / `rollback-route`)** | ✅ | ❌ | ❌ | ❌ |
55
+ | **Rollback de Estado entre Componentes (`registerAction`)** | ✅ | ❌ | ❌ | ❌ |
56
+ | **API Declarativa `<VTutorialStep>` no Template + Slots** | ✅ | ❌ | ❌ | ❌ |
57
+ | **Modo Headless UI (`:unstyled="true"` + 8 Scoped Slots)** | ✅ | ❌ | ⚠️ Parcial | ❌ |
58
+ | **Dependências Externas** | **0** | 0 | Floating UI | 0 |
59
+
60
+ ### Principais Diferenciais
61
+
62
+ * 🛡️ **Arquitetura de 4 Escudos de Clique (`wait-click`):** Em vez de clonar nós do DOM ou forçar `z-index`, o `v-tutorial` posiciona 4 escudos invisíveis ao redor do elemento destacado. O restante da tela fica bloqueado, mas **o botão real do seu sistema permanece 100% clicável** no lugar original.
63
+ * 📱 **Cascata Mobile-First Estilo Bootstrap (`xs` -> `sm` -> `md` -> `lg` -> `xl` -> `xxl`):** Defina o comportamento base para celular (`xs`) e sobrescreva `target`, `placement`, `enterActions` ou `disabled` a partir de qualquer breakpoint (`md`, `lg`, etc.). As regras cascateiam para telas maiores exatamente como no Bootstrap.
64
+ * 🧲 **Gavetas Mobile com Sistema Anti-Colisão (`bottom-sheet` e `top-sheet`):** Em telas móveis, o card ancora como uma gaveta inferior ou superior. Se o motor detectar que o card cobriria o botão destacado, ele inverte automaticamente a posição para o lado livre.
65
+ * ⏪ **Rollback Declarativo de Rotas e Estados:** Se o Passo 2 abre o menu lateral, o Passo 3 navega para `/report` e o usuário clica em **"Anterior"**, o `v-tutorial` desfaz a rota e o estado visual automaticamente (`rollback-route`, `:rollback-actions`).
66
+ * ⚡ **0% de CPU em Repouso:** Utiliza `ResizeObserver` combinado com janelas curtas de `requestAnimationFrame` apenas durante transições CSS (`transitionrun`), desligando o loop assim que a tela estabiliza.
67
+
68
+ ---
69
+
70
+ ## 2. Arquitetura Modular
71
+
72
+ O motor interno em `src/` é dividido em módulos independentes com responsabilidade única:
73
+
74
+ | Arquivo | Responsabilidade |
75
+ | :--- | :--- |
76
+ | `types.ts` | Contratos TypeScript de passos, breakpoints responsivos, mapas de ações e contextos. |
77
+ | `responsive.ts` | Detecção dos breakpoints do Bootstrap 5 (`xs` até `xxl`) e herança em cascata Mobile-First. |
78
+ | `domResolver.ts` | Busca de elementos visíveis no DOM, cálculo de `DOMRect` agrupado e auto-scroll suave. |
79
+ | `positioning.ts` | Matemática geométrica do card e da seta (`arrowStyle`), auto-flip e sistema anti-colisão mobile. |
80
+ | `useTutorial.ts` | Máquina de estados reativa, fila de passos, ações registradas e captura global de clique. |
81
+ | `TutorialProvider.vue` | Provedor visual/Headless que renderiza os escudos, anel de spotlight, seta e Scoped Slots. |
82
+ | `TutorialStep.vue` | Componente declarativo `<VTutorialStep>` com teleporte de slot e sincronização reativa. |
83
+
84
+ ---
85
+
86
+ ## 3. Instalação e Configuração Rápida
87
+
88
+ Instale o pacote via NPM, PNPM ou Yarn:
89
+
90
+ ```bash
91
+ npm install v-tutorial
92
+ ```
93
+
94
+ No arquivo `main.ts`, registre o `TutorialPlugin` e importe o CSS da biblioteca:
95
+
96
+ ```ts
97
+ // main.ts
98
+ import { createApp } from 'vue'
99
+ import App from './App.vue'
100
+ import router from './router'
101
+ import { TutorialPlugin } from 'v-tutorial'
102
+ import 'v-tutorial/style.css'
103
+
104
+ const app = createApp(App)
105
+
106
+ app.use(router)
107
+ app.use(TutorialPlugin, {
108
+ storageKey: 'meu-app-tutorial-concluido',
109
+ autoScroll: true,
110
+ scrollBehavior: 'smooth',
111
+ spotlightPadding: 6,
112
+ cardWidth: 370,
113
+ showArrow: true,
114
+ mobileSheetOnAuto: true,
115
+ router, // Opcional: Habilita o funcionamento automático de route="" e rollback-route="" nos passos
116
+ })
117
+
118
+ app.mount('#app')
119
+ ```
120
+
121
+ ---
122
+
123
+ ## 4. Modos de Passo (`info`, `wait-click`, `optional-click`)
124
+
125
+ | Modo | Botão "Próximo" | Clique no Elemento Alvo | Caso de Uso Ideal |
126
+ | :--- | :---: | :---: | :--- |
127
+ | `'info'` *(padrão)* | **Visível** | Opcional (não avança sozinho) | Telas de boas-vindas, explicações gerais ou visão de painéis. |
128
+ | `'wait-click'` | **Oculto** *(exibe "Aguardando clique...")* | **Obrigatório para avançar** | Treinamento prático onde o usuário **precisa clicar no botão real** (ex: abrir menu, abrir sistema). |
129
+ | `'optional-click'` | **Visível** | **Também avança o passo** | Quando o usuário pode testar o clique no botão (ex: fixar favorito) ou clicar em "Próximo". |
130
+
131
+ ---
132
+
133
+ ## 5. Responsividade Mobile-First Estilo Bootstrap (`xs` até `xxl`)
134
+
135
+ Assim como no Bootstrap 5, o `v-tutorial` segue a filosofia **Mobile-First**. As propriedades base definidas no `<VTutorialStep>` valem a partir de `xs` (`0px`) para cima, e qualquer propriedade definida em um breakpoint maior herda para os seguintes até ser sobrescrita:
136
+
137
+ | Breakpoint | Largura Mínima Padrão | Props de Atalho Direto |
138
+ | :--- | :---: | :--- |
139
+ | `xs` *(base)* | `0px` | `target`, `placement` |
140
+ | `sm` | `576px` | `target-sm`, `placement-sm` |
141
+ | `md` | `768px` | `target-md`, `placement-md` |
142
+ | `lg` | `992px` | `target-lg`, `placement-lg` |
143
+ | `xl` | `1200px` | `target-xl`, `placement-xl` |
144
+ | `xxl` | `1400px` | `target-xxl`, `placement-xxl` |
145
+
146
+ ### 5.1. Usando Atalhos Diretos nas Props (`target-md`, `placement-md`)
147
+ Se no celular (`xs` e `sm`) o item do menu usa a classe `.mobile-system-link` e no computador (`md` em diante) usa `.sistema-item-row a.button`:
148
+
149
+ ```vue
150
+ <VTutorialStep
151
+ id="selecionar-sistema"
152
+ target=".mobile-system-link"
153
+ target-md=".sistema-item-row a.button"
154
+ placement="bottom-sheet"
155
+ placement-md="right"
156
+ title="Abra um Sistema Técnico"
157
+ mode="wait-click"
158
+ >
159
+ <p class="mb-0">Clique no primeiro sistema destacado para abri-lo.</p>
160
+ </VTutorialStep>
161
+ ```
162
+
163
+ ### 5.2. Passos Exclusivos de Mobile ou Desktop (`disabled: true` por Breakpoint)
164
+ Quer criar um passo que ensina o usuário do celular a abrir a aba deslizante `.super-slim-slider`, mas que seja pulado automaticamente em telas `md` (`>= 768px`)? Basta usar `:breakpoints`:
165
+
166
+ ```vue
167
+ <!-- Executa em xs e sm (< 768px) e é desabilitado automaticamente em md, lg, xl e xxl (>= 768px) -->
168
+ <VTutorialStep
169
+ id="abrir-gaveta-mobile"
170
+ target=".super-slim-slider"
171
+ placement="bottom-sheet"
172
+ title="Menu Lateral no Celular"
173
+ mode="wait-click"
174
+ :breakpoints="{
175
+ md: { disabled: true }
176
+ }"
177
+ >
178
+ <p class="mb-0">Toque na aba destacada para abrir a lista de sistemas.</p>
179
+ </VTutorialStep>
180
+ ```
181
+
182
+ ---
183
+
184
+ ## 6. Uso Declarativo (`<TutorialProvider>` + `<VTutorialStep>`)
185
+
186
+ Para manter a arquitetura limpa, deixe o componente `.vue` focado na declaração dos passos e isole os mapas de ações em um composable dedicado:
187
+
188
+ ```vue
189
+ <template>
190
+ <TutorialProvider>
191
+ <VTutorialStep
192
+ id="boas-vindas"
193
+ title="Bem-vindo!"
194
+ mode="info"
195
+ placement="center"
196
+ route="/"
197
+ :enter-actions="acoesBoasVindasBase"
198
+ :breakpoints="acoesBoasVindasDesktop"
199
+ >
200
+ <p class="mb-0">Este tutorial é <strong>100% interativo</strong>.</p>
201
+ </VTutorialStep>
202
+
203
+ <VTutorialStep
204
+ id="clicar-reportar"
205
+ target=".report-link"
206
+ placement="bottom-sheet"
207
+ placement-md="right"
208
+ title="Reportar Erro ou Sugestão"
209
+ mode="wait-click"
210
+ rollback-route="/"
211
+ :enter-actions="acoesAbrirMenuUsuario"
212
+ :rollback-actions="acoesAbrirMenuUsuario"
213
+ >
214
+ <p class="mb-0">Clique na opção <strong>"Reportar erro ou sugestão"</strong>.</p>
215
+ </VTutorialStep>
216
+ </TutorialProvider>
217
+ </template>
218
+ ```
219
+
220
+ ---
221
+
222
+ ## 7. Conectando Componentes Distintos (`registerAction` e `v-tutorial`)
223
+
224
+ ### 7.1. Expondo Ações de Estado (`registerAction`)
225
+ Qualquer componente pode registrar ações globais que os passos acionam via `enterActions`, `rollbackActions` ou `leaveActions`:
226
+
227
+ ```ts
228
+ // Dentro de 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. Botão de Reiniciar Tutorial no Modal de Configurações
248
+ Chame `restartTutorial()` de qualquer lugar para limpar o `localStorage` e reiniciar o treinamento imediatamente a partir do Passo 1:
249
+
250
+ ```ts
251
+ import { useTutorial } from 'v-tutorial'
252
+
253
+ const { restartTutorial } = useTutorial()
254
+
255
+ async function reiniciarTreinamentoSistema() {
256
+ emit('fecharModal')
257
+ await restartTutorial()
258
+ }
259
+ ```
260
+
261
+ ---
262
+
263
+ ## 8. Customização Visual, Dark Mode e Variáveis CSS
264
+
265
+ O `v-tutorial` herda variáveis do **Tabler / Bootstrap** (`--tblr-primary`, `--tblr-bg-surface`) automaticamente e adapta-se ao modo escuro (`[data-bs-theme="dark"]` ou `.dark`). Para customizar em qualquer projeto:
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. Modo Headless UI e Scoped Slots
285
+
286
+ Ative `:unstyled="true"` ou substitua qualquer Scoped Slot no `<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="meu-card-customizado p-4">
292
+ <small>Breakpoint: {{ activeBreakpoint }} | Passo {{ stepIndex + 1 }}/{{ totalSteps }}</small>
293
+ <h4>{{ step?.title }}</h4>
294
+ <div v-html="step?.content"></div>
295
+ <button v-if="stepIndex > 0" @click="prevStep">Anterior</button>
296
+ <button v-if="step?.mode !== 'wait-click'" @click="nextStep">Próximo</button>
297
+ <button @click="endTutorial(true)">Pular</button>
298
+ </div>
299
+ </template>
300
+ </TutorialProvider>
301
+ ```
302
+
303
+ ---
304
+
305
+ ## 10. Referência Completa da API
306
+
307
+ ### Props de `<VTutorialStep>` / Interface `TutorialStep`
308
+
309
+ | Propriedade | Tipo | Padrão | Descrição |
310
+ | :--- | :--- | :---: | :--- |
311
+ | `id` | `string` | Auto-gerado | Identificador único do passo. |
312
+ | `target` | `string \| string[]` | `undefined` | Seletor CSS base (`xs`), ID do `v-tutorial` ou array de seletores. |
313
+ | `targetSm`..`targetXxl` | `string \| string[]` | `undefined` | Sobrescrita Mobile-First do alvo para `sm`, `md`, `lg`, `xl`, `xxl`. |
314
+ | `placement` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right' \| 'center' \| 'bottom-sheet' \| 'top-sheet'` | `'auto'` | Posicionamento base (`xs`) com prevenção automática de colisão. |
315
+ | `placementSm`..`placementXxl` | `TutorialPlacement` | `undefined` | Sobrescrita Mobile-First do posicionamento para `sm`, `md`, `lg`, `xl`, `xxl`. |
316
+ | `breakpoints` | `Partial<Record<TutorialBreakpointName, TutorialStepResponsiveOverride>>` | `undefined` | Objeto completo de sobrescrita Mobile-First por breakpoint (`disabled`, `enterActions`, `title`, etc.). |
317
+ | `disabled` | `boolean` | `false` | Ignora/pula o passo automaticamente se for `true` no breakpoint ativo. |
318
+ | `title` | `string` | **Obrigatório** | Título exibido no cabeçalho do card. |
319
+ | `mode` | `'info' \| 'wait-click' \| 'optional-click'` | `'info'` | Define o comportamento de avanço do passo. |
320
+ | `hintText` | `string` | `undefined` | Frase exibida na faixa pulsante de ação interativa. |
321
+ | `route` | `string` | `undefined` | Navega automaticamente para esta rota ao entrar no passo. |
322
+ | `rollbackRoute` | `string` | `undefined` | Rota para a qual retorna ao clicar em "Anterior". |
323
+ | `enterActions` | `Record<string, any> \| string[]` | `undefined` | Mapa de ações registradas executadas ao entrar no passo. |
324
+ | `rollbackActions` | `Record<string, any> \| string[]` | `undefined` | Mapa de ações registradas executadas ao voltar ("Anterior") para o passo. |
325
+ | `leaveActions` | `Record<string, any> \| string[]` | `undefined` | Mapa de ações registradas executadas ao sair do passo. |
326
+ | `afterClickDelay` | `number` | `280` | Tempo em `ms` após o clique no elemento antes de avançar. |
327
+ | `preventNativeClick` | `boolean` | `false` | Bloqueia a ação original do botão clicado durante o tutorial. |
328
+
329
+ ### Retorno do Composable `useTutorial()`
330
+
331
+ | Propriedade / Método | Tipo | Descrição |
332
+ | :--- | :--- | :--- |
333
+ | `isActive` | `Ref<boolean>` | Indica se o tutorial está ativo no momento. |
334
+ | `activeBreakpoint` | `ComputedRef<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl'>` | Nome do breakpoint Bootstrap ativo na janela atual. |
335
+ | `isMobileViewport` | `ComputedRef<boolean>` | `true` quando a largura da janela é menor que `md` (`< 768px`). |
336
+ | `currentStep` | `ComputedRef<TutorialStep \| null>` | Objeto do passo atual já resolvido para o breakpoint ativo. |
337
+ | `currentStepIndex` | `Ref<number>` | Índice numérico (base 0) do passo atual. |
338
+ | `totalSteps` | `ComputedRef<number>` | Quantidade total de passos habilitados no breakpoint atual. |
339
+ | `progress` | `ComputedRef<number>` | Porcentagem de conclusão (`0` a `100`). |
340
+ | `startTutorial(steps?, force?)` | `Promise<void>` | Inicia o tutorial (`force = true` ignora o `localStorage`). |
341
+ | `restartTutorial()` | `Promise<void>` | Limpa a flag do `localStorage` e reinicia imediatamente do Passo 1. |
342
+ | `nextStep()` / `prevStep()` | `Promise<void>` | Avança ou retorna um passo (acionando o rollback automaticamente). |
343
+ | `goToStep(indexOrId)` | `Promise<void>` | Pula diretamente para um passo pelo índice ou pelo `id`. |
344
+ | `endTutorial(markCompleted?)` | `void` | Fecha o tutorial imediatamente. |
345
+ | `registerAction(name, fn)` | `void` | Registra uma função nomeada que pode ser chamada pelos passos. |
346
+ | `onFinish` / `onStop` / `onStepChange` | `(cb) => () => void` | Listeners de ciclo de vida (limpos automaticamente no `onUnmounted`). |
347
+
348
+ ---
349
+
350
+ ## 📄 Licença
351
+
352
+ Distribuído sob a **Licença MIT**. Desenvolvido por [Márlon Bento Azevedo](https://github.com/marlon-bento).
@@ -0,0 +1,224 @@
1
+ import { TutorialStep, TutorialLabels, TutorialClasses, TutorialBreakpointsConfig } from './types';
2
+ type __VLS_Props = {
3
+ steps?: TutorialStep[];
4
+ storageKey?: string;
5
+ autoStart?: boolean;
6
+ startDelay?: number;
7
+ unstyled?: boolean;
8
+ showArrow?: boolean;
9
+ mobileSheetOnAuto?: boolean;
10
+ breakpoints?: Partial<TutorialBreakpointsConfig>;
11
+ spotlightPadding?: number;
12
+ cardWidth?: number;
13
+ labels?: TutorialLabels;
14
+ classes?: TutorialClasses;
15
+ };
16
+ declare function __VLS_template(): {
17
+ attrs: Partial<{}>;
18
+ slots: {
19
+ default?(_: {}): any;
20
+ 'exit-button'?(_: {
21
+ step: TutorialStep | null;
22
+ stepIndex: number;
23
+ totalSteps: number;
24
+ progress: number;
25
+ isFirstStep: boolean;
26
+ isLastStep: boolean;
27
+ nextStep: () => Promise<void>;
28
+ prevStep: () => Promise<void>;
29
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
30
+ endTutorial: (markAsCompleted?: boolean) => void;
31
+ restartTutorial: () => Promise<void>;
32
+ currentStepIndex: number;
33
+ currentStep: TutorialStep | null;
34
+ direction: import('./types').TutorialDirection;
35
+ activeBreakpoint: import('./types').TutorialBreakpointName;
36
+ viewportWidth: number;
37
+ isMobileViewport: boolean;
38
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
39
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
40
+ }): any;
41
+ spotlight?(_: {
42
+ spotlightBox: {
43
+ x: number;
44
+ y: number;
45
+ width: number;
46
+ height: number;
47
+ };
48
+ step: TutorialStep | null;
49
+ stepIndex: number;
50
+ totalSteps: number;
51
+ progress: number;
52
+ isFirstStep: boolean;
53
+ isLastStep: boolean;
54
+ nextStep: () => Promise<void>;
55
+ prevStep: () => Promise<void>;
56
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
57
+ endTutorial: (markAsCompleted?: boolean) => void;
58
+ restartTutorial: () => Promise<void>;
59
+ currentStepIndex: number;
60
+ currentStep: TutorialStep | null;
61
+ direction: import('./types').TutorialDirection;
62
+ activeBreakpoint: import('./types').TutorialBreakpointName;
63
+ viewportWidth: number;
64
+ isMobileViewport: boolean;
65
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
66
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
67
+ }): any;
68
+ card?(_: {
69
+ step: TutorialStep | null;
70
+ stepIndex: number;
71
+ totalSteps: number;
72
+ progress: number;
73
+ isFirstStep: boolean;
74
+ isLastStep: boolean;
75
+ nextStep: () => Promise<void>;
76
+ prevStep: () => Promise<void>;
77
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
78
+ endTutorial: (markAsCompleted?: boolean) => void;
79
+ restartTutorial: () => Promise<void>;
80
+ currentStepIndex: number;
81
+ currentStep: TutorialStep | null;
82
+ direction: import('./types').TutorialDirection;
83
+ activeBreakpoint: import('./types').TutorialBreakpointName;
84
+ viewportWidth: number;
85
+ isMobileViewport: boolean;
86
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
87
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
88
+ }): any;
89
+ header?(_: {
90
+ step: TutorialStep | null;
91
+ stepIndex: number;
92
+ totalSteps: number;
93
+ progress: number;
94
+ isFirstStep: boolean;
95
+ isLastStep: boolean;
96
+ nextStep: () => Promise<void>;
97
+ prevStep: () => Promise<void>;
98
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
99
+ endTutorial: (markAsCompleted?: boolean) => void;
100
+ restartTutorial: () => Promise<void>;
101
+ currentStepIndex: number;
102
+ currentStep: TutorialStep | null;
103
+ direction: import('./types').TutorialDirection;
104
+ activeBreakpoint: import('./types').TutorialBreakpointName;
105
+ viewportWidth: number;
106
+ isMobileViewport: boolean;
107
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
108
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
109
+ }): any;
110
+ body?(_: {
111
+ step: TutorialStep | null;
112
+ stepIndex: number;
113
+ totalSteps: number;
114
+ progress: number;
115
+ isFirstStep: boolean;
116
+ isLastStep: boolean;
117
+ nextStep: () => Promise<void>;
118
+ prevStep: () => Promise<void>;
119
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
120
+ endTutorial: (markAsCompleted?: boolean) => void;
121
+ restartTutorial: () => Promise<void>;
122
+ currentStepIndex: number;
123
+ currentStep: TutorialStep | null;
124
+ direction: import('./types').TutorialDirection;
125
+ activeBreakpoint: import('./types').TutorialBreakpointName;
126
+ viewportWidth: number;
127
+ isMobileViewport: boolean;
128
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
129
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
130
+ }): any;
131
+ hint?(_: {
132
+ step: TutorialStep | null;
133
+ stepIndex: number;
134
+ totalSteps: number;
135
+ progress: number;
136
+ isFirstStep: boolean;
137
+ isLastStep: boolean;
138
+ nextStep: () => Promise<void>;
139
+ prevStep: () => Promise<void>;
140
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
141
+ endTutorial: (markAsCompleted?: boolean) => void;
142
+ restartTutorial: () => Promise<void>;
143
+ currentStepIndex: number;
144
+ currentStep: TutorialStep | null;
145
+ direction: import('./types').TutorialDirection;
146
+ activeBreakpoint: import('./types').TutorialBreakpointName;
147
+ viewportWidth: number;
148
+ isMobileViewport: boolean;
149
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
150
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
151
+ }): any;
152
+ progress?(_: {
153
+ step: TutorialStep | null;
154
+ stepIndex: number;
155
+ totalSteps: number;
156
+ progress: number;
157
+ isFirstStep: boolean;
158
+ isLastStep: boolean;
159
+ nextStep: () => Promise<void>;
160
+ prevStep: () => Promise<void>;
161
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
162
+ endTutorial: (markAsCompleted?: boolean) => void;
163
+ restartTutorial: () => Promise<void>;
164
+ currentStepIndex: number;
165
+ currentStep: TutorialStep | null;
166
+ direction: import('./types').TutorialDirection;
167
+ activeBreakpoint: import('./types').TutorialBreakpointName;
168
+ viewportWidth: number;
169
+ isMobileViewport: boolean;
170
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
171
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
172
+ }): any;
173
+ footer?(_: {
174
+ step: TutorialStep | null;
175
+ stepIndex: number;
176
+ totalSteps: number;
177
+ progress: number;
178
+ isFirstStep: boolean;
179
+ isLastStep: boolean;
180
+ nextStep: () => Promise<void>;
181
+ prevStep: () => Promise<void>;
182
+ goToStep: (indexOrId: number | string, direction?: import('./types').TutorialDirection) => Promise<void>;
183
+ endTutorial: (markAsCompleted?: boolean) => void;
184
+ restartTutorial: () => Promise<void>;
185
+ currentStepIndex: number;
186
+ currentStep: TutorialStep | null;
187
+ direction: import('./types').TutorialDirection;
188
+ activeBreakpoint: import('./types').TutorialBreakpointName;
189
+ viewportWidth: number;
190
+ isMobileViewport: boolean;
191
+ runRegisteredAction: (actionName: string, ...args: any[]) => Promise<any>;
192
+ runActionMap: (actions?: import('./types').TutorialActionMap) => Promise<void>;
193
+ }): any;
194
+ };
195
+ refs: {
196
+ cardRef: HTMLDivElement;
197
+ };
198
+ rootEl: any;
199
+ };
200
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
201
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
202
+ stop: () => any;
203
+ finish: () => any;
204
+ "step-change": (step: TutorialStep | null, index: number) => any;
205
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
206
+ onStop?: (() => any) | undefined;
207
+ onFinish?: (() => any) | undefined;
208
+ "onStep-change"?: ((step: TutorialStep | null, index: number) => any) | undefined;
209
+ }>, {
210
+ showArrow: boolean;
211
+ unstyled: boolean;
212
+ mobileSheetOnAuto: boolean;
213
+ autoStart: boolean;
214
+ startDelay: number;
215
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
216
+ cardRef: HTMLDivElement;
217
+ }, any>;
218
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
219
+ export default _default;
220
+ type __VLS_WithTemplateSlots<T, S> = T & {
221
+ new (): {
222
+ $slots: S;
223
+ };
224
+ };
@@ -0,0 +1,66 @@
1
+ import { Component } from 'vue';
2
+ import { TutorialStepMode, TutorialPlacement, TutorialContext, TutorialActionMap, TutorialBreakpointName, TutorialStepResponsiveOverride } from './types';
3
+ type __VLS_Props = {
4
+ id?: string;
5
+ target?: string | string[];
6
+ title: string;
7
+ content?: string;
8
+ component?: Component;
9
+ componentProps?: Record<string, any>;
10
+ mode?: TutorialStepMode;
11
+ placement?: TutorialPlacement;
12
+ hintText?: string;
13
+ preventNativeClick?: boolean;
14
+ afterClickDelay?: number;
15
+ autoScroll?: boolean;
16
+ spotlightPadding?: number;
17
+ cardWidth?: number;
18
+ disabled?: boolean;
19
+ route?: string;
20
+ rollbackRoute?: string;
21
+ enterActions?: TutorialActionMap;
22
+ rollbackActions?: TutorialActionMap;
23
+ leaveActions?: TutorialActionMap;
24
+ /** Mapa responsivo Mobile-First: { xs, sm, md, lg, xl, xxl } */
25
+ breakpoints?: Partial<Record<TutorialBreakpointName, TutorialStepResponsiveOverride>>;
26
+ /** Atalhos diretos Mobile-First de target por breakpoint */
27
+ targetSm?: string | string[];
28
+ targetMd?: string | string[];
29
+ targetLg?: string | string[];
30
+ targetXl?: string | string[];
31
+ targetXxl?: string | string[];
32
+ /** Atalhos diretos Mobile-First de placement por breakpoint */
33
+ placementSm?: TutorialPlacement;
34
+ placementMd?: TutorialPlacement;
35
+ placementLg?: TutorialPlacement;
36
+ placementXl?: TutorialPlacement;
37
+ placementXxl?: TutorialPlacement;
38
+ beforeEnter?: (ctx: TutorialContext) => void | Promise<void>;
39
+ onRollback?: (ctx: TutorialContext) => void | Promise<void>;
40
+ onTargetClick?: (event: MouseEvent, ctx: TutorialContext) => void | Promise<void>;
41
+ afterClick?: (ctx: TutorialContext) => void | Promise<void>;
42
+ afterLeave?: (ctx: TutorialContext) => void | Promise<void>;
43
+ };
44
+ declare function __VLS_template(): {
45
+ attrs: Partial<{}>;
46
+ slots: {
47
+ default?(_: {
48
+ context: TutorialContext;
49
+ }): any;
50
+ };
51
+ refs: {};
52
+ rootEl: any;
53
+ };
54
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
55
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
56
+ placement: TutorialPlacement;
57
+ disabled: boolean;
58
+ mode: TutorialStepMode;
59
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
60
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
61
+ export default _default;
62
+ type __VLS_WithTemplateSlots<T, S> = T & {
63
+ new (): {
64
+ $slots: S;
65
+ };
66
+ };
@@ -0,0 +1,12 @@
1
+ import { TutorialStep, TutorialTargetConfig } from './types';
2
+ export declare const registeredElements: Map<string, {
3
+ el: HTMLElement;
4
+ config: TutorialTargetConfig;
5
+ }>;
6
+ export declare function verificarElementoVisivel(el: HTMLElement | null): el is HTMLElement;
7
+ export declare function resolverSeletorUnico(targetSelector: string): HTMLElement | null;
8
+ export declare function resolveStepElements(step: TutorialStep | null): HTMLElement[];
9
+ export declare function resolveStepElement(step: TutorialStep | null): HTMLElement | null;
10
+ export declare function getStepBoundingRect(step: TutorialStep | null): DOMRect | null;
11
+ export declare function rolarParaElementoSeNecessario(el: HTMLElement, autoScrollAtivo: boolean, scrollBehavior?: ScrollBehavior): Promise<void>;
12
+ export declare function aguardarElementoNoDom(step: TutorialStep | null, autoScrollAtivo: boolean, scrollBehavior?: ScrollBehavior, timeoutMs?: number): Promise<HTMLElement | null>;