@glowhop/angular-tour 1.0.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.
@@ -0,0 +1,704 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, effect, Injectable, InjectionToken, inject, computed, Directive, ElementRef, Input, Component, TemplateRef, DestroyRef, Injector, ViewChild, booleanAttribute } from '@angular/core';
3
+ import { NgTemplateOutlet } from '@angular/common';
4
+ import { styleRecordToCssText, OVERLAY_IDLE_STYLE, POINTER_IDLE_STYLE, POPOVER_IDLE_STYLE, connectGlowTourRoot, POPOVER_IDLE_ATTRIBUTES, POINTER_IDLE_ATTRIBUTES, OVERLAY_IDLE_ATTRIBUTES, OVERLAY_PATH_IDLE_ATTRIBUTES } from '@glowhop/core-tour/adapter';
5
+ import { createGlowTour as createGlowTour$1 } from '@glowhop/core-tour';
6
+
7
+ const OVERLAY_IDLE_STYLE_TEXT = styleRecordToCssText(OVERLAY_IDLE_STYLE);
8
+ const POINTER_IDLE_STYLE_TEXT = styleRecordToCssText(POINTER_IDLE_STYLE);
9
+ const POPOVER_IDLE_STYLE_TEXT = styleRecordToCssText(POPOVER_IDLE_STYLE);
10
+ const DEFAULT_POINTER_DIRECTION_CONTENT = {
11
+ bottom: "👇",
12
+ left: "👈",
13
+ right: "👉",
14
+ top: "👆",
15
+ };
16
+ const POINTER_DIRECTIONS = ["top", "bottom", "left", "right"];
17
+ class GlowTourScope {
18
+ binding = signal(null);
19
+ tour = signal(null);
20
+ snapshot = signal(null);
21
+ state = this.snapshot.asReadonly();
22
+ constructor() {
23
+ effect((onCleanup) => {
24
+ const tour = this.tour();
25
+ if (!tour) {
26
+ this.snapshot.set(null);
27
+ return;
28
+ }
29
+ this.snapshot.set(tour.state.get());
30
+ onCleanup(tour.state.subscribe((state) => this.snapshot.set(state)));
31
+ }, { allowSignalWrites: true });
32
+ }
33
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourScope, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
34
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourScope });
35
+ }
36
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourScope, decorators: [{
37
+ type: Injectable
38
+ }], ctorParameters: () => [] });
39
+ const GLOW_TOUR_SCOPE = new InjectionToken("GlowTourScope");
40
+ function useTourScope() {
41
+ const scope = inject(GLOW_TOUR_SCOPE, { optional: true });
42
+ if (!scope) {
43
+ throw new Error('GlowTour components must be rendered inside <glow-tour-root [tour]="...">.');
44
+ }
45
+ return scope;
46
+ }
47
+ /**
48
+ * Injects the tour state signal into a component.
49
+ * Must be called within a GlowTourRoot component context.
50
+ * @returns A signal containing the current tour state or null.
51
+ */
52
+ function injectGlowTour() {
53
+ return useTourScope().state;
54
+ }
55
+ class GlowTourReactiveComponent {
56
+ scope = useTourScope();
57
+ snapshot = this.scope.state;
58
+ step = computed(() => this.snapshot()?.currentStep?.currentProps ?? null);
59
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourReactiveComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
60
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourReactiveComponent, ngImport: i0 });
61
+ }
62
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourReactiveComponent, decorators: [{
63
+ type: Directive
64
+ }] });
65
+ /** Root container component for GlowTour.js. Provides tour context and manages the root binding. */
66
+ class GlowTourRoot {
67
+ /** The tour controller instance to display. */
68
+ tour;
69
+ /** Optional prefix for generated HTML IDs. */
70
+ idPrefix;
71
+ element = inject((ElementRef));
72
+ scope = inject(GlowTourScope);
73
+ active = null;
74
+ initialized = false;
75
+ ngOnChanges() {
76
+ if (this.initialized)
77
+ this.reconcile();
78
+ }
79
+ ngOnInit() {
80
+ if (!this.tour) {
81
+ throw new Error("GlowTourRoot requires a tour input.");
82
+ }
83
+ this.initialized = true;
84
+ this.reconcile();
85
+ }
86
+ ngOnDestroy() {
87
+ this.release();
88
+ }
89
+ reconcile() {
90
+ const root = this.element.nativeElement;
91
+ const tour = this.tour;
92
+ const idPrefix = this.idPrefix;
93
+ this.scope.tour.set(tour);
94
+ const current = this.active;
95
+ if (current !== null &&
96
+ current.root === root &&
97
+ current.tour === tour &&
98
+ current.idPrefix === idPrefix) {
99
+ return;
100
+ }
101
+ this.release();
102
+ const binding = connectGlowTourRoot(tour, {
103
+ idPrefix,
104
+ root,
105
+ });
106
+ const active = { binding, idPrefix, root, tour };
107
+ this.active = active;
108
+ this.scope.binding.set(binding);
109
+ }
110
+ release() {
111
+ const active = this.active;
112
+ if (!active)
113
+ return;
114
+ this.active = null;
115
+ active.binding.release();
116
+ if (this.scope.binding() === active.binding)
117
+ this.scope.binding.set(null);
118
+ }
119
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourRoot, deps: [], target: i0.ɵɵFactoryTarget.Component });
120
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourRoot, isStandalone: true, selector: "glow-tour-root", inputs: { tour: "tour", idPrefix: "idPrefix" }, host: { attributes: { "data-glow-tour-root": "" } }, providers: [GlowTourScope, { provide: GLOW_TOUR_SCOPE, useExisting: GlowTourScope }], usesOnChanges: true, ngImport: i0, template: "<ng-content />", isInline: true });
121
+ }
122
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourRoot, decorators: [{
123
+ type: Component,
124
+ args: [{
125
+ selector: "glow-tour-root",
126
+ standalone: true,
127
+ host: { "data-glow-tour-root": "" },
128
+ providers: [GlowTourScope, { provide: GLOW_TOUR_SCOPE, useExisting: GlowTourScope }],
129
+ template: "<ng-content />",
130
+ }]
131
+ }], propDecorators: { tour: [{
132
+ type: Input,
133
+ args: [{ required: true }]
134
+ }], idPrefix: [{
135
+ type: Input
136
+ }] } });
137
+ /** Header component displaying the current step's title. */
138
+ class GlowTourHeader extends GlowTourReactiveComponent {
139
+ titleTemplate = computed(() => {
140
+ const title = this.step()?.title;
141
+ return title instanceof TemplateRef ? title : null;
142
+ });
143
+ titleText = computed(() => {
144
+ const title = this.step()?.title;
145
+ return typeof title === "string" ? title : "";
146
+ });
147
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourHeader, deps: null, target: i0.ɵɵFactoryTarget.Component });
148
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourHeader, isStandalone: true, selector: "glow-tour-header", usesInheritance: true, ngImport: i0, template: `
149
+ <header data-glow-tour-header [id]="scope.binding()?.ids?.title">
150
+ @if (titleTemplate()) {
151
+ <ng-container [ngTemplateOutlet]="titleTemplate()" />
152
+ } @else {
153
+ {{ titleText() }}
154
+ }
155
+ </header>
156
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
157
+ }
158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourHeader, decorators: [{
159
+ type: Component,
160
+ args: [{
161
+ selector: "glow-tour-header",
162
+ standalone: true,
163
+ imports: [NgTemplateOutlet],
164
+ template: `
165
+ <header data-glow-tour-header [id]="scope.binding()?.ids?.title">
166
+ @if (titleTemplate()) {
167
+ <ng-container [ngTemplateOutlet]="titleTemplate()" />
168
+ } @else {
169
+ {{ titleText() }}
170
+ }
171
+ </header>
172
+ `,
173
+ }]
174
+ }] });
175
+ /** Content component displaying the current step's content with live region. */
176
+ class GlowTourContent extends GlowTourReactiveComponent {
177
+ contentTemplate = computed(() => {
178
+ const content = this.step()?.content;
179
+ return content instanceof TemplateRef ? content : null;
180
+ });
181
+ contentText = computed(() => {
182
+ const content = this.step()?.content;
183
+ return typeof content === "string" ? content : "";
184
+ });
185
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourContent, deps: null, target: i0.ɵɵFactoryTarget.Component });
186
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourContent, isStandalone: true, selector: "glow-tour-content", usesInheritance: true, ngImport: i0, template: `
187
+ <div aria-live="polite" data-glow-tour-content [id]="scope.binding()?.ids?.description">
188
+ @if (contentTemplate()) {
189
+ <ng-container [ngTemplateOutlet]="contentTemplate()" />
190
+ } @else {
191
+ {{ contentText() }}
192
+ }
193
+ </div>
194
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
195
+ }
196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourContent, decorators: [{
197
+ type: Component,
198
+ args: [{
199
+ selector: "glow-tour-content",
200
+ standalone: true,
201
+ imports: [NgTemplateOutlet],
202
+ template: `
203
+ <div aria-live="polite" data-glow-tour-content [id]="scope.binding()?.ids?.description">
204
+ @if (contentTemplate()) {
205
+ <ng-container [ngTemplateOutlet]="contentTemplate()" />
206
+ } @else {
207
+ {{ contentText() }}
208
+ }
209
+ </div>
210
+ `,
211
+ }]
212
+ }] });
213
+ /** Footer component containing action buttons. Conditionally rendered based on tour step configuration. */
214
+ class GlowTourFooter extends GlowTourReactiveComponent {
215
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourFooter, deps: null, target: i0.ɵɵFactoryTarget.Component });
216
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourFooter, isStandalone: true, selector: "glow-tour-footer", usesInheritance: true, ngImport: i0, template: `@if (!step()?.popover?.hideFooter) { <footer data-glow-tour-footer><ng-content /></footer> }`, isInline: true });
217
+ }
218
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourFooter, decorators: [{
219
+ type: Component,
220
+ args: [{
221
+ selector: "glow-tour-footer",
222
+ standalone: true,
223
+ template: `@if (!step()?.popover?.hideFooter) { <footer data-glow-tour-footer><ng-content /></footer> }`,
224
+ }]
225
+ }] });
226
+ class GlowTourBoundElement {
227
+ scope = useTourScope();
228
+ destroyRef = inject(DestroyRef);
229
+ injector = inject(Injector);
230
+ bind(element, bindElement) {
231
+ const cleanup = effect((onCleanup) => {
232
+ const binding = this.scope.binding();
233
+ if (binding)
234
+ onCleanup(bindElement(binding, element));
235
+ }, { injector: this.injector });
236
+ this.destroyRef.onDestroy(() => cleanup.destroy());
237
+ }
238
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourBoundElement, deps: [], target: i0.ɵɵFactoryTarget.Directive });
239
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourBoundElement, ngImport: i0 });
240
+ }
241
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourBoundElement, decorators: [{
242
+ type: Directive
243
+ }] });
244
+ /** Popover component containing the tour content with accessibility attributes. */
245
+ class GlowTourPopover extends GlowTourBoundElement {
246
+ element;
247
+ idleAriaHidden = POPOVER_IDLE_ATTRIBUTES["aria-hidden"];
248
+ idleInert = POPOVER_IDLE_ATTRIBUTES.inert;
249
+ idleStyle = POPOVER_IDLE_STYLE_TEXT;
250
+ ngOnInit() {
251
+ this.bind(this.element.nativeElement, (binding, element) => binding.bindPopover(element));
252
+ }
253
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourPopover, deps: null, target: i0.ɵɵFactoryTarget.Component });
254
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourPopover, isStandalone: true, selector: "glow-tour-popover", viewQueries: [{ propertyName: "element", first: true, predicate: ["tourElement"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
255
+ <section #tourElement
256
+ [attr.aria-hidden]="idleAriaHidden"
257
+ data-glow-tour-popover
258
+ [attr.aria-describedby]="scope.binding()?.ids?.description"
259
+ [attr.aria-labelledby]="scope.binding()?.ids?.title"
260
+ [id]="scope.binding()?.ids?.popover"
261
+ [attr.inert]="idleInert"
262
+ role="dialog"
263
+ [style]="idleStyle"
264
+ tabindex="-1"
265
+ ><ng-content /></section>
266
+ `, isInline: true });
267
+ }
268
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourPopover, decorators: [{
269
+ type: Component,
270
+ args: [{
271
+ selector: "glow-tour-popover",
272
+ standalone: true,
273
+ // The idle attributes/style come from imported `@glowhop/core-tour/adapter`
274
+ // constants, so ngc's AOT template analyzer (NG1010) cannot inline them as
275
+ // string-interpolated literals in the template. Bound via component fields
276
+ // instead; the values are still static, so server and client render
277
+ // byte-identical output.
278
+ template: `
279
+ <section #tourElement
280
+ [attr.aria-hidden]="idleAriaHidden"
281
+ data-glow-tour-popover
282
+ [attr.aria-describedby]="scope.binding()?.ids?.description"
283
+ [attr.aria-labelledby]="scope.binding()?.ids?.title"
284
+ [id]="scope.binding()?.ids?.popover"
285
+ [attr.inert]="idleInert"
286
+ role="dialog"
287
+ [style]="idleStyle"
288
+ tabindex="-1"
289
+ ><ng-content /></section>
290
+ `,
291
+ }]
292
+ }], propDecorators: { element: [{
293
+ type: ViewChild,
294
+ args: ["tourElement", { static: true }]
295
+ }] } });
296
+ /** Pointer component displaying directional indicators pointing to the target element. */
297
+ class GlowTourPointer extends GlowTourBoundElement {
298
+ element;
299
+ directionContentValue = signal(undefined);
300
+ idleAriaHidden = POINTER_IDLE_ATTRIBUTES["aria-hidden"];
301
+ idleStyle = POINTER_IDLE_STYLE_TEXT;
302
+ directions = POINTER_DIRECTIONS;
303
+ content = computed(() => ({
304
+ ...DEFAULT_POINTER_DIRECTION_CONTENT,
305
+ ...this.directionContentValue(),
306
+ }));
307
+ /** Optional custom content for each pointer direction. */
308
+ set directionContent(value) {
309
+ this.directionContentValue.set(value);
310
+ }
311
+ asTemplate(value) {
312
+ return value instanceof TemplateRef ? value : null;
313
+ }
314
+ ngOnInit() {
315
+ this.bind(this.element.nativeElement, (binding, element) => binding.bindPointer(element));
316
+ }
317
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourPointer, deps: null, target: i0.ɵɵFactoryTarget.Component });
318
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourPointer, isStandalone: true, selector: "glow-tour-pointer", inputs: { directionContent: "directionContent" }, viewQueries: [{ propertyName: "element", first: true, predicate: ["tourElement"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
319
+ <div #tourElement data-glow-tour-pointer [attr.aria-hidden]="idleAriaHidden" [style]="idleStyle">
320
+ @for (direction of directions; track direction) {
321
+ <div [attr.data-glow-tour-pointer-direction]="direction">
322
+ @if (asTemplate(content()[direction]); as template) {
323
+ <ng-container [ngTemplateOutlet]="template" />
324
+ } @else {
325
+ {{ content()[direction] }}
326
+ }
327
+ </div>
328
+ }
329
+ </div>
330
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
331
+ }
332
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourPointer, decorators: [{
333
+ type: Component,
334
+ args: [{
335
+ selector: "glow-tour-pointer",
336
+ standalone: true,
337
+ imports: [NgTemplateOutlet],
338
+ template: `
339
+ <div #tourElement data-glow-tour-pointer [attr.aria-hidden]="idleAriaHidden" [style]="idleStyle">
340
+ @for (direction of directions; track direction) {
341
+ <div [attr.data-glow-tour-pointer-direction]="direction">
342
+ @if (asTemplate(content()[direction]); as template) {
343
+ <ng-container [ngTemplateOutlet]="template" />
344
+ } @else {
345
+ {{ content()[direction] }}
346
+ }
347
+ </div>
348
+ }
349
+ </div>
350
+ `,
351
+ }]
352
+ }], propDecorators: { element: [{
353
+ type: ViewChild,
354
+ args: ["tourElement", { static: true }]
355
+ }], directionContent: [{
356
+ type: Input
357
+ }] } });
358
+ /** Overlay component rendering a clipped SVG mask highlighting the target element. */
359
+ class GlowTourOverlay extends GlowTourBoundElement {
360
+ element;
361
+ idleAriaHidden = OVERLAY_IDLE_ATTRIBUTES["aria-hidden"];
362
+ idleAllowInteraction = OVERLAY_IDLE_ATTRIBUTES["data-glow-tour-allow-interaction"];
363
+ idleInert = OVERLAY_IDLE_ATTRIBUTES.inert;
364
+ idleStyle = OVERLAY_IDLE_STYLE_TEXT;
365
+ idlePathCursor = OVERLAY_PATH_IDLE_ATTRIBUTES.cursor;
366
+ idlePathOpacity = OVERLAY_PATH_IDLE_ATTRIBUTES.opacity;
367
+ idlePathPointerEvents = OVERLAY_PATH_IDLE_ATTRIBUTES["pointer-events"];
368
+ ngOnInit() {
369
+ this.bind(this.element.nativeElement, (binding, element) => binding.bindOverlay(element));
370
+ }
371
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourOverlay, deps: null, target: i0.ɵɵFactoryTarget.Component });
372
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourOverlay, isStandalone: true, selector: "glow-tour-overlay", viewQueries: [{ propertyName: "element", first: true, predicate: ["tourElement"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
373
+ <svg #tourElement
374
+ [attr.aria-hidden]="idleAriaHidden"
375
+ [attr.data-glow-tour-allow-interaction]="idleAllowInteraction"
376
+ data-glow-tour-overlay
377
+ focusable="false"
378
+ [attr.inert]="idleInert"
379
+ role="presentation"
380
+ [style]="idleStyle"
381
+ viewBox="0 0 0 0"
382
+ >
383
+ <path
384
+ [attr.cursor]="idlePathCursor"
385
+ data-glow-tour-overlay-path
386
+ fill-rule="evenodd"
387
+ [attr.opacity]="idlePathOpacity"
388
+ [attr.pointer-events]="idlePathPointerEvents"
389
+ /><ng-content />
390
+ </svg>
391
+ `, isInline: true });
392
+ }
393
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourOverlay, decorators: [{
394
+ type: Component,
395
+ args: [{
396
+ selector: "glow-tour-overlay",
397
+ standalone: true,
398
+ template: `
399
+ <svg #tourElement
400
+ [attr.aria-hidden]="idleAriaHidden"
401
+ [attr.data-glow-tour-allow-interaction]="idleAllowInteraction"
402
+ data-glow-tour-overlay
403
+ focusable="false"
404
+ [attr.inert]="idleInert"
405
+ role="presentation"
406
+ [style]="idleStyle"
407
+ viewBox="0 0 0 0"
408
+ >
409
+ <path
410
+ [attr.cursor]="idlePathCursor"
411
+ data-glow-tour-overlay-path
412
+ fill-rule="evenodd"
413
+ [attr.opacity]="idlePathOpacity"
414
+ [attr.pointer-events]="idlePathPointerEvents"
415
+ /><ng-content />
416
+ </svg>
417
+ `,
418
+ }]
419
+ }], propDecorators: { element: [{
420
+ type: ViewChild,
421
+ args: ["tourElement", { static: true }]
422
+ }] } });
423
+ class GlowTourTrigger extends GlowTourReactiveComponent {
424
+ ariaLabelValue = signal(undefined);
425
+ disabledValue = signal(false);
426
+ ariaLabelText = computed(() => this.ariaLabelValue());
427
+ consumerDisabled = computed(() => this.disabledValue());
428
+ ariaControls = computed(() => this.scope.binding()?.ids.popover);
429
+ setAriaLabel(value) {
430
+ this.ariaLabelValue.set(value);
431
+ }
432
+ setDisabled(value) {
433
+ this.disabledValue.set(value);
434
+ }
435
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourTrigger, deps: null, target: i0.ɵɵFactoryTarget.Directive });
436
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourTrigger, usesInheritance: true, ngImport: i0 });
437
+ }
438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourTrigger, decorators: [{
439
+ type: Directive
440
+ }] });
441
+ /** Button component for navigating to the previous step in the tour. */
442
+ class GlowTourBackTrigger extends GlowTourTrigger {
443
+ backLabelValue = signal(undefined);
444
+ /** Optional aria-label for the back button. */
445
+ set ariaLabel(value) {
446
+ this.setAriaLabel(value);
447
+ }
448
+ /** Optional label text for the back button. */
449
+ set backLabel(value) {
450
+ this.backLabelValue.set(value);
451
+ }
452
+ /** Whether the button is disabled. */
453
+ set disabled(value) {
454
+ this.setDisabled(value);
455
+ }
456
+ isDisabled = computed(() => this.consumerDisabled() ||
457
+ !this.snapshot()?.canPrevious ||
458
+ this.step()?.popover?.disablePreviousButton === true);
459
+ label = computed(() => this.backLabelValue() ?? "Back step");
460
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourBackTrigger, deps: null, target: i0.ɵɵFactoryTarget.Component });
461
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourBackTrigger, isStandalone: true, selector: "glow-tour-back-trigger", inputs: { ariaLabel: "ariaLabel", backLabel: "backLabel", disabled: ["disabled", "disabled", booleanAttribute] }, usesInheritance: true, ngImport: i0, template: `
462
+ @if (!step()?.popover?.hidePreviousButton) {
463
+ <button
464
+ data-glow-tour-previous-trigger
465
+ [attr.aria-controls]="ariaControls()"
466
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
467
+ [attr.aria-label]="ariaLabelText() ?? label()"
468
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
469
+ [disabled]="isDisabled()"
470
+ type="button"
471
+ ><ng-content>{{ label() }}</ng-content></button>
472
+ }
473
+ `, isInline: true });
474
+ }
475
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourBackTrigger, decorators: [{
476
+ type: Component,
477
+ args: [{
478
+ selector: "glow-tour-back-trigger",
479
+ standalone: true,
480
+ template: `
481
+ @if (!step()?.popover?.hidePreviousButton) {
482
+ <button
483
+ data-glow-tour-previous-trigger
484
+ [attr.aria-controls]="ariaControls()"
485
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
486
+ [attr.aria-label]="ariaLabelText() ?? label()"
487
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
488
+ [disabled]="isDisabled()"
489
+ type="button"
490
+ ><ng-content>{{ label() }}</ng-content></button>
491
+ }
492
+ `,
493
+ }]
494
+ }], propDecorators: { ariaLabel: [{
495
+ type: Input
496
+ }], backLabel: [{
497
+ type: Input
498
+ }], disabled: [{
499
+ type: Input,
500
+ args: [{ transform: booleanAttribute }]
501
+ }] } });
502
+ /** Button component for advancing to the next step or finishing the tour. */
503
+ class GlowTourAdvanceTrigger extends GlowTourTrigger {
504
+ finishLabelValue = signal(undefined);
505
+ advanceLabelValue = signal(undefined);
506
+ /** Optional aria-label for the advance button. */
507
+ set ariaLabel(value) {
508
+ this.setAriaLabel(value);
509
+ }
510
+ /** Whether the button is disabled. */
511
+ set disabled(value) {
512
+ this.setDisabled(value);
513
+ }
514
+ /** Optional label text for the finish step. */
515
+ set finishLabel(value) {
516
+ this.finishLabelValue.set(value);
517
+ }
518
+ /** Optional label text for advancing to the next step. */
519
+ set advanceLabel(value) {
520
+ this.advanceLabelValue.set(value);
521
+ }
522
+ isDisabled = computed(() => this.consumerDisabled() ||
523
+ !this.snapshot()?.canAdvance ||
524
+ this.step()?.popover?.disableAdvanceButton === true);
525
+ label = computed(() => {
526
+ return this.snapshot()?.isLastStep
527
+ ? (this.finishLabelValue() ?? "Finish tour")
528
+ : (this.advanceLabelValue() ?? "Advance step");
529
+ });
530
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourAdvanceTrigger, deps: null, target: i0.ɵɵFactoryTarget.Component });
531
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourAdvanceTrigger, isStandalone: true, selector: "glow-tour-advance-trigger", inputs: { ariaLabel: "ariaLabel", disabled: ["disabled", "disabled", booleanAttribute], finishLabel: "finishLabel", advanceLabel: "advanceLabel" }, usesInheritance: true, ngImport: i0, template: `
532
+ @if (!step()?.popover?.hideAdvanceButton) {
533
+ <button
534
+ data-glow-tour-advance-trigger
535
+ [attr.aria-controls]="ariaControls()"
536
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
537
+ [attr.aria-label]="ariaLabelText() ?? label()"
538
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
539
+ [disabled]="isDisabled()"
540
+ type="button"
541
+ ><ng-content>{{ label() }}</ng-content></button>
542
+ }
543
+ `, isInline: true });
544
+ }
545
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourAdvanceTrigger, decorators: [{
546
+ type: Component,
547
+ args: [{
548
+ selector: "glow-tour-advance-trigger",
549
+ standalone: true,
550
+ template: `
551
+ @if (!step()?.popover?.hideAdvanceButton) {
552
+ <button
553
+ data-glow-tour-advance-trigger
554
+ [attr.aria-controls]="ariaControls()"
555
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
556
+ [attr.aria-label]="ariaLabelText() ?? label()"
557
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
558
+ [disabled]="isDisabled()"
559
+ type="button"
560
+ ><ng-content>{{ label() }}</ng-content></button>
561
+ }
562
+ `,
563
+ }]
564
+ }], propDecorators: { ariaLabel: [{
565
+ type: Input
566
+ }], disabled: [{
567
+ type: Input,
568
+ args: [{ transform: booleanAttribute }]
569
+ }], finishLabel: [{
570
+ type: Input
571
+ }], advanceLabel: [{
572
+ type: Input
573
+ }] } });
574
+ /** Button component for canceling/skipping the tour. */
575
+ class GlowTourCancelTrigger extends GlowTourTrigger {
576
+ /** Optional aria-label for the cancel button. */
577
+ set ariaLabel(value) {
578
+ this.setAriaLabel(value);
579
+ }
580
+ /** Whether the button is disabled. */
581
+ set disabled(value) {
582
+ this.setDisabled(value);
583
+ }
584
+ isDisabled = computed(() => this.consumerDisabled() || !this.snapshot()?.canCancel);
585
+ label = computed(() => "Skip");
586
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourCancelTrigger, deps: null, target: i0.ɵɵFactoryTarget.Component });
587
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: GlowTourCancelTrigger, isStandalone: true, selector: "glow-tour-cancel-trigger", inputs: { ariaLabel: "ariaLabel", disabled: ["disabled", "disabled", booleanAttribute] }, usesInheritance: true, ngImport: i0, template: `
588
+ @if (snapshot()?.canCancel) {
589
+ <button
590
+ data-glow-tour-cancel-trigger
591
+ [attr.aria-controls]="ariaControls()"
592
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
593
+ [attr.aria-label]="ariaLabelText() ?? label()"
594
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
595
+ [disabled]="isDisabled()"
596
+ type="button"
597
+ ><ng-content>{{ label() }}</ng-content></button>
598
+ }
599
+ `, isInline: true });
600
+ }
601
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourCancelTrigger, decorators: [{
602
+ type: Component,
603
+ args: [{
604
+ selector: "glow-tour-cancel-trigger",
605
+ standalone: true,
606
+ template: `
607
+ @if (snapshot()?.canCancel) {
608
+ <button
609
+ data-glow-tour-cancel-trigger
610
+ [attr.aria-controls]="ariaControls()"
611
+ [attr.aria-disabled]="isDisabled() ? 'true' : 'false'"
612
+ [attr.aria-label]="ariaLabelText() ?? label()"
613
+ [attr.data-glow-tour-consumer-disabled]="consumerDisabled() ? 'true' : null"
614
+ [disabled]="isDisabled()"
615
+ type="button"
616
+ ><ng-content>{{ label() }}</ng-content></button>
617
+ }
618
+ `,
619
+ }]
620
+ }], propDecorators: { ariaLabel: [{
621
+ type: Input
622
+ }], disabled: [{
623
+ type: Input,
624
+ args: [{ transform: booleanAttribute }]
625
+ }] } });
626
+
627
+ /** Default GlowTour.js component that renders all tour UI elements in a standard layout. */
628
+ class GlowTourDefault {
629
+ /** The tour controller instance to display. */
630
+ tour;
631
+ /** Optional prefix for generated HTML IDs. */
632
+ idPrefix;
633
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourDefault, deps: [], target: i0.ɵɵFactoryTarget.Component });
634
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: GlowTourDefault, isStandalone: true, selector: "glow-tour-default", inputs: { tour: "tour", idPrefix: "idPrefix" }, ngImport: i0, template: `
635
+ <glow-tour-root [tour]="tour" [idPrefix]="idPrefix">
636
+ <glow-tour-overlay />
637
+ <glow-tour-pointer />
638
+ <glow-tour-popover>
639
+ <glow-tour-header />
640
+ <glow-tour-content />
641
+ <glow-tour-footer>
642
+ <glow-tour-cancel-trigger />
643
+ <glow-tour-back-trigger />
644
+ <glow-tour-advance-trigger />
645
+ </glow-tour-footer>
646
+ </glow-tour-popover>
647
+ </glow-tour-root>
648
+ `, isInline: true, dependencies: [{ kind: "component", type: GlowTourRoot, selector: "glow-tour-root", inputs: ["tour", "idPrefix"] }, { kind: "component", type: GlowTourOverlay, selector: "glow-tour-overlay" }, { kind: "component", type: GlowTourPointer, selector: "glow-tour-pointer", inputs: ["directionContent"] }, { kind: "component", type: GlowTourPopover, selector: "glow-tour-popover" }, { kind: "component", type: GlowTourHeader, selector: "glow-tour-header" }, { kind: "component", type: GlowTourContent, selector: "glow-tour-content" }, { kind: "component", type: GlowTourFooter, selector: "glow-tour-footer" }, { kind: "component", type: GlowTourCancelTrigger, selector: "glow-tour-cancel-trigger", inputs: ["ariaLabel", "disabled"] }, { kind: "component", type: GlowTourBackTrigger, selector: "glow-tour-back-trigger", inputs: ["ariaLabel", "backLabel", "disabled"] }, { kind: "component", type: GlowTourAdvanceTrigger, selector: "glow-tour-advance-trigger", inputs: ["ariaLabel", "disabled", "finishLabel", "advanceLabel"] }] });
649
+ }
650
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: GlowTourDefault, decorators: [{
651
+ type: Component,
652
+ args: [{
653
+ selector: "glow-tour-default",
654
+ standalone: true,
655
+ imports: [
656
+ GlowTourRoot,
657
+ GlowTourOverlay,
658
+ GlowTourPointer,
659
+ GlowTourPopover,
660
+ GlowTourHeader,
661
+ GlowTourContent,
662
+ GlowTourFooter,
663
+ GlowTourCancelTrigger,
664
+ GlowTourBackTrigger,
665
+ GlowTourAdvanceTrigger,
666
+ ],
667
+ template: `
668
+ <glow-tour-root [tour]="tour" [idPrefix]="idPrefix">
669
+ <glow-tour-overlay />
670
+ <glow-tour-pointer />
671
+ <glow-tour-popover>
672
+ <glow-tour-header />
673
+ <glow-tour-content />
674
+ <glow-tour-footer>
675
+ <glow-tour-cancel-trigger />
676
+ <glow-tour-back-trigger />
677
+ <glow-tour-advance-trigger />
678
+ </glow-tour-footer>
679
+ </glow-tour-popover>
680
+ </glow-tour-root>
681
+ `,
682
+ }]
683
+ }], propDecorators: { tour: [{
684
+ type: Input,
685
+ args: [{ required: true }]
686
+ }], idPrefix: [{
687
+ type: Input
688
+ }] } });
689
+
690
+ /**
691
+ * Creates a new GlowTour.js instance for Angular.
692
+ * @param options Tour options for error handling.
693
+ * @returns A tour controller ready to run Angular workflows.
694
+ */
695
+ function createGlowTour(options = {}) {
696
+ return createGlowTour$1(options);
697
+ }
698
+
699
+ /**
700
+ * Generated bundle index. Do not edit.
701
+ */
702
+
703
+ export { GlowTourAdvanceTrigger, GlowTourBackTrigger, GlowTourCancelTrigger, GlowTourContent, GlowTourDefault, GlowTourFooter, GlowTourHeader, GlowTourOverlay, GlowTourPointer, GlowTourPopover, GlowTourRoot, createGlowTour, injectGlowTour };
704
+ //# sourceMappingURL=glowhop-angular-tour.mjs.map