@glowhop/core-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,3 @@
1
+ import type { ReadonlyStepProps, WorkflowDefinition } from "../definition";
2
+ export declare function validateStepProps<T>(path: string, props: ReadonlyStepProps<T>): void;
3
+ export declare function validateWorkflowOptions<T>(workflow: WorkflowDefinition<T>): void;
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@glowhop/core-tour",
3
+ "version": "1.0.0",
4
+ "description": "Framework-agnostic tour controller and DOM runtime for GlowTour.js.",
5
+ "license": "MIT",
6
+ "homepage": "https://github.com/Glowhop/GlowTour.js#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/Glowhop/GlowTour.js/issues"
9
+ },
10
+ "keywords": [
11
+ "tour",
12
+ "guided-tour",
13
+ "onboarding",
14
+ "dom"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18.19.1"
18
+ },
19
+ "files": [
20
+ "**/*"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/Glowhop/GlowTour.js.git",
28
+ "directory": "packages/core"
29
+ },
30
+ "type": "module",
31
+ "types": "./index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./index.d.ts",
35
+ "import": "./index.js"
36
+ },
37
+ "./adapter": {
38
+ "types": "./adapter.d.ts",
39
+ "import": "./adapter.js"
40
+ },
41
+ "./config": {
42
+ "types": "./config/index.d.ts",
43
+ "import": "./config/index.js"
44
+ }
45
+ },
46
+ "sideEffects": false
47
+ }
@@ -0,0 +1,2 @@
1
+ export declare function abortError(): DOMException;
2
+ export declare function abortableDelay(delay: number, signal: AbortSignal): Promise<void>;
@@ -0,0 +1,72 @@
1
+ import { type ReadonlyStartOptions, type ReadonlyStepProps, type WorkflowStepDefinition } from "../definition";
2
+ import type { StepPropsStore } from "../types";
3
+ export declare class ActiveStep<T> {
4
+ readonly definition: WorkflowStepDefinition<T>;
5
+ readonly path: string;
6
+ private readonly rootDocument?;
7
+ readonly initialProps: ReadonlyStepProps<T>;
8
+ readonly props: StepPropsStore<T>;
9
+ readonly behavior: import("../types").StepBehavior | undefined;
10
+ readonly animated: boolean | undefined;
11
+ readonly allowScroll: boolean;
12
+ target: HTMLElement | null;
13
+ constructor(definition: WorkflowStepDefinition<T>, defaults: ReadonlyStartOptions<T>, reportSubscriberError?: (error: unknown) => void, path?: string, rootDocument?: Document | undefined);
14
+ reset(): void;
15
+ get overlay(): {
16
+ readonly color?: string | undefined;
17
+ readonly opacity?: number | undefined;
18
+ readonly padding?: number | undefined;
19
+ readonly radius?: number | undefined;
20
+ readonly animated?: boolean | undefined;
21
+ readonly animation?: {
22
+ readonly duration: number;
23
+ readonly easing: string;
24
+ } | undefined;
25
+ } | undefined;
26
+ get popover(): {
27
+ readonly placementTryOrder?: readonly import("../types").TryOrderOptions[] | undefined;
28
+ readonly arrow?: {
29
+ readonly disabled?: boolean | undefined;
30
+ readonly color?: string | undefined;
31
+ readonly size?: number | undefined;
32
+ readonly borderWidth?: number | undefined;
33
+ readonly borderRadius?: number | undefined;
34
+ readonly edgePadding?: number | undefined;
35
+ readonly styleNonce?: string | undefined;
36
+ readonly disableAutoStyles?: boolean | undefined;
37
+ } | undefined;
38
+ readonly hideFooter?: boolean | undefined;
39
+ readonly disablePreviousButton?: boolean | undefined;
40
+ readonly hidePreviousButton?: boolean | undefined;
41
+ readonly disableAdvanceButton?: boolean | undefined;
42
+ readonly hideAdvanceButton?: boolean | undefined;
43
+ readonly gap?: number | undefined;
44
+ readonly keyboardShortcuts?: {
45
+ readonly previous?: readonly string[] | undefined;
46
+ readonly advance?: readonly string[] | undefined;
47
+ readonly cancel?: readonly string[] | undefined;
48
+ } | undefined;
49
+ readonly animated?: boolean | undefined;
50
+ readonly animation?: {
51
+ readonly duration: number;
52
+ readonly easing: string;
53
+ } | undefined;
54
+ } | undefined;
55
+ get indicator(): {
56
+ readonly disabled?: boolean | undefined;
57
+ readonly gap?: number | undefined;
58
+ readonly placementTryOrder?: readonly import("../types").TryOrderOptions[] | undefined;
59
+ readonly animated?: boolean | undefined;
60
+ readonly animation?: {
61
+ readonly duration: number;
62
+ readonly easing: string;
63
+ } | undefined;
64
+ } | undefined;
65
+ resolveTarget(signal: AbortSignal): Promise<HTMLElement | null>;
66
+ snapshot(): Readonly<{
67
+ id: string;
68
+ initialProps: ReadonlyStepProps<T>;
69
+ currentProps: ReadonlyStepProps<T>;
70
+ target: HTMLElement | null;
71
+ }>;
72
+ }
@@ -0,0 +1,23 @@
1
+ export declare const ADAPTER_BRIDGE_SYMBOL: unique symbol;
2
+ export declare const ADAPTER_BRIDGE_VERSION: 1;
3
+ export interface AdapterRootIds {
4
+ readonly description: string;
5
+ readonly popover: string;
6
+ readonly root: string;
7
+ readonly title: string;
8
+ }
9
+ export interface AdapterRootBinding {
10
+ readonly ids: AdapterRootIds;
11
+ bindOverlay(element: SVGSVGElement): () => void;
12
+ bindPointer(element: HTMLElement): () => void;
13
+ bindPopover(element: HTMLElement): () => void;
14
+ release(): void;
15
+ }
16
+ export interface AdapterRootConnectOptions {
17
+ readonly idPrefix?: string;
18
+ readonly root: HTMLElement;
19
+ }
20
+ export interface AdapterBridge {
21
+ readonly version: typeof ADAPTER_BRIDGE_VERSION;
22
+ connectRoot(options: AdapterRootConnectOptions): AdapterRootBinding;
23
+ }
@@ -0,0 +1,6 @@
1
+ import type { WorkflowDefinition } from "../definition";
2
+ import type { DomTourViewDriver } from "../dom/tour-view-driver";
3
+ export declare function attachRootBridge<T>(tour: object, driver: DomTourViewDriver<T>, isDisposed: () => boolean, onMountReleaseStart: () => void, onMountReleaseComplete: () => void): {
4
+ assertCanRun(workflow: WorkflowDefinition<T>): Document;
5
+ release(): void;
6
+ };
@@ -0,0 +1,3 @@
1
+ import { type ReadonlyStepProps } from "../definition";
2
+ import type { StepPropsStore } from "../types";
3
+ export declare function createStepPropsStore<T>(initialProps: ReadonlyStepProps<T>, reportListenerError: (error: unknown) => void, path?: string): StepPropsStore<T>;
@@ -0,0 +1,107 @@
1
+ import { WorkflowBuilder } from "../builder";
2
+ import type { WorkflowDefinition } from "../definition";
3
+ import { type TourViewDriver } from "../dom/tour-view-driver";
4
+ import type { GlowTour, GlowTourOptions, RunOptions, StartOptions, TourEventSource, TourState } from "../types";
5
+ interface TourControllerOptions<T> extends GlowTourOptions {
6
+ assertCanRun?: (workflow: WorkflowDefinition<T>) => Document | void;
7
+ onDispose?: () => void;
8
+ reportUnhandledError?: (error: Error) => void;
9
+ }
10
+ export declare class TourController<T> {
11
+ private readonly driver;
12
+ private readonly options;
13
+ private snapshot;
14
+ private workflow;
15
+ private steps;
16
+ private index;
17
+ private direction;
18
+ private status;
19
+ private error;
20
+ private operationToken;
21
+ private publicationRevision;
22
+ private operation;
23
+ private disposed;
24
+ private retainedPresentation;
25
+ private readonly stateListeners;
26
+ private readonly stepPropsSubscriptions;
27
+ private tourStartedAt;
28
+ private stepEnteredAt;
29
+ private commandSource;
30
+ readonly state: Readonly<{
31
+ get: () => TourState<T>;
32
+ subscribe: (listener: (state: TourState<T>) => void) => () => void;
33
+ }>;
34
+ constructor(driver: TourViewDriver<T>, options?: TourControllerOptions<T>);
35
+ create(name: string, options?: StartOptions<T>): WorkflowBuilder<T>;
36
+ run(workflow: WorkflowDefinition<T>, runOptions?: RunOptions): Promise<void>;
37
+ advance(source?: TourEventSource): Promise<void>;
38
+ previous(source?: TourEventSource): Promise<void>;
39
+ goToStep(index: number): Promise<void>;
40
+ cancel(source?: TourEventSource): Promise<void>;
41
+ dispose(): void;
42
+ isDisposed(): boolean;
43
+ /** @internal Called by the private root bridge before it releases DOM resources. */
44
+ beginMountRelease(): void;
45
+ /** @internal Called after the private root bridge has finished releasing its lease. */
46
+ completeMountRelease(): void;
47
+ private enter;
48
+ private transitionFromPublic;
49
+ private transition;
50
+ private runActions;
51
+ private resolveTarget;
52
+ private recoverDisconnectedTarget;
53
+ private advancePastMissingTarget;
54
+ private advancePastRecoveryMissingTarget;
55
+ private missingTargetError;
56
+ private finish;
57
+ private cancelCurrent;
58
+ private createLifecycleHookContext;
59
+ /**
60
+ * Restores the controller to its pre-`run()` idle state. Used when an
61
+ * aborted lifecycle hook prevents the tour from ever becoming active
62
+ * (`onStart` abort, and the zero-step `onFinish` abort edge case).
63
+ */
64
+ private resetToIdle;
65
+ private handleFailure;
66
+ private beginOperation;
67
+ private createStepContext;
68
+ private createBeforeActionStepContext;
69
+ private invalidateOperation;
70
+ private signalFor;
71
+ private assertCurrent;
72
+ private isCurrent;
73
+ private assertNotDisposed;
74
+ private currentStep;
75
+ private releaseStepPropsSubscriptions;
76
+ private canNavigate;
77
+ private isAdvanceButtonAvailable;
78
+ private isPreviousButtonAvailable;
79
+ private isCancelAvailable;
80
+ private isPresentedAdvanceAvailable;
81
+ private isPresentedPreviousAvailable;
82
+ private isPresentedCancelAvailable;
83
+ private canCancel;
84
+ private setStatus;
85
+ private publish;
86
+ private notifyStateListener;
87
+ /**
88
+ * True when at least one listener is attached. Every emission site checks this
89
+ * first so that a tour with no monitoring builds no payloads and reads no clock.
90
+ */
91
+ private hasEventListeners;
92
+ private emit;
93
+ private notifyEventListener;
94
+ /** Emits `step:leave` for the step being left, with the time spent on it. */
95
+ private emitStepLeave;
96
+ private reportSubscriberError;
97
+ private reportUnhandledError;
98
+ private createSnapshot;
99
+ private capturePresentation;
100
+ }
101
+ /**
102
+ * Creates a new GlowTour.js instance.
103
+ * @param options Tour options for error handling.
104
+ * @returns A tour controller ready to run workflows.
105
+ */
106
+ export declare function createGlowTour<T>(options?: GlowTourOptions): GlowTour<T>;
107
+ export {};
@@ -0,0 +1,32 @@
1
+ type FocusDirection = "advance" | "previous";
2
+ export interface FocusGuardScope {
3
+ popover: HTMLElement;
4
+ direction: FocusDirection;
5
+ allowedTarget?: HTMLElement | null;
6
+ allowTargetInteraction?: boolean;
7
+ autoFocus?: boolean;
8
+ fallback?: HTMLElement | null;
9
+ }
10
+ export declare class FocusGuard {
11
+ private initialFocus;
12
+ private document;
13
+ private popover;
14
+ private allowedTarget;
15
+ private allowTargetInteraction;
16
+ private fallback;
17
+ private fallbackLease;
18
+ private direction;
19
+ private active;
20
+ private redirecting;
21
+ private readonly handleFocusIn;
22
+ activate(scope: FocusGuardScope): void;
23
+ update(scope: FocusGuardScope): void;
24
+ focus(): void;
25
+ deactivate(): void;
26
+ private isAllowed;
27
+ private focusFallback;
28
+ private setFallback;
29
+ private restoreFallback;
30
+ private findFocusable;
31
+ }
32
+ export {};
@@ -0,0 +1,6 @@
1
+ export declare const FOCUSABLE_SELECTOR: string;
2
+ export declare const TOUR_TRIGGER_SELECTOR: string;
3
+ export declare function focusableElements(root: HTMLElement): HTMLElement[];
4
+ export declare function focusableElementsOwnedBy(root: HTMLElement): HTMLElement[];
5
+ export declare function focusableTourControls(root: HTMLElement): HTMLElement[];
6
+ export declare function isFocusable(element: HTMLElement): boolean;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Locks page scroll on `document.body` while a tour is active, compensating
3
+ * for the scrollbar's width so hiding it does not shift the layout.
4
+ *
5
+ * Mirrors the setup/teardown shape of {@link "./focus-guard".FocusGuard}:
6
+ * `activate` captures and overrides the body's inline scroll-affecting
7
+ * styles, `deactivate` restores exactly what was there before.
8
+ */
9
+ export declare class ScrollLock {
10
+ private document;
11
+ private previousOverflow;
12
+ private previousPaddingRight;
13
+ private active;
14
+ activate(document: Document | null | undefined): void;
15
+ deactivate(): void;
16
+ private scrollbarWidth;
17
+ private computedPaddingRight;
18
+ }