@tent-official/react-walkthrough 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.mjs ADDED
@@ -0,0 +1,651 @@
1
+ import { useRef, useEffect, useCallback, useState } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+ import styled, { keyframes, css } from 'styled-components';
4
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/WalkthroughOverlay.js
7
+ var listeners = /* @__PURE__ */ new Set();
8
+ var globalState = {
9
+ activeTour: null
10
+ };
11
+ var notify = () => {
12
+ listeners.forEach((fn) => fn({ ...globalState }));
13
+ };
14
+ var setGlobalState = (updater) => {
15
+ globalState = typeof updater === "function" ? updater(globalState) : { ...globalState, ...updater };
16
+ notify();
17
+ };
18
+ var useGlobalState = () => {
19
+ const [state, setState] = useState(globalState);
20
+ useEffect(() => {
21
+ const handler = (s) => setState(s);
22
+ listeners.add(handler);
23
+ return () => listeners.delete(handler);
24
+ }, []);
25
+ return state;
26
+ };
27
+ var getStorageKey = (storageKey) => {
28
+ return storageKey ? `walkthrough-done:${storageKey}` : "walkthrough-done";
29
+ };
30
+ var getStorageData = (storageKey) => {
31
+ try {
32
+ return JSON.parse(localStorage.getItem(getStorageKey(storageKey)) || "{}");
33
+ } catch (e) {
34
+ return {};
35
+ }
36
+ };
37
+ var markDone = (storageKey, name) => {
38
+ const key = getStorageKey(storageKey);
39
+ const data = getStorageData(storageKey);
40
+ data[name] = true;
41
+ localStorage.setItem(key, JSON.stringify(data));
42
+ window.dispatchEvent(new Event("walkthrough-done"));
43
+ };
44
+ var isDone = (storageKey, name) => {
45
+ const data = getStorageData(storageKey);
46
+ return data[name] === true;
47
+ };
48
+ var isAnyDepDone = (storageKey, deps) => {
49
+ if (!deps || deps.length === 0) return true;
50
+ return deps.some((d) => isDone(storageKey, d));
51
+ };
52
+ var resetWalkthrough = ({ storageKey = "", walkthroughList = [] } = {}) => {
53
+ const key = getStorageKey(storageKey);
54
+ const data = getStorageData(storageKey);
55
+ walkthroughList.forEach((n) => {
56
+ delete data[n];
57
+ });
58
+ localStorage.setItem(key, JSON.stringify(data));
59
+ window.dispatchEvent(new Event("walkthrough-done"));
60
+ };
61
+ var easeOutCubic = (t) => {
62
+ return 1 - Math.pow(1 - t, 3);
63
+ };
64
+ var lerp = (a, b, t) => {
65
+ return a + (b - a) * t;
66
+ };
67
+ var popIn = keyframes`
68
+ from {
69
+ opacity: 0;
70
+ transform: translateY(10px) scale(0.96);
71
+ }
72
+ to {
73
+ opacity: 1;
74
+ transform: translateY(0) scale(1);
75
+ }
76
+ `;
77
+ var fadeSlideIn = keyframes`
78
+ from {
79
+ opacity: 0;
80
+ transform: translateX(12px);
81
+ }
82
+ to {
83
+ opacity: 1;
84
+ transform: translateX(0);
85
+ }
86
+ `;
87
+ var OverlayWrapper = styled.div`
88
+ position: fixed;
89
+ inset: 0;
90
+ z-index: 10001;
91
+ pointer-events: none;
92
+ width: 100vw;
93
+ height: 100vh;
94
+
95
+ & svg {
96
+ width: 100%;
97
+ height: 100%;
98
+ }
99
+ `;
100
+ var ClickLayer = styled.div`
101
+ position: fixed;
102
+ inset: 0;
103
+ z-index: 10000;
104
+ cursor: default;
105
+ `;
106
+ var PopoverContainer = styled.div`
107
+ position: absolute;
108
+ z-index: 99999;
109
+ background: #fff;
110
+ box-shadow:
111
+ 0 12px 40px rgba(0, 0, 0, 0.18),
112
+ 0 2px 10px rgba(0, 0, 0, 0.06);
113
+ animation: ${popIn} 0.28s cubic-bezier(0.34, 1.56, 0.64, 1);
114
+ `;
115
+ var PopoverBody = styled.div`
116
+ animation: ${fadeSlideIn} 0.3s ease-out;
117
+ `;
118
+ var PopoverTitle = styled.h3`
119
+ font-size: 15px;
120
+ font-weight: 700;
121
+ color: #1a1a2e;
122
+ margin: 0 0 10px;
123
+ line-height: 1.3;
124
+ `;
125
+ var DescriptionScrollArea = styled.div`
126
+ ${({ $height }) => $height && $height !== "auto" ? css`
127
+ max-height: ${typeof $height === "number" ? `${$height}px` : $height};
128
+ overflow-y: auto;
129
+ ` : ""}
130
+ `;
131
+ var DescriptionBlock = styled.div`
132
+ display: flex;
133
+ flex-direction: ${({ $direction = "row" }) => $direction};
134
+ font-size: 13px;
135
+ color: #666;
136
+ line-height: 1.6;
137
+ margin: 0 0 4px;
138
+
139
+ ${({ $direction }) => $direction === "column" ? css`
140
+ gap: 2px;
141
+ ` : css`
142
+ align-items: baseline;
143
+ gap: 4px;
144
+ `}
145
+ `;
146
+ var DescriptionTitle = styled.span`
147
+ font-weight: 600;
148
+ color: #333;
149
+ white-space: nowrap;
150
+ `;
151
+ var PopoverFooter = styled.div`
152
+ display: flex;
153
+ align-items: center;
154
+ justify-content: space-between;
155
+ margin-top: 16px;
156
+ gap: 8px;
157
+ `;
158
+ var StepCounter = styled.span`
159
+ font-size: 13px;
160
+ font-weight: 600;
161
+ color: #a1a1aa;
162
+ `;
163
+ var ButtonGroup = styled.div`
164
+ display: flex;
165
+ gap: 6px;
166
+ `;
167
+ var Button = styled.button`
168
+ border: none;
169
+ border-radius: 8px;
170
+ padding: 7px 16px;
171
+ font-size: 13px;
172
+ font-weight: 600;
173
+ cursor: pointer;
174
+ transition: all 0.15s ease;
175
+ outline: none;
176
+
177
+ ${(p) => p.$variant === "skip" && css`
178
+ background: ${p.$skipColor || "transparent"};
179
+ color: ${p.$skipColor ? "#fff" : "#a1a1aa"};
180
+ &:hover {
181
+ opacity: 0.8;
182
+ }
183
+ `}
184
+
185
+ ${(p) => p.$variant === "prev" && css`
186
+ background: ${p.$prevColor || "#f4f4f5"};
187
+ color: ${p.$prevColor ? "#fff" : "#3f3f46"};
188
+ &:hover {
189
+ opacity: 0.8;
190
+ }
191
+ `}
192
+
193
+ ${(p) => p.$variant === "next" && css`
194
+ background: ${p.$nextColor || "#4f46e5"};
195
+ color: #fff;
196
+ box-shadow: 0 2px 8px rgba(79, 70, 229, 0.3);
197
+ &:hover {
198
+ opacity: 0.9;
199
+ box-shadow: 0 4px 12px rgba(79, 70, 229, 0.4);
200
+ transform: translateY(-1px);
201
+ }
202
+ &:active {
203
+ transform: translateY(0);
204
+ }
205
+ `}
206
+ `;
207
+ var useWalkthrough = ({
208
+ name,
209
+ storageKey = "",
210
+ dependsOn = [],
211
+ steps,
212
+ onWalkthroughComplete,
213
+ isShowSkip = true,
214
+ isShowPrev = true,
215
+ nextLabel = "Next \u2192",
216
+ prevLabel = "Back",
217
+ skipLabel = "Skip",
218
+ doneLabel = "Done \u2713",
219
+ nextColor,
220
+ prevColor,
221
+ skipColor
222
+ }) => {
223
+ const started = useRef(false);
224
+ const onCompleteRef = useRef(onWalkthroughComplete);
225
+ useEffect(() => {
226
+ onCompleteRef.current = onWalkthroughComplete;
227
+ }, [onWalkthroughComplete]);
228
+ const start = useCallback(() => {
229
+ if (isDone(storageKey, name) || started.current) return;
230
+ started.current = true;
231
+ setGlobalState({
232
+ activeTour: {
233
+ name,
234
+ steps,
235
+ currentStep: 0,
236
+ storageKey,
237
+ onWalkthroughComplete: onCompleteRef.current,
238
+ isShowSkip,
239
+ isShowPrev,
240
+ nextLabel,
241
+ prevLabel,
242
+ skipLabel,
243
+ doneLabel,
244
+ nextColor,
245
+ prevColor,
246
+ skipColor
247
+ }
248
+ });
249
+ }, [
250
+ name,
251
+ steps,
252
+ storageKey,
253
+ isShowSkip,
254
+ isShowPrev,
255
+ nextLabel,
256
+ prevLabel,
257
+ skipLabel,
258
+ doneLabel,
259
+ nextColor,
260
+ prevColor,
261
+ skipColor
262
+ ]);
263
+ useEffect(() => {
264
+ const check = () => {
265
+ if (isDone(storageKey, name)) return;
266
+ started.current = false;
267
+ if (isAnyDepDone(storageKey, dependsOn) && !globalState.activeTour) {
268
+ start();
269
+ }
270
+ };
271
+ check();
272
+ window.addEventListener("walkthrough-done", check);
273
+ return () => window.removeEventListener("walkthrough-done", check);
274
+ }, [name, storageKey, dependsOn, start]);
275
+ return { start };
276
+ };
277
+ var useAnimatedRect = (step, transitionMs = 350) => {
278
+ const [displayRect, setDisplayRect] = useState(null);
279
+ const targetRef = useRef(null);
280
+ const currentRef = useRef(null);
281
+ const rafRef = useRef(null);
282
+ useEffect(() => {
283
+ if (!step) {
284
+ setDisplayRect(null);
285
+ currentRef.current = null;
286
+ targetRef.current = null;
287
+ return;
288
+ }
289
+ const el = document.getElementById(step.el);
290
+ if (!el) {
291
+ setDisplayRect(null);
292
+ return;
293
+ }
294
+ const compute = () => {
295
+ var _a;
296
+ const r = el.getBoundingClientRect();
297
+ const padding = (_a = step.padding) != null ? _a : 8;
298
+ return {
299
+ top: r.top - padding + window.scrollY,
300
+ left: r.left - padding + window.scrollX,
301
+ width: r.width + padding * 2,
302
+ height: r.height + padding * 2
303
+ };
304
+ };
305
+ const newTarget = compute();
306
+ targetRef.current = newTarget;
307
+ el.scrollIntoView({ behavior: "smooth", block: "center" });
308
+ if (!currentRef.current) {
309
+ currentRef.current = newTarget;
310
+ setDisplayRect(newTarget);
311
+ return;
312
+ }
313
+ const from = { ...currentRef.current };
314
+ const to = newTarget;
315
+ const startTime = performance.now();
316
+ const tick = (now) => {
317
+ const elapsed = now - startTime;
318
+ const progress = Math.min(elapsed / transitionMs, 1);
319
+ const eased = easeOutCubic(progress);
320
+ const interpolated = {
321
+ top: lerp(from.top, to.top, eased),
322
+ left: lerp(from.left, to.left, eased),
323
+ width: lerp(from.width, to.width, eased),
324
+ height: lerp(from.height, to.height, eased)
325
+ };
326
+ currentRef.current = interpolated;
327
+ setDisplayRect(interpolated);
328
+ if (progress < 1) {
329
+ rafRef.current = requestAnimationFrame(tick);
330
+ } else {
331
+ currentRef.current = to;
332
+ setDisplayRect(to);
333
+ }
334
+ };
335
+ rafRef.current = requestAnimationFrame(tick);
336
+ const onLayout = () => {
337
+ const updated = compute();
338
+ targetRef.current = updated;
339
+ currentRef.current = updated;
340
+ setDisplayRect(updated);
341
+ };
342
+ window.addEventListener("resize", onLayout);
343
+ window.addEventListener("scroll", onLayout, true);
344
+ return () => {
345
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
346
+ window.removeEventListener("resize", onLayout);
347
+ window.removeEventListener("scroll", onLayout, true);
348
+ };
349
+ }, [step]);
350
+ return displayRect;
351
+ };
352
+ var clampSize = (value, max) => {
353
+ if (value === "auto" || value === void 0) return "auto";
354
+ const num = typeof value === "string" ? parseInt(value, 10) : value;
355
+ const clamped = Math.min(num, max - 12);
356
+ return clamped;
357
+ };
358
+ var EDGE_MARGIN = 8;
359
+ var computePopoverPosition = (rect, popoverW, popoverH, gap, preferred) => {
360
+ const vw = window.innerWidth;
361
+ const vh = window.innerHeight;
362
+ const clampLeft = (left) => Math.max(EDGE_MARGIN, Math.min(left, vw - popoverW - EDGE_MARGIN));
363
+ const clampTop = (top) => Math.max(EDGE_MARGIN, Math.min(top, vh - popoverH - EDGE_MARGIN));
364
+ const positions = {
365
+ bottom: {
366
+ top: rect.top + rect.height + gap,
367
+ left: clampLeft(rect.left)
368
+ },
369
+ top: {
370
+ top: rect.top - popoverH - gap,
371
+ left: clampLeft(rect.left)
372
+ },
373
+ right: {
374
+ top: clampTop(rect.top),
375
+ left: rect.left + rect.width + gap
376
+ },
377
+ left: {
378
+ top: clampTop(rect.top),
379
+ left: rect.left - popoverW - gap
380
+ }
381
+ };
382
+ const fitsInViewport = (pos) => pos.top >= EDGE_MARGIN && pos.left >= EDGE_MARGIN && pos.top + popoverH <= vh - EDGE_MARGIN && pos.left + popoverW <= vw - EDGE_MARGIN;
383
+ if (preferred && positions[preferred] && fitsInViewport(positions[preferred])) {
384
+ return positions[preferred];
385
+ }
386
+ const order = ["bottom", "top", "right", "left"];
387
+ for (const dir of order) {
388
+ if (fitsInViewport(positions[dir])) {
389
+ return positions[dir];
390
+ }
391
+ }
392
+ const spaceBottom = vh - (rect.top + rect.height + gap);
393
+ const spaceTop = rect.top - gap;
394
+ const spaceRight = vw - (rect.left + rect.width + gap);
395
+ const spaceLeft = rect.left - gap;
396
+ const best = [
397
+ { dir: "bottom", space: spaceBottom },
398
+ { dir: "top", space: spaceTop },
399
+ { dir: "right", space: spaceRight },
400
+ { dir: "left", space: spaceLeft }
401
+ ].sort((a, b) => b.space - a.space)[0].dir;
402
+ const fallback = positions[best];
403
+ return {
404
+ top: Math.max(EDGE_MARGIN, Math.min(fallback.top, vh - popoverH - EDGE_MARGIN)),
405
+ left: Math.max(EDGE_MARGIN, Math.min(fallback.left, vw - popoverW - EDGE_MARGIN))
406
+ };
407
+ };
408
+ var WalkthroughOverlay = ({
409
+ $popoverPadding = 12,
410
+ $popoverBorderRadius = 8,
411
+ $popoverGap = 12,
412
+ $fontFamily,
413
+ $animationSpeed = 350
414
+ } = {}) => {
415
+ var _a, _b;
416
+ const { activeTour } = useGlobalState();
417
+ const nextBtnRef = useRef(null);
418
+ const popoverRef = useRef(null);
419
+ const [popoverPos, setPopoverPos] = useState(null);
420
+ const [validSteps, setValidSteps] = useState([]);
421
+ const waitingForElsRef = useRef(false);
422
+ useEffect(() => {
423
+ if (!activeTour) {
424
+ setValidSteps([]);
425
+ waitingForElsRef.current = false;
426
+ return;
427
+ }
428
+ waitingForElsRef.current = true;
429
+ const compute = () => activeTour.steps.map((s, i) => ({ ...s, _originalIdx: i })).filter((s) => document.getElementById(s.el));
430
+ const found = compute();
431
+ if (found.length > 0) {
432
+ setValidSteps(found);
433
+ return;
434
+ }
435
+ setValidSteps([]);
436
+ const observer = new MutationObserver(() => {
437
+ const updated = compute();
438
+ if (updated.length > 0) {
439
+ waitingForElsRef.current = false;
440
+ setValidSteps(updated);
441
+ observer.disconnect();
442
+ }
443
+ });
444
+ observer.observe(document.body, { childList: true, subtree: true });
445
+ return () => {
446
+ observer.disconnect();
447
+ waitingForElsRef.current = false;
448
+ };
449
+ }, [activeTour]);
450
+ const currentOriginalIdx = (_a = activeTour == null ? void 0 : activeTour.currentStep) != null ? _a : 0;
451
+ const currentValidPos = validSteps.findIndex(
452
+ (s) => s._originalIdx === currentOriginalIdx
453
+ );
454
+ const step = currentValidPos !== -1 ? validSteps[currentValidPos] : null;
455
+ const rect = useAnimatedRect(step, $animationSpeed);
456
+ const completeTour = useCallback(() => {
457
+ if (!activeTour) return;
458
+ const { storageKey: sk, name: n, onWalkthroughComplete: cb } = activeTour;
459
+ setGlobalState({ activeTour: null });
460
+ markDone(sk, n);
461
+ if (cb) cb(n);
462
+ }, [activeTour]);
463
+ useEffect(() => {
464
+ if (!activeTour) return;
465
+ if (currentValidPos !== -1) return;
466
+ if (waitingForElsRef.current) return;
467
+ if (validSteps.length === 0) {
468
+ completeTour();
469
+ return;
470
+ }
471
+ const nextValid = validSteps.find(
472
+ (s) => s._originalIdx > currentOriginalIdx
473
+ );
474
+ if (nextValid) {
475
+ setGlobalState((s) => ({
476
+ ...s,
477
+ activeTour: { ...s.activeTour, currentStep: nextValid._originalIdx }
478
+ }));
479
+ } else {
480
+ completeTour();
481
+ }
482
+ }, [
483
+ activeTour,
484
+ currentValidPos,
485
+ currentOriginalIdx,
486
+ validSteps,
487
+ completeTour
488
+ ]);
489
+ useEffect(() => {
490
+ if (!popoverRef.current || !rect || !step) {
491
+ setPopoverPos(null);
492
+ return;
493
+ }
494
+ const targetEl = document.getElementById(step.el);
495
+ if (!targetEl) {
496
+ setPopoverPos(null);
497
+ return;
498
+ }
499
+ const targetRect = targetEl.getBoundingClientRect();
500
+ const inViewport = targetRect.bottom > 0 && targetRect.top < window.innerHeight && targetRect.right > 0 && targetRect.left < window.innerWidth;
501
+ if (!inViewport) {
502
+ setPopoverPos(null);
503
+ return;
504
+ }
505
+ const measured = popoverRef.current.getBoundingClientRect();
506
+ const pos = computePopoverPosition(
507
+ rect,
508
+ measured.width,
509
+ measured.height,
510
+ $popoverGap,
511
+ step.position
512
+ );
513
+ setPopoverPos(pos);
514
+ }, [rect, step, $popoverGap]);
515
+ useEffect(() => {
516
+ if (nextBtnRef.current) {
517
+ nextBtnRef.current.focus();
518
+ }
519
+ }, [activeTour == null ? void 0 : activeTour.currentStep, popoverPos]);
520
+ const [contentKey, setContentKey] = useState(0);
521
+ const prevStepRef = useRef(null);
522
+ useEffect(() => {
523
+ var _a2;
524
+ const idx = (_a2 = activeTour == null ? void 0 : activeTour.currentStep) != null ? _a2 : null;
525
+ if (idx !== prevStepRef.current) {
526
+ setContentKey((k) => k + 1);
527
+ prevStepRef.current = idx;
528
+ }
529
+ }, [activeTour == null ? void 0 : activeTour.currentStep]);
530
+ if (!activeTour || !step || !rect) return null;
531
+ const totalSteps = validSteps.length;
532
+ const isLast = currentValidPos === totalSteps - 1;
533
+ const borderRadius = (_b = step.borderRadius) != null ? _b : 10;
534
+ const {
535
+ isShowSkip = true,
536
+ isShowPrev = true,
537
+ nextLabel = "Next \u2192",
538
+ prevLabel = "Back",
539
+ skipLabel = "Skip",
540
+ doneLabel = "Done \u2713",
541
+ nextColor,
542
+ prevColor,
543
+ skipColor
544
+ } = activeTour;
545
+ const next = () => {
546
+ if (step.isTriggerEl) {
547
+ const el = document.getElementById(step.el);
548
+ if (el) el.click();
549
+ }
550
+ if (isLast) {
551
+ completeTour();
552
+ } else {
553
+ const nextStep = validSteps[currentValidPos + 1];
554
+ setGlobalState((s) => ({
555
+ ...s,
556
+ activeTour: { ...s.activeTour, currentStep: nextStep._originalIdx }
557
+ }));
558
+ }
559
+ };
560
+ const prev = () => {
561
+ if (currentValidPos > 0) {
562
+ const prevStep = validSteps[currentValidPos - 1];
563
+ setGlobalState((s) => ({
564
+ ...s,
565
+ activeTour: { ...s.activeTour, currentStep: prevStep._originalIdx }
566
+ }));
567
+ }
568
+ };
569
+ const skip = () => {
570
+ completeTour();
571
+ };
572
+ const popoverWidth = clampSize(step.width, window.innerWidth);
573
+ const popoverHeight = step.height ? clampSize(step.height, window.innerHeight) : void 0;
574
+ const popoverStyle = {
575
+ top: popoverPos ? popoverPos.top : -9999,
576
+ left: popoverPos ? popoverPos.left : -9999,
577
+ visibility: popoverPos ? "visible" : "hidden",
578
+ width: popoverWidth,
579
+ padding: $popoverPadding,
580
+ borderRadius: $popoverBorderRadius,
581
+ fontFamily: $fontFamily || '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
582
+ };
583
+ const overlay = /* @__PURE__ */ jsxs(Fragment, { children: [
584
+ /* @__PURE__ */ jsx(ClickLayer, {}),
585
+ /* @__PURE__ */ jsx(OverlayWrapper, { children: /* @__PURE__ */ jsxs("svg", { children: [
586
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("mask", { id: "wt-mask", children: [
587
+ /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "100%", height: "100%", fill: "white" }),
588
+ /* @__PURE__ */ jsx(
589
+ "rect",
590
+ {
591
+ x: rect.left,
592
+ y: rect.top,
593
+ width: rect.width,
594
+ height: rect.height,
595
+ rx: borderRadius,
596
+ fill: "black"
597
+ }
598
+ )
599
+ ] }) }),
600
+ /* @__PURE__ */ jsx(
601
+ "rect",
602
+ {
603
+ x: "0",
604
+ y: "0",
605
+ width: "100%",
606
+ height: "100%",
607
+ fill: "rgba(0,0,0,0.52)",
608
+ mask: "url(#wt-mask)"
609
+ }
610
+ )
611
+ ] }) }),
612
+ /* @__PURE__ */ jsxs(PopoverContainer, { ref: popoverRef, style: popoverStyle, children: [
613
+ /* @__PURE__ */ jsxs(PopoverBody, { children: [
614
+ step.title && /* @__PURE__ */ jsx(PopoverTitle, { children: step.title }),
615
+ /* @__PURE__ */ jsx(DescriptionScrollArea, { $height: popoverHeight, children: Array.isArray(step.description) && step.description.map((d, i) => /* @__PURE__ */ jsxs(DescriptionBlock, { $direction: d.direction, children: [
616
+ d.title && /* @__PURE__ */ jsxs(DescriptionTitle, { children: [
617
+ d.title,
618
+ ": "
619
+ ] }),
620
+ /* @__PURE__ */ jsx("span", { children: d.description })
621
+ ] }, i)) })
622
+ ] }, contentKey),
623
+ /* @__PURE__ */ jsxs(PopoverFooter, { children: [
624
+ /* @__PURE__ */ jsxs(StepCounter, { children: [
625
+ currentValidPos + 1,
626
+ "/",
627
+ totalSteps
628
+ ] }),
629
+ /* @__PURE__ */ jsxs(ButtonGroup, { children: [
630
+ isShowSkip && /* @__PURE__ */ jsx(Button, { $variant: "skip", $skipColor: skipColor, onClick: skip, children: skipLabel }),
631
+ isShowPrev && currentValidPos > 0 && /* @__PURE__ */ jsx(Button, { $variant: "prev", $prevColor: prevColor, onClick: prev, children: prevLabel }),
632
+ /* @__PURE__ */ jsx(
633
+ Button,
634
+ {
635
+ ref: nextBtnRef,
636
+ $variant: "next",
637
+ $nextColor: nextColor,
638
+ onClick: next,
639
+ children: isLast ? doneLabel : nextLabel
640
+ }
641
+ )
642
+ ] })
643
+ ] })
644
+ ] })
645
+ ] });
646
+ return createPortal(overlay, document.body);
647
+ };
648
+
649
+ export { WalkthroughOverlay, resetWalkthrough, useWalkthrough };
650
+ //# sourceMappingURL=index.mjs.map
651
+ //# sourceMappingURL=index.mjs.map