@matthesketh/react-guidetour 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.
package/dist/index.js ADDED
@@ -0,0 +1,2168 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.tsx
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ ACTIONS: () => ACTIONS,
34
+ EVENTS: () => EVENTS,
35
+ LIFECYCLE: () => LIFECYCLE,
36
+ ORIGIN: () => ORIGIN,
37
+ STATUS: () => STATUS,
38
+ default: () => components_default
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/literals/index.ts
43
+ var ACTIONS = {
44
+ INIT: "init",
45
+ START: "start",
46
+ STOP: "stop",
47
+ RESET: "reset",
48
+ PREV: "prev",
49
+ NEXT: "next",
50
+ GO: "go",
51
+ CLOSE: "close",
52
+ SKIP: "skip",
53
+ UPDATE: "update"
54
+ };
55
+ var EVENTS = {
56
+ TOUR_START: "tour:start",
57
+ STEP_BEFORE: "step:before",
58
+ BEACON: "beacon",
59
+ TOOLTIP: "tooltip",
60
+ STEP_AFTER: "step:after",
61
+ TOUR_END: "tour:end",
62
+ TOUR_STATUS: "tour:status",
63
+ TARGET_NOT_FOUND: "error:target_not_found",
64
+ ERROR: "error"
65
+ };
66
+ var LIFECYCLE = {
67
+ INIT: "init",
68
+ READY: "ready",
69
+ BEACON: "beacon",
70
+ TOOLTIP: "tooltip",
71
+ COMPLETE: "complete",
72
+ ERROR: "error"
73
+ };
74
+ var ORIGIN = {
75
+ BUTTON_CLOSE: "button_close",
76
+ BUTTON_PRIMARY: "button_primary",
77
+ KEYBOARD: "keyboard",
78
+ OVERLAY: "overlay"
79
+ };
80
+ var STATUS = {
81
+ IDLE: "idle",
82
+ READY: "ready",
83
+ WAITING: "waiting",
84
+ RUNNING: "running",
85
+ PAUSED: "paused",
86
+ SKIPPED: "skipped",
87
+ FINISHED: "finished",
88
+ ERROR: "error"
89
+ };
90
+
91
+ // src/components/index.tsx
92
+ var import_react6 = require("react");
93
+ var import_deep_equal = __toESM(require("@gilbarbara/deep-equal"));
94
+ var import_is_lite6 = __toESM(require("is-lite"));
95
+ var import_tree_changes3 = __toESM(require("tree-changes"));
96
+
97
+ // src/modules/dom.ts
98
+ var import_scroll = __toESM(require("scroll"));
99
+ var import_scrollparent = __toESM(require("scrollparent"));
100
+ function canUseDOM() {
101
+ var _a;
102
+ return !!(typeof window !== "undefined" && ((_a = window.document) == null ? void 0 : _a.createElement));
103
+ }
104
+ function getClientRect(element) {
105
+ if (!element) {
106
+ return null;
107
+ }
108
+ return element.getBoundingClientRect();
109
+ }
110
+ function getDocumentHeight(median = false) {
111
+ const { body, documentElement } = document;
112
+ if (!body || !documentElement) {
113
+ return 0;
114
+ }
115
+ if (median) {
116
+ const heights = [
117
+ body.scrollHeight,
118
+ body.offsetHeight,
119
+ documentElement.clientHeight,
120
+ documentElement.scrollHeight,
121
+ documentElement.offsetHeight
122
+ ].sort((a, b) => a - b);
123
+ const middle = Math.floor(heights.length / 2);
124
+ if (heights.length % 2 === 0) {
125
+ return (heights[middle - 1] + heights[middle]) / 2;
126
+ }
127
+ return heights[middle];
128
+ }
129
+ return Math.max(
130
+ body.scrollHeight,
131
+ body.offsetHeight,
132
+ documentElement.clientHeight,
133
+ documentElement.scrollHeight,
134
+ documentElement.offsetHeight
135
+ );
136
+ }
137
+ function getElement(element) {
138
+ if (typeof element === "string") {
139
+ try {
140
+ return document.querySelector(element);
141
+ } catch (error) {
142
+ if (process.env.NODE_ENV !== "production") {
143
+ console.error(error);
144
+ }
145
+ return null;
146
+ }
147
+ }
148
+ return element;
149
+ }
150
+ function getStyleComputedProperty(el) {
151
+ if (!el || el.nodeType !== 1) {
152
+ return null;
153
+ }
154
+ return getComputedStyle(el);
155
+ }
156
+ function getScrollParent(element, skipFix, forListener) {
157
+ if (!element) {
158
+ return scrollDocument();
159
+ }
160
+ const parent = (0, import_scrollparent.default)(element);
161
+ if (parent) {
162
+ if (parent.isSameNode(scrollDocument())) {
163
+ if (forListener) {
164
+ return document;
165
+ }
166
+ return scrollDocument();
167
+ }
168
+ const hasScrolling = parent.scrollHeight > parent.offsetHeight;
169
+ if (!hasScrolling && !skipFix) {
170
+ parent.style.overflow = "initial";
171
+ return scrollDocument();
172
+ }
173
+ }
174
+ return parent;
175
+ }
176
+ function hasCustomScrollParent(element, skipFix) {
177
+ if (!element) {
178
+ return false;
179
+ }
180
+ const parent = getScrollParent(element, skipFix);
181
+ return parent ? !parent.isSameNode(scrollDocument()) : false;
182
+ }
183
+ function hasCustomOffsetParent(element) {
184
+ return element.offsetParent !== document.body;
185
+ }
186
+ function hasPosition(el, type = "fixed") {
187
+ if (!el || !(el instanceof HTMLElement)) {
188
+ return false;
189
+ }
190
+ const { nodeName } = el;
191
+ const styles = getStyleComputedProperty(el);
192
+ if (nodeName === "BODY" || nodeName === "HTML") {
193
+ return false;
194
+ }
195
+ if (styles && styles.position === type) {
196
+ return true;
197
+ }
198
+ if (!el.parentNode) {
199
+ return false;
200
+ }
201
+ return hasPosition(el.parentNode, type);
202
+ }
203
+ function isElementVisible(element) {
204
+ var _a;
205
+ if (!element) {
206
+ return false;
207
+ }
208
+ let parentElement = element;
209
+ while (parentElement) {
210
+ if (parentElement === document.body) {
211
+ break;
212
+ }
213
+ if (parentElement instanceof HTMLElement) {
214
+ const { display, visibility } = getComputedStyle(parentElement);
215
+ if (display === "none" || visibility === "hidden") {
216
+ return false;
217
+ }
218
+ }
219
+ parentElement = (_a = parentElement.parentElement) != null ? _a : null;
220
+ }
221
+ return true;
222
+ }
223
+ function getElementPosition(element, offset, skipFix) {
224
+ var _a, _b, _c;
225
+ const elementRect = getClientRect(element);
226
+ const parent = getScrollParent(element, skipFix);
227
+ const hasScrollParent = hasCustomScrollParent(element, skipFix);
228
+ const isFixedTarget = hasPosition(element);
229
+ let parentTop = 0;
230
+ let top = (_a = elementRect == null ? void 0 : elementRect.top) != null ? _a : 0;
231
+ if (hasScrollParent && isFixedTarget) {
232
+ const offsetTop = (_b = element == null ? void 0 : element.offsetTop) != null ? _b : 0;
233
+ const parentScrollTop = (_c = parent == null ? void 0 : parent.scrollTop) != null ? _c : 0;
234
+ top = offsetTop - parentScrollTop;
235
+ } else if (parent instanceof HTMLElement) {
236
+ parentTop = parent.scrollTop;
237
+ if (!hasScrollParent && !hasPosition(element)) {
238
+ top += parentTop;
239
+ }
240
+ if (!parent.isSameNode(scrollDocument())) {
241
+ top += scrollDocument().scrollTop;
242
+ }
243
+ }
244
+ return Math.floor(top - offset);
245
+ }
246
+ function getScrollTo(element, offset, skipFix) {
247
+ var _a;
248
+ if (!element) {
249
+ return 0;
250
+ }
251
+ const { offsetTop = 0, scrollTop = 0 } = (_a = (0, import_scrollparent.default)(element)) != null ? _a : {};
252
+ let top = element.getBoundingClientRect().top + scrollTop;
253
+ if (!!offsetTop && (hasCustomScrollParent(element, skipFix) || hasCustomOffsetParent(element))) {
254
+ top -= offsetTop;
255
+ }
256
+ const output = Math.floor(top - offset);
257
+ return output < 0 ? 0 : output;
258
+ }
259
+ function scrollDocument() {
260
+ var _a;
261
+ return (_a = document.scrollingElement) != null ? _a : document.documentElement;
262
+ }
263
+ function scrollTo(value, options) {
264
+ const { duration, element } = options;
265
+ return new Promise((resolve, reject) => {
266
+ const { scrollTop } = element;
267
+ const limit = value > scrollTop ? value - scrollTop : scrollTop - value;
268
+ import_scroll.default.top(element, value, { duration: limit < 100 ? 50 : duration }, (error) => {
269
+ if (error && error.message !== "Element already at target scroll position") {
270
+ return reject(error);
271
+ }
272
+ return resolve();
273
+ });
274
+ });
275
+ }
276
+
277
+ // src/modules/helpers.tsx
278
+ var import_react = require("react");
279
+ var import_react_innertext = __toESM(require("react-innertext"));
280
+ var import_is_lite = __toESM(require("is-lite"));
281
+ function isSafari() {
282
+ if (typeof window === "undefined" || typeof navigator === "undefined") {
283
+ return false;
284
+ }
285
+ return /(Version\/([\d._]+).*Safari|CriOS|FxiOS| Mobile\/)/.test(navigator.userAgent);
286
+ }
287
+ function getObjectType(value) {
288
+ return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
289
+ }
290
+ function getReactNodeText(input, options = {}) {
291
+ const { defaultValue, step, steps } = options;
292
+ let text = (0, import_react_innertext.default)(input);
293
+ if (!text) {
294
+ if ((0, import_react.isValidElement)(input) && !Object.values(input.props).length && getObjectType(input.type) === "function") {
295
+ const component = input.type({});
296
+ text = getReactNodeText(component, options);
297
+ } else {
298
+ text = (0, import_react_innertext.default)(defaultValue);
299
+ }
300
+ } else if ((text.includes("{step}") || text.includes("{steps}")) && step && steps) {
301
+ text = text.replace("{step}", step.toString()).replace("{steps}", steps.toString());
302
+ }
303
+ return text;
304
+ }
305
+ function hasValidKeys(object, keys) {
306
+ if (!import_is_lite.default.plainObject(object) || !import_is_lite.default.array(keys)) {
307
+ return false;
308
+ }
309
+ return Object.keys(object).every((d) => keys.includes(d));
310
+ }
311
+ function hexToRGB(hex) {
312
+ const shorthandRegex = /^#?([\da-f])([\da-f])([\da-f])$/i;
313
+ const properHex = hex.replace(shorthandRegex, (_m, r, g, b) => r + r + g + g + b + b);
314
+ const result = /^#?([\da-f]{2})([\da-f]{2})([\da-f]{2})$/i.exec(properHex);
315
+ return result ? [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)] : [];
316
+ }
317
+ function hideBeacon(step) {
318
+ return step.disableBeacon || step.placement === "center";
319
+ }
320
+ function log({ data, debug = false, title, warn = false }) {
321
+ const logFn = warn ? console.warn || console.error : console.log;
322
+ if (debug) {
323
+ if (title && data) {
324
+ console.groupCollapsed(
325
+ `%creact-guidetour: ${title}`,
326
+ "color: #ff0044; font-weight: bold; font-size: 12px;"
327
+ );
328
+ if (Array.isArray(data)) {
329
+ data.forEach((d) => {
330
+ if (import_is_lite.default.plainObject(d) && d.key) {
331
+ logFn.apply(console, [d.key, d.value]);
332
+ } else {
333
+ logFn.apply(console, [d]);
334
+ }
335
+ });
336
+ } else {
337
+ logFn.apply(console, [data]);
338
+ }
339
+ console.groupEnd();
340
+ } else {
341
+ console.error("Missing title or data props");
342
+ }
343
+ }
344
+ }
345
+ function noop() {
346
+ return void 0;
347
+ }
348
+ function objectKeys(input) {
349
+ return Object.keys(input);
350
+ }
351
+ function omit(input, ...filter) {
352
+ if (!import_is_lite.default.plainObject(input)) {
353
+ throw new TypeError("Expected an object");
354
+ }
355
+ const output = {};
356
+ for (const key in input) {
357
+ if ({}.hasOwnProperty.call(input, key)) {
358
+ if (!filter.includes(key)) {
359
+ output[key] = input[key];
360
+ }
361
+ }
362
+ }
363
+ return output;
364
+ }
365
+ function pick(input, ...filter) {
366
+ if (!import_is_lite.default.plainObject(input)) {
367
+ throw new TypeError("Expected an object");
368
+ }
369
+ if (!filter.length) {
370
+ return input;
371
+ }
372
+ const output = {};
373
+ for (const key in input) {
374
+ if ({}.hasOwnProperty.call(input, key)) {
375
+ if (filter.includes(key)) {
376
+ output[key] = input[key];
377
+ }
378
+ }
379
+ }
380
+ return output;
381
+ }
382
+ function replaceLocaleContent(input, step, steps) {
383
+ const replacer = (text) => text.replace("{step}", String(step)).replace("{steps}", String(steps));
384
+ if (getObjectType(input) === "string") {
385
+ return replacer(input);
386
+ }
387
+ if (!(0, import_react.isValidElement)(input)) {
388
+ return input;
389
+ }
390
+ const { children } = input.props;
391
+ if (getObjectType(children) === "string" && children.includes("{step}")) {
392
+ return (0, import_react.cloneElement)(input, {
393
+ children: replacer(children)
394
+ });
395
+ }
396
+ if (Array.isArray(children)) {
397
+ return (0, import_react.cloneElement)(input, {
398
+ children: children.map((child) => {
399
+ if (typeof child === "string") {
400
+ return replacer(child);
401
+ }
402
+ return replaceLocaleContent(child, step, steps);
403
+ })
404
+ });
405
+ }
406
+ if (getObjectType(input.type) === "function" && !Object.values(input.props).length) {
407
+ const component = input.type({});
408
+ return replaceLocaleContent(component, step, steps);
409
+ }
410
+ return input;
411
+ }
412
+ function shouldScroll(options) {
413
+ const { isFirstStep, lifecycle, previousLifecycle, scrollToFirstStep, step, target } = options;
414
+ return !step.disableScrolling && (!isFirstStep || scrollToFirstStep || lifecycle === LIFECYCLE.TOOLTIP) && step.placement !== "center" && (!step.isFixed || !hasPosition(target)) && // fixed steps don't need to scroll
415
+ previousLifecycle !== lifecycle && [LIFECYCLE.BEACON, LIFECYCLE.TOOLTIP].includes(lifecycle);
416
+ }
417
+
418
+ // src/modules/step.ts
419
+ var import_deepmerge2 = __toESM(require("deepmerge"));
420
+ var import_is_lite2 = __toESM(require("is-lite"));
421
+
422
+ // src/defaults.ts
423
+ var defaultFloaterProps = {
424
+ wrapperOptions: {
425
+ offset: -18,
426
+ position: true
427
+ }
428
+ };
429
+ var defaultLocale = {
430
+ back: "Back",
431
+ close: "Close",
432
+ last: "Last",
433
+ next: "Next",
434
+ nextLabelWithProgress: "Next (Step {step} of {steps})",
435
+ open: "Open the dialog",
436
+ skip: "Skip"
437
+ };
438
+ var defaultStep = {
439
+ event: "click",
440
+ placement: "bottom",
441
+ offset: 10,
442
+ disableBeacon: false,
443
+ disableCloseOnEsc: false,
444
+ disableOverlay: false,
445
+ disableOverlayClose: false,
446
+ disableScrollParentFix: false,
447
+ disableScrolling: false,
448
+ hideBackButton: false,
449
+ hideCloseButton: false,
450
+ hideFooter: false,
451
+ isFixed: false,
452
+ locale: defaultLocale,
453
+ showProgress: false,
454
+ showSkipButton: false,
455
+ spotlightClicks: false,
456
+ spotlightPadding: 10
457
+ };
458
+ var defaultProps = {
459
+ continuous: false,
460
+ debug: false,
461
+ disableCloseOnEsc: false,
462
+ disableOverlay: false,
463
+ disableOverlayClose: false,
464
+ disableScrolling: false,
465
+ disableScrollParentFix: false,
466
+ getHelpers: noop(),
467
+ hideBackButton: false,
468
+ run: true,
469
+ scrollOffset: 20,
470
+ scrollDuration: 300,
471
+ scrollToFirstStep: false,
472
+ showSkipButton: false,
473
+ showProgress: false,
474
+ spotlightClicks: false,
475
+ spotlightPadding: 10,
476
+ steps: []
477
+ };
478
+
479
+ // src/styles.ts
480
+ var import_deepmerge = __toESM(require("deepmerge"));
481
+ var defaultOptions = {
482
+ arrowColor: "#fff",
483
+ backgroundColor: "#fff",
484
+ beaconSize: 36,
485
+ overlayColor: "rgba(0, 0, 0, 0.5)",
486
+ primaryColor: "#f04",
487
+ spotlightShadow: "0 0 15px rgba(0, 0, 0, 0.5)",
488
+ textColor: "#333",
489
+ width: 380,
490
+ zIndex: 100
491
+ };
492
+ var buttonBase = {
493
+ backgroundColor: "transparent",
494
+ border: 0,
495
+ borderRadius: 0,
496
+ color: "#555",
497
+ cursor: "pointer",
498
+ fontSize: 16,
499
+ lineHeight: 1,
500
+ padding: 8,
501
+ WebkitAppearance: "none"
502
+ };
503
+ var spotlight = {
504
+ borderRadius: 4,
505
+ position: "absolute"
506
+ };
507
+ function getStyles(props, step) {
508
+ var _a, _b, _c, _d, _e;
509
+ const { floaterProps, styles } = props;
510
+ const mergedFloaterProps = (0, import_deepmerge.default)((_a = step.floaterProps) != null ? _a : {}, floaterProps != null ? floaterProps : {});
511
+ const mergedStyles = (0, import_deepmerge.default)(styles != null ? styles : {}, (_b = step.styles) != null ? _b : {});
512
+ const options = (0, import_deepmerge.default)(defaultOptions, mergedStyles.options || {});
513
+ const hideBeacon2 = step.placement === "center" || step.disableBeacon;
514
+ let { width } = options;
515
+ if (window.innerWidth > 480) {
516
+ width = 380;
517
+ }
518
+ if ("width" in options) {
519
+ width = typeof options.width === "number" && window.innerWidth < options.width ? window.innerWidth - 30 : options.width;
520
+ }
521
+ const overlay = {
522
+ bottom: 0,
523
+ left: 0,
524
+ overflow: "hidden",
525
+ position: "absolute",
526
+ right: 0,
527
+ top: 0,
528
+ zIndex: options.zIndex
529
+ };
530
+ const defaultStyles = {
531
+ beacon: {
532
+ ...buttonBase,
533
+ display: hideBeacon2 ? "none" : "inline-block",
534
+ height: options.beaconSize,
535
+ position: "relative",
536
+ width: options.beaconSize,
537
+ zIndex: options.zIndex
538
+ },
539
+ beaconInner: {
540
+ animation: "joyride-beacon-inner 1.2s infinite ease-in-out",
541
+ backgroundColor: options.primaryColor,
542
+ borderRadius: "50%",
543
+ display: "block",
544
+ height: "50%",
545
+ left: "50%",
546
+ opacity: 0.7,
547
+ position: "absolute",
548
+ top: "50%",
549
+ transform: "translate(-50%, -50%)",
550
+ width: "50%"
551
+ },
552
+ beaconOuter: {
553
+ animation: "joyride-beacon-outer 1.2s infinite ease-in-out",
554
+ backgroundColor: `rgba(${hexToRGB(options.primaryColor).join(",")}, 0.2)`,
555
+ border: `2px solid ${options.primaryColor}`,
556
+ borderRadius: "50%",
557
+ boxSizing: "border-box",
558
+ display: "block",
559
+ height: "100%",
560
+ left: 0,
561
+ opacity: 0.9,
562
+ position: "absolute",
563
+ top: 0,
564
+ transformOrigin: "center",
565
+ width: "100%"
566
+ },
567
+ tooltip: {
568
+ backgroundColor: options.backgroundColor,
569
+ borderRadius: 5,
570
+ boxSizing: "border-box",
571
+ color: options.textColor,
572
+ fontSize: 16,
573
+ maxWidth: "100%",
574
+ padding: 15,
575
+ position: "relative",
576
+ width
577
+ },
578
+ tooltipContainer: {
579
+ lineHeight: 1.4,
580
+ textAlign: "center"
581
+ },
582
+ tooltipTitle: {
583
+ fontSize: 18,
584
+ margin: 0
585
+ },
586
+ tooltipContent: {
587
+ padding: "20px 10px"
588
+ },
589
+ tooltipFooter: {
590
+ alignItems: "center",
591
+ display: "flex",
592
+ justifyContent: "flex-end",
593
+ marginTop: 15
594
+ },
595
+ tooltipFooterSpacer: {
596
+ flex: 1
597
+ },
598
+ buttonNext: {
599
+ ...buttonBase,
600
+ backgroundColor: options.primaryColor,
601
+ borderRadius: 4,
602
+ color: "#fff"
603
+ },
604
+ buttonBack: {
605
+ ...buttonBase,
606
+ color: options.primaryColor,
607
+ marginLeft: "auto",
608
+ marginRight: 5
609
+ },
610
+ buttonClose: {
611
+ ...buttonBase,
612
+ color: options.textColor,
613
+ height: 14,
614
+ padding: 15,
615
+ position: "absolute",
616
+ right: 0,
617
+ top: 0,
618
+ width: 14
619
+ },
620
+ buttonSkip: {
621
+ ...buttonBase,
622
+ color: options.textColor,
623
+ fontSize: 14
624
+ },
625
+ overlay: {
626
+ ...overlay,
627
+ backgroundColor: options.overlayColor,
628
+ mixBlendMode: "hard-light"
629
+ },
630
+ overlayLegacy: {
631
+ ...overlay
632
+ },
633
+ overlayLegacyCenter: {
634
+ ...overlay,
635
+ backgroundColor: options.overlayColor
636
+ },
637
+ spotlight: {
638
+ ...spotlight,
639
+ backgroundColor: "gray"
640
+ },
641
+ spotlightLegacy: {
642
+ ...spotlight,
643
+ boxShadow: `0 0 0 9999px ${options.overlayColor}, ${options.spotlightShadow}`
644
+ },
645
+ floaterStyles: {
646
+ arrow: {
647
+ color: (_e = (_d = (_c = mergedFloaterProps == null ? void 0 : mergedFloaterProps.styles) == null ? void 0 : _c.arrow) == null ? void 0 : _d.color) != null ? _e : options.arrowColor
648
+ },
649
+ options: {
650
+ zIndex: options.zIndex + 100
651
+ }
652
+ },
653
+ options
654
+ };
655
+ return (0, import_deepmerge.default)(defaultStyles, mergedStyles);
656
+ }
657
+
658
+ // src/modules/step.ts
659
+ function getTourProps(props) {
660
+ return pick(
661
+ props,
662
+ "beaconComponent",
663
+ "disableCloseOnEsc",
664
+ "disableOverlay",
665
+ "disableOverlayClose",
666
+ "disableScrolling",
667
+ "disableScrollParentFix",
668
+ "floaterProps",
669
+ "hideBackButton",
670
+ "hideCloseButton",
671
+ "locale",
672
+ "showProgress",
673
+ "showSkipButton",
674
+ "spotlightClicks",
675
+ "spotlightPadding",
676
+ "styles",
677
+ "tooltipComponent"
678
+ );
679
+ }
680
+ function getMergedStep(props, currentStep) {
681
+ var _a, _b, _c, _d, _e, _f, _g;
682
+ const step = currentStep != null ? currentStep : {};
683
+ const mergedStep = import_deepmerge2.default.all([defaultStep, getTourProps(props), step], {
684
+ isMergeableObject: import_is_lite2.default.plainObject
685
+ });
686
+ const mergedStyles = getStyles(props, mergedStep);
687
+ const scrollParent2 = hasCustomScrollParent(
688
+ getElement(mergedStep.target),
689
+ mergedStep.disableScrollParentFix
690
+ );
691
+ const floaterProps = import_deepmerge2.default.all([
692
+ defaultFloaterProps,
693
+ (_a = props.floaterProps) != null ? _a : {},
694
+ (_b = mergedStep.floaterProps) != null ? _b : {}
695
+ ]);
696
+ floaterProps.offset = mergedStep.offset;
697
+ floaterProps.styles = (0, import_deepmerge2.default)((_c = floaterProps.styles) != null ? _c : {}, mergedStyles.floaterStyles);
698
+ floaterProps.offset += (_e = (_d = props.spotlightPadding) != null ? _d : mergedStep.spotlightPadding) != null ? _e : 0;
699
+ if (mergedStep.placementBeacon && floaterProps.wrapperOptions) {
700
+ floaterProps.wrapperOptions.placement = mergedStep.placementBeacon;
701
+ }
702
+ if (scrollParent2 && ((_f = floaterProps.modifiers) == null ? void 0 : _f.preventOverflow)) {
703
+ floaterProps.modifiers.preventOverflow.options = {
704
+ ...floaterProps.modifiers.preventOverflow.options,
705
+ boundary: "window"
706
+ };
707
+ }
708
+ return {
709
+ ...mergedStep,
710
+ locale: import_deepmerge2.default.all([defaultLocale, (_g = props.locale) != null ? _g : {}, mergedStep.locale || {}]),
711
+ floaterProps,
712
+ styles: omit(mergedStyles, "floaterStyles")
713
+ };
714
+ }
715
+ function validateStep(step, debug = false) {
716
+ if (!import_is_lite2.default.plainObject(step)) {
717
+ log({
718
+ title: "validateStep",
719
+ data: "step must be an object",
720
+ warn: true,
721
+ debug
722
+ });
723
+ return false;
724
+ }
725
+ if (!step.target) {
726
+ log({
727
+ title: "validateStep",
728
+ data: "target is missing from the step",
729
+ warn: true,
730
+ debug
731
+ });
732
+ return false;
733
+ }
734
+ return true;
735
+ }
736
+ function validateSteps(steps, debug = false) {
737
+ if (!import_is_lite2.default.array(steps)) {
738
+ log({
739
+ title: "validateSteps",
740
+ data: "steps must be an array",
741
+ warn: true,
742
+ debug
743
+ });
744
+ return false;
745
+ }
746
+ return steps.every((d) => validateStep(d, debug));
747
+ }
748
+
749
+ // src/modules/store.ts
750
+ var import_is_lite3 = __toESM(require("is-lite"));
751
+ var defaultState = {
752
+ action: "init",
753
+ controlled: false,
754
+ index: 0,
755
+ lifecycle: LIFECYCLE.INIT,
756
+ origin: null,
757
+ size: 0,
758
+ status: STATUS.IDLE
759
+ };
760
+ var validKeys = objectKeys(omit(defaultState, "controlled", "size"));
761
+ var Store = class {
762
+ constructor(options) {
763
+ this.data = /* @__PURE__ */ new Map();
764
+ this.store = /* @__PURE__ */ new Map();
765
+ this.addListener = (listener) => {
766
+ this.listener = listener;
767
+ };
768
+ this.setSteps = (steps) => {
769
+ const { size, status } = this.getState();
770
+ const state = {
771
+ size: steps.length,
772
+ status
773
+ };
774
+ this.data.set("steps", steps);
775
+ if (status === STATUS.WAITING && !size && steps.length) {
776
+ state.status = STATUS.RUNNING;
777
+ }
778
+ this.setState(state);
779
+ };
780
+ this.getPopper = (name) => {
781
+ if (name === "beacon") {
782
+ return this.beaconPopper;
783
+ }
784
+ return this.tooltipPopper;
785
+ };
786
+ this.setPopper = (name, popper) => {
787
+ if (name === "beacon") {
788
+ this.beaconPopper = popper;
789
+ } else {
790
+ this.tooltipPopper = popper;
791
+ }
792
+ };
793
+ this.cleanupPoppers = () => {
794
+ this.beaconPopper = null;
795
+ this.tooltipPopper = null;
796
+ };
797
+ this.close = (origin = null) => {
798
+ const { index, status } = this.getState();
799
+ if (status !== STATUS.RUNNING) {
800
+ return;
801
+ }
802
+ this.setState({
803
+ ...this.getNextState({ action: ACTIONS.CLOSE, index: index + 1, origin })
804
+ });
805
+ };
806
+ this.go = (nextIndex) => {
807
+ const { controlled, status } = this.getState();
808
+ if (controlled || status !== STATUS.RUNNING) {
809
+ return;
810
+ }
811
+ const step = this.getSteps()[nextIndex];
812
+ this.setState({
813
+ ...this.getNextState({ action: ACTIONS.GO, index: nextIndex }),
814
+ status: step ? status : STATUS.FINISHED
815
+ });
816
+ };
817
+ this.info = () => this.getState();
818
+ this.next = () => {
819
+ const { index, status } = this.getState();
820
+ if (status !== STATUS.RUNNING) {
821
+ return;
822
+ }
823
+ this.setState(this.getNextState({ action: ACTIONS.NEXT, index: index + 1 }));
824
+ };
825
+ this.open = () => {
826
+ const { status } = this.getState();
827
+ if (status !== STATUS.RUNNING) {
828
+ return;
829
+ }
830
+ this.setState({
831
+ ...this.getNextState({ action: ACTIONS.UPDATE, lifecycle: LIFECYCLE.TOOLTIP })
832
+ });
833
+ };
834
+ this.prev = () => {
835
+ const { index, status } = this.getState();
836
+ if (status !== STATUS.RUNNING) {
837
+ return;
838
+ }
839
+ this.setState({
840
+ ...this.getNextState({ action: ACTIONS.PREV, index: index - 1 })
841
+ });
842
+ };
843
+ this.reset = (restart = false) => {
844
+ const { controlled } = this.getState();
845
+ if (controlled) {
846
+ return;
847
+ }
848
+ this.setState({
849
+ ...this.getNextState({ action: ACTIONS.RESET, index: 0 }),
850
+ status: restart ? STATUS.RUNNING : STATUS.READY
851
+ });
852
+ };
853
+ this.skip = () => {
854
+ const { status } = this.getState();
855
+ if (status !== STATUS.RUNNING) {
856
+ return;
857
+ }
858
+ this.setState({
859
+ action: ACTIONS.SKIP,
860
+ lifecycle: LIFECYCLE.INIT,
861
+ status: STATUS.SKIPPED
862
+ });
863
+ };
864
+ this.start = (nextIndex) => {
865
+ const { index, size } = this.getState();
866
+ this.setState({
867
+ ...this.getNextState(
868
+ {
869
+ action: ACTIONS.START,
870
+ index: import_is_lite3.default.number(nextIndex) ? nextIndex : index
871
+ },
872
+ true
873
+ ),
874
+ status: size ? STATUS.RUNNING : STATUS.WAITING
875
+ });
876
+ };
877
+ this.stop = (advance = false) => {
878
+ const { index, status } = this.getState();
879
+ if ([STATUS.FINISHED, STATUS.SKIPPED].includes(status)) {
880
+ return;
881
+ }
882
+ this.setState({
883
+ ...this.getNextState({ action: ACTIONS.STOP, index: index + (advance ? 1 : 0) }),
884
+ status: STATUS.PAUSED
885
+ });
886
+ };
887
+ this.update = (state) => {
888
+ var _a, _b;
889
+ if (!hasValidKeys(state, validKeys)) {
890
+ throw new Error(`State is not valid. Valid keys: ${validKeys.join(", ")}`);
891
+ }
892
+ this.setState({
893
+ ...this.getNextState(
894
+ {
895
+ ...this.getState(),
896
+ ...state,
897
+ action: (_a = state.action) != null ? _a : ACTIONS.UPDATE,
898
+ origin: (_b = state.origin) != null ? _b : null
899
+ },
900
+ true
901
+ )
902
+ });
903
+ };
904
+ const { continuous = false, stepIndex, steps = [] } = options != null ? options : {};
905
+ this.setState(
906
+ {
907
+ action: ACTIONS.INIT,
908
+ controlled: import_is_lite3.default.number(stepIndex),
909
+ continuous,
910
+ index: import_is_lite3.default.number(stepIndex) ? stepIndex : 0,
911
+ lifecycle: LIFECYCLE.INIT,
912
+ origin: null,
913
+ status: steps.length ? STATUS.READY : STATUS.IDLE
914
+ },
915
+ true
916
+ );
917
+ this.beaconPopper = null;
918
+ this.tooltipPopper = null;
919
+ this.listener = null;
920
+ this.setSteps(steps);
921
+ }
922
+ getState() {
923
+ if (!this.store.size) {
924
+ return { ...defaultState };
925
+ }
926
+ return {
927
+ action: this.store.get("action") || "",
928
+ controlled: this.store.get("controlled") || false,
929
+ index: parseInt(this.store.get("index"), 10),
930
+ lifecycle: this.store.get("lifecycle") || "",
931
+ origin: this.store.get("origin") || null,
932
+ size: this.store.get("size") || 0,
933
+ status: this.store.get("status") || ""
934
+ };
935
+ }
936
+ getNextState(state, force = false) {
937
+ var _a, _b, _c, _d, _e;
938
+ const { action, controlled, index, size, status } = this.getState();
939
+ const newIndex = import_is_lite3.default.number(state.index) ? state.index : index;
940
+ const nextIndex = controlled && !force ? index : Math.min(Math.max(newIndex, 0), size);
941
+ return {
942
+ action: (_a = state.action) != null ? _a : action,
943
+ controlled,
944
+ index: nextIndex,
945
+ lifecycle: (_b = state.lifecycle) != null ? _b : LIFECYCLE.INIT,
946
+ origin: (_c = state.origin) != null ? _c : null,
947
+ size: (_d = state.size) != null ? _d : size,
948
+ status: nextIndex === size ? STATUS.FINISHED : (_e = state.status) != null ? _e : status
949
+ };
950
+ }
951
+ getSteps() {
952
+ const steps = this.data.get("steps");
953
+ return Array.isArray(steps) ? steps : [];
954
+ }
955
+ hasUpdatedState(oldState) {
956
+ const before = JSON.stringify(oldState);
957
+ const after = JSON.stringify(this.getState());
958
+ return before !== after;
959
+ }
960
+ setState(nextState, initial = false) {
961
+ const state = this.getState();
962
+ const {
963
+ action,
964
+ index,
965
+ lifecycle,
966
+ origin = null,
967
+ size,
968
+ status
969
+ } = {
970
+ ...state,
971
+ ...nextState
972
+ };
973
+ this.store.set("action", action);
974
+ this.store.set("index", index);
975
+ this.store.set("lifecycle", lifecycle);
976
+ this.store.set("origin", origin);
977
+ this.store.set("size", size);
978
+ this.store.set("status", status);
979
+ if (initial) {
980
+ this.store.set("controlled", nextState.controlled);
981
+ this.store.set("continuous", nextState.continuous);
982
+ }
983
+ if (this.listener && this.hasUpdatedState(state)) {
984
+ this.listener(this.getState());
985
+ }
986
+ }
987
+ getHelpers() {
988
+ return {
989
+ close: this.close,
990
+ go: this.go,
991
+ info: this.info,
992
+ next: this.next,
993
+ open: this.open,
994
+ prev: this.prev,
995
+ reset: this.reset,
996
+ skip: this.skip
997
+ };
998
+ }
999
+ };
1000
+ function createStore(options) {
1001
+ return new Store(options);
1002
+ }
1003
+
1004
+ // src/components/Overlay.tsx
1005
+ var import_react2 = require("react");
1006
+ var import_tree_changes = __toESM(require("tree-changes"));
1007
+
1008
+ // src/components/Spotlight.tsx
1009
+ var import_jsx_runtime = require("react/jsx-runtime");
1010
+ function JoyrideSpotlight({ styles }) {
1011
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1012
+ "div",
1013
+ {
1014
+ className: "react-joyride__spotlight",
1015
+ "data-test-id": "spotlight",
1016
+ style: styles
1017
+ },
1018
+ "JoyrideSpotlight"
1019
+ );
1020
+ }
1021
+ var Spotlight_default = JoyrideSpotlight;
1022
+
1023
+ // src/components/Overlay.tsx
1024
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1025
+ function JoyrideOverlay(props) {
1026
+ const {
1027
+ continuous,
1028
+ debug,
1029
+ disableOverlay,
1030
+ disableOverlayClose,
1031
+ disableScrolling,
1032
+ disableScrollParentFix = false,
1033
+ lifecycle,
1034
+ onClickOverlay,
1035
+ placement,
1036
+ spotlightClicks,
1037
+ spotlightPadding = 0,
1038
+ styles,
1039
+ target
1040
+ } = props;
1041
+ const [isScrolling, setIsScrolling] = (0, import_react2.useState)(false);
1042
+ const [mouseOverSpotlight, setMouseOverSpotlight] = (0, import_react2.useState)(false);
1043
+ const [showSpotlight, setShowSpotlight] = (0, import_react2.useState)(true);
1044
+ const [, setForceRender] = (0, import_react2.useState)(0);
1045
+ const isActiveRef = (0, import_react2.useRef)(false);
1046
+ const resizeTimeoutRef = (0, import_react2.useRef)(void 0);
1047
+ const scrollTimeoutRef = (0, import_react2.useRef)(void 0);
1048
+ const scrollParentRef = (0, import_react2.useRef)(void 0);
1049
+ const previousPropsRef = (0, import_react2.useRef)(props);
1050
+ const getSpotlightStyles = (0, import_react2.useCallback)(() => {
1051
+ var _a, _b, _c;
1052
+ const element = getElement(target);
1053
+ const elementRect = getClientRect(element);
1054
+ const isFixedTarget = hasPosition(element);
1055
+ const top = getElementPosition(element, spotlightPadding, disableScrollParentFix);
1056
+ return {
1057
+ ...styles.spotlight,
1058
+ height: Math.round(((_a = elementRect == null ? void 0 : elementRect.height) != null ? _a : 0) + spotlightPadding * 2),
1059
+ left: Math.round(((_b = elementRect == null ? void 0 : elementRect.left) != null ? _b : 0) - spotlightPadding),
1060
+ opacity: showSpotlight ? 1 : 0,
1061
+ pointerEvents: spotlightClicks ? "none" : "auto",
1062
+ position: isFixedTarget ? "fixed" : "absolute",
1063
+ top,
1064
+ transition: "opacity 0.2s",
1065
+ width: Math.round(((_c = elementRect == null ? void 0 : elementRect.width) != null ? _c : 0) + spotlightPadding * 2)
1066
+ };
1067
+ }, [target, spotlightPadding, disableScrollParentFix, styles.spotlight, showSpotlight, spotlightClicks]);
1068
+ const handleMouseMove = (0, import_react2.useCallback)((event) => {
1069
+ const spotStyles = getSpotlightStyles();
1070
+ const { height, left, position, top, width } = spotStyles;
1071
+ const offsetY = position === "fixed" ? event.clientY : event.pageY;
1072
+ const offsetX = position === "fixed" ? event.clientX : event.pageX;
1073
+ const inSpotlightHeight = offsetY >= top && offsetY <= top + height;
1074
+ const inSpotlightWidth = offsetX >= left && offsetX <= left + width;
1075
+ const inSpotlight = inSpotlightWidth && inSpotlightHeight;
1076
+ setMouseOverSpotlight((prev) => {
1077
+ if (inSpotlight !== prev) {
1078
+ return inSpotlight;
1079
+ }
1080
+ return prev;
1081
+ });
1082
+ }, [getSpotlightStyles]);
1083
+ const handleScroll = (0, import_react2.useCallback)(() => {
1084
+ const element = getElement(target);
1085
+ if (scrollParentRef.current !== document) {
1086
+ setIsScrolling((prev) => {
1087
+ if (!prev) {
1088
+ setShowSpotlight(false);
1089
+ return true;
1090
+ }
1091
+ return prev;
1092
+ });
1093
+ clearTimeout(scrollTimeoutRef.current);
1094
+ scrollTimeoutRef.current = window.setTimeout(() => {
1095
+ if (isActiveRef.current) {
1096
+ setIsScrolling(false);
1097
+ setShowSpotlight(true);
1098
+ }
1099
+ }, 50);
1100
+ } else if (hasPosition(element, "sticky")) {
1101
+ setForceRender((c) => c + 1);
1102
+ }
1103
+ }, [target]);
1104
+ const handleResize = (0, import_react2.useCallback)(() => {
1105
+ clearTimeout(resizeTimeoutRef.current);
1106
+ resizeTimeoutRef.current = window.setTimeout(() => {
1107
+ if (isActiveRef.current) {
1108
+ setForceRender((c) => c + 1);
1109
+ }
1110
+ }, 100);
1111
+ }, []);
1112
+ (0, import_react2.useEffect)(() => {
1113
+ const element = getElement(target);
1114
+ scrollParentRef.current = getScrollParent(element != null ? element : document.body, disableScrollParentFix, true);
1115
+ isActiveRef.current = true;
1116
+ if (process.env.NODE_ENV !== "production") {
1117
+ if (!disableScrolling && hasCustomScrollParent(element, true)) {
1118
+ log({
1119
+ title: "step has a custom scroll parent and can cause trouble with scrolling",
1120
+ data: [{ key: "parent", value: scrollParentRef.current }],
1121
+ debug
1122
+ });
1123
+ }
1124
+ }
1125
+ window.addEventListener("resize", handleResize);
1126
+ return () => {
1127
+ var _a;
1128
+ isActiveRef.current = false;
1129
+ window.removeEventListener("mousemove", handleMouseMove);
1130
+ window.removeEventListener("resize", handleResize);
1131
+ clearTimeout(resizeTimeoutRef.current);
1132
+ clearTimeout(scrollTimeoutRef.current);
1133
+ (_a = scrollParentRef.current) == null ? void 0 : _a.removeEventListener("scroll", handleScroll);
1134
+ };
1135
+ }, []);
1136
+ (0, import_react2.useEffect)(() => {
1137
+ var _a;
1138
+ const previousProps = previousPropsRef.current;
1139
+ const { changed } = (0, import_tree_changes.default)(previousProps, props);
1140
+ if (changed("target") || changed("disableScrollParentFix")) {
1141
+ const element = getElement(target);
1142
+ scrollParentRef.current = getScrollParent(element != null ? element : document.body, disableScrollParentFix, true);
1143
+ }
1144
+ if (changed("lifecycle", LIFECYCLE.TOOLTIP)) {
1145
+ (_a = scrollParentRef.current) == null ? void 0 : _a.addEventListener("scroll", handleScroll, { passive: true });
1146
+ setTimeout(() => {
1147
+ if (!isScrolling) {
1148
+ setShowSpotlight(true);
1149
+ }
1150
+ }, 100);
1151
+ }
1152
+ if (changed("spotlightClicks") || changed("disableOverlay") || changed("lifecycle")) {
1153
+ if (spotlightClicks && lifecycle === LIFECYCLE.TOOLTIP) {
1154
+ window.addEventListener("mousemove", handleMouseMove, false);
1155
+ } else if (lifecycle !== LIFECYCLE.TOOLTIP) {
1156
+ window.removeEventListener("mousemove", handleMouseMove);
1157
+ }
1158
+ }
1159
+ previousPropsRef.current = props;
1160
+ });
1161
+ const hideSpotlight = () => {
1162
+ const hiddenLifecycles = [
1163
+ LIFECYCLE.INIT,
1164
+ LIFECYCLE.BEACON,
1165
+ LIFECYCLE.COMPLETE,
1166
+ LIFECYCLE.ERROR
1167
+ ];
1168
+ return disableOverlay || (continuous ? hiddenLifecycles.includes(lifecycle) : lifecycle !== LIFECYCLE.TOOLTIP);
1169
+ };
1170
+ if (hideSpotlight()) {
1171
+ return null;
1172
+ }
1173
+ const spotlightStyles = getSpotlightStyles();
1174
+ const overlayStyles = {
1175
+ cursor: disableOverlayClose ? "default" : "pointer",
1176
+ height: getDocumentHeight(),
1177
+ pointerEvents: mouseOverSpotlight ? "none" : "auto",
1178
+ ...styles.overlay
1179
+ };
1180
+ let spotlight2 = placement !== "center" && showSpotlight && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Spotlight_default, { styles: spotlightStyles });
1181
+ if (isSafari()) {
1182
+ const { mixBlendMode, zIndex, ...safariOverlay } = overlayStyles;
1183
+ spotlight2 = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { ...safariOverlay }, children: spotlight2 });
1184
+ delete overlayStyles.backgroundColor;
1185
+ }
1186
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1187
+ "div",
1188
+ {
1189
+ className: "react-joyride__overlay",
1190
+ "data-test-id": "overlay",
1191
+ onClick: onClickOverlay,
1192
+ role: "presentation",
1193
+ style: overlayStyles,
1194
+ children: spotlight2
1195
+ }
1196
+ );
1197
+ }
1198
+
1199
+ // src/components/Portal.tsx
1200
+ var import_react3 = require("react");
1201
+ var import_react_dom = require("react-dom");
1202
+ function JoyridePortal({ children, id }) {
1203
+ const nodeRef = (0, import_react3.useRef)(null);
1204
+ (0, import_react3.useEffect)(() => {
1205
+ if (!canUseDOM()) {
1206
+ return;
1207
+ }
1208
+ const node = document.createElement("div");
1209
+ node.id = id;
1210
+ document.body.appendChild(node);
1211
+ nodeRef.current = node;
1212
+ return () => {
1213
+ if (node.parentNode === document.body) {
1214
+ document.body.removeChild(node);
1215
+ }
1216
+ nodeRef.current = null;
1217
+ };
1218
+ }, [id]);
1219
+ if (!canUseDOM() || !nodeRef.current) {
1220
+ return null;
1221
+ }
1222
+ return (0, import_react_dom.createPortal)(children, nodeRef.current);
1223
+ }
1224
+
1225
+ // src/components/Step.tsx
1226
+ var import_react5 = require("react");
1227
+ var import_react_floater = __toESM(require("react-floater"));
1228
+ var import_is_lite5 = __toESM(require("is-lite"));
1229
+ var import_tree_changes2 = __toESM(require("tree-changes"));
1230
+
1231
+ // src/modules/scope.ts
1232
+ var Scope = class {
1233
+ constructor(element, options) {
1234
+ this.canBeTabbed = (element) => {
1235
+ const { tabIndex } = element;
1236
+ if (tabIndex === null || tabIndex < 0) {
1237
+ return false;
1238
+ }
1239
+ return this.canHaveFocus(element);
1240
+ };
1241
+ this.canHaveFocus = (element) => {
1242
+ const validTabNodes = /input|select|textarea|button|object/;
1243
+ const nodeName = element.nodeName.toLowerCase();
1244
+ const isValid = validTabNodes.test(nodeName) && !element.getAttribute("disabled") || nodeName === "a" && !!element.getAttribute("href");
1245
+ return isValid && this.isVisible(element);
1246
+ };
1247
+ this.findValidTabElements = () => [].slice.call(this.element.querySelectorAll("*"), 0).filter(this.canBeTabbed);
1248
+ this.handleKeyDown = (event) => {
1249
+ const { code = "Tab" } = this.options;
1250
+ if (event.code === code) {
1251
+ this.interceptTab(event);
1252
+ }
1253
+ };
1254
+ this.interceptTab = (event) => {
1255
+ event.preventDefault();
1256
+ const elements = this.findValidTabElements();
1257
+ const { shiftKey } = event;
1258
+ if (!elements.length) {
1259
+ return;
1260
+ }
1261
+ let x = document.activeElement ? elements.indexOf(document.activeElement) : 0;
1262
+ if (x === -1 || !shiftKey && x + 1 === elements.length) {
1263
+ x = 0;
1264
+ } else if (shiftKey && x === 0) {
1265
+ x = elements.length - 1;
1266
+ } else {
1267
+ x += shiftKey ? -1 : 1;
1268
+ }
1269
+ elements[x].focus();
1270
+ };
1271
+ // eslint-disable-next-line class-methods-use-this
1272
+ this.isHidden = (element) => {
1273
+ const noSize = element.offsetWidth <= 0 && element.offsetHeight <= 0;
1274
+ const style = window.getComputedStyle(element);
1275
+ if (noSize && !element.innerHTML) {
1276
+ return true;
1277
+ }
1278
+ return noSize && style.getPropertyValue("overflow") !== "visible" || style.getPropertyValue("display") === "none";
1279
+ };
1280
+ this.isVisible = (element) => {
1281
+ let parentElement = element;
1282
+ while (parentElement) {
1283
+ if (parentElement instanceof HTMLElement) {
1284
+ if (parentElement === document.body) {
1285
+ break;
1286
+ }
1287
+ if (this.isHidden(parentElement)) {
1288
+ return false;
1289
+ }
1290
+ parentElement = parentElement.parentNode;
1291
+ }
1292
+ }
1293
+ return true;
1294
+ };
1295
+ this.removeScope = () => {
1296
+ window.removeEventListener("keydown", this.handleKeyDown);
1297
+ };
1298
+ this.checkFocus = (target) => {
1299
+ if (document.activeElement !== target) {
1300
+ target.focus();
1301
+ window.requestAnimationFrame(() => this.checkFocus(target));
1302
+ }
1303
+ };
1304
+ this.setFocus = () => {
1305
+ const { selector } = this.options;
1306
+ if (!selector) {
1307
+ return;
1308
+ }
1309
+ const target = this.element.querySelector(selector);
1310
+ if (target) {
1311
+ window.requestAnimationFrame(() => this.checkFocus(target));
1312
+ }
1313
+ };
1314
+ if (!(element instanceof HTMLElement)) {
1315
+ throw new TypeError("Invalid parameter: element must be an HTMLElement");
1316
+ }
1317
+ this.element = element;
1318
+ this.options = options;
1319
+ window.addEventListener("keydown", this.handleKeyDown, false);
1320
+ this.setFocus();
1321
+ }
1322
+ };
1323
+
1324
+ // src/components/Beacon.tsx
1325
+ var import_react4 = require("react");
1326
+ var import_is_lite4 = __toESM(require("is-lite"));
1327
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1328
+ function JoyrideBeacon(props) {
1329
+ const {
1330
+ beaconComponent,
1331
+ continuous,
1332
+ index,
1333
+ isLastStep,
1334
+ locale,
1335
+ nonce,
1336
+ onClickOrHover,
1337
+ shouldFocus,
1338
+ size,
1339
+ step,
1340
+ styles
1341
+ } = props;
1342
+ const beaconRef = (0, import_react4.useRef)(null);
1343
+ const setBeaconRef = (0, import_react4.useCallback)((c) => {
1344
+ beaconRef.current = c;
1345
+ }, []);
1346
+ (0, import_react4.useEffect)(() => {
1347
+ if (beaconComponent) {
1348
+ return;
1349
+ }
1350
+ const head = document.head || document.getElementsByTagName("head")[0];
1351
+ const style = document.createElement("style");
1352
+ style.id = "joyride-beacon-animation";
1353
+ if (nonce) {
1354
+ style.setAttribute("nonce", nonce);
1355
+ }
1356
+ const css = `
1357
+ @keyframes joyride-beacon-inner {
1358
+ 20% {
1359
+ opacity: 0.9;
1360
+ }
1361
+
1362
+ 90% {
1363
+ opacity: 0.7;
1364
+ }
1365
+ }
1366
+
1367
+ @keyframes joyride-beacon-outer {
1368
+ 0% {
1369
+ transform: scale(1);
1370
+ }
1371
+
1372
+ 45% {
1373
+ opacity: 0.7;
1374
+ transform: scale(0.75);
1375
+ }
1376
+
1377
+ 100% {
1378
+ opacity: 0.9;
1379
+ transform: scale(1);
1380
+ }
1381
+ }
1382
+ `;
1383
+ style.appendChild(document.createTextNode(css));
1384
+ head.appendChild(style);
1385
+ return () => {
1386
+ const existingStyle = document.getElementById("joyride-beacon-animation");
1387
+ if (existingStyle == null ? void 0 : existingStyle.parentNode) {
1388
+ existingStyle.parentNode.removeChild(existingStyle);
1389
+ }
1390
+ };
1391
+ }, [beaconComponent, nonce]);
1392
+ (0, import_react4.useEffect)(() => {
1393
+ if (process.env.NODE_ENV !== "production") {
1394
+ if (!import_is_lite4.default.domElement(beaconRef.current)) {
1395
+ console.warn("beacon is not a valid DOM element");
1396
+ }
1397
+ }
1398
+ setTimeout(() => {
1399
+ if (import_is_lite4.default.domElement(beaconRef.current) && shouldFocus) {
1400
+ beaconRef.current.focus();
1401
+ }
1402
+ }, 0);
1403
+ }, [shouldFocus]);
1404
+ const title = getReactNodeText(locale.open);
1405
+ const sharedProps = {
1406
+ "aria-label": title,
1407
+ onClick: onClickOrHover,
1408
+ onMouseEnter: onClickOrHover,
1409
+ ref: setBeaconRef,
1410
+ title
1411
+ };
1412
+ if (beaconComponent) {
1413
+ const BeaconComponent = beaconComponent;
1414
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1415
+ BeaconComponent,
1416
+ {
1417
+ continuous,
1418
+ index,
1419
+ isLastStep,
1420
+ size,
1421
+ step,
1422
+ ...sharedProps
1423
+ }
1424
+ );
1425
+ }
1426
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1427
+ "button",
1428
+ {
1429
+ className: "react-joyride__beacon",
1430
+ "data-test-id": "button-beacon",
1431
+ style: styles.beacon,
1432
+ type: "button",
1433
+ ...sharedProps,
1434
+ children: [
1435
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles.beaconInner }),
1436
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: styles.beaconOuter })
1437
+ ]
1438
+ },
1439
+ "JoyrideBeacon"
1440
+ );
1441
+ }
1442
+
1443
+ // src/components/Tooltip/CloseButton.tsx
1444
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1445
+ function JoyrideTooltipCloseButton({ styles, ...props }) {
1446
+ const { color, height, width, ...style } = styles;
1447
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { style, type: "button", ...props, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1448
+ "svg",
1449
+ {
1450
+ height: typeof height === "number" ? `${height}px` : height,
1451
+ preserveAspectRatio: "xMidYMid",
1452
+ version: "1.1",
1453
+ viewBox: "0 0 18 18",
1454
+ width: typeof width === "number" ? `${width}px` : width,
1455
+ xmlns: "http://www.w3.org/2000/svg",
1456
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("g", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1457
+ "path",
1458
+ {
1459
+ d: "M8.13911129,9.00268191 L0.171521827,17.0258467 C-0.0498027049,17.248715 -0.0498027049,17.6098394 0.171521827,17.8327545 C0.28204354,17.9443526 0.427188206,17.9998706 0.572051765,17.9998706 C0.71714958,17.9998706 0.862013139,17.9443526 0.972581703,17.8327545 L9.0000937,9.74924618 L17.0276057,17.8327545 C17.1384085,17.9443526 17.2832721,17.9998706 17.4281356,17.9998706 C17.5729992,17.9998706 17.718097,17.9443526 17.8286656,17.8327545 C18.0499901,17.6098862 18.0499901,17.2487618 17.8286656,17.0258467 L9.86135722,9.00268191 L17.8340066,0.973848225 C18.0553311,0.750979934 18.0553311,0.389855532 17.8340066,0.16694039 C17.6126821,-0.0556467968 17.254037,-0.0556467968 17.0329467,0.16694039 L9.00042166,8.25611765 L0.967006424,0.167268345 C0.745681892,-0.0553188426 0.387317931,-0.0553188426 0.165993399,0.167268345 C-0.0553311331,0.390136635 -0.0553311331,0.751261038 0.165993399,0.974176179 L8.13920499,9.00268191 L8.13911129,9.00268191 Z",
1460
+ fill: color
1461
+ }
1462
+ ) })
1463
+ }
1464
+ ) });
1465
+ }
1466
+ var CloseButton_default = JoyrideTooltipCloseButton;
1467
+
1468
+ // src/components/Tooltip/Container.tsx
1469
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1470
+ function JoyrideTooltipContainer(props) {
1471
+ const { backProps, closeProps, index, isLastStep, primaryProps, skipProps, step, tooltipProps } = props;
1472
+ const { content, hideBackButton, hideCloseButton, hideFooter, showSkipButton, styles, title } = step;
1473
+ const output = {};
1474
+ output.primary = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1475
+ "button",
1476
+ {
1477
+ "data-test-id": "button-primary",
1478
+ style: styles.buttonNext,
1479
+ type: "button",
1480
+ ...primaryProps
1481
+ }
1482
+ );
1483
+ if (showSkipButton && !isLastStep) {
1484
+ output.skip = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1485
+ "button",
1486
+ {
1487
+ "aria-live": "off",
1488
+ "data-test-id": "button-skip",
1489
+ style: styles.buttonSkip,
1490
+ type: "button",
1491
+ ...skipProps
1492
+ }
1493
+ );
1494
+ }
1495
+ if (!hideBackButton && index > 0) {
1496
+ output.back = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "data-test-id": "button-back", style: styles.buttonBack, type: "button", ...backProps });
1497
+ }
1498
+ output.close = !hideCloseButton && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseButton_default, { "data-test-id": "button-close", styles: styles.buttonClose, ...closeProps });
1499
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
1500
+ "div",
1501
+ {
1502
+ "aria-label": getReactNodeText(title != null ? title : content),
1503
+ className: "react-joyride__tooltip",
1504
+ style: styles.tooltip,
1505
+ ...tooltipProps,
1506
+ children: [
1507
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.tooltipContainer, children: [
1508
+ title && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { "aria-label": getReactNodeText(title), style: styles.tooltipTitle, children: title }),
1509
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.tooltipContent, children: content })
1510
+ ] }),
1511
+ !hideFooter && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: styles.tooltipFooter, children: [
1512
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: styles.tooltipFooterSpacer, children: output.skip }),
1513
+ output.back,
1514
+ output.primary
1515
+ ] }),
1516
+ output.close
1517
+ ]
1518
+ },
1519
+ "JoyrideTooltip"
1520
+ );
1521
+ }
1522
+ var Container_default = JoyrideTooltipContainer;
1523
+
1524
+ // src/components/Tooltip/index.tsx
1525
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1526
+ function JoyrideTooltip(props) {
1527
+ const { continuous, helpers, index, isLastStep, setTooltipRef, size, step } = props;
1528
+ const handleClickBack = (event) => {
1529
+ event.preventDefault();
1530
+ helpers.prev();
1531
+ };
1532
+ const handleClickClose = (event) => {
1533
+ event.preventDefault();
1534
+ helpers.close("button_close");
1535
+ };
1536
+ const handleClickPrimary = (event) => {
1537
+ event.preventDefault();
1538
+ if (!continuous) {
1539
+ helpers.close("button_primary");
1540
+ return;
1541
+ }
1542
+ helpers.next();
1543
+ };
1544
+ const handleClickSkip = (event) => {
1545
+ event.preventDefault();
1546
+ helpers.skip();
1547
+ };
1548
+ const getElementsProps = () => {
1549
+ const { back, close, last, next, nextLabelWithProgress, skip } = step.locale;
1550
+ const backText = getReactNodeText(back);
1551
+ const closeText = getReactNodeText(close);
1552
+ const lastText = getReactNodeText(last);
1553
+ const nextText = getReactNodeText(next);
1554
+ const skipText = getReactNodeText(skip);
1555
+ let primary = close;
1556
+ let primaryText = closeText;
1557
+ if (continuous) {
1558
+ primary = next;
1559
+ primaryText = nextText;
1560
+ if (step.showProgress && !isLastStep) {
1561
+ const labelWithProgress = getReactNodeText(nextLabelWithProgress, {
1562
+ step: index + 1,
1563
+ steps: size
1564
+ });
1565
+ primary = replaceLocaleContent(nextLabelWithProgress, index + 1, size);
1566
+ primaryText = labelWithProgress;
1567
+ }
1568
+ if (isLastStep) {
1569
+ primary = last;
1570
+ primaryText = lastText;
1571
+ }
1572
+ }
1573
+ return {
1574
+ backProps: {
1575
+ "aria-label": backText,
1576
+ children: back,
1577
+ "data-action": "back",
1578
+ onClick: handleClickBack,
1579
+ role: "button",
1580
+ title: backText
1581
+ },
1582
+ closeProps: {
1583
+ "aria-label": closeText,
1584
+ children: close,
1585
+ "data-action": "close",
1586
+ onClick: handleClickClose,
1587
+ role: "button",
1588
+ title: closeText
1589
+ },
1590
+ primaryProps: {
1591
+ "aria-label": primaryText,
1592
+ children: primary,
1593
+ "data-action": "primary",
1594
+ onClick: handleClickPrimary,
1595
+ role: "button",
1596
+ title: primaryText
1597
+ },
1598
+ skipProps: {
1599
+ "aria-label": skipText,
1600
+ children: skip,
1601
+ "data-action": "skip",
1602
+ onClick: handleClickSkip,
1603
+ role: "button",
1604
+ title: skipText
1605
+ },
1606
+ tooltipProps: {
1607
+ "aria-modal": true,
1608
+ ref: setTooltipRef,
1609
+ role: "alertdialog"
1610
+ }
1611
+ };
1612
+ };
1613
+ const { beaconComponent, tooltipComponent, ...cleanStep } = step;
1614
+ if (tooltipComponent) {
1615
+ const renderProps = {
1616
+ ...getElementsProps(),
1617
+ continuous,
1618
+ index,
1619
+ isLastStep,
1620
+ size,
1621
+ step: cleanStep,
1622
+ setTooltipRef
1623
+ };
1624
+ const TooltipComponent = tooltipComponent;
1625
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TooltipComponent, { ...renderProps });
1626
+ }
1627
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1628
+ Container_default,
1629
+ {
1630
+ ...getElementsProps(),
1631
+ continuous,
1632
+ index,
1633
+ isLastStep,
1634
+ size,
1635
+ step
1636
+ }
1637
+ );
1638
+ }
1639
+
1640
+ // src/components/Step.tsx
1641
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1642
+ function JoyrideStep(props) {
1643
+ var _a;
1644
+ const {
1645
+ action,
1646
+ callback,
1647
+ continuous,
1648
+ controlled,
1649
+ debug,
1650
+ helpers,
1651
+ index,
1652
+ lifecycle,
1653
+ nonce,
1654
+ shouldScroll: shouldScroll2,
1655
+ size,
1656
+ status,
1657
+ step,
1658
+ store
1659
+ } = props;
1660
+ const scopeRef = (0, import_react5.useRef)(null);
1661
+ const tooltipRef = (0, import_react5.useRef)(null);
1662
+ const previousPropsRef = (0, import_react5.useRef)(props);
1663
+ const setTooltipRef = (0, import_react5.useCallback)((element) => {
1664
+ tooltipRef.current = element;
1665
+ }, []);
1666
+ const handleClickHoverBeacon = (0, import_react5.useCallback)((event) => {
1667
+ if (event.type === "mouseenter" && step.event !== "hover") {
1668
+ return;
1669
+ }
1670
+ store.update({ lifecycle: LIFECYCLE.TOOLTIP });
1671
+ }, [step.event, store]);
1672
+ const setPopper = (0, import_react5.useCallback)((popper, type) => {
1673
+ var _a2;
1674
+ if (type === "wrapper") {
1675
+ store.setPopper("beacon", popper);
1676
+ } else {
1677
+ store.setPopper("tooltip", popper);
1678
+ }
1679
+ if (store.getPopper("beacon") && (store.getPopper("tooltip") || step.placement === "center") && lifecycle === LIFECYCLE.INIT) {
1680
+ store.update({
1681
+ action,
1682
+ lifecycle: LIFECYCLE.READY
1683
+ });
1684
+ }
1685
+ if ((_a2 = step.floaterProps) == null ? void 0 : _a2.getPopper) {
1686
+ step.floaterProps.getPopper(popper, type);
1687
+ }
1688
+ }, [action, lifecycle, step.placement, step.floaterProps, store]);
1689
+ (0, import_react5.useEffect)(() => {
1690
+ log({
1691
+ title: `step:${index}`,
1692
+ data: [{ key: "props", value: props }],
1693
+ debug
1694
+ });
1695
+ }, []);
1696
+ (0, import_react5.useEffect)(() => {
1697
+ return () => {
1698
+ var _a2;
1699
+ (_a2 = scopeRef.current) == null ? void 0 : _a2.removeScope();
1700
+ };
1701
+ }, []);
1702
+ (0, import_react5.useEffect)(() => {
1703
+ var _a2;
1704
+ const previousProps = previousPropsRef.current;
1705
+ const { changed, changedFrom } = (0, import_tree_changes2.default)(previousProps, props);
1706
+ const state = helpers.info();
1707
+ const skipBeacon = continuous && action !== ACTIONS.CLOSE && (index > 0 || action === ACTIONS.PREV);
1708
+ const hasStoreChanged = changed("action") || changed("index") || changed("lifecycle") || changed("status");
1709
+ const isInitial = changedFrom("lifecycle", [LIFECYCLE.TOOLTIP, LIFECYCLE.INIT], LIFECYCLE.INIT);
1710
+ const isAfterAction = changed("action", [
1711
+ ACTIONS.NEXT,
1712
+ ACTIONS.PREV,
1713
+ ACTIONS.SKIP,
1714
+ ACTIONS.CLOSE
1715
+ ]);
1716
+ const isControlled = controlled && index === previousProps.index;
1717
+ if (isAfterAction && (isInitial || isControlled)) {
1718
+ callback({
1719
+ ...state,
1720
+ index: previousProps.index,
1721
+ lifecycle: LIFECYCLE.COMPLETE,
1722
+ step: previousProps.step,
1723
+ type: EVENTS.STEP_AFTER
1724
+ });
1725
+ }
1726
+ if (step.placement === "center" && status === STATUS.RUNNING && changed("index") && action !== ACTIONS.START && lifecycle === LIFECYCLE.INIT) {
1727
+ store.update({ lifecycle: LIFECYCLE.READY });
1728
+ }
1729
+ if (hasStoreChanged) {
1730
+ const element = getElement(step.target);
1731
+ const elementExists = !!element;
1732
+ const hasRenderedTarget = elementExists && isElementVisible(element);
1733
+ if (hasRenderedTarget) {
1734
+ if (changedFrom("status", STATUS.READY, STATUS.RUNNING) || changedFrom("lifecycle", LIFECYCLE.INIT, LIFECYCLE.READY)) {
1735
+ callback({
1736
+ ...state,
1737
+ step,
1738
+ type: EVENTS.STEP_BEFORE
1739
+ });
1740
+ }
1741
+ } else {
1742
+ console.warn(elementExists ? "Target not visible" : "Target not mounted", step);
1743
+ callback({
1744
+ ...state,
1745
+ type: EVENTS.TARGET_NOT_FOUND,
1746
+ step
1747
+ });
1748
+ if (!controlled) {
1749
+ store.update({ index: index + (action === ACTIONS.PREV ? -1 : 1) });
1750
+ }
1751
+ }
1752
+ }
1753
+ if (changedFrom("lifecycle", LIFECYCLE.INIT, LIFECYCLE.READY)) {
1754
+ store.update({
1755
+ lifecycle: hideBeacon(step) || skipBeacon ? LIFECYCLE.TOOLTIP : LIFECYCLE.BEACON
1756
+ });
1757
+ }
1758
+ if (changed("index")) {
1759
+ log({
1760
+ title: `step:${lifecycle}`,
1761
+ data: [{ key: "props", value: props }],
1762
+ debug
1763
+ });
1764
+ }
1765
+ if (changed("lifecycle", LIFECYCLE.BEACON)) {
1766
+ callback({
1767
+ ...state,
1768
+ step,
1769
+ type: EVENTS.BEACON
1770
+ });
1771
+ }
1772
+ if (changed("lifecycle", LIFECYCLE.TOOLTIP)) {
1773
+ callback({
1774
+ ...state,
1775
+ step,
1776
+ type: EVENTS.TOOLTIP
1777
+ });
1778
+ if (shouldScroll2 && tooltipRef.current) {
1779
+ scopeRef.current = new Scope(tooltipRef.current, { selector: "[data-action=primary]" });
1780
+ scopeRef.current.setFocus();
1781
+ }
1782
+ }
1783
+ if (changedFrom("lifecycle", [LIFECYCLE.TOOLTIP, LIFECYCLE.INIT], LIFECYCLE.INIT)) {
1784
+ (_a2 = scopeRef.current) == null ? void 0 : _a2.removeScope();
1785
+ store.cleanupPoppers();
1786
+ }
1787
+ previousPropsRef.current = props;
1788
+ });
1789
+ const target = getElement(step.target);
1790
+ if (!validateStep(step) || !import_is_lite5.default.domElement(target)) {
1791
+ return null;
1792
+ }
1793
+ const isOpen = hideBeacon(step) || lifecycle === LIFECYCLE.TOOLTIP;
1794
+ const TooltipComponent = () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1795
+ JoyrideTooltip,
1796
+ {
1797
+ continuous,
1798
+ helpers,
1799
+ index,
1800
+ isLastStep: index + 1 === size,
1801
+ setTooltipRef,
1802
+ size,
1803
+ step
1804
+ }
1805
+ );
1806
+ const { content: _c, component: _comp, ...safeFloaterProps } = (_a = step.floaterProps) != null ? _a : {};
1807
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "react-joyride__step", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1808
+ import_react_floater.default,
1809
+ {
1810
+ ...safeFloaterProps,
1811
+ component: TooltipComponent,
1812
+ debug,
1813
+ getPopper: setPopper,
1814
+ id: `react-joyride-step-${index}`,
1815
+ open: isOpen,
1816
+ placement: step.placement,
1817
+ target: step.target,
1818
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1819
+ JoyrideBeacon,
1820
+ {
1821
+ beaconComponent: step.beaconComponent,
1822
+ continuous,
1823
+ index,
1824
+ isLastStep: index + 1 === size,
1825
+ locale: step.locale,
1826
+ nonce,
1827
+ onClickOrHover: handleClickHoverBeacon,
1828
+ shouldFocus: shouldScroll2,
1829
+ size,
1830
+ step,
1831
+ styles: step.styles
1832
+ }
1833
+ )
1834
+ }
1835
+ ) }, `JoyrideStep-${index}`);
1836
+ }
1837
+
1838
+ // src/components/index.tsx
1839
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1840
+ var defaultPropsValues = {
1841
+ continuous: false,
1842
+ debug: false,
1843
+ disableCloseOnEsc: false,
1844
+ disableOverlay: false,
1845
+ disableOverlayClose: false,
1846
+ disableScrolling: false,
1847
+ disableScrollParentFix: false,
1848
+ hideBackButton: false,
1849
+ run: true,
1850
+ scrollOffset: 20,
1851
+ scrollDuration: 300,
1852
+ scrollToFirstStep: false,
1853
+ showSkipButton: false,
1854
+ showProgress: false,
1855
+ spotlightClicks: false,
1856
+ spotlightPadding: 10,
1857
+ steps: []
1858
+ };
1859
+ function Joyride(inputProps) {
1860
+ const props = { ...defaultPropsValues, ...inputProps };
1861
+ const {
1862
+ callback: callbackProp,
1863
+ continuous,
1864
+ debug,
1865
+ disableCloseOnEsc,
1866
+ getHelpers,
1867
+ nonce,
1868
+ run,
1869
+ scrollDuration,
1870
+ scrollOffset,
1871
+ scrollToFirstStep,
1872
+ stepIndex,
1873
+ steps
1874
+ } = props;
1875
+ const storeRef = (0, import_react6.useRef)(
1876
+ createStore({
1877
+ ...props,
1878
+ controlled: run && import_is_lite6.default.number(stepIndex)
1879
+ })
1880
+ );
1881
+ const helpersRef = (0, import_react6.useRef)(storeRef.current.getHelpers());
1882
+ const [state, setState] = (0, import_react6.useState)(storeRef.current.getState());
1883
+ const previousStateRef = (0, import_react6.useRef)(state);
1884
+ const previousPropsRef = (0, import_react6.useRef)(props);
1885
+ const mountedRef = (0, import_react6.useRef)(false);
1886
+ const store = storeRef.current;
1887
+ const helpers = helpersRef.current;
1888
+ const triggerCallback = (0, import_react6.useCallback)(
1889
+ (data) => {
1890
+ if (import_is_lite6.default.function(callbackProp)) {
1891
+ callbackProp(data);
1892
+ }
1893
+ },
1894
+ [callbackProp]
1895
+ );
1896
+ const handleKeyboard = (0, import_react6.useCallback)(
1897
+ (event) => {
1898
+ const { index: currentIndex, lifecycle: lifecycle2 } = storeRef.current.getState();
1899
+ const currentSteps = props.steps;
1900
+ const currentStep = currentSteps[currentIndex];
1901
+ if (lifecycle2 === LIFECYCLE.TOOLTIP) {
1902
+ if (event.code === "Escape" && currentStep && !currentStep.disableCloseOnEsc) {
1903
+ storeRef.current.close("keyboard");
1904
+ }
1905
+ }
1906
+ },
1907
+ [props.steps]
1908
+ );
1909
+ const handleClickOverlay = (0, import_react6.useCallback)(() => {
1910
+ const currentState = storeRef.current.getState();
1911
+ const step = getMergedStep(props, steps[currentState.index]);
1912
+ if (!step.disableOverlayClose) {
1913
+ helpers.close("overlay");
1914
+ }
1915
+ }, [props, steps, helpers]);
1916
+ (0, import_react6.useEffect)(() => {
1917
+ store.addListener(setState);
1918
+ log({
1919
+ title: "init",
1920
+ data: [
1921
+ { key: "props", value: props },
1922
+ { key: "state", value: state }
1923
+ ],
1924
+ debug
1925
+ });
1926
+ if (getHelpers) {
1927
+ getHelpers(helpers);
1928
+ }
1929
+ }, []);
1930
+ (0, import_react6.useEffect)(() => {
1931
+ if (!canUseDOM()) {
1932
+ return;
1933
+ }
1934
+ if (validateSteps(steps, debug) && run) {
1935
+ store.start();
1936
+ }
1937
+ if (!disableCloseOnEsc) {
1938
+ document.body.addEventListener("keydown", handleKeyboard, { passive: true });
1939
+ }
1940
+ mountedRef.current = true;
1941
+ return () => {
1942
+ if (!disableCloseOnEsc) {
1943
+ document.body.removeEventListener("keydown", handleKeyboard);
1944
+ }
1945
+ };
1946
+ }, []);
1947
+ (0, import_react6.useEffect)(() => {
1948
+ if (!mountedRef.current || !canUseDOM()) {
1949
+ return;
1950
+ }
1951
+ const previousProps = previousPropsRef.current;
1952
+ const { changedProps } = (0, import_tree_changes3.default)(previousProps, props);
1953
+ const changedPropsFn = (key) => {
1954
+ const prev = previousProps[key];
1955
+ const curr = props[key];
1956
+ return prev !== curr;
1957
+ };
1958
+ const stepsChanged = !(0, import_deep_equal.default)(previousProps.steps, steps);
1959
+ if (stepsChanged) {
1960
+ if (validateSteps(steps, debug)) {
1961
+ store.setSteps(steps);
1962
+ } else {
1963
+ console.warn("Steps are not valid", steps);
1964
+ }
1965
+ }
1966
+ if (changedPropsFn("run")) {
1967
+ if (run) {
1968
+ store.start(stepIndex);
1969
+ } else {
1970
+ store.stop();
1971
+ }
1972
+ }
1973
+ const stepIndexChanged = import_is_lite6.default.number(stepIndex) && changedPropsFn("stepIndex");
1974
+ if (stepIndexChanged) {
1975
+ const currentState = store.getState();
1976
+ let nextAction = import_is_lite6.default.number(previousProps.stepIndex) && previousProps.stepIndex < stepIndex ? ACTIONS.NEXT : ACTIONS.PREV;
1977
+ if (currentState.action === ACTIONS.STOP) {
1978
+ nextAction = ACTIONS.START;
1979
+ }
1980
+ if (![STATUS.FINISHED, STATUS.SKIPPED].includes(currentState.status)) {
1981
+ store.update({
1982
+ action: currentState.action === ACTIONS.CLOSE ? ACTIONS.CLOSE : nextAction,
1983
+ index: stepIndex,
1984
+ lifecycle: LIFECYCLE.INIT
1985
+ });
1986
+ }
1987
+ }
1988
+ previousPropsRef.current = props;
1989
+ });
1990
+ (0, import_react6.useEffect)(() => {
1991
+ if (!mountedRef.current || !canUseDOM()) {
1992
+ return;
1993
+ }
1994
+ const previousState = previousStateRef.current;
1995
+ const { action, controlled, index: index2, lifecycle: lifecycle2, status: status2 } = state;
1996
+ const { changed, changedFrom } = (0, import_tree_changes3.default)(previousState, state);
1997
+ const step = getMergedStep(props, steps[index2]);
1998
+ const target = getElement(step.target);
1999
+ if (!controlled && status2 === STATUS.RUNNING && index2 === 0 && !target) {
2000
+ store.update({ index: index2 + 1 });
2001
+ triggerCallback({
2002
+ ...state,
2003
+ type: EVENTS.TARGET_NOT_FOUND,
2004
+ step
2005
+ });
2006
+ }
2007
+ const callbackData = {
2008
+ ...state,
2009
+ index: index2,
2010
+ step
2011
+ };
2012
+ const isAfterAction = changed("action", [
2013
+ ACTIONS.NEXT,
2014
+ ACTIONS.PREV,
2015
+ ACTIONS.SKIP,
2016
+ ACTIONS.CLOSE
2017
+ ]);
2018
+ if (isAfterAction && changed("status", STATUS.PAUSED)) {
2019
+ const previousStep = getMergedStep(props, steps[previousState.index]);
2020
+ triggerCallback({
2021
+ ...callbackData,
2022
+ index: previousState.index,
2023
+ lifecycle: LIFECYCLE.COMPLETE,
2024
+ step: previousStep,
2025
+ type: EVENTS.STEP_AFTER
2026
+ });
2027
+ }
2028
+ if (changed("status", [STATUS.FINISHED, STATUS.SKIPPED])) {
2029
+ const previousStep = getMergedStep(props, steps[previousState.index]);
2030
+ if (!controlled) {
2031
+ triggerCallback({
2032
+ ...callbackData,
2033
+ index: previousState.index,
2034
+ lifecycle: LIFECYCLE.COMPLETE,
2035
+ step: previousStep,
2036
+ type: EVENTS.STEP_AFTER
2037
+ });
2038
+ }
2039
+ triggerCallback({
2040
+ ...callbackData,
2041
+ type: EVENTS.TOUR_END,
2042
+ // Return the last step when the tour is finished
2043
+ step: previousStep,
2044
+ index: previousState.index
2045
+ });
2046
+ store.reset();
2047
+ } else if (changedFrom("status", [STATUS.IDLE, STATUS.READY], STATUS.RUNNING)) {
2048
+ triggerCallback({
2049
+ ...callbackData,
2050
+ type: EVENTS.TOUR_START
2051
+ });
2052
+ } else if (changed("status") || changed("action", ACTIONS.RESET)) {
2053
+ triggerCallback({
2054
+ ...callbackData,
2055
+ type: EVENTS.TOUR_STATUS
2056
+ });
2057
+ }
2058
+ scrollToStep(previousState);
2059
+ previousStateRef.current = state;
2060
+ });
2061
+ function scrollToStep(previousState) {
2062
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
2063
+ const { index: index2, lifecycle: lifecycle2, status: status2 } = state;
2064
+ const {
2065
+ disableScrollParentFix = false
2066
+ } = props;
2067
+ const step = getMergedStep(props, steps[index2]);
2068
+ const target = getElement(step.target);
2069
+ const shouldScrollToStep = shouldScroll({
2070
+ isFirstStep: index2 === 0,
2071
+ lifecycle: lifecycle2,
2072
+ previousLifecycle: previousState.lifecycle,
2073
+ scrollToFirstStep,
2074
+ step,
2075
+ target
2076
+ });
2077
+ if (status2 === STATUS.RUNNING && shouldScrollToStep) {
2078
+ const hasCustomScroll = hasCustomScrollParent(target, disableScrollParentFix);
2079
+ const scrollParent2 = getScrollParent(target, disableScrollParentFix);
2080
+ let scrollY = Math.floor(getScrollTo(target, scrollOffset, disableScrollParentFix)) || 0;
2081
+ log({
2082
+ title: "scrollToStep",
2083
+ data: [
2084
+ { key: "index", value: index2 },
2085
+ { key: "lifecycle", value: lifecycle2 },
2086
+ { key: "status", value: status2 }
2087
+ ],
2088
+ debug
2089
+ });
2090
+ const beaconPopper = store.getPopper("beacon");
2091
+ const tooltipPopper = store.getPopper("tooltip");
2092
+ if (lifecycle2 === LIFECYCLE.BEACON && beaconPopper) {
2093
+ const placement = (_b = (_a = beaconPopper.state) == null ? void 0 : _a.placement) != null ? _b : "";
2094
+ const popperTop = (_f = (_e = (_d = (_c = beaconPopper.state) == null ? void 0 : _c.rects) == null ? void 0 : _d.popper) == null ? void 0 : _e.y) != null ? _f : 0;
2095
+ if (!["bottom"].includes(placement) && !hasCustomScroll) {
2096
+ scrollY = Math.floor(popperTop - scrollOffset);
2097
+ }
2098
+ } else if (lifecycle2 === LIFECYCLE.TOOLTIP && tooltipPopper) {
2099
+ const placement = (_h = (_g = tooltipPopper.state) == null ? void 0 : _g.placement) != null ? _h : "";
2100
+ const popperTop = (_l = (_k = (_j = (_i = tooltipPopper.state) == null ? void 0 : _i.rects) == null ? void 0 : _j.popper) == null ? void 0 : _k.y) != null ? _l : 0;
2101
+ const flipped = ((_o = (_n = (_m = tooltipPopper.state) == null ? void 0 : _m.modifiersData) == null ? void 0 : _n.flip) == null ? void 0 : _o.overflows) != null;
2102
+ if (["top", "right", "left"].includes(placement) && !flipped && !hasCustomScroll) {
2103
+ scrollY = Math.floor(popperTop - scrollOffset);
2104
+ } else {
2105
+ scrollY -= step.spotlightPadding;
2106
+ }
2107
+ }
2108
+ scrollY = scrollY >= 0 ? scrollY : 0;
2109
+ if (status2 === STATUS.RUNNING) {
2110
+ scrollTo(scrollY, { element: scrollParent2, duration: scrollDuration }).then(
2111
+ () => {
2112
+ setTimeout(() => {
2113
+ var _a2;
2114
+ (_a2 = store.getPopper("tooltip")) == null ? void 0 : _a2.update();
2115
+ }, 10);
2116
+ }
2117
+ );
2118
+ }
2119
+ }
2120
+ }
2121
+ if (!canUseDOM()) {
2122
+ return null;
2123
+ }
2124
+ const { index, lifecycle, status } = state;
2125
+ const isRunning = status === STATUS.RUNNING;
2126
+ const content = {};
2127
+ if (isRunning && steps[index]) {
2128
+ const step = getMergedStep(props, steps[index]);
2129
+ content.step = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2130
+ JoyrideStep,
2131
+ {
2132
+ ...state,
2133
+ callback: triggerCallback,
2134
+ continuous,
2135
+ debug,
2136
+ helpers,
2137
+ nonce,
2138
+ shouldScroll: !step.disableScrolling && (index !== 0 || scrollToFirstStep),
2139
+ step,
2140
+ store
2141
+ }
2142
+ );
2143
+ content.overlay = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(JoyridePortal, { id: "react-joyride-portal", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2144
+ JoyrideOverlay,
2145
+ {
2146
+ ...step,
2147
+ continuous,
2148
+ debug,
2149
+ lifecycle,
2150
+ onClickOverlay: handleClickOverlay
2151
+ }
2152
+ ) });
2153
+ }
2154
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "react-joyride", children: [
2155
+ content.step,
2156
+ content.overlay
2157
+ ] });
2158
+ }
2159
+ var components_default = Joyride;
2160
+ // Annotate the CommonJS export names for ESM import in node:
2161
+ 0 && (module.exports = {
2162
+ ACTIONS,
2163
+ EVENTS,
2164
+ LIFECYCLE,
2165
+ ORIGIN,
2166
+ STATUS
2167
+ });
2168
+ //# sourceMappingURL=index.js.map