@thelol3882/sapar 0.0.0-stage → 0.3.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.
Files changed (50) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +380 -2
  3. package/dist/adapter-Y9yB3-q3.d.ts +14 -0
  4. package/dist/adapter-fFZPsINL.d.ts +14 -0
  5. package/dist/chunk-7B66QEMY.js +536 -0
  6. package/dist/chunk-7B66QEMY.js.map +1 -0
  7. package/dist/chunk-FM64UDKJ.js +893 -0
  8. package/dist/chunk-FM64UDKJ.js.map +1 -0
  9. package/dist/chunk-VC6XLWM3.js +176 -0
  10. package/dist/chunk-VC6XLWM3.js.map +1 -0
  11. package/dist/chunk-ZBVQGMR4.js +583 -0
  12. package/dist/chunk-ZBVQGMR4.js.map +1 -0
  13. package/dist/cli/index.js +1335 -0
  14. package/dist/core/index.d.ts +273 -0
  15. package/dist/core/index.js +71 -0
  16. package/dist/core/index.js.map +1 -0
  17. package/dist/expo/index.d.ts +189 -0
  18. package/dist/expo/index.js +39 -0
  19. package/dist/expo/index.js.map +1 -0
  20. package/dist/expo-router/index.d.ts +18 -0
  21. package/dist/expo-router/index.js +46 -0
  22. package/dist/expo-router/index.js.map +1 -0
  23. package/dist/next/index.d.ts +18 -0
  24. package/dist/next/index.js +49 -0
  25. package/dist/next/index.js.map +1 -0
  26. package/dist/presentation-CClsPRT6.d.ts +12 -0
  27. package/dist/react/index.d.ts +35 -0
  28. package/dist/react/index.js +29 -0
  29. package/dist/react/index.js.map +1 -0
  30. package/dist/rtk/index.d.ts +751 -0
  31. package/dist/rtk/index.js +114 -0
  32. package/dist/rtk/index.js.map +1 -0
  33. package/dist/stepCount-CTYYFWiV.d.ts +57 -0
  34. package/dist/types-CHD2pB5X.d.ts +192 -0
  35. package/dist/web/index.d.ts +112 -0
  36. package/dist/web/index.js +34 -0
  37. package/dist/web/index.js.map +1 -0
  38. package/package.json +147 -3
  39. package/templates/expo/AnnouncementModal.tsx +102 -0
  40. package/templates/expo/TourCard.tsx +112 -0
  41. package/templates/expo/WhatsNewButton.tsx +87 -0
  42. package/templates/expo/WhatsNewPanel.tsx +167 -0
  43. package/templates/mantine/AnnouncementModal.tsx +66 -0
  44. package/templates/mantine/TourCard.tsx +84 -0
  45. package/templates/mantine/WhatsNewButton.tsx +62 -0
  46. package/templates/mantine/WhatsNewPanel.tsx +129 -0
  47. package/templates/tailwind/AnnouncementModal.tsx +100 -0
  48. package/templates/tailwind/TourCard.tsx +69 -0
  49. package/templates/tailwind/WhatsNewButton.tsx +56 -0
  50. package/templates/tailwind/WhatsNewPanel.tsx +174 -0
@@ -0,0 +1,536 @@
1
+ import {
2
+ defaultAnnounceStep,
3
+ defaultProgress,
4
+ useSaparAdapter,
5
+ useTourStep
6
+ } from "./chunk-VC6XLWM3.js";
7
+ import {
8
+ resolvePresentation,
9
+ spotlightPath
10
+ } from "./chunk-FM64UDKJ.js";
11
+
12
+ // src/web/measure.ts
13
+ function measureElement(element) {
14
+ if (!element?.isConnected) return null;
15
+ const { left, top, width, height } = element.getBoundingClientRect();
16
+ return { x: left, y: top, width, height };
17
+ }
18
+
19
+ // src/web/registry.ts
20
+ var ANCHOR_ATTRIBUTE = "data-sapar";
21
+ var elements = /* @__PURE__ */ new Map();
22
+ var waiters = /* @__PURE__ */ new Map();
23
+ var listeners = /* @__PURE__ */ new Set();
24
+ var isDevelopment = () => typeof process !== "undefined" && process.env.NODE_ENV !== "production";
25
+ function notifyListeners() {
26
+ listeners.forEach((listener) => listener());
27
+ }
28
+ function registerAnchor(key, element) {
29
+ const existing = elements.get(key);
30
+ if (existing && existing !== element && existing.isConnected && isDevelopment()) {
31
+ console.warn(`[sapar] Duplicate anchor "${key}": the most recently registered element wins. Keys must be unique.`);
32
+ }
33
+ elements.set(key, element);
34
+ waiters.get(key)?.forEach((resolve) => resolve(element));
35
+ notifyListeners();
36
+ return () => {
37
+ if (elements.get(key) !== element) return;
38
+ elements.delete(key);
39
+ notifyListeners();
40
+ };
41
+ }
42
+ function getAnchorElement(key) {
43
+ const registered = elements.get(key);
44
+ if (registered?.isConnected) return registered;
45
+ if (typeof document === "undefined") return null;
46
+ return document.querySelector(`[${ANCHOR_ATTRIBUTE}="${CSS.escape(key)}"]`);
47
+ }
48
+ function waitForAnchor(key, timeoutMs) {
49
+ const present = getAnchorElement(key);
50
+ if (present) return Promise.resolve(present);
51
+ return new Promise((resolve) => {
52
+ const pending = waiters.get(key) ?? /* @__PURE__ */ new Set();
53
+ waiters.set(key, pending);
54
+ const observer = new MutationObserver(() => {
55
+ const element = getAnchorElement(key);
56
+ if (element) settle(element);
57
+ });
58
+ const timer = setTimeout(() => settle(null), timeoutMs);
59
+ function settle(element) {
60
+ clearTimeout(timer);
61
+ observer.disconnect();
62
+ pending.delete(settle);
63
+ if (pending.size === 0 && waiters.get(key) === pending) waiters.delete(key);
64
+ resolve(element);
65
+ }
66
+ pending.add(settle);
67
+ observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: [ANCHOR_ATTRIBUTE] });
68
+ });
69
+ }
70
+ var removalObserver = null;
71
+ function watchDocument() {
72
+ removalObserver = new MutationObserver(notifyListeners);
73
+ removalObserver.observe(document.body, {
74
+ childList: true,
75
+ subtree: true,
76
+ attributes: true,
77
+ attributeFilter: [ANCHOR_ATTRIBUTE]
78
+ });
79
+ }
80
+ function stopWatchingDocument() {
81
+ removalObserver?.disconnect();
82
+ removalObserver = null;
83
+ }
84
+ function subscribeToAnchors(listener) {
85
+ if (listeners.size === 0) watchDocument();
86
+ listeners.add(listener);
87
+ return () => {
88
+ listeners.delete(listener);
89
+ if (listeners.size === 0) stopWatchingDocument();
90
+ };
91
+ }
92
+
93
+ // src/web/stores.ts
94
+ function storageWithMemoryFallback(resolve) {
95
+ const memory = /* @__PURE__ */ new Map();
96
+ function readStored(key) {
97
+ try {
98
+ return resolve().getItem(key);
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+ return {
104
+ get: (key) => readStored(key) ?? memory.get(key) ?? null,
105
+ set(key, value) {
106
+ try {
107
+ resolve().setItem(key, value);
108
+ } catch {
109
+ memory.set(key, value);
110
+ }
111
+ },
112
+ remove(key) {
113
+ memory.delete(key);
114
+ try {
115
+ resolve().removeItem(key);
116
+ } catch {
117
+ }
118
+ }
119
+ };
120
+ }
121
+ var localStorageStore = () => storageWithMemoryFallback(() => window.localStorage);
122
+ var browserSessionStore = () => storageWithMemoryFallback(() => window.sessionStorage);
123
+
124
+ // src/web/adapter.ts
125
+ var SCROLL_SETTLE_TIMEOUT_MS = 1e3;
126
+ var SCROLL_STABLE_FRAMES = 2;
127
+ var nextFrame = () => new Promise((resolve) => requestAnimationFrame(() => resolve()));
128
+ async function waitForScrollSettle(element) {
129
+ const deadline = performance.now() + SCROLL_SETTLE_TIMEOUT_MS;
130
+ let previous = element.getBoundingClientRect();
131
+ let stableFrames = 0;
132
+ while (stableFrames < SCROLL_STABLE_FRAMES && element.isConnected && performance.now() < deadline) {
133
+ await nextFrame();
134
+ const current = element.getBoundingClientRect();
135
+ stableFrames = current.top === previous.top && current.left === previous.left ? stableFrames + 1 : 0;
136
+ previous = current;
137
+ }
138
+ }
139
+ function createHandle(key) {
140
+ return {
141
+ key,
142
+ measure: async () => measureElement(getAnchorElement(key)),
143
+ onPress(listener) {
144
+ const handleClick = (event) => {
145
+ const element = getAnchorElement(key);
146
+ if (element && event.target instanceof Node && element.contains(event.target)) listener();
147
+ };
148
+ document.addEventListener("click", handleClick, true);
149
+ return () => document.removeEventListener("click", handleClick, true);
150
+ }
151
+ };
152
+ }
153
+ function createWebAdapter(options) {
154
+ const { compactBreakpointPx = 768 } = options;
155
+ return {
156
+ platform: "web",
157
+ async resolveAnchor(key, { timeoutMs }) {
158
+ const element = await waitForAnchor(key, timeoutMs);
159
+ return element ? createHandle(key) : null;
160
+ },
161
+ async scrollIntoView(handle, { reducedMotion }) {
162
+ const element = getAnchorElement(handle.key);
163
+ if (!element) return;
164
+ element.scrollIntoView({ block: "center", inline: "nearest", behavior: reducedMotion ? "instant" : "smooth" });
165
+ await waitForScrollSettle(element);
166
+ },
167
+ currentRoute: options.currentRoute,
168
+ async navigate(route) {
169
+ await options.navigate(route);
170
+ await nextFrame();
171
+ },
172
+ prefersReducedMotion: () => typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches,
173
+ isCompact: () => window.innerWidth < compactBreakpointPx,
174
+ session: options.session ?? browserSessionStore(),
175
+ now: Date.now
176
+ };
177
+ }
178
+
179
+ // src/web/BodyPortal.tsx
180
+ import { useSyncExternalStore } from "react";
181
+ import { createPortal } from "react-dom";
182
+ var subscribeNever = () => () => {
183
+ };
184
+ function BodyPortal({ children }) {
185
+ const isClient = useSyncExternalStore(subscribeNever, () => true, () => false);
186
+ return isClient ? createPortal(children, document.body) : null;
187
+ }
188
+
189
+ // src/web/useTourAnchor.ts
190
+ import { useCallback } from "react";
191
+ function useTourAnchor(key) {
192
+ const ref = useCallback((node) => node ? registerAnchor(key, node) : void 0, [key]);
193
+ return { ref, [ANCHOR_ATTRIBUTE]: key };
194
+ }
195
+
196
+ // src/web/useElementRect.ts
197
+ import { useEffect, useState } from "react";
198
+ function sameRect(a, b) {
199
+ if (!a || !b) return a === b;
200
+ return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
201
+ }
202
+ function useElementRect(element) {
203
+ const [measured, setMeasured] = useState(null);
204
+ useEffect(() => {
205
+ if (!element) return;
206
+ let frame = 0;
207
+ const remeasure = () => {
208
+ frame = 0;
209
+ const rect = measureElement(element);
210
+ setMeasured(
211
+ (previous) => previous?.element === element && sameRect(previous.rect, rect) ? previous : { element, rect }
212
+ );
213
+ };
214
+ const schedule = () => {
215
+ if (frame === 0) frame = requestAnimationFrame(remeasure);
216
+ };
217
+ const observer = new ResizeObserver(schedule);
218
+ observer.observe(element);
219
+ window.addEventListener("scroll", schedule, { passive: true, capture: true });
220
+ window.addEventListener("resize", schedule, { passive: true });
221
+ remeasure();
222
+ return () => {
223
+ observer.disconnect();
224
+ window.removeEventListener("scroll", schedule, true);
225
+ window.removeEventListener("resize", schedule);
226
+ cancelAnimationFrame(frame);
227
+ };
228
+ }, [element]);
229
+ return measured?.element === element ? measured.rect : measureElement(element);
230
+ }
231
+
232
+ // src/web/TourPopover.tsx
233
+ import { autoUpdate, flip, offset as offsetBy, shift, useFloating } from "@floating-ui/react-dom";
234
+
235
+ // src/web/dataAttributes.ts
236
+ var flag = (on) => on ? "" : void 0;
237
+
238
+ // src/web/environment.ts
239
+ import { useSyncExternalStore as useSyncExternalStore2 } from "react";
240
+ var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
241
+ function subscribeToReducedMotion(listener) {
242
+ const query = window.matchMedia(REDUCED_MOTION_QUERY);
243
+ query.addEventListener("change", listener);
244
+ return () => query.removeEventListener("change", listener);
245
+ }
246
+ function subscribeToResize(listener) {
247
+ window.addEventListener("resize", listener);
248
+ return () => window.removeEventListener("resize", listener);
249
+ }
250
+ function useReducedMotion() {
251
+ const adapter = useSaparAdapter();
252
+ return useSyncExternalStore2(
253
+ subscribeToReducedMotion,
254
+ () => adapter?.prefersReducedMotion() ?? false,
255
+ () => false
256
+ );
257
+ }
258
+ function useIsCompact() {
259
+ const adapter = useSaparAdapter();
260
+ return useSyncExternalStore2(
261
+ subscribeToResize,
262
+ () => adapter?.isCompact() ?? false,
263
+ () => false
264
+ );
265
+ }
266
+
267
+ // src/web/useAnchorElement.ts
268
+ import { useSyncExternalStore as useSyncExternalStore3 } from "react";
269
+ function useAnchorElement(key) {
270
+ return useSyncExternalStore3(
271
+ subscribeToAnchors,
272
+ () => key === void 0 ? null : getAnchorElement(key),
273
+ () => null
274
+ );
275
+ }
276
+
277
+ // src/web/TourPopover.tsx
278
+ import { jsx } from "react/jsx-runtime";
279
+ var DEFAULT_OFFSET_PX = 12;
280
+ var VIEWPORT_PADDING_PX = 8;
281
+ var SHEET_STYLE = { position: "fixed", left: 0, right: 0, bottom: 0 };
282
+ var CENTERED_STYLE = { position: "fixed", top: "50%", left: "50%", transform: "translate(-50%, -50%)" };
283
+ function Popover({
284
+ anchor,
285
+ placement,
286
+ offset = DEFAULT_OFFSET_PX,
287
+ presentation = "auto",
288
+ className,
289
+ style,
290
+ children
291
+ }) {
292
+ const element = useAnchorElement(anchor);
293
+ const compact = useIsCompact();
294
+ const sheet = resolvePresentation({ presentation, compact, fits: void 0 }) === "sheet";
295
+ const centered = element === null;
296
+ const anchored = !sheet && !centered;
297
+ const floating = useFloating({
298
+ placement: placement === "auto" ? "bottom" : placement,
299
+ strategy: "fixed",
300
+ elements: { reference: anchored ? element : null },
301
+ middleware: [offsetBy(offset), flip(), shift({ padding: VIEWPORT_PADDING_PX })],
302
+ whileElementsMounted: autoUpdate
303
+ });
304
+ const layout = sheet ? SHEET_STYLE : centered ? CENTERED_STYLE : floating.floatingStyles;
305
+ return /* @__PURE__ */ jsx(
306
+ "div",
307
+ {
308
+ ref: floating.refs.setFloating,
309
+ className,
310
+ style: { ...layout, ...style },
311
+ "data-placement": anchored ? floating.placement : void 0,
312
+ "data-presentation": sheet ? "sheet" : "anchored",
313
+ "data-compact": flag(sheet),
314
+ "data-centered": flag(centered),
315
+ children
316
+ }
317
+ );
318
+ }
319
+ function TourPopover(props) {
320
+ const tourStep = useTourStep();
321
+ if (!tourStep) return null;
322
+ return /* @__PURE__ */ jsx(BodyPortal, { children: /* @__PURE__ */ jsx(Popover, { ...props, anchor: tourStep.step.anchor, placement: tourStep.step.placement }) });
323
+ }
324
+
325
+ // src/web/TourSpotlight.tsx
326
+ import { jsx as jsx2 } from "react/jsx-runtime";
327
+ var PAGE_BOUNDS = { width: 1e5, height: 1e5 };
328
+ var DEFAULT_RADIUS = 8;
329
+ var TRANSITION_MS = 150;
330
+ function Spotlight({
331
+ anchor,
332
+ padding,
333
+ onClickOutside,
334
+ className,
335
+ style,
336
+ radius = DEFAULT_RADIUS
337
+ }) {
338
+ const element = useAnchorElement(anchor);
339
+ const rect = useElementRect(element);
340
+ const reducedMotion = useReducedMotion();
341
+ return /* @__PURE__ */ jsx2(
342
+ "svg",
343
+ {
344
+ "aria-hidden": "true",
345
+ className,
346
+ color: "rgb(0 0 0 / 0.5)",
347
+ "data-centered": flag(rect === null),
348
+ style: { position: "fixed", inset: 0, width: "100%", height: "100%", pointerEvents: "none", ...style },
349
+ children: /* @__PURE__ */ jsx2(
350
+ "path",
351
+ {
352
+ d: spotlightPath({ rect, padding, radius, bounds: PAGE_BOUNDS }),
353
+ fill: "currentColor",
354
+ fillRule: "evenodd",
355
+ onClick: onClickOutside,
356
+ style: {
357
+ pointerEvents: "auto",
358
+ transitionProperty: reducedMotion ? "none" : "d",
359
+ transitionDuration: `${TRANSITION_MS}ms`
360
+ }
361
+ }
362
+ )
363
+ }
364
+ );
365
+ }
366
+ function TourSpotlight({ onClickOutside, ...rest }) {
367
+ const tourStep = useTourStep();
368
+ if (!tourStep) return null;
369
+ return /* @__PURE__ */ jsx2(BodyPortal, { children: /* @__PURE__ */ jsx2(
370
+ Spotlight,
371
+ {
372
+ ...rest,
373
+ anchor: tourStep.step.anchor,
374
+ padding: tourStep.step.padding,
375
+ onClickOutside: onClickOutside ?? tourStep.skip
376
+ }
377
+ ) });
378
+ }
379
+
380
+ // src/web/TourOverlay.tsx
381
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
382
+ function TourOverlay({
383
+ spotlightClassName,
384
+ spotlightStyle,
385
+ popoverClassName,
386
+ popoverStyle,
387
+ onClickOutside,
388
+ presentation,
389
+ children
390
+ }) {
391
+ const tourStep = useTourStep();
392
+ if (!tourStep) return null;
393
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
394
+ /* @__PURE__ */ jsx3(TourSpotlight, { className: spotlightClassName, style: spotlightStyle, onClickOutside }),
395
+ /* @__PURE__ */ jsx3(TourPopover, { className: popoverClassName, style: popoverStyle, presentation, children: typeof children === "function" ? children(tourStep) : children })
396
+ ] });
397
+ }
398
+
399
+ // src/web/TourStep.tsx
400
+ import {
401
+ createContext,
402
+ useContext,
403
+ useEffect as useEffect2,
404
+ useId,
405
+ useMemo,
406
+ useRef
407
+ } from "react";
408
+ import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
409
+ var StepPartsContext = createContext(null);
410
+ function useStepParts() {
411
+ const parts = useContext(StepPartsContext);
412
+ if (!parts) throw new Error("TourStep parts must be rendered inside <TourStep.Root>.");
413
+ return parts;
414
+ }
415
+ var VISUALLY_HIDDEN = {
416
+ position: "absolute",
417
+ width: 1,
418
+ height: 1,
419
+ margin: -1,
420
+ padding: 0,
421
+ overflow: "hidden",
422
+ clip: "rect(0, 0, 0, 0)",
423
+ whiteSpace: "nowrap",
424
+ border: 0
425
+ };
426
+ function Dialog({
427
+ tourStep,
428
+ announceStep = defaultAnnounceStep,
429
+ onKeyDown,
430
+ children,
431
+ ...rest
432
+ }) {
433
+ const ref = useRef(null);
434
+ const baseId = useId();
435
+ const parts = useMemo(
436
+ () => ({ tourStep, titleId: `${baseId}-title`, bodyId: `${baseId}-body` }),
437
+ [tourStep, baseId]
438
+ );
439
+ const { step, position, total } = tourStep;
440
+ useEffect2(() => ref.current?.focus({ preventScroll: true }), [step.key]);
441
+ function handleKeyDown(event) {
442
+ onKeyDown?.(event);
443
+ if (event.key !== "Escape") return;
444
+ event.stopPropagation();
445
+ tourStep.skip();
446
+ }
447
+ return /* @__PURE__ */ jsx4(StepPartsContext.Provider, { value: parts, children: /* @__PURE__ */ jsxs2(
448
+ "div",
449
+ {
450
+ ...rest,
451
+ ref,
452
+ role: "dialog",
453
+ "aria-modal": false,
454
+ "aria-labelledby": parts.titleId,
455
+ "aria-describedby": parts.bodyId,
456
+ tabIndex: -1,
457
+ "data-first": flag(tourStep.isFirst),
458
+ "data-last": flag(tourStep.isLast),
459
+ onKeyDown: handleKeyDown,
460
+ children: [
461
+ /* @__PURE__ */ jsx4("div", { "aria-live": "polite", style: VISUALLY_HIDDEN, children: announceStep({ position, total, title: step.title }) }),
462
+ children
463
+ ]
464
+ }
465
+ ) });
466
+ }
467
+ function Root(props) {
468
+ const tourStep = useTourStep();
469
+ return tourStep ? /* @__PURE__ */ jsx4(Dialog, { ...props, tourStep }) : null;
470
+ }
471
+ function Title({ children, ...rest }) {
472
+ const { tourStep, titleId } = useStepParts();
473
+ return /* @__PURE__ */ jsx4("h2", { ...rest, id: titleId, children: children ?? tourStep.step.title });
474
+ }
475
+ function Body({ children, ...rest }) {
476
+ const { tourStep, bodyId } = useStepParts();
477
+ return /* @__PURE__ */ jsx4("p", { ...rest, id: bodyId, children: children ?? tourStep.step.body });
478
+ }
479
+ function Progress({ children, ...rest }) {
480
+ const { position, total } = useStepParts().tourStep;
481
+ const count = { position, total };
482
+ const content = typeof children === "function" ? children(count) : children ?? defaultProgress(count);
483
+ return /* @__PURE__ */ jsx4("span", { ...rest, children: content });
484
+ }
485
+ function StepButton({ render, ...props }) {
486
+ const buttonProps = { type: "button", ...props };
487
+ return render ? render(buttonProps) : /* @__PURE__ */ jsx4("button", { ...buttonProps });
488
+ }
489
+ function runThen(handler, action) {
490
+ return (event) => {
491
+ handler?.(event);
492
+ void action();
493
+ };
494
+ }
495
+ function Next({
496
+ doneLabel = "Done",
497
+ nextLabel = "Next",
498
+ showOnPress = false,
499
+ children,
500
+ onClick,
501
+ ...rest
502
+ }) {
503
+ const { tourStep } = useStepParts();
504
+ if (tourStep.step.advanceOn === "press" && !showOnPress) return null;
505
+ return /* @__PURE__ */ jsx4(StepButton, { ...rest, onClick: runThen(onClick, tourStep.next), children: children ?? (tourStep.isLast ? doneLabel : nextLabel) });
506
+ }
507
+ function Back({ children = "Back", onClick, ...rest }) {
508
+ const { tourStep } = useStepParts();
509
+ if (tourStep.isFirst) return null;
510
+ return /* @__PURE__ */ jsx4(StepButton, { ...rest, onClick: runThen(onClick, tourStep.previous), children });
511
+ }
512
+ function Skip({ children = "Skip", onClick, ...rest }) {
513
+ const { tourStep } = useStepParts();
514
+ return /* @__PURE__ */ jsx4(StepButton, { ...rest, onClick: runThen(onClick, tourStep.skip), children });
515
+ }
516
+ function Close({ children = "\xD7", ...rest }) {
517
+ return /* @__PURE__ */ jsx4(Skip, { "aria-label": "Close tour", ...rest, children });
518
+ }
519
+ var TourStep = { Root, Title, Body, Progress, Next, Back, Skip, Close };
520
+
521
+ export {
522
+ registerAnchor,
523
+ getAnchorElement,
524
+ waitForAnchor,
525
+ localStorageStore,
526
+ browserSessionStore,
527
+ createWebAdapter,
528
+ BodyPortal,
529
+ useTourAnchor,
530
+ useElementRect,
531
+ TourPopover,
532
+ TourSpotlight,
533
+ TourOverlay,
534
+ TourStep
535
+ };
536
+ //# sourceMappingURL=chunk-7B66QEMY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/web/measure.ts","../src/web/registry.ts","../src/web/stores.ts","../src/web/adapter.ts","../src/web/BodyPortal.tsx","../src/web/useTourAnchor.ts","../src/web/useElementRect.ts","../src/web/TourPopover.tsx","../src/web/dataAttributes.ts","../src/web/environment.ts","../src/web/useAnchorElement.ts","../src/web/TourSpotlight.tsx","../src/web/TourOverlay.tsx","../src/web/TourStep.tsx"],"sourcesContent":["import type { AnchorRect } from '../core';\n\nexport function measureElement(element: HTMLElement | null): AnchorRect | null {\n // A detached element reports an all-zero rect, which would read as a real anchor at the top-left corner.\n if (!element?.isConnected) return null;\n const { left, top, width, height } = element.getBoundingClientRect();\n return { x: left, y: top, width, height };\n}\n","export const ANCHOR_ATTRIBUTE = 'data-sapar';\n\nconst elements = new Map<string, HTMLElement>();\nconst waiters = new Map<string, Set<(element: HTMLElement | null) => void>>();\nconst listeners = new Set<() => void>();\n\nconst isDevelopment = (): boolean => typeof process !== 'undefined' && process.env.NODE_ENV !== 'production';\n\nfunction notifyListeners(): void {\n listeners.forEach((listener) => listener());\n}\n\nexport function registerAnchor(key: string, element: HTMLElement): () => void {\n const existing = elements.get(key);\n // A disconnected predecessor is just a remount whose cleanup has not run yet.\n if (existing && existing !== element && existing.isConnected && isDevelopment()) {\n console.warn(`[sapar] Duplicate anchor \"${key}\": the most recently registered element wins. Keys must be unique.`);\n }\n\n elements.set(key, element);\n waiters.get(key)?.forEach((resolve) => resolve(element));\n notifyListeners();\n\n return () => {\n if (elements.get(key) !== element) return;\n elements.delete(key);\n notifyListeners();\n };\n}\n\nexport function getAnchorElement(key: string): HTMLElement | null {\n const registered = elements.get(key);\n if (registered?.isConnected) return registered;\n if (typeof document === 'undefined') return null;\n return document.querySelector<HTMLElement>(`[${ANCHOR_ATTRIBUTE}=\"${CSS.escape(key)}\"]`);\n}\n\n/** Resolves `null` on timeout. Woken by registration, or by a DOM mutation for plain `data-sapar` markup. */\nexport function waitForAnchor(key: string, timeoutMs: number): Promise<HTMLElement | null> {\n const present = getAnchorElement(key);\n if (present) return Promise.resolve(present);\n\n return new Promise((resolve) => {\n const pending = waiters.get(key) ?? new Set();\n waiters.set(key, pending);\n\n const observer = new MutationObserver(() => {\n const element = getAnchorElement(key);\n if (element) settle(element);\n });\n const timer = setTimeout(() => settle(null), timeoutMs);\n\n function settle(element: HTMLElement | null): void {\n clearTimeout(timer);\n observer.disconnect();\n pending.delete(settle);\n if (pending.size === 0 && waiters.get(key) === pending) waiters.delete(key);\n resolve(element);\n }\n\n pending.add(settle);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: [ANCHOR_ATTRIBUTE] });\n });\n}\n\n// Registration only reports hook anchors, and a hook's cleanup runs before React removes its node, so a removed\n// anchor (either spelling) is noticed from the DOM itself.\nlet removalObserver: MutationObserver | null = null;\n\nfunction watchDocument(): void {\n removalObserver = new MutationObserver(notifyListeners);\n removalObserver.observe(document.body, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [ANCHOR_ATTRIBUTE],\n });\n}\n\nfunction stopWatchingDocument(): void {\n removalObserver?.disconnect();\n removalObserver = null;\n}\n\nexport function subscribeToAnchors(listener: () => void): () => void {\n if (listeners.size === 0) watchDocument();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n if (listeners.size === 0) stopWatchingDocument();\n };\n}\n","interface SyncStore {\n get(key: string): string | null;\n set(key: string, value: string): void;\n remove(key: string): void;\n}\n\n// `resolve` is called per operation because merely touching `window.localStorage` can throw (blocked cookies, SSR).\nfunction storageWithMemoryFallback(resolve: () => Storage): SyncStore {\n const memory = new Map<string, string>();\n\n function readStored(key: string): string | null {\n try {\n return resolve().getItem(key);\n } catch {\n return null;\n }\n }\n\n return {\n get: (key) => readStored(key) ?? memory.get(key) ?? null,\n set(key, value) {\n try {\n resolve().setItem(key, value);\n } catch {\n memory.set(key, value);\n }\n },\n remove(key) {\n memory.delete(key);\n try {\n resolve().removeItem(key);\n } catch {\n // Nothing persisted, nothing to remove.\n }\n },\n };\n}\n\nexport const localStorageStore = (): SyncStore => storageWithMemoryFallback(() => window.localStorage);\n\nexport const browserSessionStore = (): SyncStore => storageWithMemoryFallback(() => window.sessionStorage);\n","import type { AnchorHandle, PlatformAdapter, SessionStore } from '../core';\nimport { measureElement } from './measure';\nimport { getAnchorElement, waitForAnchor } from './registry';\nimport { browserSessionStore } from './stores';\n\nexport interface WebAdapterOptions {\n /** Push navigation, e.g. `router.push`. */\n navigate: (route: string) => void | Promise<void>;\n /** The route the host router currently reports. */\n currentRoute: () => string;\n /** Viewports narrower than this are compact. Default 768. */\n compactBreakpointPx?: number;\n session?: SessionStore;\n}\n\nconst SCROLL_SETTLE_TIMEOUT_MS = 1000;\nconst SCROLL_STABLE_FRAMES = 2;\n\nconst nextFrame = (): Promise<void> => new Promise((resolve) => requestAnimationFrame(() => resolve()));\n\n// Smooth scrolling has no spec'd duration, so watch the element until it stops moving.\nasync function waitForScrollSettle(element: HTMLElement): Promise<void> {\n const deadline = performance.now() + SCROLL_SETTLE_TIMEOUT_MS;\n let previous = element.getBoundingClientRect();\n let stableFrames = 0;\n\n while (stableFrames < SCROLL_STABLE_FRAMES && element.isConnected && performance.now() < deadline) {\n await nextFrame();\n const current = element.getBoundingClientRect();\n stableFrames = current.top === previous.top && current.left === previous.left ? stableFrames + 1 : 0;\n previous = current;\n }\n}\n\n// The element is looked up on every call (and press is caught at the document) because React may remount it.\nfunction createHandle(key: string): AnchorHandle {\n return {\n key,\n measure: async () => measureElement(getAnchorElement(key)),\n onPress(listener) {\n const handleClick = (event: MouseEvent): void => {\n const element = getAnchorElement(key);\n if (element && event.target instanceof Node && element.contains(event.target)) listener();\n };\n document.addEventListener('click', handleClick, true);\n return () => document.removeEventListener('click', handleClick, true);\n },\n };\n}\n\nexport function createWebAdapter(options: WebAdapterOptions): PlatformAdapter {\n const { compactBreakpointPx = 768 } = options;\n\n return {\n platform: 'web',\n async resolveAnchor(key, { timeoutMs }) {\n const element = await waitForAnchor(key, timeoutMs);\n return element ? createHandle(key) : null;\n },\n async scrollIntoView(handle, { reducedMotion }) {\n const element = getAnchorElement(handle.key);\n if (!element) return;\n element.scrollIntoView({ block: 'center', inline: 'nearest', behavior: reducedMotion ? 'instant' : 'smooth' });\n await waitForScrollSettle(element);\n },\n currentRoute: options.currentRoute,\n async navigate(route) {\n await options.navigate(route);\n await nextFrame();\n },\n prefersReducedMotion: () =>\n typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches,\n isCompact: () => window.innerWidth < compactBreakpointPx,\n session: options.session ?? browserSessionStore(),\n now: Date.now,\n };\n}\n","'use client';\n\nimport { useSyncExternalStore, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\n\nconst subscribeNever = (): (() => void) => () => {};\n\n/** Renders nothing on the server and during hydration, then portals into `document.body`. */\nexport function BodyPortal({ children }: { children: ReactNode }) {\n const isClient = useSyncExternalStore(subscribeNever, () => true, () => false);\n return isClient ? createPortal(children, document.body) : null;\n}\n","'use client';\n\nimport { useCallback, type RefCallback } from 'react';\nimport { ANCHOR_ATTRIBUTE, registerAnchor } from './registry';\n\nexport interface TourAnchorProps<K extends string, E extends HTMLElement> {\n ref: RefCallback<E>;\n [ANCHOR_ATTRIBUTE]: K;\n}\n\n/** Spread the result onto the element a tour step points at: `<button {...useTourAnchor('billing.upgrade')} />`. */\nexport function useTourAnchor<K extends string = string, E extends HTMLElement = HTMLElement>(\n key: K,\n): TourAnchorProps<K, E> {\n const ref = useCallback<RefCallback<E>>((node) => (node ? registerAnchor(key, node) : undefined), [key]);\n return { ref, [ANCHOR_ATTRIBUTE]: key };\n}\n","'use client';\n\nimport { useEffect, useState } from 'react';\nimport type { AnchorRect } from '../core';\nimport { measureElement } from './measure';\n\nfunction sameRect(a: AnchorRect | null, b: AnchorRect | null): boolean {\n if (!a || !b) return a === b;\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\ninterface Measured {\n element: HTMLElement;\n rect: AnchorRect | null;\n}\n\n/** Live viewport rect of `element`, re-measured at most once per animation frame; null when there is none or it is detached. */\nexport function useElementRect(element: HTMLElement | null): AnchorRect | null {\n // The rect is stored with the element it belongs to, so it can never be read for another one.\n const [measured, setMeasured] = useState<Measured | null>(null);\n\n useEffect(() => {\n if (!element) return;\n let frame = 0;\n\n const remeasure = (): void => {\n frame = 0;\n const rect = measureElement(element);\n setMeasured((previous) =>\n previous?.element === element && sameRect(previous.rect, rect) ? previous : { element, rect },\n );\n };\n const schedule = (): void => {\n if (frame === 0) frame = requestAnimationFrame(remeasure);\n };\n\n const observer = new ResizeObserver(schedule);\n observer.observe(element);\n // Capture: scroll does not bubble, and the anchor may sit in a nested scroller.\n window.addEventListener('scroll', schedule, { passive: true, capture: true });\n window.addEventListener('resize', schedule, { passive: true });\n remeasure();\n\n return () => {\n observer.disconnect();\n window.removeEventListener('scroll', schedule, true);\n window.removeEventListener('resize', schedule);\n cancelAnimationFrame(frame);\n };\n }, [element]);\n\n // Until the effect has measured a new element, measure it directly to avoid a frame without its rect.\n return measured?.element === element ? measured.rect : measureElement(element);\n}\n","'use client';\n\nimport { autoUpdate, flip, offset as offsetBy, shift, useFloating } from '@floating-ui/react-dom';\nimport type { CSSProperties, ReactNode } from 'react';\nimport { resolvePresentation, type Presentation, type Placement } from '../core';\nimport { useTourStep } from '../react';\nimport { BodyPortal } from './BodyPortal';\nimport { flag } from './dataAttributes';\nimport { useIsCompact } from './environment';\nimport { useAnchorElement } from './useAnchorElement';\n\nconst DEFAULT_OFFSET_PX = 12;\nconst VIEWPORT_PADDING_PX = 8;\n\nconst SHEET_STYLE: CSSProperties = { position: 'fixed', left: 0, right: 0, bottom: 0 };\nconst CENTERED_STYLE: CSSProperties = { position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' };\n\nexport interface TourPopoverProps {\n className?: string;\n style?: CSSProperties;\n /** Gap in px between the anchor and the popover. */\n offset?: number;\n /**\n * `'anchored'` puts the popover next to the anchor (centred without one), `'sheet'` is a bottom sheet, and\n * `'auto'` is a sheet on viewports narrower than the adapter's `compactBreakpointPx` (default 768). Default `'auto'`.\n */\n presentation?: Presentation;\n children?: ReactNode;\n}\n\nfunction Popover({\n anchor,\n placement,\n offset = DEFAULT_OFFSET_PX,\n presentation = 'auto',\n className,\n style,\n children,\n}: TourPopoverProps & { anchor: string | undefined; placement: Placement }) {\n const element = useAnchorElement(anchor);\n const compact = useIsCompact();\n const sheet = resolvePresentation({ presentation, compact, fits: undefined }) === 'sheet';\n const centered = element === null;\n const anchored = !sheet && !centered;\n\n const floating = useFloating({\n placement: placement === 'auto' ? 'bottom' : placement,\n strategy: 'fixed',\n elements: { reference: anchored ? element : null },\n middleware: [offsetBy(offset), flip(), shift({ padding: VIEWPORT_PADDING_PX })],\n whileElementsMounted: autoUpdate,\n });\n\n const layout = sheet ? SHEET_STYLE : centered ? CENTERED_STYLE : floating.floatingStyles;\n\n return (\n <div\n ref={floating.refs.setFloating}\n className={className}\n style={{ ...layout, ...style }}\n data-placement={anchored ? floating.placement : undefined}\n data-presentation={sheet ? 'sheet' : 'anchored'}\n data-compact={flag(sheet)}\n data-centered={flag(centered)}\n >\n {children}\n </div>\n );\n}\n\nexport function TourPopover(props: TourPopoverProps) {\n const tourStep = useTourStep();\n if (!tourStep) return null;\n\n return (\n <BodyPortal>\n <Popover {...props} anchor={tourStep.step.anchor} placement={tourStep.step.placement} />\n </BodyPortal>\n );\n}\n","/** Presence-style `data-*` value, matched by Tailwind's `data-[flag]:` variants. */\nexport const flag = (on: boolean): '' | undefined => (on ? '' : undefined);\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { useSaparAdapter } from '../react';\n\nconst REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';\n\nfunction subscribeToReducedMotion(listener: () => void): () => void {\n const query = window.matchMedia(REDUCED_MOTION_QUERY);\n query.addEventListener('change', listener);\n return () => query.removeEventListener('change', listener);\n}\n\nfunction subscribeToResize(listener: () => void): () => void {\n window.addEventListener('resize', listener);\n return () => window.removeEventListener('resize', listener);\n}\n\nexport function useReducedMotion(): boolean {\n const adapter = useSaparAdapter();\n return useSyncExternalStore(\n subscribeToReducedMotion,\n () => adapter?.prefersReducedMotion() ?? false,\n () => false,\n );\n}\n\nexport function useIsCompact(): boolean {\n const adapter = useSaparAdapter();\n return useSyncExternalStore(\n subscribeToResize,\n () => adapter?.isCompact() ?? false,\n () => false,\n );\n}\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { getAnchorElement, subscribeToAnchors } from './registry';\n\n/** The element currently behind `key`; follows remounts. */\nexport function useAnchorElement(key: string | undefined): HTMLElement | null {\n return useSyncExternalStore(\n subscribeToAnchors,\n () => (key === undefined ? null : getAnchorElement(key)),\n () => null,\n );\n}\n","'use client';\n\nimport type { CSSProperties } from 'react';\nimport { spotlightPath } from '../core';\nimport { useTourStep } from '../react';\nimport { flag } from './dataAttributes';\nimport { useReducedMotion } from './environment';\nimport { BodyPortal } from './BodyPortal';\nimport { useAnchorElement } from './useAnchorElement';\nimport { useElementRect } from './useElementRect';\n\n// Larger than any viewport, so the dim layer never needs the window size.\nconst PAGE_BOUNDS = { width: 100_000, height: 100_000 };\nconst DEFAULT_RADIUS = 8;\nconst TRANSITION_MS = 150;\n\nexport interface TourSpotlightProps {\n /** Colours the dim layer through `currentColor`, e.g. `text-black/50` (or `style.color`). */\n className?: string;\n style?: CSSProperties;\n /** Corner radius of the cutout in px. */\n radius?: number;\n /** Called when the dim layer is clicked. Defaults to skipping the tour. */\n onClickOutside?: () => void;\n}\n\nfunction Spotlight({\n anchor,\n padding,\n onClickOutside,\n className,\n style,\n radius = DEFAULT_RADIUS,\n}: TourSpotlightProps & { anchor: string | undefined; padding: number; onClickOutside: () => void }) {\n const element = useAnchorElement(anchor);\n const rect = useElementRect(element);\n const reducedMotion = useReducedMotion();\n\n return (\n <svg\n aria-hidden=\"true\"\n className={className}\n color=\"rgb(0 0 0 / 0.5)\"\n data-centered={flag(rect === null)}\n style={{ position: 'fixed', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', ...style }}\n >\n {/* The hole is unpainted, so clicks inside it reach the real element underneath. */}\n <path\n d={spotlightPath({ rect, padding, radius, bounds: PAGE_BOUNDS })}\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n onClick={onClickOutside}\n style={{\n pointerEvents: 'auto',\n transitionProperty: reducedMotion ? 'none' : 'd',\n transitionDuration: `${TRANSITION_MS}ms`,\n }}\n />\n </svg>\n );\n}\n\nexport function TourSpotlight({ onClickOutside, ...rest }: TourSpotlightProps) {\n const tourStep = useTourStep();\n if (!tourStep) return null;\n\n return (\n <BodyPortal>\n <Spotlight\n {...rest}\n anchor={tourStep.step.anchor}\n padding={tourStep.step.padding}\n onClickOutside={onClickOutside ?? tourStep.skip}\n />\n </BodyPortal>\n );\n}\n","'use client';\n\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useTourStep, type TourStepState } from '../react';\nimport { TourPopover, type TourPopoverProps } from './TourPopover';\nimport { TourSpotlight } from './TourSpotlight';\n\nexport interface TourOverlayProps extends Pick<TourPopoverProps, 'presentation'> {\n spotlightClassName?: string;\n spotlightStyle?: CSSProperties;\n popoverClassName?: string;\n popoverStyle?: CSSProperties;\n onClickOutside?: () => void;\n /** The step card, either directly or built from the running step. */\n children: ReactNode | ((tourStep: TourStepState) => ReactNode);\n}\n\nexport function TourOverlay({\n spotlightClassName,\n spotlightStyle,\n popoverClassName,\n popoverStyle,\n onClickOutside,\n presentation,\n children,\n}: TourOverlayProps) {\n const tourStep = useTourStep();\n if (!tourStep) return null;\n\n return (\n <>\n <TourSpotlight className={spotlightClassName} style={spotlightStyle} onClickOutside={onClickOutside} />\n <TourPopover className={popoverClassName} style={popoverStyle} presentation={presentation}>\n {typeof children === 'function' ? children(tourStep) : children}\n </TourPopover>\n </>\n );\n}\n","'use client';\n\nimport {\n createContext,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n type ComponentPropsWithoutRef,\n type CSSProperties,\n type KeyboardEvent,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n defaultAnnounceStep,\n defaultProgress,\n useTourStep,\n type StepAnnouncement,\n type StepCount,\n type TourStepState,\n} from '../react';\nimport { flag } from './dataAttributes';\n\ninterface StepParts {\n tourStep: TourStepState;\n titleId: string;\n bodyId: string;\n}\n\nconst StepPartsContext = createContext<StepParts | null>(null);\n\nfunction useStepParts(): StepParts {\n const parts = useContext(StepPartsContext);\n if (!parts) throw new Error('TourStep parts must be rendered inside <TourStep.Root>.');\n return parts;\n}\n\nconst VISUALLY_HIDDEN: CSSProperties = {\n position: 'absolute',\n width: 1,\n height: 1,\n margin: -1,\n padding: 0,\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: 0,\n};\n\nexport interface TourStepRootProps extends ComponentPropsWithoutRef<'div'> {\n /** Text read by screen readers on each step change. */\n announceStep?: (step: StepAnnouncement) => string;\n}\n\nfunction Dialog({\n tourStep,\n announceStep = defaultAnnounceStep,\n onKeyDown,\n children,\n ...rest\n}: TourStepRootProps & { tourStep: TourStepState }) {\n const ref = useRef<HTMLDivElement>(null);\n const baseId = useId();\n const parts = useMemo(\n () => ({ tourStep, titleId: `${baseId}-title`, bodyId: `${baseId}-body` }),\n [tourStep, baseId],\n );\n const { step, position, total } = tourStep;\n\n useEffect(() => ref.current?.focus({ preventScroll: true }), [step.key]);\n\n function handleKeyDown(event: KeyboardEvent<HTMLDivElement>): void {\n onKeyDown?.(event);\n if (event.key !== 'Escape') return;\n event.stopPropagation();\n tourStep.skip();\n }\n\n return (\n <StepPartsContext.Provider value={parts}>\n <div\n {...rest}\n ref={ref}\n role=\"dialog\"\n aria-modal={false}\n aria-labelledby={parts.titleId}\n aria-describedby={parts.bodyId}\n tabIndex={-1}\n data-first={flag(tourStep.isFirst)}\n data-last={flag(tourStep.isLast)}\n onKeyDown={handleKeyDown}\n >\n <div aria-live=\"polite\" style={VISUALLY_HIDDEN}>\n {announceStep({ position, total, title: step.title })}\n </div>\n {children}\n </div>\n </StepPartsContext.Provider>\n );\n}\n\nfunction Root(props: TourStepRootProps) {\n const tourStep = useTourStep();\n return tourStep ? <Dialog {...props} tourStep={tourStep} /> : null;\n}\n\nfunction Title({ children, ...rest }: ComponentPropsWithoutRef<'h2'>) {\n const { tourStep, titleId } = useStepParts();\n return (\n <h2 {...rest} id={titleId}>\n {children ?? tourStep.step.title}\n </h2>\n );\n}\n\nfunction Body({ children, ...rest }: ComponentPropsWithoutRef<'p'>) {\n const { tourStep, bodyId } = useStepParts();\n return (\n <p {...rest} id={bodyId}>\n {children ?? tourStep.step.body}\n </p>\n );\n}\n\nexport interface TourStepProgressProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children'> {\n /** Defaults to `\"{position} / {total}\"`. */\n children?: ReactNode | ((count: StepCount) => ReactNode);\n}\n\nfunction Progress({ children, ...rest }: TourStepProgressProps) {\n const { position, total } = useStepParts().tourStep;\n const count = { position, total };\n const content = typeof children === 'function' ? children(count) : (children ?? defaultProgress(count));\n return <span {...rest}>{content}</span>;\n}\n\ntype ButtonProps = ComponentPropsWithoutRef<'button'>;\n\nexport interface TourStepButtonProps extends ButtonProps {\n /** Renders your own button (a design-system component) with the wired-up props. */\n render?: (props: ButtonProps) => ReactElement;\n}\n\nfunction StepButton({ render, ...props }: TourStepButtonProps) {\n const buttonProps: ButtonProps = { type: 'button', ...props };\n return render ? render(buttonProps) : <button {...buttonProps} />;\n}\n\nfunction runThen(handler: ButtonProps['onClick'], action: () => unknown) {\n return (event: MouseEvent<HTMLButtonElement>): void => {\n handler?.(event);\n void action();\n };\n}\n\nexport interface TourStepNextProps extends TourStepButtonProps {\n /** Labels for the last step and the others. Ignored when `children` is given. */\n doneLabel?: ReactNode;\n nextLabel?: ReactNode;\n /** Steps that advance when the anchor is pressed hide this button unless set. */\n showOnPress?: boolean;\n}\n\nfunction Next({\n doneLabel = 'Done',\n nextLabel = 'Next',\n showOnPress = false,\n children,\n onClick,\n ...rest\n}: TourStepNextProps) {\n const { tourStep } = useStepParts();\n if (tourStep.step.advanceOn === 'press' && !showOnPress) return null;\n\n return (\n <StepButton {...rest} onClick={runThen(onClick, tourStep.next)}>\n {children ?? (tourStep.isLast ? doneLabel : nextLabel)}\n </StepButton>\n );\n}\n\nfunction Back({ children = 'Back', onClick, ...rest }: TourStepButtonProps) {\n const { tourStep } = useStepParts();\n if (tourStep.isFirst) return null;\n\n return (\n <StepButton {...rest} onClick={runThen(onClick, tourStep.previous)}>\n {children}\n </StepButton>\n );\n}\n\nfunction Skip({ children = 'Skip', onClick, ...rest }: TourStepButtonProps) {\n const { tourStep } = useStepParts();\n return (\n <StepButton {...rest} onClick={runThen(onClick, tourStep.skip)}>\n {children}\n </StepButton>\n );\n}\n\nfunction Close({ children = '×', ...rest }: TourStepButtonProps) {\n return (\n <Skip aria-label=\"Close tour\" {...rest}>\n {children}\n </Skip>\n );\n}\n\nexport const TourStep = { Root, Title, Body, Progress, Next, Back, Skip, Close };\n"],"mappings":"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","names":["useSyncExternalStore","useSyncExternalStore","useSyncExternalStore","useSyncExternalStore","jsx","jsx","useEffect","jsx","jsxs","useEffect"]}