@glowhop/core-tour 1.3.0 → 1.4.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.
- package/CHANGELOG.md +182 -0
- package/README.md +3 -3
- package/builder/index.d.ts +15 -16
- package/config/index.d.ts +1 -1
- package/config/index.js +161 -134
- package/config/types.d.ts +27 -19
- package/definition/step-props.d.ts +9 -1
- package/definition/types.d.ts +10 -10
- package/definition/workflow-definition.d.ts +4 -7
- package/dom/tour-view-driver.d.ts +46 -3
- package/elements/base.d.ts +24 -2
- package/elements/popover.d.ts +18 -6
- package/index.d.ts +1 -1
- package/index.js +628 -472
- package/package.json +1 -1
- package/runtime/active-step.d.ts +16 -54
- package/runtime/tour-controller.d.ts +30 -12
- package/state/focus-guard.d.ts +15 -0
- package/types/index.d.ts +153 -85
- package/utils/options.d.ts +13 -1
package/package.json
CHANGED
package/runtime/active-step.d.ts
CHANGED
|
@@ -1,68 +1,30 @@
|
|
|
1
1
|
import { type ReadonlyStartOptions, type ReadonlyStepProps, type WorkflowStepDefinition } from "../definition";
|
|
2
|
-
import type { StepPropsStore } from "../types";
|
|
2
|
+
import type { StepPropsStore, TourDirection } from "../types";
|
|
3
3
|
export declare class ActiveStep<T> {
|
|
4
4
|
readonly definition: WorkflowStepDefinition<T>;
|
|
5
5
|
readonly path: string;
|
|
6
6
|
private readonly rootDocument?;
|
|
7
7
|
readonly initialProps: ReadonlyStepProps<T>;
|
|
8
8
|
readonly props: StepPropsStore<T>;
|
|
9
|
-
readonly behavior: import("../types").StepBehavior | undefined;
|
|
10
9
|
readonly animated: boolean | undefined;
|
|
11
|
-
readonly allowScroll: boolean;
|
|
12
10
|
target: HTMLElement | null;
|
|
11
|
+
/** Shown without its target (`missingTarget.strategy: "detached"`); `target` is then the body. */
|
|
12
|
+
detached: boolean;
|
|
13
|
+
/** The navigation that last brought the tour to this step. */
|
|
14
|
+
direction: TourDirection;
|
|
13
15
|
constructor(definition: WorkflowStepDefinition<T>, defaults: ReadonlyStartOptions<T>, reportSubscriberError?: (error: unknown) => void, path?: string, rootDocument?: Document | undefined);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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;
|
|
16
|
+
/**
|
|
17
|
+
* Reads `behavior.allowInteraction` live: `props.update({ behavior })` changes it while the step runs.
|
|
18
|
+
* A detached step has no target to interact with, so it always blocks the page.
|
|
19
|
+
*/
|
|
20
|
+
allowsInteraction(): boolean;
|
|
21
|
+
/** Reads `behavior.autoFocus` live: `false` hands every focus move to the page. */
|
|
22
|
+
autoFocuses(): boolean;
|
|
23
|
+
/** Reads `behavior.allowScroll` live: `props.update({ behavior })` changes it while the step runs. */
|
|
24
|
+
allowsScroll(): boolean;
|
|
65
25
|
resolveTarget(signal: AbortSignal): Promise<HTMLElement | null>;
|
|
26
|
+
/** Marks the step detached and returns the body it stands on, or `null` without a document. */
|
|
27
|
+
detach(): HTMLElement;
|
|
66
28
|
snapshot(): Readonly<{
|
|
67
29
|
id: string;
|
|
68
30
|
initialProps: ReadonlyStepProps<T>;
|
|
@@ -4,11 +4,11 @@ import { type TourViewDriver } from "../dom/tour-view-driver";
|
|
|
4
4
|
import type { GlowTour, GlowTourOptions, RunOptions, StartOptions, TourEventSource, TourState } from "../types";
|
|
5
5
|
/**
|
|
6
6
|
* How long a step stays frozen on its last known position after its target
|
|
7
|
-
* disappears from the DOM, before the configured `
|
|
7
|
+
* disappears from the DOM, before the configured `missingTarget.strategy`
|
|
8
8
|
* takes over. Covers the dominant case — a framework remounting the target
|
|
9
9
|
* within a frame or two — without a visible unmount/remount flicker. Not
|
|
10
10
|
* configurable: it is a presentation detail of the recovery, not a policy
|
|
11
|
-
* choice; `
|
|
11
|
+
* choice; `missingTarget.strategy` and `missingTarget.timeout` remain the only knobs.
|
|
12
12
|
* Exported for the test suite's timing assertions only.
|
|
13
13
|
*/
|
|
14
14
|
export declare const TARGET_LOSS_GRACE_MS = 150;
|
|
@@ -44,6 +44,11 @@ export declare class TourController<T> {
|
|
|
44
44
|
private readonly stepPropsSubscriptions;
|
|
45
45
|
private tourStartedAt;
|
|
46
46
|
private stepEnteredAt;
|
|
47
|
+
/**
|
|
48
|
+
* The step `tour:start` names, while that event is held back. It is emitted just before the
|
|
49
|
+
* first event that can no longer be taken back, so a start that a `beforeEnter` aborts emits nothing.
|
|
50
|
+
*/
|
|
51
|
+
private pendingTourStart;
|
|
47
52
|
private commandSource;
|
|
48
53
|
readonly state: Readonly<{
|
|
49
54
|
get: () => TourState<T>;
|
|
@@ -51,10 +56,12 @@ export declare class TourController<T> {
|
|
|
51
56
|
}>;
|
|
52
57
|
constructor(driver: TourViewDriver<T>, options?: TourControllerOptions<T>);
|
|
53
58
|
create(name: string, options?: StartOptions<T>): WorkflowBuilder<T>;
|
|
54
|
-
|
|
59
|
+
start(workflow: WorkflowDefinition<T>, runOptions?: RunOptions): Promise<void>;
|
|
55
60
|
advance(source?: TourEventSource): Promise<void>;
|
|
56
61
|
previous(source?: TourEventSource): Promise<void>;
|
|
57
|
-
|
|
62
|
+
goTo(id: string): Promise<void>;
|
|
63
|
+
/** The direction of a jump from the current step to the step at `index`. */
|
|
64
|
+
private directionTo;
|
|
58
65
|
cancel(source?: TourEventSource): Promise<void>;
|
|
59
66
|
dispose(): void;
|
|
60
67
|
isDisposed(): boolean;
|
|
@@ -62,15 +69,25 @@ export declare class TourController<T> {
|
|
|
62
69
|
beginMountRelease(): void;
|
|
63
70
|
/** @internal Called after the private root bridge has finished releasing its lease. */
|
|
64
71
|
completeMountRelease(): void;
|
|
65
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Moves to the step at `index`, or further in `direction` past steps skipped for a missing target.
|
|
74
|
+
* Nothing is emitted before `beforeEnter` lets the navigation through, so an abort leaves no trace.
|
|
75
|
+
* Then come the held `tour:start`, a `step:skip` per skipped step, and one `step:leave` for the
|
|
76
|
+
* step being left. `lostStep` is the step whose target disappeared during recovery: it cannot stay
|
|
77
|
+
* on screen, so skipping backward past the first step cancels the tour, and a `beforeEnter` abort
|
|
78
|
+
* turns into its missing-target error.
|
|
79
|
+
*/
|
|
80
|
+
private navigate;
|
|
66
81
|
private transitionFromPublic;
|
|
67
82
|
private transition;
|
|
83
|
+
/** Runs `beforeEnter` or `beforeLeave`, and tells whether it called `abort()` before settling. */
|
|
84
|
+
private runStepHook;
|
|
68
85
|
private runActions;
|
|
69
86
|
private resolveTarget;
|
|
70
87
|
/**
|
|
71
88
|
* Repeatedly re-resolves `step.target` until it succeeds or `budgetMs`
|
|
72
89
|
* elapses, polling every 16ms like `resolveTarget`. Unlike `resolveTarget`
|
|
73
|
-
* it never applies `
|
|
90
|
+
* it never applies `missingTarget.strategy` itself — callers decide what a
|
|
74
91
|
* timed-out budget means (grace period vs. a "wait" strategy's own
|
|
75
92
|
* timeout), so the same polling loop serves both.
|
|
76
93
|
*/
|
|
@@ -91,22 +108,21 @@ export declare class TourController<T> {
|
|
|
91
108
|
* comes back, so it has to keep working.
|
|
92
109
|
*/
|
|
93
110
|
private recoverDisconnectedTarget;
|
|
94
|
-
private advancePastMissingTarget;
|
|
95
|
-
private advancePastRecoveryMissingTarget;
|
|
96
111
|
private missingTargetError;
|
|
97
112
|
private finish;
|
|
98
113
|
private cancelCurrent;
|
|
99
114
|
private createLifecycleHookContext;
|
|
100
115
|
/**
|
|
101
|
-
* Restores the controller to its pre-`
|
|
102
|
-
* aborted
|
|
103
|
-
*
|
|
116
|
+
* Restores the controller to its pre-`start()` idle state. Used when an
|
|
117
|
+
* aborted hook prevents the tour from ever becoming active (`onStart`, the
|
|
118
|
+
* first step's `beforeEnter`, and the zero-step `onFinish` edge case). A
|
|
119
|
+
* tour this `start()` replaced is still on screen, so it is cleared first.
|
|
104
120
|
*/
|
|
105
121
|
private resetToIdle;
|
|
106
122
|
private handleFailure;
|
|
107
123
|
private beginOperation;
|
|
108
124
|
private createStepContext;
|
|
109
|
-
private
|
|
125
|
+
private createStepHookContext;
|
|
110
126
|
private invalidateOperation;
|
|
111
127
|
private signalFor;
|
|
112
128
|
private assertCurrent;
|
|
@@ -132,6 +148,8 @@ export declare class TourController<T> {
|
|
|
132
148
|
private hasEventListeners;
|
|
133
149
|
private emit;
|
|
134
150
|
private notifyEventListener;
|
|
151
|
+
/** Emits the held `tour:start` once, before the first event that can no longer be taken back. */
|
|
152
|
+
private flushTourStart;
|
|
135
153
|
/** Emits `step:leave` for the step being left, with the time spent on it. */
|
|
136
154
|
private emitStepLeave;
|
|
137
155
|
private reportSubscriberError;
|
package/state/focus-guard.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export interface FocusGuardScope {
|
|
|
5
5
|
allowedTarget?: HTMLElement | null;
|
|
6
6
|
allowTargetInteraction?: boolean;
|
|
7
7
|
autoFocus?: boolean;
|
|
8
|
+
/** The caller focuses a control later: keep a focus already in scope until then. */
|
|
9
|
+
deferFocus?: boolean;
|
|
8
10
|
fallback?: HTMLElement | null;
|
|
9
11
|
}
|
|
10
12
|
export declare class FocusGuard {
|
|
@@ -22,7 +24,20 @@ export declare class FocusGuard {
|
|
|
22
24
|
activate(scope: FocusGuardScope): void;
|
|
23
25
|
update(scope: FocusGuardScope): void;
|
|
24
26
|
focus(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Remembers the element focus returns to when the guard deactivates. The driver calls it before
|
|
29
|
+
* making the rest of the page inert, because inerting an ancestor blurs the focused element.
|
|
30
|
+
* Does nothing once a focus is remembered or the guard is active. `pending` is a focus a clear
|
|
31
|
+
* could not give back before this show replaced it, and wins over the current focus.
|
|
32
|
+
*/
|
|
33
|
+
captureInitialFocus(reference: HTMLElement, pending?: HTMLElement | null): void;
|
|
25
34
|
deactivate(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Stops guarding and returns the element focus should go back to, without moving focus. Lets
|
|
37
|
+
* the caller restore it once the page has left `inert`: screen readers ignore focus moved onto
|
|
38
|
+
* content their accessibility tree has not caught up with yet.
|
|
39
|
+
*/
|
|
40
|
+
release(): HTMLElement | null;
|
|
26
41
|
private isAllowed;
|
|
27
42
|
private focusFallback;
|
|
28
43
|
private setFallback;
|
package/types/index.d.ts
CHANGED
|
@@ -16,32 +16,70 @@ export interface TargetResolverContext {
|
|
|
16
16
|
}
|
|
17
17
|
/** Configures step-level interaction behavior and error handling. */
|
|
18
18
|
export interface StepBehavior {
|
|
19
|
-
/** Allow user interaction with the page
|
|
19
|
+
/** Allow user interaction with the target: the page is no longer inert and pointer events reach the target through the cutout, while the dimmed area still catches clicks. Change it during the step with `context.props.update({ behavior: { allowInteraction } })`. @default false */
|
|
20
20
|
allowInteraction?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
/** Leave the page scrollable while the step is shown; set `false` to lock it. Change it during the step with `context.props.update({ behavior: { allowScroll } })`. @default true */
|
|
22
|
+
allowScroll?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Focus the popover's Advance control (Back when going back) when the step is shown. Set `false`
|
|
25
|
+
* to never move focus during the step: it stays where it is, on the body when a modal step
|
|
26
|
+
* makes the page inert, and placing it is up to you. Focus that leaves the popover and target
|
|
27
|
+
* is still pulled back, and focus returns to where it was when the tour ends. @default true
|
|
28
|
+
*/
|
|
29
|
+
autoFocus?: boolean;
|
|
30
|
+
/** Scroll the target into view when the step is entered. @default true */
|
|
31
|
+
autoScroll?: boolean;
|
|
32
|
+
/** What the step does when its target cannot be found. */
|
|
33
|
+
missingTarget?: MissingTargetOptions;
|
|
27
34
|
/** Scroll behavior options. */
|
|
28
35
|
scroll?: ScrollOptions;
|
|
29
|
-
/** Timeout in ms to wait for target to appear before applying missingTargetStrategy. @default 3000 */
|
|
30
|
-
targetTimeout?: number;
|
|
31
36
|
/**
|
|
32
37
|
* Behavior when the dimmed overlay backdrop (outside the cutout around the
|
|
33
38
|
* target) is clicked: `"advance"` moves to the next step, `"cancel"` ends
|
|
34
39
|
* the tour, `"none"` ignores the click. Has no effect when
|
|
35
|
-
* `allowInteraction` is `true
|
|
36
|
-
* there is no modal backdrop to click.
|
|
40
|
+
* `allowInteraction` is `true`: clicks on the dimmed area are then ignored.
|
|
37
41
|
* @default "none"
|
|
38
42
|
*/
|
|
39
43
|
overlayClick?: "none" | "advance" | "cancel";
|
|
40
44
|
}
|
|
45
|
+
/** How a step handles a target that cannot be found. */
|
|
46
|
+
export interface MissingTargetOptions {
|
|
47
|
+
/**
|
|
48
|
+
* `"wait"` retries until `timeout`, `"skip"` moves past the step, `"error"` fails the tour,
|
|
49
|
+
* `"detached"` shows the popover centered in the viewport over a backdrop that covers the whole
|
|
50
|
+
* screen. A detached step has no pointer and no cutout, does not scroll, keeps the page blocked
|
|
51
|
+
* even when `allowInteraction` is `true`, and binds no `targetEvents`; its `context.target` is the
|
|
52
|
+
* document's `<body>`.
|
|
53
|
+
* @default "error"
|
|
54
|
+
*/
|
|
55
|
+
strategy?: "wait" | "skip" | "error" | "detached";
|
|
56
|
+
/** How long to look for the target with the `"wait"` strategy, in milliseconds. @default 3000 */
|
|
57
|
+
timeout?: number;
|
|
58
|
+
}
|
|
41
59
|
/** Placement directions for positioning the pointer or popover around the target. */
|
|
42
60
|
export type TryOrderOptions = "top" | "bottom" | "left" | "right";
|
|
43
61
|
/** A resolved placement direction, including `"center"` for centered positioning. */
|
|
44
62
|
export type ResolvedPlacement = TryOrderOptions | "center";
|
|
63
|
+
/** One CSS class, or several. A string may hold several space-separated classes. */
|
|
64
|
+
export type ClassValue = string | readonly string[];
|
|
65
|
+
/**
|
|
66
|
+
* Classes added to the tour components while a step is shown, one entry per component.
|
|
67
|
+
*
|
|
68
|
+
* They are added to the classes passed to the component itself, never replacing them. A step's entry
|
|
69
|
+
* overrides the workflow's entry for the same component; the components the step leaves out keep the
|
|
70
|
+
* workflow's classes.
|
|
71
|
+
*/
|
|
72
|
+
export interface TourClassNames {
|
|
73
|
+
overlay?: ClassValue;
|
|
74
|
+
popover?: ClassValue;
|
|
75
|
+
pointer?: ClassValue;
|
|
76
|
+
header?: ClassValue;
|
|
77
|
+
content?: ClassValue;
|
|
78
|
+
footer?: ClassValue;
|
|
79
|
+
advance?: ClassValue;
|
|
80
|
+
previous?: ClassValue;
|
|
81
|
+
cancel?: ClassValue;
|
|
82
|
+
}
|
|
45
83
|
/** Base configuration for animated elements. */
|
|
46
84
|
export interface BaseOptions {
|
|
47
85
|
/** Enable or disable animations. */
|
|
@@ -51,8 +89,8 @@ export interface BaseOptions {
|
|
|
51
89
|
}
|
|
52
90
|
/** Configures the pointer indicator that highlights the target element. */
|
|
53
91
|
export interface IndicatorOptions extends BaseOptions {
|
|
54
|
-
/** Hide the indicator. @default false */
|
|
55
|
-
|
|
92
|
+
/** Hide the indicator. It only shows on steps that allow interaction. @default false */
|
|
93
|
+
hidden?: boolean;
|
|
56
94
|
/** Gap between the target and the indicator in pixels. */
|
|
57
95
|
gap?: number;
|
|
58
96
|
/** Placement preference order when positioning the indicator. @default ["left", "right", "top", "bottom"] */
|
|
@@ -72,7 +110,7 @@ export interface OverlayOptions extends BaseOptions {
|
|
|
72
110
|
/** Configures the arrow that points from the popover to the target. */
|
|
73
111
|
export interface PopoverArrowOptions {
|
|
74
112
|
/** Hide the arrow. @default false */
|
|
75
|
-
|
|
113
|
+
hidden?: boolean;
|
|
76
114
|
/** Color of the arrow (CSS color). */
|
|
77
115
|
color?: string;
|
|
78
116
|
/** Size of the arrow in pixels. @default 12 */
|
|
@@ -90,11 +128,41 @@ export interface PopoverArrowOptions {
|
|
|
90
128
|
*/
|
|
91
129
|
styleNonce?: string;
|
|
92
130
|
/**
|
|
93
|
-
*
|
|
131
|
+
* Inject the built-in arrow `<style>` element. Set `false` to provide the
|
|
94
132
|
* equivalent rules yourself through whatever channel your CSP allows, such
|
|
95
133
|
* as an external stylesheet.
|
|
134
|
+
* @default true
|
|
96
135
|
*/
|
|
97
|
-
|
|
136
|
+
autoStyles?: boolean;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Whether the user may run a tour control. `"enabled"` is the default. New states may be added in
|
|
140
|
+
* a minor version.
|
|
141
|
+
*/
|
|
142
|
+
export type TourControlState = "enabled" | "disabled";
|
|
143
|
+
/** One navigation command: whether the user may run it and the keys that run it. */
|
|
144
|
+
export interface TourControl {
|
|
145
|
+
/**
|
|
146
|
+
* `"disabled"` blocks the command everywhere the tour UI offers it: its button is disabled, and
|
|
147
|
+
* its keys and `overlayClick` do nothing. Navigation through the tour API and the step context
|
|
148
|
+
* stays available. To hide a button, give it a class through `classNames`.
|
|
149
|
+
* @default "enabled"
|
|
150
|
+
*/
|
|
151
|
+
state?: TourControlState;
|
|
152
|
+
/** Keys that run the command while the step is shown. An empty array turns them off. */
|
|
153
|
+
keys?: readonly string[];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The advance, previous and cancel commands. A step's controls override the workflow ones field by
|
|
157
|
+
* field: a step that only sets `advance.state` keeps the workflow's `advance.keys`.
|
|
158
|
+
*/
|
|
159
|
+
export interface TourControls {
|
|
160
|
+
/** @default { state: "enabled", keys: ["Enter", "ArrowRight"] } */
|
|
161
|
+
advance?: TourControl;
|
|
162
|
+
/** @default { state: "enabled", keys: ["ArrowLeft", "Backspace"] } */
|
|
163
|
+
previous?: TourControl;
|
|
164
|
+
/** @default { state: "enabled", keys: ["Escape"] } */
|
|
165
|
+
cancel?: TourControl;
|
|
98
166
|
}
|
|
99
167
|
/** Configures the popover box that displays content for each step. */
|
|
100
168
|
export interface PopoverOptions extends BaseOptions {
|
|
@@ -102,39 +170,8 @@ export interface PopoverOptions extends BaseOptions {
|
|
|
102
170
|
placementTryOrder?: readonly TryOrderOptions[];
|
|
103
171
|
/** Arrow configuration. */
|
|
104
172
|
arrow?: PopoverArrowOptions;
|
|
105
|
-
/** Hide the footer section. @default false */
|
|
106
|
-
hideFooter?: boolean;
|
|
107
|
-
/**
|
|
108
|
-
* Disables only previous-button and previous-keyboard controls. Programmatic
|
|
109
|
-
* navigation through the tour API and step context remains available.
|
|
110
|
-
*/
|
|
111
|
-
disablePreviousButton?: boolean;
|
|
112
|
-
/** Hide the previous button. @default false */
|
|
113
|
-
hidePreviousButton?: boolean;
|
|
114
|
-
/**
|
|
115
|
-
* Disables only advance-button and advance-keyboard controls. Programmatic
|
|
116
|
-
* navigation through the tour API and step context remains available.
|
|
117
|
-
*/
|
|
118
|
-
disableAdvanceButton?: boolean;
|
|
119
|
-
/** Hide the advance button. @default false */
|
|
120
|
-
hideAdvanceButton?: boolean;
|
|
121
173
|
/** Gap between the target and the popover in pixels. @default 16 */
|
|
122
174
|
gap?: number;
|
|
123
|
-
/** Keyboard shortcuts for navigation. */
|
|
124
|
-
keyboardShortcuts?: {
|
|
125
|
-
/**
|
|
126
|
-
* Keys that trigger previous step. @default ["ArrowLeft", "Backspace"]
|
|
127
|
-
*/
|
|
128
|
-
previous?: readonly string[];
|
|
129
|
-
/**
|
|
130
|
-
* Keys that trigger advance step. @default ["Enter", "ArrowRight"]
|
|
131
|
-
*/
|
|
132
|
-
advance?: readonly string[];
|
|
133
|
-
/**
|
|
134
|
-
* Keys that trigger cancel. @default ["Escape"]
|
|
135
|
-
*/
|
|
136
|
-
cancel?: readonly string[];
|
|
137
|
-
};
|
|
138
175
|
}
|
|
139
176
|
/**
|
|
140
177
|
* Scroll behavior options passed to Element.scrollIntoView().
|
|
@@ -165,8 +202,8 @@ export interface AnimationOptions {
|
|
|
165
202
|
export interface LifecycleHookContext<T> {
|
|
166
203
|
/**
|
|
167
204
|
* The step associated with this lifecycle transition:
|
|
168
|
-
* - `onStart`: the
|
|
169
|
-
* `null` if the workflow has no steps.
|
|
205
|
+
* - `onStart`: the step `start()` starts on (the `startAt` step, or the first
|
|
206
|
+
* step), or `null` if the workflow has no steps.
|
|
170
207
|
* - `onCancel`: the step the tour is currently on when cancellation is
|
|
171
208
|
* requested. Always non-null in practice, since a step is always active
|
|
172
209
|
* at the point a tour can be cancelled.
|
|
@@ -190,15 +227,6 @@ export interface LifecycleHookContext<T> {
|
|
|
190
227
|
}
|
|
191
228
|
/** Options for starting a tour workflow. */
|
|
192
229
|
export interface StartOptions<T> {
|
|
193
|
-
/** Allow users to cancel the tour. @default true */
|
|
194
|
-
cancellable?: boolean;
|
|
195
|
-
/**
|
|
196
|
-
* Leaves page scroll available while the tour is active. Set `false` to lock
|
|
197
|
-
* scroll instead, restoring it on finish, cancel, error, or dispose.
|
|
198
|
-
*
|
|
199
|
-
* @default true
|
|
200
|
-
*/
|
|
201
|
-
allowScroll?: boolean;
|
|
202
230
|
/** Default overlay options for all steps. */
|
|
203
231
|
overlay?: OverlayOptions;
|
|
204
232
|
/** Default popover options for all steps. */
|
|
@@ -209,6 +237,10 @@ export interface StartOptions<T> {
|
|
|
209
237
|
animated?: boolean;
|
|
210
238
|
/** Default step behavior for all steps. */
|
|
211
239
|
behavior?: StepBehavior;
|
|
240
|
+
/** Default controls for all steps. See `TourControls`. */
|
|
241
|
+
controls?: TourControls;
|
|
242
|
+
/** Classes added to the tour components on every step. See `TourClassNames`. */
|
|
243
|
+
classNames?: TourClassNames;
|
|
212
244
|
/** Lifecycle hook called when the tour starts. */
|
|
213
245
|
onStart?: (context: LifecycleHookContext<T>) => void | Promise<void>;
|
|
214
246
|
/** Lifecycle hook called when the tour is cancelled. */
|
|
@@ -225,12 +257,22 @@ export interface StartOptions<T> {
|
|
|
225
257
|
}
|
|
226
258
|
/** Update to step properties, either as a full replacement or via a function. */
|
|
227
259
|
export type StepPropsUpdate<T> = ReadonlyStepProps<T> | ((current: ReadonlyStepProps<T>) => ReadonlyStepProps<T>);
|
|
260
|
+
/**
|
|
261
|
+
* Partial change to step properties, for `StepPropsStore.update`. Fields it leaves out are kept.
|
|
262
|
+
* `data` is merged key by key; `overlay`, `popover`, `indicator`, `behavior` and `controls` are
|
|
263
|
+
* merged the way step options merge over workflow defaults; arrays such as `placementTryOrder` or
|
|
264
|
+
* `keys` are replaced. `classNames` is merged per component: a component it names gets exactly the
|
|
265
|
+
* classes given.
|
|
266
|
+
*/
|
|
267
|
+
export type StepPropsPatch<T> = Partial<ReadonlyStepProps<T>>;
|
|
228
268
|
/** Store for the current step's properties. */
|
|
229
269
|
export interface StepPropsStore<T> {
|
|
230
270
|
/** Get the current step properties. */
|
|
231
271
|
get(): ReadonlyStepProps<T>;
|
|
232
|
-
/**
|
|
272
|
+
/** Replace the current step properties. */
|
|
233
273
|
set(update: StepPropsUpdate<T>): void;
|
|
274
|
+
/** Merge a partial change into the current step properties. See `StepPropsPatch`. */
|
|
275
|
+
update(patch: StepPropsPatch<T> | ((current: ReadonlyStepProps<T>) => StepPropsPatch<T>)): void;
|
|
234
276
|
/** Subscribe to changes in step properties. Returns an unsubscribe function. */
|
|
235
277
|
subscribe(listener: (props: ReadonlyStepProps<T>) => void): () => void;
|
|
236
278
|
}
|
|
@@ -242,17 +284,39 @@ export interface StepContext<T> {
|
|
|
242
284
|
cancel(): Promise<void>;
|
|
243
285
|
/** Navigate to the previous step. */
|
|
244
286
|
previous(): Promise<void>;
|
|
245
|
-
/**
|
|
287
|
+
/**
|
|
288
|
+
* Navigate to the step with this id, skipping the steps in between. Stops the remaining actions
|
|
289
|
+
* of this step, like `advance()`. Throws when no step has this id.
|
|
290
|
+
*/
|
|
291
|
+
goTo(id: string): Promise<void>;
|
|
292
|
+
/**
|
|
293
|
+
* The direction of the navigation that entered this step. Captured when the context is created, so
|
|
294
|
+
* it does not change while the step's callbacks run.
|
|
295
|
+
*/
|
|
296
|
+
readonly direction: TourDirection;
|
|
297
|
+
/** The step properties as initially configured, before any `props.set()`. */
|
|
298
|
+
readonly initialProps: ReadonlyStepProps<T>;
|
|
299
|
+
/** The DOM element being highlighted for this step, or the document's `<body>` for a detached step. */
|
|
246
300
|
readonly target: HTMLElement;
|
|
247
301
|
/** Store for reading and updating the current step's properties. */
|
|
248
302
|
readonly props: StepPropsStore<T>;
|
|
249
303
|
/** Signal that aborts when the step is exited or the tour is cancelled. */
|
|
250
304
|
readonly signal: AbortSignal;
|
|
251
305
|
}
|
|
252
|
-
/**
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
306
|
+
/**
|
|
307
|
+
* Context passed to the `beforeEnter` and `beforeLeave` step hooks. It has no navigation methods:
|
|
308
|
+
* a transition is already in progress when these hooks run. `direction` is the direction of that
|
|
309
|
+
* navigation, so the step being left and the step being entered see the same value.
|
|
310
|
+
*/
|
|
311
|
+
export interface StepHookContext<T> extends Omit<StepContext<T>, "advance" | "cancel" | "goTo" | "previous"> {
|
|
312
|
+
/**
|
|
313
|
+
* Call it synchronously, or before the hook's returned promise resolves, to stop the navigation.
|
|
314
|
+
* The tour stays on the step it was on and emits nothing: `beforeLeave` keeps the step, and
|
|
315
|
+
* `beforeEnter` does not show the next one. When `beforeEnter` aborts the first step of `start()`,
|
|
316
|
+
* the tour goes back to `idle`, like an `onStart` abort.
|
|
317
|
+
*/
|
|
318
|
+
abort(): void;
|
|
319
|
+
}
|
|
256
320
|
/** Context passed to target event handlers. */
|
|
257
321
|
export type StepEventContext<T> = StepContext<T>;
|
|
258
322
|
/** Options for the waitUntil step action. */
|
|
@@ -268,16 +332,16 @@ export type StepActionResult = boolean | void;
|
|
|
268
332
|
export type StepAction<T> = (context: StepContext<T>) => Promise<StepActionResult> | StepActionResult;
|
|
269
333
|
/** A step action or a delay in milliseconds. */
|
|
270
334
|
export type StepActionInstruction<T> = StepAction<T> | number;
|
|
271
|
-
/** A callback that runs before
|
|
272
|
-
export type
|
|
335
|
+
/** A callback that runs before a step is entered or left (`beforeEnter` / `beforeLeave`). */
|
|
336
|
+
export type StepHookAction<T> = (context: StepHookContext<T>) => void | Promise<void>;
|
|
273
337
|
/** Handler for an event fired on the target element during a step. */
|
|
274
|
-
export interface
|
|
338
|
+
export interface TargetEventHandler<TStepProps, TEvent extends Event = Event> {
|
|
275
339
|
/** Event name(s) to listen for. */
|
|
276
340
|
event: string;
|
|
277
341
|
/** Callback invoked when the event fires. */
|
|
278
342
|
callback: (event: TEvent, context: StepEventContext<TStepProps>) => void | Promise<void>;
|
|
279
343
|
}
|
|
280
|
-
/** Tour lifecycle status. */
|
|
344
|
+
/** Tour lifecycle status. New statuses may be added in a minor release: keep a default branch when switching over it. */
|
|
281
345
|
export type TourStatus = "idle" | "starting" | "transitioning" | "active" | "finished" | "cancelled" | "error" | "disposed";
|
|
282
346
|
/** Direction of tour navigation. */
|
|
283
347
|
export type TourDirection = "advance" | "previous";
|
|
@@ -331,13 +395,16 @@ export interface GlowTour<T> {
|
|
|
331
395
|
/** Create a new workflow builder with the given name. */
|
|
332
396
|
create(name: string, options?: StartOptions<T>): WorkflowBuilder<T>;
|
|
333
397
|
/** Run a workflow, optionally starting at a specific step. */
|
|
334
|
-
|
|
398
|
+
start(workflow: WorkflowDefinition<T>, options?: RunOptions): Promise<void>;
|
|
335
399
|
/** Advance to the next step. */
|
|
336
400
|
advance(): Promise<void>;
|
|
337
401
|
/** Go to the previous step. */
|
|
338
402
|
previous(): Promise<void>;
|
|
339
|
-
/**
|
|
340
|
-
|
|
403
|
+
/**
|
|
404
|
+
* Go to the step with this id, skipping the steps in between. Does nothing while a transition is
|
|
405
|
+
* in progress or when that step is already shown. Throws when no step has this id.
|
|
406
|
+
*/
|
|
407
|
+
goTo(id: string): Promise<void>;
|
|
341
408
|
/** Cancel the current tour. */
|
|
342
409
|
cancel(): Promise<void>;
|
|
343
410
|
/** Dispose the tour and free resources. */
|
|
@@ -346,7 +413,7 @@ export interface GlowTour<T> {
|
|
|
346
413
|
readonly state: ReadonlyTourState<T>;
|
|
347
414
|
}
|
|
348
415
|
/**
|
|
349
|
-
* Per-run options. Unlike `StartOptions`, these belong to one `
|
|
416
|
+
* Per-run options. Unlike `StartOptions`, these belong to one `start()` call and
|
|
350
417
|
* are never baked into the reusable workflow definition.
|
|
351
418
|
*/
|
|
352
419
|
export interface RunOptions {
|
|
@@ -365,13 +432,15 @@ export interface RunOptions {
|
|
|
365
432
|
/**
|
|
366
433
|
* What triggered a transition.
|
|
367
434
|
*
|
|
368
|
-
* `"api"` covers every call your own code makes
|
|
369
|
-
* `
|
|
370
|
-
*
|
|
435
|
+
* `"api"` covers every call your own code makes: `advance()`, `previous()`,
|
|
436
|
+
* `goTo()`, `cancel()`, and the same methods on the context of a step action.
|
|
437
|
+
* The other three are the user acting on the tour UI directly.
|
|
438
|
+
*
|
|
439
|
+
* New sources may be added in a minor release: keep a default branch when switching over it.
|
|
371
440
|
*/
|
|
372
441
|
export type TourEventSource = "api" | "trigger" | "keyboard" | "overlay";
|
|
373
|
-
/** Name of a monitoring event. */
|
|
374
|
-
export type TourEventType = "tour:start" | "step:enter" | "step:leave" | "tour:complete" | "tour:cancel" | "tour:error";
|
|
442
|
+
/** Name of a monitoring event. New events may be added in a minor release: keep a default branch when switching over it. */
|
|
443
|
+
export type TourEventType = "tour:start" | "step:enter" | "step:leave" | "step:skip" | "tour:complete" | "tour:cancel" | "tour:error";
|
|
375
444
|
/**
|
|
376
445
|
* A monitoring event, as handed to `onEvent`.
|
|
377
446
|
*
|
|
@@ -402,7 +471,7 @@ export interface TourEvent {
|
|
|
402
471
|
* How long the thing this event names had been running, in milliseconds.
|
|
403
472
|
*
|
|
404
473
|
* For `step:leave`, the time spent on that step. For `tour:complete`,
|
|
405
|
-
* `tour:cancel` and `tour:error`, the time since `
|
|
474
|
+
* `tour:cancel` and `tour:error`, the time since `start()` was called. For
|
|
406
475
|
* `tour:start` and `step:enter` — the beginnings — always `0`.
|
|
407
476
|
*/
|
|
408
477
|
readonly durationMs: number;
|
|
@@ -444,11 +513,6 @@ export type StepParameters<T> = {
|
|
|
444
513
|
id: string;
|
|
445
514
|
/** The target element or selector for this step. */
|
|
446
515
|
target: TargetResolver;
|
|
447
|
-
/**
|
|
448
|
-
* Reset step properties to initial values when entering this step.
|
|
449
|
-
* @default true
|
|
450
|
-
*/
|
|
451
|
-
resetPropsOnEnter?: boolean;
|
|
452
516
|
/** Overlay options for this step (overrides workflow defaults). */
|
|
453
517
|
overlay?: OverlayOptions;
|
|
454
518
|
/** Popover options for this step (overrides workflow defaults). */
|
|
@@ -457,8 +521,12 @@ export type StepParameters<T> = {
|
|
|
457
521
|
indicator?: IndicatorOptions;
|
|
458
522
|
/** Step behavior (overrides workflow defaults). */
|
|
459
523
|
behavior?: StepBehavior;
|
|
460
|
-
/**
|
|
461
|
-
|
|
524
|
+
/** Navigation controls for this step (overrides workflow defaults field by field). See `TourControls`. */
|
|
525
|
+
controls?: TourControls;
|
|
526
|
+
/** Classes added to the tour components on this step (overrides workflow defaults per component). See `TourClassNames`. */
|
|
527
|
+
classNames?: TourClassNames;
|
|
528
|
+
/** The title content for this step. Without a title, the popover is named by its content. */
|
|
529
|
+
title?: T;
|
|
462
530
|
/** The body content for this step. */
|
|
463
531
|
content: T;
|
|
464
532
|
/** Arbitrary data associated with this step. */
|
package/utils/options.d.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { DeepReadonly, ReadonlyStepProps } from "../definition";
|
|
2
|
+
import type { AnimationOptions, IndicatorOptions, OverlayOptions, PopoverOptions, ScrollOptions, StepBehavior, StepPropsPatch, TourControls } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Merges a partial change into step props: fields it leaves out are kept, `data` is merged key by
|
|
5
|
+
* key, `overlay` / `popover` / `indicator` / `behavior` / `controls` go through their option merges,
|
|
6
|
+
* `classNames` is merged per component, and arrays are replaced.
|
|
7
|
+
* Builds a step's initial props over the workflow defaults, and backs `StepPropsStore.update`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function mergeStepProps<T>(base: StepPropsPatch<T>, patch: StepPropsPatch<T>): ReadonlyStepProps<T>;
|
|
2
10
|
export declare function mergeOverlayOptions(defaults?: OverlayOptions, overrides?: OverlayOptions): OverlayOptions | undefined;
|
|
3
11
|
export declare function mergeIndicatorOptions(defaults?: IndicatorOptions, overrides?: IndicatorOptions): IndicatorOptions | undefined;
|
|
4
12
|
export declare function mergePopoverOptions(defaults?: PopoverOptions, overrides?: PopoverOptions): PopoverOptions | undefined;
|
|
5
13
|
export declare function mergeScrollOptions(defaults?: ScrollOptions, overrides?: ScrollOptions): ScrollOptions | undefined;
|
|
6
14
|
export declare function mergeAnimationOptions(defaults?: AnimationOptions, overrides?: AnimationOptions): AnimationOptions | undefined;
|
|
7
15
|
export declare function mergeStepBehavior(defaults?: StepBehavior, overrides?: StepBehavior): StepBehavior | undefined;
|
|
16
|
+
/** Whether a control is enabled, so its button, keys and `overlayClick` may run its command. */
|
|
17
|
+
export declare function isControlAvailable(props: {
|
|
18
|
+
readonly controls?: DeepReadonly<TourControls>;
|
|
19
|
+
} | undefined, command: "advance" | "previous" | "cancel"): boolean;
|