@seniorsistemas/angular-components 19.2.0 → 19.3.0

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.
Files changed (33) hide show
  1. package/dynamic-form/dynamic-form/dynamic-form.directive.d.ts +3 -0
  2. package/dynamic-form/dynamic-form/form-field/configurations/fields/field.d.ts +7 -0
  3. package/dynamic-form/public-api.d.ts +2 -3
  4. package/esm2022/dynamic-form/dynamic-form/dynamic-form.directive.mjs +17 -1
  5. package/esm2022/dynamic-form/dynamic-form/form-field/configurations/fields/field.mjs +1 -1
  6. package/esm2022/dynamic-form/public-api.mjs +3 -4
  7. package/esm2022/lib/locale/fallback.mjs +10 -2
  8. package/esm2022/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.mjs +460 -0
  9. package/esm2022/spotlight/lib/spotlight/spotlight-step.directive.mjs +50 -0
  10. package/esm2022/spotlight/lib/spotlight/spotlight-tour.service.mjs +251 -0
  11. package/esm2022/spotlight/lib/spotlight/spotlight.component.mjs +193 -0
  12. package/esm2022/spotlight/lib/spotlight/types/spotlight-position.mjs +2 -0
  13. package/esm2022/spotlight/lib/spotlight/types/spotlight-step.mjs +2 -0
  14. package/esm2022/spotlight/lib/spotlight/types/spotlight-stop-event.mjs +2 -0
  15. package/esm2022/spotlight/public-api.mjs +4 -0
  16. package/esm2022/spotlight/seniorsistemas-angular-components-spotlight.mjs +5 -0
  17. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs +16 -0
  18. package/fesm2022/seniorsistemas-angular-components-dynamic-form.mjs.map +1 -1
  19. package/fesm2022/seniorsistemas-angular-components-spotlight.mjs +947 -0
  20. package/fesm2022/seniorsistemas-angular-components-spotlight.mjs.map +1 -0
  21. package/fesm2022/seniorsistemas-angular-components.mjs +9 -1
  22. package/fesm2022/seniorsistemas-angular-components.mjs.map +1 -1
  23. package/package.json +13 -7
  24. package/spotlight/README.md +311 -0
  25. package/spotlight/index.d.ts +5 -0
  26. package/spotlight/lib/spotlight/spotlight-overlay/spotlight-overlay.component.d.ts +70 -0
  27. package/spotlight/lib/spotlight/spotlight-step.directive.d.ts +28 -0
  28. package/spotlight/lib/spotlight/spotlight-tour.service.d.ts +146 -0
  29. package/spotlight/lib/spotlight/spotlight.component.d.ts +82 -0
  30. package/spotlight/lib/spotlight/types/spotlight-position.d.ts +1 -0
  31. package/spotlight/lib/spotlight/types/spotlight-step.d.ts +21 -0
  32. package/spotlight/lib/spotlight/types/spotlight-stop-event.d.ts +13 -0
  33. package/spotlight/public-api.d.ts +6 -0
@@ -0,0 +1,311 @@
1
+ # Spotlight
2
+
3
+ ## Descrição
4
+
5
+ O Spotlight é uma biblioteca para criação de **tours guiados** (onboarding com múltiplos passos) e **destaques simples** (dicas únicas sobre um elemento). O posicionamento do popover é gerenciado automaticamente pelo Angular CDK, com fallbacks inteligentes para manter o popover sempre visível.
6
+
7
+ Dois modos de operação:
8
+
9
+ - **Tour**: sequência de passos com navegação Próximo / Voltar / Concluído, contador de progresso, focus trap e bloqueio de scroll.
10
+ - **Destaque simples**: popover único com botão "Entendi" e opção de "Não mostrar novamente".
11
+
12
+ ## Instalação
13
+
14
+ ```bash
15
+ npm install @seniorsistemas/angular-components/spotlight
16
+ ```
17
+
18
+ ## Conceitos
19
+
20
+ ### Diretiva `sSpotlightStep`
21
+
22
+ Registra um elemento do DOM como alvo de um passo do tour. Deve ser aplicada ao elemento que receberá o destaque.
23
+
24
+ ```html
25
+ <button sSpotlightStep="meu-botao">Salvar</button>
26
+ ```
27
+
28
+ O valor do atributo é o `stepId`, que deve corresponder ao `stepId` definido nos passos do tour.
29
+ Quando o valor do binding muda dinamicamente, a diretiva desregistra o ID anterior e registra o novo automaticamente.
30
+
31
+ ### `SpotlightTourService`
32
+
33
+ Serviço singleton que controla o estado do tour. Injete-o no componente que inicia o tour.
34
+
35
+ ---
36
+
37
+ ## Tour (múltiplos passos)
38
+
39
+ ### 1. Marque os elementos no template
40
+
41
+ ```html
42
+ <input sSpotlightStep="produto-nome" ... />
43
+ <select sSpotlightStep="produto-categoria" ... />
44
+ <button sSpotlightStep="salvar-btn">Salvar</button>
45
+ ```
46
+
47
+ ### 2. Inicie o tour pelo serviço
48
+
49
+ ```typescript
50
+ import { SpotlightTourService, SpotlightStep } from '@seniorsistemas/angular-components/spotlight';
51
+
52
+ @Component({ ... })
53
+ export class MeuComponent {
54
+ private readonly tourService = inject(SpotlightTourService);
55
+
56
+ private readonly passos: SpotlightStep[] = [
57
+ {
58
+ stepId: 'produto-nome',
59
+ title: 'Nome do produto',
60
+ message: 'Informe o nome completo do produto.',
61
+ position: 'bottom-center',
62
+ },
63
+ {
64
+ stepId: 'produto-categoria',
65
+ title: 'Categoria',
66
+ message: 'Selecione a categoria correta.',
67
+ position: 'bottom-end',
68
+ beforeNext: () => {
69
+ // Executado antes de avançar — útil para trocar abas, expandir seções, etc.
70
+ this.activeTab.set('detalhes');
71
+ },
72
+ },
73
+ {
74
+ stepId: 'salvar-btn',
75
+ title: 'Salvar',
76
+ message: 'Clique aqui para salvar as alterações.',
77
+ position: 'top-center',
78
+ },
79
+ ];
80
+
81
+ public iniciarTour(): void {
82
+ this.tourService.start(this.passos);
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### 3. Reaja aos eventos do tour
88
+
89
+ ```typescript
90
+ private readonly destroyRef = inject(DestroyRef);
91
+
92
+ public constructor() {
93
+ this.tourService.stopped$
94
+ .pipe(takeUntilDestroyed(this.destroyRef))
95
+ .subscribe((event) => {
96
+ // Salve o estado para persistência
97
+ localStorage.setItem('tour-onboarding', JSON.stringify({
98
+ reason: event.reason, // 'completed' | 'interrupted'
99
+ doNotShowAgain: event.doNotShowAgain,
100
+ stepIndex: event.stepIndex,
101
+ }));
102
+ });
103
+ }
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Destaque Simples
109
+
110
+ Use `tourService.spotlight()` para exibir um destaque em um único elemento.
111
+
112
+ ```html
113
+ <div sSpotlightStep="novo-recurso">...</div>
114
+ ```
115
+
116
+ ```typescript
117
+ import { SpotlightTourService, SpotlightConfig } from '@seniorsistemas/angular-components/spotlight';
118
+
119
+ @Component({ ... })
120
+ export class MeuComponent {
121
+ private readonly tourService = inject(SpotlightTourService);
122
+
123
+ public mostrarDica(): void {
124
+ const config: SpotlightConfig = {
125
+ title: 'Novidade!',
126
+ message: 'Este recurso foi adicionado recentemente.',
127
+ position: 'bottom-center',
128
+ // showDoNotShowAgain é true por padrão — passe false para suprimir o checkbox
129
+ dismissible: true,
130
+ };
131
+
132
+ this.tourService.spotlight('novo-recurso', config);
133
+ }
134
+ }
135
+ ```
136
+
137
+ Ao encerrar, `stopped$` emite com `reason: 'dismissed'` (usuário fechou) ou `reason: 'completed'` (clicou em "Entendi"). Quando `doNotShowAgain` é `true`, salve essa preferência para não exibir novamente.
138
+
139
+ ---
140
+
141
+ ## `SpotlightStep`
142
+
143
+ | Propriedade | Tipo | Obrigatório | Descrição |
144
+ |---|---|---|---|
145
+ | `stepId` | `string` | ✓ | Identificador único do passo. Deve corresponder ao valor do `sSpotlightStep` no template. |
146
+ | `title` | `string \| TemplateRef<any>` | ✓ | Título do popover (máx. recomendado: 30 caracteres). |
147
+ | `message` | `string \| TemplateRef<any>` | ✓ | Texto descritivo (máx. recomendado: 75 caracteres). |
148
+ | `position` | `SpotlightPosition` | — | Posição preferida do popover. Padrão: `'bottom-center'`. |
149
+ | `content` | `TemplateRef<any> \| null` | — | Conteúdo visual customizado (imagem, gif, vídeo) exibido acima da mensagem. |
150
+ | `actions` | `SpotlightStepAction[]` | — | Botões de ação customizados exibidos antes dos botões de navegação. |
151
+ | `showBackdrop` | `boolean` | — | Exibe o backdrop escurecido ao redor do elemento destacado. Padrão: `true`. |
152
+ | `dismissible` | `boolean` | — | Permite fechar o spotlight clicando fora ou pressionando Escape. Padrão: `true`. |
153
+ | `beforeNext` | `() => void \| Promise<void>` | — | Callback executado antes de avançar para o próximo passo. Suporta async/await. |
154
+ | `beforePrevious` | `() => void \| Promise<void>` | — | Callback executado antes de voltar ao passo anterior. Suporta async/await. |
155
+
156
+ ## `SpotlightConfig`
157
+
158
+ Equivalente ao `SpotlightStep` sem `stepId`, `beforeNext` e `beforePrevious`. Usado exclusivamente com `tourService.spotlight()`. Inclui a propriedade adicional:
159
+
160
+ | Propriedade | Tipo | Descrição |
161
+ |---|---|---|
162
+ | `showDoNotShowAgain` | `boolean` | Exibe o checkbox "Não mostrar novamente". Padrão: `true`. Passe `false` para suprimir. |
163
+
164
+ ## `SpotlightStepAction`
165
+
166
+ | Propriedade | Tipo | Descrição |
167
+ |---|---|---|
168
+ | `label` | `string` | Texto do botão. |
169
+ | `handler` | `() => void` | Função executada ao clicar no botão. |
170
+
171
+ ---
172
+
173
+ ## `SpotlightTourService`
174
+
175
+ ### Propriedades
176
+
177
+ | Propriedade | Tipo | Descrição |
178
+ |---|---|---|
179
+ | `isActive` | `Signal<boolean>` | `true` enquanto o tour estiver ativo. |
180
+ | `currentStep` | `Signal<SpotlightStep \| undefined>` | Passo atualmente exibido. |
181
+ | `currentIndex` | `Signal<number>` | Índice do passo atual (base 0). |
182
+ | `totalSteps` | `Signal<number>` | Total de passos do tour. |
183
+ | `stopped$` | `Observable<SpotlightStopEvent>` | Emite quando o tour é encerrado. |
184
+ | `stepChanged$` | `Observable<SpotlightStepChangedEvent>` | Emite ao mudar de passo (incluindo o primeiro). |
185
+
186
+ ### Métodos
187
+
188
+ | Método | Descrição |
189
+ |---|---|
190
+ | `start(steps: SpotlightStep[])` | Inicia o tour com a lista de passos fornecida. Ignora arrays vazios. Se houver um tour ativo, encerra-o (emitindo `stopped$`) antes de iniciar o novo. |
191
+ | `spotlight(stepId, config: SpotlightConfig)` | Exibe um destaque simples em um único elemento. |
192
+ | `next(doNotShowAgain?: boolean)` | Avança para o próximo passo ou conclui o tour. |
193
+ | `previous()` | Volta ao passo anterior. |
194
+ | `stop(event?: Partial<SpotlightStopEvent>)` | Encerra o tour programaticamente. |
195
+ | `registerElement(stepId, el)` | Registra um elemento (usado internamente pela diretiva). |
196
+ | `unregisterElement(stepId)` | Remove o registro de um elemento. |
197
+ | `getElement(stepId)` | Retorna o `ElementRef` registrado para o `stepId`. |
198
+
199
+ ---
200
+
201
+ ## Eventos (`SpotlightStopEvent`)
202
+
203
+ Emitido por `stopped$` ao encerrar o tour.
204
+
205
+ | Campo | Tipo | Descrição |
206
+ |---|---|---|
207
+ | `reason` | `SpotlightStopReason` | Razão do encerramento. |
208
+ | `doNotShowAgain` | `boolean` | `true` se o usuário marcou "Não mostrar novamente". |
209
+ | `stepId` | `string` | `stepId` do passo em que o tour foi encerrado. |
210
+ | `stepIndex` | `number` | Índice (base 0) do passo em que o tour foi encerrado. |
211
+ | `totalSteps` | `number` | Total de passos do tour. |
212
+
213
+ ### `SpotlightStopReason`
214
+
215
+ | Valor | Quando ocorre | Comportamento recomendado |
216
+ |---|---|---|
217
+ | `'completed'` | Usuário clicou em "Concluído" ou "Entendi" | Nunca reexibir |
218
+ | `'interrupted'` | Usuário fechou o tour antes de concluir (X, Escape, clique fora) | Reexibir na próxima sessão |
219
+ | `'dismissed'` | Usuário fechou um destaque simples | Reexibir após cooldown |
220
+
221
+ ### `SpotlightStepChangedEvent`
222
+
223
+ Emitido por `stepChanged$` a cada mudança de passo.
224
+
225
+ | Campo | Tipo | Descrição |
226
+ |---|---|---|
227
+ | `stepId` | `string` | `stepId` do novo passo. |
228
+ | `stepIndex` | `number` | Índice (base 0) do novo passo. |
229
+ | `totalSteps` | `number` | Total de passos do tour. |
230
+
231
+ ---
232
+
233
+ ## Posições Disponíveis (`SpotlightPosition`)
234
+
235
+ | Valor | Descrição |
236
+ |---|---|
237
+ | `'top-start'` | Acima do elemento, alinhado à esquerda |
238
+ | `'top-center'` | Acima do elemento, centralizado |
239
+ | `'top-end'` | Acima do elemento, alinhado à direita |
240
+ | `'bottom-start'` | Abaixo do elemento, alinhado à esquerda |
241
+ | `'bottom-center'` | Abaixo do elemento, centralizado |
242
+ | `'bottom-end'` | Abaixo do elemento, alinhado à direita |
243
+ | `'left-start'` | À esquerda do elemento, alinhado ao topo |
244
+ | `'left-center'` | À esquerda do elemento, centralizado |
245
+ | `'left-end'` | À esquerda do elemento, alinhado à base |
246
+ | `'right-start'` | À direita do elemento, alinhado ao topo |
247
+ | `'right-center'` | À direita do elemento, centralizado |
248
+ | `'right-end'` | À direita do elemento, alinhado à base |
249
+
250
+ > O CDK ajusta automaticamente a posição quando não há espaço suficiente, garantindo que o popover sempre permaneça visível.
251
+
252
+ ---
253
+
254
+ ## Persistência
255
+
256
+ A persistência do estado (se o tour já foi visto, preferência "Não mostrar novamente", etc.) é responsabilidade do produto consumidor. Use os dados emitidos por `stopped$` para implementar a estratégia adequada:
257
+
258
+ ```typescript
259
+ this.tourService.stopped$.subscribe((event) => {
260
+ const estado = {
261
+ reason: event.reason,
262
+ doNotShowAgain: event.doNotShowAgain,
263
+ contentVersion: 'v2', // versão do conteúdo do tour, controlada pelo produto
264
+ };
265
+ localStorage.setItem('tour-onboarding', JSON.stringify(estado));
266
+ });
267
+
268
+ // Na inicialização:
269
+ const salvo = JSON.parse(localStorage.getItem('tour-onboarding') ?? 'null');
270
+ const deveExibir =
271
+ !salvo ||
272
+ salvo.contentVersion !== 'v2' || // novo conteúdo → reexibir
273
+ salvo.reason === 'interrupted'; // não concluiu → reexibir
274
+
275
+ if (deveExibir && !salvo?.doNotShowAgain) {
276
+ // Chamar tourService.start(passos) no momento adequado
277
+ }
278
+ ```
279
+
280
+ ---
281
+
282
+ ## Telemetria
283
+
284
+ Use os observables do serviço para enviar eventos ao seu sistema de analytics:
285
+
286
+ ```typescript
287
+ // Tour iniciado (step 0)
288
+ this.tourService.stepChanged$
289
+ .pipe(filter((e) => e.stepIndex === 0 && e.totalSteps > 1))
290
+ .subscribe(() => analytics.track('tour_viewed'));
291
+
292
+ // Tour concluído
293
+ this.tourService.stopped$
294
+ .pipe(filter((e) => e.reason === 'completed' && e.totalSteps > 1))
295
+ .subscribe(() => analytics.track('tour_completed'));
296
+
297
+ // Tour interrompido
298
+ this.tourService.stopped$
299
+ .pipe(filter((e) => e.reason === 'interrupted'))
300
+ .subscribe(() => analytics.track('tour_interrupted'));
301
+
302
+ // Destaque simples fechado
303
+ this.tourService.stopped$
304
+ .pipe(filter((e) => e.reason === 'dismissed'))
305
+ .subscribe(() => analytics.track('spotlight_dismissed'));
306
+
307
+ // "Não mostrar novamente" marcado
308
+ this.tourService.stopped$
309
+ .pipe(filter((e) => e.doNotShowAgain))
310
+ .subscribe(() => analytics.track('spotlight_do_not_show_again_checked'));
311
+ ```
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@seniorsistemas/angular-components/spotlight" />
5
+ export * from './public-api';
@@ -0,0 +1,70 @@
1
+ import { OnDestroy, OnInit } from '@angular/core';
2
+ import { SpotlightStep } from '../types/spotlight-step';
3
+ import * as i0 from "@angular/core";
4
+ export declare class SpotlightOverlayComponent implements OnInit, OnDestroy {
5
+ private readonly tourService;
6
+ private readonly destroyRef;
7
+ private readonly zone;
8
+ private readonly cdkOverlay;
9
+ private readonly environmentInjector;
10
+ private readonly focusTrapFactory;
11
+ /** @internal */
12
+ readonly isActive: import("@angular/core").Signal<boolean>;
13
+ /** @internal */
14
+ readonly currentStep: import("@angular/core").Signal<(SpotlightStep & {
15
+ showDoNotShowAgain?: boolean;
16
+ }) | undefined>;
17
+ /** @internal */
18
+ readonly currentIndex: import("@angular/core").Signal<number>;
19
+ /** @internal */
20
+ readonly totalSteps: import("@angular/core").Signal<number>;
21
+ /** @internal*/
22
+ readonly targetRect: import("@angular/core").WritableSignal<DOMRect | null>;
23
+ /** @internal */
24
+ readonly topMaskStyle: import("@angular/core").Signal<Record<string, string>>;
25
+ /** @internal */
26
+ readonly leftMaskStyle: import("@angular/core").Signal<Record<string, string>>;
27
+ /** @internal */
28
+ readonly rightMaskStyle: import("@angular/core").Signal<Record<string, string>>;
29
+ /** @internal */
30
+ readonly bottomMaskStyle: import("@angular/core").Signal<Record<string, string>>;
31
+ /** @internal */
32
+ readonly transparentBlockerStyle: import("@angular/core").Signal<Record<string, string>>;
33
+ private resizeObserver;
34
+ private popoverOverlayRef;
35
+ private popoverComponentRef;
36
+ private popoverSubs;
37
+ private focusTrap;
38
+ private previouslyFocusedElement;
39
+ constructor();
40
+ ngOnInit(): void;
41
+ ngOnDestroy(): void;
42
+ /** @internal */
43
+ onNext(): void;
44
+ /** @internal */
45
+ onPrevious(): void;
46
+ /** @internal */
47
+ onClose(): void;
48
+ /** @internal */
49
+ onDismiss(): void;
50
+ private updatePopoverOverlay;
51
+ private setPopoverZIndex;
52
+ private attachPopoverPortal;
53
+ private updatePopoverInputs;
54
+ private scheduleSync;
55
+ private activateTourMode;
56
+ /**
57
+ * After a step change, moves focus back to the first tabbable element inside the
58
+ * popover so the user does not lose keyboard position.
59
+ * No-op when there is no active focus trap (simple spotlight mode).
60
+ */
61
+ private scheduleFocusTrapRefocus;
62
+ private syncDirectionAndArrow;
63
+ private destroyPopoverOverlay;
64
+ private updateTargetRect;
65
+ private refreshRect;
66
+ private observeElement;
67
+ private disconnectResizeObserver;
68
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpotlightOverlayComponent, never>;
69
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpotlightOverlayComponent, "s-spotlight-overlay", never, {}, {}, never, never, true, never>;
70
+ }
@@ -0,0 +1,28 @@
1
+ import { OnDestroy } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Diretiva que registra um elemento do DOM como alvo de um passo do Spotlight Tour.
5
+ *
6
+ * Aplique a diretiva em qualquer elemento e forneça um ID único que corresponda
7
+ * ao `stepId` configurado no `SpotlightTourService`. O elemento será automaticamente
8
+ * registrado ao ser criado e atualizado caso o ID mude dinamicamente.
9
+ *
10
+ * @example
11
+ * ```html
12
+ * <button [sSpotlightStep]="'meu-botao'">Clique aqui</button>
13
+ * ```
14
+ */
15
+ export declare class SpotlightStepDirective implements OnDestroy {
16
+ /**
17
+ * ID único do passo do tour ao qual este elemento está associado.
18
+ * Deve corresponder ao `stepId` definido em `SpotlightStep`.
19
+ */
20
+ sSpotlightStep: import("@angular/core").InputSignal<string>;
21
+ private readonly el;
22
+ private readonly tourService;
23
+ private currentId;
24
+ constructor();
25
+ ngOnDestroy(): void;
26
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpotlightStepDirective, never>;
27
+ static ɵdir: i0.ɵɵDirectiveDeclaration<SpotlightStepDirective, "[sSpotlightStep]", never, { "sSpotlightStep": { "alias": "sSpotlightStep"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
28
+ }
@@ -0,0 +1,146 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import { Observable } from 'rxjs';
3
+ import { SpotlightConfig, SpotlightStep } from './types/spotlight-step';
4
+ import { SpotlightStepChangedEvent, SpotlightStopEvent } from './types/spotlight-stop-event';
5
+ import * as i0 from "@angular/core";
6
+ /** @internal */
7
+ type SpotlightStepInternal = SpotlightStep & {
8
+ showDoNotShowAgain?: boolean;
9
+ };
10
+ /**
11
+ * Serviço central do Spotlight Tour.
12
+ *
13
+ * Gerencia o estado do tour (passos, índice atual, ativo/inativo), a navegação entre
14
+ * passos e o registro de elementos do DOM associados a cada `stepId`.
15
+ *
16
+ * Use `start()` para iniciar um tour com múltiplos passos ou `spotlight()` para
17
+ * exibir um destaque simples em um único elemento.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * // Tour com múltiplos passos
22
+ * this.tourService.start([
23
+ * { stepId: 'passo-1', title: 'Título', message: 'Mensagem' },
24
+ * { stepId: 'passo-2', title: 'Título', message: 'Mensagem' },
25
+ * ]);
26
+ *
27
+ * // Destaque simples
28
+ * this.tourService.spotlight('meu-elemento', { title: 'Dica', message: 'Detalhes' });
29
+ * ```
30
+ */
31
+ export declare class SpotlightTourService {
32
+ private readonly overlay;
33
+ private readonly environmentInjector;
34
+ private overlayRef;
35
+ private readonly _steps;
36
+ private readonly _currentIndex;
37
+ private readonly _isActive;
38
+ private readonly _registrationVersion;
39
+ private readonly _registeredElements;
40
+ private _pendingDoNotShowAgain;
41
+ private readonly _stopped$;
42
+ private readonly _stepChanged$;
43
+ /** Signal somente-leitura que indica se o tour está ativo no momento. */
44
+ readonly isActive: import("@angular/core").Signal<boolean>;
45
+ /** Signal somente-leitura com o índice (0-based) do passo exibido atualmente. */
46
+ readonly currentIndex: import("@angular/core").Signal<number>;
47
+ /** Signal computado com o total de passos do tour em andamento. */
48
+ readonly totalSteps: import("@angular/core").Signal<number>;
49
+ /** Signal computado com os dados do passo atualmente exibido. */
50
+ readonly currentStep: import("@angular/core").Signal<SpotlightStepInternal | undefined>;
51
+ /**
52
+ * Observable emitido quando o tour é encerrado, seja por conclusão, interrupção
53
+ * ou descarte. Carrega um `SpotlightStopEvent` com o motivo e o estado final.
54
+ */
55
+ readonly stopped$: Observable<SpotlightStopEvent>;
56
+ /**
57
+ * Observable emitido sempre que o passo exibido muda, incluindo o início do tour.
58
+ * Carrega um `SpotlightStepChangedEvent` com o `stepId` e o índice do novo passo.
59
+ */
60
+ readonly stepChanged$: Observable<SpotlightStepChangedEvent>;
61
+ /**
62
+ * Signal somente-leitura incrementado a cada chamada de `registerElement` ou
63
+ * `unregisterElement`. Permite que outros componentes reajam a mudanças no
64
+ * registro de elementos sem polling.
65
+ */
66
+ readonly registrationVersion: import("@angular/core").Signal<number>;
67
+ /**
68
+ * Inicia um tour com a lista de passos fornecida.
69
+ *
70
+ * O tour começa pelo primeiro passo da lista. Emite `stepChanged$` para o passo inicial.
71
+ * Se `steps` for um array vazio, o método não faz nada.
72
+ * Se já houver um tour ativo, ele é encerrado (emitindo `stopped$` com `reason: 'interrupted'`)
73
+ * antes de o novo tour começar.
74
+ *
75
+ * @param steps Lista de passos a percorrer em ordem.
76
+ */
77
+ start(steps: SpotlightStep[]): void;
78
+ /**
79
+ * Exibe um destaque simples (passo único) no elemento identificado por `stepId`.
80
+ *
81
+ * Equivalente a chamar `start()` com um array de um único passo.
82
+ * O checkbox "Não mostrar novamente" é exibido por padrão (`showDoNotShowAgain: true`);
83
+ * passe `showDoNotShowAgain: false` em `config` para suprimi-lo.
84
+ *
85
+ * @param stepId ID do elemento registrado via `sSpotlightStep` ou `registerElement`.
86
+ * @param config Configuração visual e comportamental do destaque.
87
+ */
88
+ spotlight(stepId: string, config: SpotlightConfig): void;
89
+ /**
90
+ * Avança para o próximo passo do tour.
91
+ *
92
+ * Se o passo atual definir `beforeNext`, aguarda sua resolução antes de avançar.
93
+ * No último passo, encerra o tour com `reason: 'completed'`.
94
+ *
95
+ * @param doNotShowAgain Quando `true`, o evento `stopped$` será emitido com
96
+ * `doNotShowAgain: true` ao concluir o tour. Relevante apenas no último passo.
97
+ */
98
+ next(doNotShowAgain?: boolean): void;
99
+ /**
100
+ * Retorna ao passo anterior do tour.
101
+ *
102
+ * Se o passo atual definir `beforePrevious`, aguarda sua resolução antes de voltar.
103
+ * Não faz nada se o tour estiver no primeiro passo.
104
+ */
105
+ previous(): void;
106
+ /**
107
+ * Encerra o tour imediatamente e emite o evento `stopped$`.
108
+ *
109
+ * @param event Dados parciais do evento de parada. Valores não fornecidos são
110
+ * preenchidos com os defaults: `reason: 'interrupted'`, `doNotShowAgain: false`
111
+ * e o `stepId`/`stepIndex`/`totalSteps` do momento atual.
112
+ */
113
+ stop(event?: Partial<SpotlightStopEvent>): void;
114
+ /**
115
+ * Registra um elemento do DOM como alvo do passo identificado por `stepId`.
116
+ *
117
+ * Normalmente chamado pela diretiva `sSpotlightStep`. Use diretamente apenas
118
+ * quando precisar registrar elementos criados programaticamente.
119
+ *
120
+ * @param stepId ID único do passo ao qual o elemento pertence.
121
+ * @param el Referência ao elemento do DOM.
122
+ */
123
+ registerElement(stepId: string, el: ElementRef): void;
124
+ /**
125
+ * Remove o registro do elemento associado a `stepId`.
126
+ *
127
+ * Normalmente chamado pela diretiva `sSpotlightStep` no `ngOnDestroy`.
128
+ *
129
+ * @param stepId ID do passo cujo elemento deve ser removido.
130
+ */
131
+ unregisterElement(stepId: string): void;
132
+ /**
133
+ * Retorna o `ElementRef` registrado para o `stepId` informado,
134
+ * ou `undefined` se nenhum elemento estiver registrado.
135
+ *
136
+ * @param stepId ID do passo a buscar.
137
+ */
138
+ getElement(stepId: string): ElementRef | undefined;
139
+ private advance;
140
+ private retreat;
141
+ private attachOverlay;
142
+ private detachOverlay;
143
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpotlightTourService, never>;
144
+ static ɵprov: i0.ɵɵInjectableDeclaration<SpotlightTourService>;
145
+ }
146
+ export {};
@@ -0,0 +1,82 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { SpotlightPosition } from './types/spotlight-position';
3
+ import { SpotlightStepAction } from './types/spotlight-step';
4
+ import * as i0 from "@angular/core";
5
+ /**
6
+ * Componente de popover do Spotlight.
7
+ *
8
+ * Exibe o card de destaque com título, mensagem, seta direcional, contador de passos,
9
+ * botões de navegação e, em modo simples (passo único), o checkbox "não mostrar novamente".
10
+ *
11
+ * Este componente é instanciado programaticamente pelo `SpotlightOverlayComponent`
12
+ * via CDK Overlay. Normalmente não é usado diretamente no template.
13
+ */
14
+ export declare class SpotlightComponent {
15
+ /** Título do popover. Aceita string ou `TemplateRef` para conteúdo dinâmico. */
16
+ title: import("@angular/core").InputSignal<string | TemplateRef<any>>;
17
+ /** Mensagem principal do popover. Aceita string ou `TemplateRef` para conteúdo dinâmico. */
18
+ message: import("@angular/core").InputSignal<string | TemplateRef<any> | undefined>;
19
+ /** Template opcional para área de mídia/conteúdo customizado acima da mensagem. */
20
+ content: import("@angular/core").InputSignal<TemplateRef<any> | null>;
21
+ /** Posição do popover em relação ao elemento alvo. @default 'bottom-center' */
22
+ position: import("@angular/core").InputSignal<SpotlightPosition>;
23
+ /** Número do passo atual (1-based) exibido no contador. @default 1 */
24
+ currentStep: import("@angular/core").InputSignal<number>;
25
+ /** Total de passos do tour, usado no contador e para controle de botões. @default 1 */
26
+ totalSteps: import("@angular/core").InputSignal<number>;
27
+ /**
28
+ * Exibe o checkbox "não mostrar novamente" (apenas em passo único).
29
+ * Passe `false` para suprimir o checkbox quando não for necessário persistir a preferência.
30
+ * @default true
31
+ */
32
+ showDoNotShowAgain: import("@angular/core").InputSignal<boolean>;
33
+ /** Lista de botões de ação adicionais exibidos na área de rodapé. */
34
+ actions: import("@angular/core").InputSignal<SpotlightStepAction[]>;
35
+ /**
36
+ * Deslocamento em pixels para posicionar a seta manualmente no eixo principal.
37
+ * Quando `null`, o alinhamento é controlado pela `position`. @default null
38
+ */
39
+ arrowOffsetPx: import("@angular/core").InputSignal<number | null>;
40
+ /** Emitido ao clicar no botão de fechar (X). */
41
+ closed: import("@angular/core").OutputEmitterRef<void>;
42
+ /** Emitido ao clicar em "Próximo". */
43
+ next: import("@angular/core").OutputEmitterRef<void>;
44
+ /** Emitido ao clicar em "Voltar". */
45
+ previous: import("@angular/core").OutputEmitterRef<void>;
46
+ /** Emitido ao clicar em "Entendido" (modo simples, passo único). */
47
+ understand: import("@angular/core").OutputEmitterRef<void>;
48
+ /** Estado atual do checkbox "não mostrar novamente". */
49
+ isDoNotShowAgainChecked: import("@angular/core").WritableSignal<boolean>;
50
+ private static instanceCount;
51
+ /** @internal */
52
+ protected readonly instanceId: string;
53
+ /** @internal */
54
+ readonly titleId: string;
55
+ /** @internal */
56
+ readonly descId: string;
57
+ get titleTemplate(): TemplateRef<any> | null;
58
+ get titleString(): string;
59
+ get messageTemplate(): TemplateRef<any> | null;
60
+ get messageString(): string;
61
+ get arrowPosition(): SpotlightPosition;
62
+ get isArrowTop(): boolean;
63
+ get isArrowBottom(): boolean;
64
+ get isArrowLeft(): boolean;
65
+ get isArrowRight(): boolean;
66
+ get arrowRotation(): string;
67
+ get arrowAlignmentClass(): string;
68
+ get arrowPaddingStyle(): Record<string, string>;
69
+ /** Emite o evento `closed`. Chamado pelo botão de fechar no template. */
70
+ onClose(): void;
71
+ /** Emite o evento `next`. Chamado pelo botão "Próximo" no template. */
72
+ onNext(): void;
73
+ /** Emite o evento `previous`. Chamado pelo botão "Voltar" no template. */
74
+ onPrevious(): void;
75
+ /** Emite o evento `understand`. Chamado pelo botão "Entendido" no template. */
76
+ onUnderstand(): void;
77
+ /** Alterna o estado de `isDoNotShowAgainChecked`. */
78
+ toggleDoNotShowAgain(): void;
79
+ private getOppositeDirection;
80
+ static ɵfac: i0.ɵɵFactoryDeclaration<SpotlightComponent, never>;
81
+ static ɵcmp: i0.ɵɵComponentDeclaration<SpotlightComponent, "s-spotlight", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "content": { "alias": "content"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "currentStep": { "alias": "currentStep"; "required": false; "isSignal": true; }; "totalSteps": { "alias": "totalSteps"; "required": false; "isSignal": true; }; "showDoNotShowAgain": { "alias": "showDoNotShowAgain"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "arrowOffsetPx": { "alias": "arrowOffsetPx"; "required": false; "isSignal": true; }; }, { "closed": "closed"; "next": "next"; "previous": "previous"; "understand": "understand"; }, never, never, true, never>;
82
+ }
@@ -0,0 +1 @@
1
+ export type SpotlightPosition = 'top-start' | 'top-center' | 'top-end' | 'right-start' | 'right-center' | 'right-end' | 'bottom-start' | 'bottom-center' | 'bottom-end' | 'left-start' | 'left-center' | 'left-end';
@@ -0,0 +1,21 @@
1
+ import { TemplateRef } from '@angular/core';
2
+ import { SpotlightPosition } from './spotlight-position';
3
+ export interface SpotlightStepAction {
4
+ label: string;
5
+ handler: () => void;
6
+ }
7
+ export interface SpotlightStep {
8
+ stepId: string;
9
+ title: string | TemplateRef<any>;
10
+ message: string | TemplateRef<any>;
11
+ position?: SpotlightPosition;
12
+ content?: TemplateRef<any> | null;
13
+ actions?: SpotlightStepAction[];
14
+ showBackdrop?: boolean;
15
+ dismissible?: boolean;
16
+ beforeNext?: () => void | Promise<void>;
17
+ beforePrevious?: () => void | Promise<void>;
18
+ }
19
+ export type SpotlightConfig = Omit<SpotlightStep, 'stepId' | 'beforeNext' | 'beforePrevious'> & {
20
+ showDoNotShowAgain?: boolean;
21
+ };