@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,136 @@
1
+ import type { WorkflowDefinition } from "../definition";
2
+ import type { IndicatorOptions, LifecycleHookContext, OverlayOptions, PopoverOptions, PrimitiveValue, StepAction, StepBehavior, StepTransitionAction } from "../types";
3
+ /**
4
+ * A tour-level lifecycle hook callback (`onStart`, `onCancel`, `onFinish`), generic over the
5
+ * config's content type `T` (defaults to `string`, the untrusted-JSON case).
6
+ *
7
+ * There is no built-in (JSON-object) form for this slot: `LifecycleHookContext` carries no
8
+ * `target` at all (only `step: TourCurrentStep<T> | null`), so none of the DOM-oriented
9
+ * `BuiltinAction` variants (which all assume a `target`/`signal`) have a valid mapping here. A
10
+ * lifecycle hook is therefore only expressible as a same-runtime JS function — never as plain
11
+ * JSON.
12
+ */
13
+ export type LifecycleActionRef<T = string> = (context: LifecycleHookContext<T>) => void | Promise<void>;
14
+ /**
15
+ * One of the built-in action instructions, discriminated by `type`. Each variant maps 1:1 onto an
16
+ * existing `WorkflowStepBuilder` verb and mirrors its options.
17
+ *
18
+ * There is no `waitUntil` variant: a `waitUntil` predicate is arbitrary logic and cannot be
19
+ * expressed as JSON, and this format has no registry to reference one by id.
20
+ * `{ type: "waitUntilElement" }` covers the common case of waiting for a condition — waiting for
21
+ * an element to appear — without needing an arbitrary predicate.
22
+ *
23
+ * Not generic: a builtin action holds no content, so it carries no `T`.
24
+ */
25
+ export type BuiltinAction = {
26
+ readonly type: "wait";
27
+ readonly ms: number;
28
+ } | {
29
+ readonly type: "waitUntilElement";
30
+ readonly selector: string;
31
+ readonly interval?: number;
32
+ readonly timeout?: number;
33
+ } | {
34
+ readonly type: "clickTarget";
35
+ } | {
36
+ readonly type: "focusTarget";
37
+ };
38
+ /**
39
+ * A reference to a step action, resolved at build time by discriminating on its runtime shape:
40
+ * - `typeof ref === "function"` -> used inline as-is (JS escape hatch, not serializable).
41
+ * - a plain object with a `type` field -> a {@link BuiltinAction}, mapped onto the matching
42
+ * builder verb.
43
+ * - anything else is a validation error.
44
+ *
45
+ * Used for `actions[]` and `eventHandlers[].action`, which both run against a full `StepContext`
46
+ * (`target`, `signal`, navigation methods) — the same context `BuiltinAction`'s verbs assume, so
47
+ * builtins are valid here.
48
+ */
49
+ export type StepActionRef<T = string> = BuiltinAction | StepAction<T>;
50
+ /**
51
+ * A reference to a transition hook (`advanceAction`/`previousAction`/`cancelAction`).
52
+ *
53
+ * `BeforeActionStepContext` has a `target` but no `signal`/navigation methods, which the
54
+ * `BuiltinAction` verbs (`wait`, `waitUntilElement`, `clickTarget`, `focusTarget`) all need — none
55
+ * of them can run in this slot. With no registry to fall back on, a transition hook is therefore
56
+ * only expressible as a same-runtime JS function, never as plain JSON. This is a plain function
57
+ * type (not a union) precisely because there is nothing else valid to put here.
58
+ */
59
+ export type TransitionActionRef<T = string> = StepTransitionAction<T>;
60
+ /** JSON config form of a single `onTargetEvent` registration. */
61
+ export interface EventHandlerConfig<T = string> {
62
+ /** Event name, or multiple event names sharing the same action. */
63
+ readonly event: string | readonly string[];
64
+ readonly action: StepActionRef<T>;
65
+ }
66
+ /**
67
+ * JSON config form of a single tour step.
68
+ *
69
+ * Generic over `T`, the type of `title`/`content`. Defaults to `string` for the untrusted-JSON
70
+ * path (`JSON.parse()` output); callers building same-runtime configs can instantiate with their
71
+ * framework's content type (e.g. `StepConfig<ReactNode>`) to pass rich content straight through.
72
+ */
73
+ export interface StepConfig<T = string> {
74
+ /** Stable identifier for this step, unique within the workflow. Required. */
75
+ readonly id: string;
76
+ /** CSS selector for the step's target. Functions and `HTMLElement` are not supported in config form. */
77
+ readonly target: string;
78
+ readonly resetPropsOnEnter?: boolean;
79
+ readonly overlay?: OverlayOptions;
80
+ readonly popover?: PopoverOptions;
81
+ readonly indicator?: IndicatorOptions;
82
+ readonly behavior?: StepBehavior;
83
+ readonly title: T;
84
+ readonly content: T;
85
+ readonly data?: Record<string, PrimitiveValue>;
86
+ readonly actions?: readonly StepActionRef<T>[];
87
+ readonly eventHandlers?: readonly EventHandlerConfig<T>[];
88
+ readonly advanceAction?: TransitionActionRef<T>;
89
+ readonly previousAction?: TransitionActionRef<T>;
90
+ readonly cancelAction?: TransitionActionRef<T>;
91
+ }
92
+ /**
93
+ * A complete, JSON-serializable tour definition.
94
+ *
95
+ * Generic over `T` (defaults to `string`) so the same format covers both the untrusted-JSON path
96
+ * and same-runtime configs carrying framework content (`ReactNode`, `VNode`, `JSX.Element`, ...).
97
+ */
98
+ export interface WorkflowConfig<T = string> {
99
+ readonly name: string;
100
+ readonly cancellable?: boolean;
101
+ readonly allowScroll?: boolean;
102
+ readonly overlay?: OverlayOptions;
103
+ readonly popover?: PopoverOptions;
104
+ readonly indicator?: IndicatorOptions;
105
+ readonly animated?: boolean;
106
+ readonly behavior?: StepBehavior;
107
+ readonly onStart?: LifecycleActionRef<T>;
108
+ readonly onCancel?: LifecycleActionRef<T>;
109
+ readonly onFinish?: LifecycleActionRef<T>;
110
+ readonly steps: readonly StepConfig<T>[];
111
+ }
112
+ /** A single validation failure, with a path pointing at the offending config field. */
113
+ export interface ConfigValidationIssue {
114
+ /** Path into the config, e.g. `steps[2].eventHandlers[0].action`. */
115
+ readonly path: string;
116
+ readonly message: string;
117
+ }
118
+ /**
119
+ * Aggregate error thrown when a `WorkflowConfig` fails validation.
120
+ *
121
+ * Carries every issue found in a single pass over the whole config (decision: fail-fast on the
122
+ * first problem would force multiple edit/re-run cycles for a hand-written or generated JSON
123
+ * document), rather than throwing on the first issue encountered.
124
+ */
125
+ export declare class ConfigValidationError extends Error {
126
+ readonly issues: readonly ConfigValidationIssue[];
127
+ constructor(issues: readonly ConfigValidationIssue[]);
128
+ }
129
+ /**
130
+ * The `WorkflowDefinition` produced from a `WorkflowConfig<T>`, with the original (frozen) config
131
+ * attached so a future JSON exporter can round-trip cheaply without re-deriving it from the built
132
+ * definition.
133
+ */
134
+ export interface WorkflowDefinitionFromConfig<T = string> extends WorkflowDefinition<T> {
135
+ readonly source: Readonly<WorkflowConfig<T>>;
136
+ }
@@ -0,0 +1,37 @@
1
+ import type { WorkflowConfig } from "./types";
2
+ /**
3
+ * Validates a `title`/`content` value at `path`. Returns an error message, or `null` when the
4
+ * value is acceptable.
5
+ * @param value The candidate value.
6
+ * @param path Error path for this field, e.g. `steps[2].title`.
7
+ * @param validateContent Custom content validator; when omitted, the value must be a `string`.
8
+ */
9
+ type ContentValidator = (value: unknown, path: string) => string | null;
10
+ /** Options accepted by `validateWorkflowConfig` (and threaded through internally). */
11
+ export interface ValidateWorkflowConfigOptions {
12
+ /**
13
+ * Validates `title`/`content` values. Returns an error message, or `null` when the value is
14
+ * acceptable. Omit this to keep the default strict behavior — `title`/`content` must be plain
15
+ * strings — which is required for the untrusted-JSON path (`JSON.parse()` output). Callers using
16
+ * a rich content type `T` (e.g. `ReactNode`) must supply this to accept non-string values.
17
+ */
18
+ readonly validateContent?: ContentValidator;
19
+ }
20
+ /**
21
+ * Validates and narrows an unknown value to a `WorkflowConfig<T>`.
22
+ *
23
+ * Performs a single pass over the whole config, collecting every issue (unknown/extra keys, wrong
24
+ * types, missing required fields, invalid nested options, builtins used in slots that cannot run
25
+ * them, etc.) rather than throwing on the first one — see `ConfigValidationError`.
26
+ *
27
+ * By default, `title`/`content` must be plain strings — the runtime cannot otherwise know what
28
+ * `T` is, and this default keeps the untrusted-JSON path strict. Pass `options.validateContent`
29
+ * to accept a richer `T` (e.g. `ReactNode`).
30
+ *
31
+ * @param config The parsed JSON (or equivalent plain object) to validate.
32
+ * @param options Validation options; see {@link ValidateWorkflowConfigOptions}.
33
+ * @throws {ConfigValidationError} When one or more issues are found.
34
+ * @returns The same value, narrowed to `WorkflowConfig<T>`.
35
+ */
36
+ export declare function validateWorkflowConfig<T = string>(config: unknown, options?: ValidateWorkflowConfigOptions): WorkflowConfig<T>;
37
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export { cloneStepProps, freezeStepProps } from "./step-props";
2
+ export type { DeepReadonly, ReadonlyStartOptions, ReadonlyStepProps, StepProps, WorkflowDefinition, WorkflowStepDefinition, } from "./types";
3
+ export { cloneWorkflowStepDraft, createWorkflowDefinition, type WorkflowStepDraft, } from "./workflow-definition";
@@ -0,0 +1,13 @@
1
+ import type { ReadonlyStepProps, StepProps } from "./types";
2
+ /**
3
+ * Creates a shallow clone of step properties with deep clones of nested objects.
4
+ * @param props The properties to clone.
5
+ * @returns A mutable copy of the properties.
6
+ */
7
+ export declare function cloneStepProps<T>(props: ReadonlyStepProps<T>): StepProps<T>;
8
+ /**
9
+ * Creates a deep-frozen copy of step properties.
10
+ * @param props The properties to freeze.
11
+ * @returns An immutable copy of the properties.
12
+ */
13
+ export declare function freezeStepProps<T>(props: ReadonlyStepProps<T>): ReadonlyStepProps<T>;
@@ -0,0 +1,38 @@
1
+ import type { EventHandler, IndicatorOptions, OverlayOptions, PopoverOptions, PrimitiveValue, StartOptions, StepActionInstruction, StepBehavior, StepParameters, StepTransitionAction, TargetResolver } from "../types";
2
+ /** Recursively makes all properties readonly at any depth. */
3
+ export type DeepReadonly<T> = T extends (...arguments_: infer _Arguments) => infer _Return ? T : T extends readonly (infer TEntry)[] ? readonly DeepReadonly<TEntry>[] : T extends object ? {
4
+ readonly [TKey in keyof T]: DeepReadonly<T[TKey]>;
5
+ } : T;
6
+ /** Step properties (title, content, and optional display options) excluding target and behavior. */
7
+ export type StepProps<T> = Omit<StepParameters<T>, "id" | "target" | "resetPropsOnEnter" | "behavior">;
8
+ /** Immutable step properties. */
9
+ export type ReadonlyStepProps<T> = {
10
+ readonly title: T;
11
+ readonly content: T;
12
+ readonly data?: Readonly<Record<string, PrimitiveValue>>;
13
+ readonly overlay?: DeepReadonly<OverlayOptions>;
14
+ readonly popover?: DeepReadonly<PopoverOptions>;
15
+ readonly indicator?: DeepReadonly<IndicatorOptions>;
16
+ };
17
+ /** Immutable tour start options. */
18
+ export type ReadonlyStartOptions<T> = DeepReadonly<StartOptions<T>>;
19
+ /** A single step in a tour workflow (immutable). */
20
+ export interface WorkflowStepDefinition<T> {
21
+ /** Stable identifier, unique within the workflow. */
22
+ readonly id: string;
23
+ readonly target: TargetResolver;
24
+ readonly resetPropsOnEnter?: boolean;
25
+ readonly behavior?: DeepReadonly<StepBehavior>;
26
+ readonly props: ReadonlyStepProps<T>;
27
+ readonly actions: readonly StepActionInstruction<T>[];
28
+ readonly eventHandlers: readonly EventHandler<T>[];
29
+ readonly advanceAction: StepTransitionAction<T> | null;
30
+ readonly previousAction: StepTransitionAction<T> | null;
31
+ readonly cancelAction: StepTransitionAction<T> | null;
32
+ }
33
+ /** A complete tour workflow definition (immutable). */
34
+ export interface WorkflowDefinition<T> {
35
+ readonly name: string;
36
+ readonly options: ReadonlyStartOptions<T>;
37
+ readonly steps: readonly WorkflowStepDefinition<T>[];
38
+ }
@@ -0,0 +1,28 @@
1
+ import type { EventHandler, StartOptions, StepActionInstruction, StepParameters, StepTransitionAction } from "../types";
2
+ import type { StepProps, WorkflowDefinition, WorkflowStepDefinition } from "./types";
3
+ export interface WorkflowStepDraft<T> {
4
+ id: string;
5
+ target: StepParameters<T>["target"];
6
+ resetPropsOnEnter?: boolean;
7
+ props: StepProps<T>;
8
+ behavior?: StepParameters<T>["behavior"];
9
+ actions: StepActionInstruction<T>[];
10
+ eventHandlers: EventHandler<T>[];
11
+ advanceAction: StepTransitionAction<T> | null;
12
+ previousAction: StepTransitionAction<T> | null;
13
+ cancelAction: StepTransitionAction<T> | null;
14
+ }
15
+ /**
16
+ * Creates a mutable copy of a workflow step definition.
17
+ * @param definition The step definition to clone.
18
+ * @returns A mutable copy that can be further modified.
19
+ */
20
+ export declare function cloneWorkflowStepDraft<T>(definition: WorkflowStepDefinition<T> | WorkflowStepDraft<T>): WorkflowStepDraft<T>;
21
+ /**
22
+ * Creates a frozen workflow definition from a name, options, and step drafts.
23
+ * @param name The workflow name.
24
+ * @param options Tour start options and lifecycle hooks.
25
+ * @param drafts The workflow steps.
26
+ * @returns A frozen workflow definition ready to run.
27
+ */
28
+ export declare function createWorkflowDefinition<T>(name: string, options: StartOptions<T>, drafts: readonly WorkflowStepDraft<T>[]): WorkflowDefinition<T>;
@@ -0,0 +1,13 @@
1
+ export declare class DomMutationLease {
2
+ private readonly element;
3
+ private readonly attributes;
4
+ private readonly styles;
5
+ private released;
6
+ constructor(element: HTMLElement | SVGElement);
7
+ setAttribute(name: string, value: string | null): void;
8
+ setStyle(name: string, value: string | null, priority?: string): void;
9
+ releaseStyle(name: string): void;
10
+ release(): void;
11
+ private styleMutation;
12
+ private restoreStyle;
13
+ }
@@ -0,0 +1,113 @@
1
+ import type { ActiveStep } from "../runtime/active-step";
2
+ import type { TourDirection, TourEventSource } from "../types";
3
+ export interface TourViewCommands {
4
+ advance(source: TourEventSource): Promise<void>;
5
+ canAdvance(): boolean;
6
+ canCancel(): boolean;
7
+ canPrevious(): boolean;
8
+ isAdvanceDisabled(): boolean;
9
+ isCancelDisabled(): boolean;
10
+ isPreviousDisabled(): boolean;
11
+ previous(source: TourEventSource): Promise<void>;
12
+ cancel(source: TourEventSource): Promise<void>;
13
+ reportError(error: unknown): Promise<void>;
14
+ targetDisconnected(target: HTMLElement): Promise<void>;
15
+ subscribeCapabilities?(listener: (active: boolean) => void): () => void;
16
+ }
17
+ export interface TourViewDriver<T> {
18
+ show(step: ActiveStep<T>, direction: TourDirection, signal: AbortSignal, onBeforePopoverAppear?: () => void | Promise<void>): Promise<void> | void;
19
+ clear(signal: AbortSignal): Promise<void> | void;
20
+ dispose(): void;
21
+ releaseMount?(): void;
22
+ setCommands?(commands: TourViewCommands): void;
23
+ }
24
+ export declare class NoopTourViewDriver<T> implements TourViewDriver<T> {
25
+ show(_step: ActiveStep<T>, _direction: TourDirection, _signal: AbortSignal, onBeforePopoverAppear?: () => void | Promise<void>): void | Promise<void> | undefined;
26
+ clear(_signal: AbortSignal): void;
27
+ dispose(): void;
28
+ releaseMount(): void;
29
+ }
30
+ export declare class DomTourViewDriver<T> implements TourViewDriver<T> {
31
+ private readonly focusGuard;
32
+ private readonly scrollLock;
33
+ private readonly modalToken;
34
+ private readonly stepCleanups;
35
+ private commands;
36
+ private direction;
37
+ private currentStep;
38
+ private currentSignal;
39
+ private disposed;
40
+ private generation;
41
+ private active;
42
+ private lastTargetRect;
43
+ private lastViewport;
44
+ private inertBranches;
45
+ private modalDocument;
46
+ private modalRoot;
47
+ private overlay;
48
+ private pendingKeyboardCommand;
49
+ private pointer;
50
+ private pendingFocusGeneration;
51
+ private popover;
52
+ private presentationDirty;
53
+ private rafId;
54
+ private rafCancel;
55
+ private root;
56
+ private scrollAbort;
57
+ constructor(commands?: TourViewCommands);
58
+ setCommands(commands: TourViewCommands): void;
59
+ registerRoot(element: HTMLElement | null): void;
60
+ registerOverlay(element: SVGSVGElement | null): void;
61
+ registerPopover(element: HTMLElement | null): void;
62
+ registerPointer(element: HTMLElement | null): void;
63
+ show(step: ActiveStep<T>, direction: TourDirection, signal: AbortSignal, onBeforePopoverAppear?: () => void | Promise<void>): Promise<void>;
64
+ clear(signal: AbortSignal): Promise<void>;
65
+ releaseMount(): void;
66
+ dispose(): void;
67
+ private refreshRegisteredElements;
68
+ private activateRegisteredElements;
69
+ private initializeElements;
70
+ private syncModality;
71
+ private releaseModality;
72
+ private restoreInertBranches;
73
+ private appear;
74
+ private attachStepResources;
75
+ private listen;
76
+ private schedulePosition;
77
+ private updatePosition;
78
+ private observeDynamicOperation;
79
+ private handleKeydown;
80
+ private handleOverlayClick;
81
+ private queueTransitionKeydown;
82
+ private flushPendingKeyboardCommand;
83
+ private loopFocus;
84
+ private activateFocus;
85
+ private syncScrollLock;
86
+ private syncShortcutLabels;
87
+ private attachButtonHandlers;
88
+ private findClickedTrigger;
89
+ private observeControls;
90
+ private deferTriggerCommand;
91
+ private syncControlState;
92
+ private findTriggers;
93
+ private ownsTrigger;
94
+ private command;
95
+ private commandForGeneration;
96
+ private commandForStep;
97
+ private canCommand;
98
+ private syncControl;
99
+ private isConsumerDisabled;
100
+ private isLiveDisabled;
101
+ private isPointerEnabled;
102
+ private cleanupStepResources;
103
+ private isCurrentTargetAvailable;
104
+ private stopForDisconnectedTarget;
105
+ private beginGeneration;
106
+ private cancelAnimationsOnAbort;
107
+ private cancelElementAnimations;
108
+ private isCurrentGeneration;
109
+ private scrollTargetIntoView;
110
+ private throwIfAborted;
111
+ private throwIfStale;
112
+ private getWindow;
113
+ }
@@ -0,0 +1,62 @@
1
+ import type { IndicatorOptions, OverlayOptions, PopoverOptions } from "../types";
2
+ export interface TourElementStep {
3
+ readonly indicator?: IndicatorOptions;
4
+ readonly overlay?: OverlayOptions;
5
+ readonly popover?: PopoverOptions;
6
+ }
7
+ export default abstract class GlowTourElement {
8
+ protected element: HTMLElement | SVGSVGElement;
9
+ options?: {
10
+ duration?: number;
11
+ easing?: string;
12
+ disabled?: boolean;
13
+ } | undefined;
14
+ private readonly animations;
15
+ private readonly cancelledAnimations;
16
+ private released;
17
+ constructor(element: HTMLElement | SVGSVGElement, options?: {
18
+ duration?: number;
19
+ easing?: string;
20
+ disabled?: boolean;
21
+ } | undefined);
22
+ setAnimationOptions(options: {
23
+ duration?: number;
24
+ easing?: string;
25
+ disabled?: boolean;
26
+ }): void;
27
+ protected _getAnimationOptions(): KeyframeAnimationOptions;
28
+ protected _isAnimated(): boolean;
29
+ protected _startAnimation(keyframes: Keyframe[] | PropertyIndexedKeyframes, options?: KeyframeAnimationOptions, target?: Element): Animation | null;
30
+ /**
31
+ * The document driving `animation.finished`, when there is one.
32
+ *
33
+ * `Animation.timeline` is the document timeline, and a hidden document
34
+ * freezes it — see {@link _finishWhileDocumentHidden}.
35
+ */
36
+ private _getDocument;
37
+ /**
38
+ * Ends an animation that cannot progress, and keeps ending it for as long as
39
+ * the document stays hidden.
40
+ *
41
+ * A hidden document freezes its timeline: `currentTime` stops advancing, the
42
+ * animation stays `running` forever, and `animation.finished` never settles.
43
+ * Awaiting it would strand the caller — a tour transition would never
44
+ * complete, leaving the controller stuck in `transitioning`. Finishing the
45
+ * animation resolves `finished` even on a frozen timeline, so the transition
46
+ * lands on its final state immediately instead of hanging.
47
+ *
48
+ * @returns A cleanup function removing the visibility listener.
49
+ */
50
+ private _finishWhileDocumentHidden;
51
+ protected _waitForAnimation(animation: Animation): Promise<boolean>;
52
+ protected abstract _disappear(): Promise<void>;
53
+ protected abstract _getNextStyles(position: DOMRect, step: TourElementStep): Keyframe;
54
+ abstract updatePosition(nextPosition: DOMRect, step: TourElementStep): void;
55
+ abstract initializeProps(): void;
56
+ getElement(): HTMLElement | SVGSVGElement | null;
57
+ disappear(): Promise<void>;
58
+ release(): void;
59
+ cancelAnimations(): void;
60
+ protected _cancelAnimation(animation: Animation): void;
61
+ protected abstract _release(): void;
62
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Single source of truth for the "idle" presentation of tour elements — the
3
+ * out-of-flow, invisible layout each element must have before a tour ever
4
+ * runs (or before an adapter's runtime has bound to the DOM at all).
5
+ *
6
+ * `initializeProps()` on {@link OverlayElement}, {@link PointerElement} and
7
+ * {@link PopoverElement} applies these same constants imperatively once an
8
+ * adapter binds an element. Framework adapters render them directly into
9
+ * their markup (server and client alike) so the idle state holds even
10
+ * before hydration/binding runs, with no dependency on `@glowhop/styles-tour`
11
+ * or any other optional theme.
12
+ *
13
+ * Deliberately excluded: the overlay's `viewBox`, which depends on the live
14
+ * viewport and can only be computed once the element exists in a real DOM.
15
+ */
16
+ /** A CSS declaration block keyed by kebab-case property names. */
17
+ export type CssStyleRecord = Readonly<Record<string, string>>;
18
+ /** Idle inline style for the overlay `<svg>` element. */
19
+ export declare const OVERLAY_IDLE_STYLE: CssStyleRecord;
20
+ /** Idle attributes for the overlay `<svg>` element. */
21
+ export declare const OVERLAY_IDLE_ATTRIBUTES: {
22
+ readonly "aria-hidden": "true";
23
+ readonly "data-glow-tour-allow-interaction": "false";
24
+ readonly inert: "true";
25
+ };
26
+ /**
27
+ * Idle attributes for the overlay's cutout `<path>`. Genuinely load-bearing,
28
+ * not dead code: the parent `<svg>` is `pointer-events: none` and
29
+ * `setInteractionAllowed` toggles it, so `pointer-events: auto` here is what
30
+ * makes only the drawn region clickable — what `behavior.overlayClick`
31
+ * depends on.
32
+ */
33
+ export declare const OVERLAY_PATH_IDLE_ATTRIBUTES: {
34
+ readonly cursor: "auto";
35
+ readonly opacity: "0";
36
+ readonly "pointer-events": "auto";
37
+ };
38
+ /** Idle inline style for the pointer/indicator element. */
39
+ export declare const POINTER_IDLE_STYLE: CssStyleRecord;
40
+ /** Idle attributes for the pointer/indicator element. */
41
+ export declare const POINTER_IDLE_ATTRIBUTES: {
42
+ readonly "aria-hidden": "true";
43
+ };
44
+ /** Idle inline style for the popover element. */
45
+ export declare const POPOVER_IDLE_STYLE: CssStyleRecord;
46
+ /** Idle attributes for the popover element. */
47
+ export declare const POPOVER_IDLE_ATTRIBUTES: {
48
+ readonly "aria-hidden": "true";
49
+ readonly inert: "true";
50
+ readonly tabindex: "-1";
51
+ };
52
+ /**
53
+ * Serializes a style record to CSS text, e.g. for a static `style="..."`
54
+ * attribute (Vanilla, Angular).
55
+ */
56
+ export declare function styleRecordToCssText(style: CssStyleRecord): string;
57
+ /**
58
+ * Converts a kebab-case style record to a camelCase object, as required by
59
+ * React's `style` prop. Vue and Solid accept kebab-case property names
60
+ * directly and can use the canonical record as-is.
61
+ */
62
+ export declare function styleRecordToCamelCase(style: CssStyleRecord): Readonly<Record<string, string>>;
@@ -0,0 +1,22 @@
1
+ import GlowTourElement, { type TourElementStep } from "./base";
2
+ export default class OverlayElement extends GlowTourElement {
3
+ private currentTransition;
4
+ private visualState;
5
+ setInteractionAllowed(allowed: boolean): void;
6
+ moveToTarget(nextPosition: DOMRect, step: TourElementStep): Promise<void>;
7
+ animateTo(position: DOMRect, step: TourElementStep): Promise<void>;
8
+ _getNextStyles(position: DOMRect, step: TourElementStep): Keyframe;
9
+ initializeProps(): void;
10
+ private _getPathElement;
11
+ protected _release(): void;
12
+ updatePosition(nextPosition: DOMRect, step: TourElementStep, animateChanges?: boolean, onTransition?: (transition: Promise<void>) => void): void;
13
+ cancelAnimations(): void;
14
+ private applyStyles;
15
+ private commitAndCancelCurrentTransition;
16
+ private getCurrentRenderedStyles;
17
+ private getRenderedTargetStyles;
18
+ private _getVisualState;
19
+ private _isSameVisualState;
20
+ _appear(position: DOMRect, step: TourElementStep): Promise<void>;
21
+ _disappear(): Promise<void>;
22
+ }
@@ -0,0 +1,24 @@
1
+ import type { ResolvedPlacement } from "../types";
2
+ import GlowTourElement, { type TourElementStep } from "./base";
3
+ export default class PointerElement extends GlowTourElement {
4
+ private animation;
5
+ private popoverPlacement?;
6
+ private directionNodes;
7
+ initializeProps(): void;
8
+ protected _getNextStyles(position: DOMRect, step: TourElementStep): Keyframe;
9
+ moveToTarget(nextPosition: DOMRect, step: TourElementStep, appear: boolean, popoverPlacement?: ResolvedPlacement): Promise<void>;
10
+ updatePosition(nextPosition: DOMRect, step: TourElementStep, popoverPlacement?: ResolvedPlacement): void;
11
+ syncVisibility(visible: boolean, position: DOMRect, step: TourElementStep, popoverPlacement?: ResolvedPlacement): void;
12
+ cancelAnimations(): void;
13
+ private _appear;
14
+ protected _disappear(): Promise<void>;
15
+ private _resolvePosition;
16
+ private _getCandidates;
17
+ private _startPointerAnimation;
18
+ private _stopAnimation;
19
+ protected _release(): void;
20
+ private _setPlacement;
21
+ private _syncDirectionVisibility;
22
+ private _ensureDirectionNodes;
23
+ private _getTargetTransform;
24
+ }
@@ -0,0 +1,5 @@
1
+ export interface PopoverArrowStylesOptions {
2
+ readonly nonce?: string;
3
+ readonly disabled?: boolean;
4
+ }
5
+ export declare function ensurePopoverArrowStyles(element: Element, options?: PopoverArrowStylesOptions): void;
@@ -0,0 +1,33 @@
1
+ import type { ResolvedPlacement } from "../types";
2
+ import GlowTourElement, { type TourElementStep } from "./base";
3
+ export interface PopoverPosition {
4
+ placement: ResolvedPlacement;
5
+ x: number;
6
+ y: number;
7
+ arrowOffset: number | null;
8
+ }
9
+ export default class PopoverElement extends GlowTourElement {
10
+ private appliedPosition;
11
+ private pendingReposition;
12
+ private repositionPhase;
13
+ private repositionGeneration;
14
+ private readonly mutationLease;
15
+ protected _getNextStyles(position: DOMRect, step: TourElementStep): Keyframe;
16
+ resolvePosition(targetPosition: DOMRect, step: TourElementStep): PopoverPosition;
17
+ private _centerPosition;
18
+ private _applyPositionState;
19
+ moveToTarget(nextPosition: DOMRect, step: TourElementStep, appear: boolean, onChange?: () => void | Promise<void>): Promise<void>;
20
+ initializeProps(): void;
21
+ updatePosition(nextPosition: DOMRect, step: TourElementStep, onReposition?: (reposition: Promise<void>) => void): ResolvedPlacement;
22
+ cancelAnimations(): void;
23
+ private _flushReposition;
24
+ private _applyTransform;
25
+ private _stationaryPosition;
26
+ private _applyArrowStyles;
27
+ private _applyArrowStyle;
28
+ _appear(position: DOMRect, step: TourElementStep): Promise<void>;
29
+ _disappear(): Promise<void>;
30
+ protected _release(): void;
31
+ private _applyVisibleState;
32
+ private _applyHiddenState;
33
+ }
package/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export type { EventName, WorkflowBuilder, WorkflowStepBuilder } from "./builder";
2
+ export type { ReadonlyStartOptions, ReadonlyStepProps, WorkflowDefinition, WorkflowStepDefinition, } from "./definition";
3
+ export { createGlowTour } from "./runtime/tour-controller";
4
+ export type { AnimationOptions, BaseOptions, BeforeActionStepContext, EventHandler, GlowTour, GlowTourOptions, IndicatorOptions, LifecycleHookContext, OverlayOptions, PopoverArrowOptions, PopoverOptions, PrimitiveValue, ReadonlyTourState, ResolvedPlacement, ScrollOptions, StartOptions, StepAction, StepActionInstruction, StepActionResult, StepBehavior, StepContext, StepEventContext, StepParameters, StepPropsStore, StepPropsUpdate, StepTransitionAction, TargetResolver, TargetResolverContext, TourCurrentStep, TourDirection, TourEvent, TourEventListener, TourEventSource, TourEventType, TourState, TourStatus, TryOrderOptions, WaitUntilOptions, } from "./types";