@tent-official/react-walkthrough 1.1.94 → 1.1.96

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/README.md CHANGED
@@ -155,6 +155,21 @@ resetWalkthrough({
155
155
  | `storageSuffix` | `string` | `""` | Storage suffix |
156
156
  | `walkthroughList` | `string[]` | `[]` | Names of walkthroughs to reset |
157
157
 
158
+ ### `getCompletedWalkthroughs(options?)`
159
+
160
+ Get a list of all completed walkthrough names. Returns an array of walkthrough name strings that have been marked as done.
161
+
162
+ ```js
163
+ import { getCompletedWalkthroughs } from "@tent-official/react-walkthrough";
164
+
165
+ const list = getCompletedWalkthroughs({ storageSuffix: "my-app" });
166
+ // => ["intro-tour", "feature-tour"]
167
+ ```
168
+
169
+ | Option | Type | Default | Description |
170
+ | --- | --- | --- | --- |
171
+ | `storageSuffix` | `string` | `""` | Storage suffix matching the one used in useWalkthrough |
172
+
158
173
  ## Dependency Chains
159
174
 
160
175
  You can create sequential walkthroughs using `dependsOn`:
package/dist/index.d.mts CHANGED
@@ -140,6 +140,18 @@ interface IReadElementOptions {
140
140
  /** Optional AbortSignal to cancel waiting for the element */
141
141
  signal?: AbortSignal;
142
142
  }
143
+ /**
144
+ * Options for the getCompletedWalkthroughs function.
145
+ */
146
+ interface IGetCompletedWalkthroughsOptions {
147
+ /** Storage suffix matching the one used in useWalkthrough. Default: "" */
148
+ storageSuffix?: string;
149
+ }
150
+ /**
151
+ * Get a list of all completed walkthrough names.
152
+ * Returns an array of walkthrough name strings that have been marked as done.
153
+ */
154
+ declare function getCompletedWalkthroughs(options?: IGetCompletedWalkthroughsOptions): string[];
143
155
  /**
144
156
  * Reset specified walkthroughs so they can be replayed without page refresh.
145
157
  */
@@ -161,4 +173,4 @@ declare function useWalkthrough(options: IUseWalkthroughOptions): IUseWalkthroug
161
173
  */
162
174
  declare function WalkthroughOverlay(props?: IWalkthroughOverlayProps): ReactPortal | null;
163
175
 
164
- export { type IReadElementOptions, type IResetWalkthroughOptions, type IStepDescription, type IUseWalkthroughOptions, type IUseWalkthroughReturn, type IWalkthroughOverlayProps, type IWalkthroughStep, type TDescriptionDirection, type TPopoverPosition, WalkthroughOverlay, readElement, resetWalkthrough, useWalkthrough };
176
+ export { type IGetCompletedWalkthroughsOptions, type IReadElementOptions, type IResetWalkthroughOptions, type IStepDescription, type IUseWalkthroughOptions, type IUseWalkthroughReturn, type IWalkthroughOverlayProps, type IWalkthroughStep, type TDescriptionDirection, type TPopoverPosition, WalkthroughOverlay, getCompletedWalkthroughs, readElement, resetWalkthrough, useWalkthrough };
package/dist/index.d.ts CHANGED
@@ -140,6 +140,18 @@ interface IReadElementOptions {
140
140
  /** Optional AbortSignal to cancel waiting for the element */
141
141
  signal?: AbortSignal;
142
142
  }
143
+ /**
144
+ * Options for the getCompletedWalkthroughs function.
145
+ */
146
+ interface IGetCompletedWalkthroughsOptions {
147
+ /** Storage suffix matching the one used in useWalkthrough. Default: "" */
148
+ storageSuffix?: string;
149
+ }
150
+ /**
151
+ * Get a list of all completed walkthrough names.
152
+ * Returns an array of walkthrough name strings that have been marked as done.
153
+ */
154
+ declare function getCompletedWalkthroughs(options?: IGetCompletedWalkthroughsOptions): string[];
143
155
  /**
144
156
  * Reset specified walkthroughs so they can be replayed without page refresh.
145
157
  */
@@ -161,4 +173,4 @@ declare function useWalkthrough(options: IUseWalkthroughOptions): IUseWalkthroug
161
173
  */
162
174
  declare function WalkthroughOverlay(props?: IWalkthroughOverlayProps): ReactPortal | null;
163
175
 
164
- export { type IReadElementOptions, type IResetWalkthroughOptions, type IStepDescription, type IUseWalkthroughOptions, type IUseWalkthroughReturn, type IWalkthroughOverlayProps, type IWalkthroughStep, type TDescriptionDirection, type TPopoverPosition, WalkthroughOverlay, readElement, resetWalkthrough, useWalkthrough };
176
+ export { type IGetCompletedWalkthroughsOptions, type IReadElementOptions, type IResetWalkthroughOptions, type IStepDescription, type IUseWalkthroughOptions, type IUseWalkthroughReturn, type IWalkthroughOverlayProps, type IWalkthroughStep, type TDescriptionDirection, type TPopoverPosition, WalkthroughOverlay, getCompletedWalkthroughs, readElement, resetWalkthrough, useWalkthrough };
package/dist/index.js CHANGED
@@ -51,6 +51,10 @@ var isAnyDepDone = (storageSuffix, deps) => {
51
51
  if (!deps || deps.length === 0) return true;
52
52
  return deps.some((d) => isDone(storageSuffix, d));
53
53
  };
54
+ var getCompletedWalkthroughs = ({ storageSuffix = "" } = {}) => {
55
+ const data = getStorageData(storageSuffix);
56
+ return Object.keys(data).filter((name) => data[name] === true);
57
+ };
54
58
  var resetWalkthrough = ({ storageSuffix = "", walkthroughList = [] } = {}) => {
55
59
  const key = getStorageKey(storageSuffix);
56
60
  const data = getStorageData(storageSuffix);
@@ -519,7 +523,21 @@ var computePopoverPosition = (rect, popoverW, popoverH, gap, preferred) => {
519
523
  const vw = window.innerWidth;
520
524
  const vh = window.innerHeight;
521
525
  const clampLeft = (left) => Math.max(EDGE_MARGIN, Math.min(left, vw - popoverW - EDGE_MARGIN));
522
- const clampTop = (top) => Math.max(EDGE_MARGIN, Math.min(top, vh - popoverH - EDGE_MARGIN));
526
+ const spaceBottom = vh - (rect.top + rect.height + gap) - EDGE_MARGIN;
527
+ const spaceTop = rect.top - gap - EDGE_MARGIN;
528
+ const spaceRight = vw - (rect.left + rect.width + gap) - EDGE_MARGIN;
529
+ const spaceLeft = rect.left - gap - EDGE_MARGIN;
530
+ const clampTopForVertical = (top, dir) => {
531
+ const clamped = Math.max(EDGE_MARGIN, Math.min(top, vh - popoverH - EDGE_MARGIN));
532
+ if (dir === "top") {
533
+ return Math.min(clamped, rect.top - gap - popoverH);
534
+ }
535
+ if (dir === "bottom") {
536
+ return Math.max(clamped, rect.top + rect.height + gap);
537
+ }
538
+ return clamped;
539
+ };
540
+ const clampTopForHorizontal = (top) => Math.max(EDGE_MARGIN, Math.min(top, vh - popoverH - EDGE_MARGIN));
523
541
  const positions = {
524
542
  bottom: {
525
543
  top: rect.top + rect.height + gap,
@@ -530,28 +548,36 @@ var computePopoverPosition = (rect, popoverW, popoverH, gap, preferred) => {
530
548
  left: clampLeft(rect.left)
531
549
  },
532
550
  right: {
533
- top: clampTop(rect.top),
551
+ top: clampTopForHorizontal(rect.top),
534
552
  left: rect.left + rect.width + gap
535
553
  },
536
554
  left: {
537
- top: clampTop(rect.top),
555
+ top: clampTopForHorizontal(rect.top),
538
556
  left: rect.left - popoverW - gap
539
557
  }
540
558
  };
541
559
  const fitsInViewport = (pos) => pos.top >= EDGE_MARGIN && pos.left >= EDGE_MARGIN && pos.top + popoverH <= vh - EDGE_MARGIN && pos.left + popoverW <= vw - EDGE_MARGIN;
560
+ const buildResult = (pos, dir) => {
561
+ let maxH = null;
562
+ if (dir === "bottom") {
563
+ maxH = vh - pos.top - EDGE_MARGIN;
564
+ } else if (dir === "top") {
565
+ maxH = rect.top - gap - EDGE_MARGIN;
566
+ } else {
567
+ maxH = vh - EDGE_MARGIN * 2;
568
+ }
569
+ if (maxH >= popoverH) maxH = null;
570
+ return { top: pos.top, left: pos.left, ...maxH != null && { maxHeight: Math.max(maxH, 60) } };
571
+ };
542
572
  if (preferred && positions[preferred] && fitsInViewport(positions[preferred])) {
543
- return positions[preferred];
573
+ return buildResult(positions[preferred], preferred);
544
574
  }
545
575
  const order = ["bottom", "top", "right", "left"];
546
576
  for (const dir of order) {
547
577
  if (fitsInViewport(positions[dir])) {
548
- return positions[dir];
578
+ return buildResult(positions[dir], dir);
549
579
  }
550
580
  }
551
- const spaceBottom = vh - (rect.top + rect.height + gap);
552
- const spaceTop = rect.top - gap;
553
- const spaceRight = vw - (rect.left + rect.width + gap);
554
- const spaceLeft = rect.left - gap;
555
581
  const best = [
556
582
  { dir: "bottom", space: spaceBottom },
557
583
  { dir: "top", space: spaceTop },
@@ -559,10 +585,9 @@ var computePopoverPosition = (rect, popoverW, popoverH, gap, preferred) => {
559
585
  { dir: "left", space: spaceLeft }
560
586
  ].sort((a, b) => b.space - a.space)[0].dir;
561
587
  const fallback = positions[best];
562
- return {
563
- top: Math.max(EDGE_MARGIN, Math.min(fallback.top, vh - popoverH - EDGE_MARGIN)),
564
- left: Math.max(EDGE_MARGIN, Math.min(fallback.left, vw - popoverW - EDGE_MARGIN))
565
- };
588
+ const clampedTop = best === "top" || best === "bottom" ? clampTopForVertical(fallback.top, best) : clampTopForHorizontal(fallback.top);
589
+ const clampedLeft = Math.max(EDGE_MARGIN, Math.min(fallback.left, vw - popoverW - EDGE_MARGIN));
590
+ return buildResult({ top: clampedTop, left: clampedLeft }, best);
566
591
  };
567
592
  var WT_CONTAINER_ID = "wt-portal-root";
568
593
  var getPortalContainer = () => {
@@ -823,8 +848,9 @@ var WalkthroughOverlay = ({
823
848
  const el = document.getElementById(resolveElId(step.el));
824
849
  if (!el) return;
825
850
  }
851
+ if (!popoverPos) return;
826
852
  setPopoverHidden(false);
827
- }, [popoverHidden, isAnimating, step]);
853
+ }, [popoverHidden, isAnimating, step, popoverPos]);
828
854
  if (!activeTour) return null;
829
855
  if (_activeOverlayId !== null && _activeOverlayId !== instanceIdRef.current) {
830
856
  return null;
@@ -920,6 +946,7 @@ var WalkthroughOverlay = ({
920
946
  completeTour();
921
947
  } else {
922
948
  setPopoverHidden(true);
949
+ setPopoverPos(null);
923
950
  const nextValidStep = validSteps[currentValidPos + 1];
924
951
  const nextOrigIdx = hasTrigger && !nextValidStep ? currentOrigIdx + 1 : (_a2 = nextValidStep == null ? void 0 : nextValidStep._originalIdx) != null ? _a2 : currentOrigIdx + 1;
925
952
  setGlobalState((s) => ({
@@ -932,6 +959,7 @@ var WalkthroughOverlay = ({
932
959
  const hasTrigger = !!step.triggerElOnNext;
933
960
  if (hasTrigger) {
934
961
  setPopoverHidden(true);
962
+ setPopoverPos(null);
935
963
  const triggerTarget = typeof step.triggerElOnNext === "string" ? document.getElementById(resolveElId(step.triggerElOnNext)) : document.getElementById(resolveElId(step.el));
936
964
  if (triggerTarget) {
937
965
  triggerTarget.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true, button: 0, ctrlKey: false, pointerId: 1, pointerType: "mouse" }));
@@ -982,6 +1010,7 @@ var WalkthroughOverlay = ({
982
1010
  return;
983
1011
  }
984
1012
  setPopoverHidden(true);
1013
+ setPopoverPos(null);
985
1014
  if (activeTour.handleWhenLastStep) activeTour.handleWhenLastStep();
986
1015
  setTimeout(() => completeTour(), 300);
987
1016
  return;
@@ -991,6 +1020,7 @@ var WalkthroughOverlay = ({
991
1020
  const prev = () => {
992
1021
  if (currentValidPos > 0) {
993
1022
  setPopoverHidden(true);
1023
+ setPopoverPos(null);
994
1024
  const prevStep = validSteps[currentValidPos - 1];
995
1025
  setGlobalState((s) => ({
996
1026
  ...s,
@@ -1030,7 +1060,11 @@ var WalkthroughOverlay = ({
1030
1060
  minWidth: $popoverMinWidth,
1031
1061
  padding: $popoverPadding,
1032
1062
  borderRadius: $popoverBorderRadius,
1033
- fontFamily: "inherit"
1063
+ fontFamily: "inherit",
1064
+ ...popoverPos.maxHeight != null && {
1065
+ maxHeight: popoverPos.maxHeight,
1066
+ overflowY: "auto"
1067
+ }
1034
1068
  } : {
1035
1069
  position: "fixed",
1036
1070
  top: -9999,
@@ -1145,6 +1179,7 @@ var WalkthroughOverlay = ({
1145
1179
  };
1146
1180
 
1147
1181
  exports.WalkthroughOverlay = WalkthroughOverlay;
1182
+ exports.getCompletedWalkthroughs = getCompletedWalkthroughs;
1148
1183
  exports.readElement = readElement;
1149
1184
  exports.resetWalkthrough = resetWalkthrough;
1150
1185
  exports.useWalkthrough = useWalkthrough;