@flowsterix/react 0.12.0 → 0.13.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.
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsProvider.d.ts","sourceRoot":"","sources":["../../src/devtools/DevToolsProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAatC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAoF1C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CAsR5D"}
1
+ {"version":3,"file":"DevToolsProvider.d.ts","sourceRoot":"","sources":["../../src/devtools/DevToolsProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAatC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAoF1C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,CAAA;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,UAAU,CAAC,EAAE,WAAW,CAAA;CACzB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CA8R5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"FlowsTab.d.ts","sourceRoot":"","sources":["../../../src/devtools/components/FlowsTab.tsx"],"names":[],"mappings":"AAqFA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAC3B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,2CA6G5C"}
1
+ {"version":3,"file":"FlowsTab.d.ts","sourceRoot":"","sources":["../../../src/devtools/components/FlowsTab.tsx"],"names":[],"mappings":"AA0FA,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAC3B;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,2CA4H5C"}
@@ -1 +1 @@
1
- {"version":3,"file":"TabNav.d.ts","sourceRoot":"","sources":["../../../src/devtools/components/TabNav.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAgE3C,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,WAAW,CAAA;IACtB,WAAW,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAA;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,2CAqGxC"}
1
+ {"version":3,"file":"TabNav.d.ts","sourceRoot":"","sources":["../../../src/devtools/components/TabNav.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AA+D3C,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,WAAW,CAAA;IACtB,WAAW,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,CAAA;IACvC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,2CAiHxC"}
@@ -1406,12 +1406,15 @@ function TabNav(props) {
1406
1406
  {
1407
1407
  style: stepsBadgeStyle,
1408
1408
  initial: stepCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
1409
- animate: { scale: 1 },
1409
+ animate: {
1410
+ scale: stepCountChanged && !reducedMotion ? [1.3, 1] : 1,
1411
+ opacity: 1
1412
+ },
1410
1413
  exit: { scale: 0.8, opacity: 0 },
1411
1414
  transition: reducedMotion ? { duration: 0 } : springs.bouncy,
1412
1415
  children: stepCount
1413
1416
  },
1414
- `step-badge-${stepCount}`
1417
+ "step-badge"
1415
1418
  ) })
1416
1419
  ]
1417
1420
  }
@@ -1429,13 +1432,16 @@ function TabNav(props) {
1429
1432
  _react3.motion.span,
1430
1433
  {
1431
1434
  style: flowsBadgeStyle,
1432
- initial: flowCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
1433
- animate: { scale: 1 },
1435
+ initial: { scale: 0.8, opacity: 0 },
1436
+ animate: {
1437
+ scale: flowCountChanged && !reducedMotion ? [1.3, 1] : 1,
1438
+ opacity: 1
1439
+ },
1434
1440
  exit: { scale: 0.8, opacity: 0 },
1435
1441
  transition: reducedMotion ? { duration: 0 } : springs.bouncy,
1436
1442
  children: flowCount
1437
1443
  },
1438
- `flow-badge-${flowCount}`
1444
+ "flow-badge"
1439
1445
  ) })
1440
1446
  ]
1441
1447
  }
@@ -2178,6 +2184,7 @@ var styles8 = {
2178
2184
  function FlowsTab(props) {
2179
2185
  const { container } = props;
2180
2186
  const { flows, refreshFlows, deleteFlow, updateFlow } = useFlowsData();
2187
+ const reducedMotion = useReducedMotion();
2181
2188
  const [editModal, setEditModal] = _react.useState.call(void 0, {
2182
2189
  isOpen: false,
2183
2190
  flowId: "",
@@ -2257,15 +2264,33 @@ function FlowsTab(props) {
2257
2264
  }
2258
2265
  )
2259
2266
  ] }),
2260
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { style: styles8.flowList, children: flows.map((flow) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2261
- FlowItem,
2267
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2268
+ _react3.motion.div,
2262
2269
  {
2263
- flow,
2264
- onEdit: () => handleEdit(flow.flowId, flow.state),
2265
- onDelete: () => void handleDelete(flow.flowId)
2266
- },
2267
- flow.flowId
2268
- )) }),
2270
+ style: styles8.flowList,
2271
+ variants: reducedMotion ? void 0 : listContainerVariants,
2272
+ initial: "hidden",
2273
+ animate: "visible",
2274
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { mode: "popLayout", children: flows.map((flow) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2275
+ _react3.motion.div,
2276
+ {
2277
+ variants: reducedMotion ? void 0 : listItemVariants,
2278
+ initial: "hidden",
2279
+ animate: "visible",
2280
+ exit: "exit",
2281
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2282
+ FlowItem,
2283
+ {
2284
+ flow,
2285
+ onEdit: () => handleEdit(flow.flowId, flow.state),
2286
+ onDelete: () => void handleDelete(flow.flowId)
2287
+ }
2288
+ )
2289
+ },
2290
+ flow.flowId
2291
+ )) })
2292
+ }
2293
+ ),
2269
2294
  editModal.state && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2270
2295
  FlowEditModal,
2271
2296
  {
@@ -2873,7 +2898,8 @@ function DevToolsProvider(props) {
2873
2898
  };
2874
2899
  const headerStyle = {
2875
2900
  ...styles9.header,
2876
- ...isPanelDragging && styles9.headerDragging
2901
+ ...isPanelDragging && styles9.headerDragging,
2902
+ ...collapsed && { borderBottom: "none" }
2877
2903
  };
2878
2904
  const portalContainer = _nullishCoalesce(shadowContainer, () => ( document.body));
2879
2905
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
@@ -2891,6 +2917,8 @@ function DevToolsProvider(props) {
2891
2917
  _react3.motion.div,
2892
2918
  {
2893
2919
  style: panelStyle,
2920
+ layoutRoot: true,
2921
+ layout: "size",
2894
2922
  initial: { opacity: 0, x: 20, scale: 0.95 },
2895
2923
  animate: { opacity: 1, x: 0, scale: 1 },
2896
2924
  transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
@@ -2938,15 +2966,22 @@ function DevToolsProvider(props) {
2938
2966
  ]
2939
2967
  }
2940
2968
  ),
2941
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _react3.AnimatePresence, { initial: false, children: !collapsed && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2969
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2942
2970
  _react3.motion.div,
2943
2971
  {
2944
- style: { ...styles9.body, overflow: "hidden" },
2945
- initial: { height: 0, opacity: 0 },
2946
- animate: { height: "auto", opacity: 1 },
2947
- exit: { height: 0, opacity: 0 },
2948
- transition: springs.smooth,
2949
- children: [
2972
+ style: {
2973
+ ...styles9.body,
2974
+ overflow: "hidden",
2975
+ flex: collapsed ? "0 0 auto" : "1 1 auto"
2976
+ },
2977
+ initial: false,
2978
+ animate: { height: collapsed ? 0 : "auto", opacity: collapsed ? 0 : 1 },
2979
+ transition: {
2980
+ height: springs.smooth,
2981
+ opacity: { duration: 0.12 }
2982
+ },
2983
+ "aria-hidden": collapsed,
2984
+ children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { pointerEvents: collapsed ? "none" : "auto" }, children: [
2950
2985
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2951
2986
  TabNav,
2952
2987
  {
@@ -2968,9 +3003,9 @@ function DevToolsProvider(props) {
2968
3003
  onExport: exportSteps
2969
3004
  }
2970
3005
  ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FlowsTab, { container: shadowContainer })
2971
- ]
3006
+ ] })
2972
3007
  }
2973
- ) })
3008
+ )
2974
3009
  ]
2975
3010
  }
2976
3011
  ),
@@ -7,7 +7,7 @@ import {
7
7
  // src/devtools/DevToolsProvider.tsx
8
8
  import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef2, useState as useState11 } from "react";
9
9
  import { createPortal as createPortal3 } from "react-dom";
10
- import { AnimatePresence as AnimatePresence7, motion as motion9 } from "motion/react";
10
+ import { motion as motion9 } from "motion/react";
11
11
 
12
12
  // src/devtools/motion.ts
13
13
  import { useEffect, useState } from "react";
@@ -1302,8 +1302,8 @@ function StepList(props) {
1302
1302
  }
1303
1303
 
1304
1304
  // src/devtools/components/TabNav.tsx
1305
+ import { AnimatePresence as AnimatePresence4, motion as motion5 } from "motion/react";
1305
1306
  import { useEffect as useEffect3, useRef } from "react";
1306
- import { motion as motion5, AnimatePresence as AnimatePresence4 } from "motion/react";
1307
1307
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1308
1308
  var styles5 = {
1309
1309
  container: {
@@ -1406,12 +1406,15 @@ function TabNav(props) {
1406
1406
  {
1407
1407
  style: stepsBadgeStyle,
1408
1408
  initial: stepCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
1409
- animate: { scale: 1 },
1409
+ animate: {
1410
+ scale: stepCountChanged && !reducedMotion ? [1.3, 1] : 1,
1411
+ opacity: 1
1412
+ },
1410
1413
  exit: { scale: 0.8, opacity: 0 },
1411
1414
  transition: reducedMotion ? { duration: 0 } : springs.bouncy,
1412
1415
  children: stepCount
1413
1416
  },
1414
- `step-badge-${stepCount}`
1417
+ "step-badge"
1415
1418
  ) })
1416
1419
  ]
1417
1420
  }
@@ -1429,13 +1432,16 @@ function TabNav(props) {
1429
1432
  motion5.span,
1430
1433
  {
1431
1434
  style: flowsBadgeStyle,
1432
- initial: flowCountChanged && !reducedMotion ? { scale: 1.3 } : { scale: 1 },
1433
- animate: { scale: 1 },
1435
+ initial: { scale: 0.8, opacity: 0 },
1436
+ animate: {
1437
+ scale: flowCountChanged && !reducedMotion ? [1.3, 1] : 1,
1438
+ opacity: 1
1439
+ },
1434
1440
  exit: { scale: 0.8, opacity: 0 },
1435
1441
  transition: reducedMotion ? { duration: 0 } : springs.bouncy,
1436
1442
  children: flowCount
1437
1443
  },
1438
- `flow-badge-${flowCount}`
1444
+ "flow-badge"
1439
1445
  ) })
1440
1446
  ]
1441
1447
  }
@@ -1456,7 +1462,7 @@ function TabNav(props) {
1456
1462
 
1457
1463
  // src/devtools/components/FlowsTab.tsx
1458
1464
  import { useCallback as useCallback4, useState as useState9 } from "react";
1459
- import { motion as motion8 } from "motion/react";
1465
+ import { motion as motion8, AnimatePresence as AnimatePresence7 } from "motion/react";
1460
1466
 
1461
1467
  // src/devtools/hooks/useFlowsData.ts
1462
1468
  import { useCallback as useCallback2, useEffect as useEffect4, useState as useState6, useSyncExternalStore } from "react";
@@ -2178,6 +2184,7 @@ var styles8 = {
2178
2184
  function FlowsTab(props) {
2179
2185
  const { container } = props;
2180
2186
  const { flows, refreshFlows, deleteFlow, updateFlow } = useFlowsData();
2187
+ const reducedMotion = useReducedMotion();
2181
2188
  const [editModal, setEditModal] = useState9({
2182
2189
  isOpen: false,
2183
2190
  flowId: "",
@@ -2257,15 +2264,33 @@ function FlowsTab(props) {
2257
2264
  }
2258
2265
  )
2259
2266
  ] }),
2260
- /* @__PURE__ */ jsx8("div", { style: styles8.flowList, children: flows.map((flow) => /* @__PURE__ */ jsx8(
2261
- FlowItem,
2267
+ /* @__PURE__ */ jsx8(
2268
+ motion8.div,
2262
2269
  {
2263
- flow,
2264
- onEdit: () => handleEdit(flow.flowId, flow.state),
2265
- onDelete: () => void handleDelete(flow.flowId)
2266
- },
2267
- flow.flowId
2268
- )) }),
2270
+ style: styles8.flowList,
2271
+ variants: reducedMotion ? void 0 : listContainerVariants,
2272
+ initial: "hidden",
2273
+ animate: "visible",
2274
+ children: /* @__PURE__ */ jsx8(AnimatePresence7, { mode: "popLayout", children: flows.map((flow) => /* @__PURE__ */ jsx8(
2275
+ motion8.div,
2276
+ {
2277
+ variants: reducedMotion ? void 0 : listItemVariants,
2278
+ initial: "hidden",
2279
+ animate: "visible",
2280
+ exit: "exit",
2281
+ children: /* @__PURE__ */ jsx8(
2282
+ FlowItem,
2283
+ {
2284
+ flow,
2285
+ onEdit: () => handleEdit(flow.flowId, flow.state),
2286
+ onDelete: () => void handleDelete(flow.flowId)
2287
+ }
2288
+ )
2289
+ },
2290
+ flow.flowId
2291
+ )) })
2292
+ }
2293
+ ),
2269
2294
  editModal.state && /* @__PURE__ */ jsx8(
2270
2295
  FlowEditModal,
2271
2296
  {
@@ -2873,7 +2898,8 @@ function DevToolsProvider(props) {
2873
2898
  };
2874
2899
  const headerStyle = {
2875
2900
  ...styles9.header,
2876
- ...isPanelDragging && styles9.headerDragging
2901
+ ...isPanelDragging && styles9.headerDragging,
2902
+ ...collapsed && { borderBottom: "none" }
2877
2903
  };
2878
2904
  const portalContainer = shadowContainer ?? document.body;
2879
2905
  return /* @__PURE__ */ jsxs9(Fragment3, { children: [
@@ -2891,6 +2917,8 @@ function DevToolsProvider(props) {
2891
2917
  motion9.div,
2892
2918
  {
2893
2919
  style: panelStyle,
2920
+ layoutRoot: true,
2921
+ layout: "size",
2894
2922
  initial: { opacity: 0, x: 20, scale: 0.95 },
2895
2923
  animate: { opacity: 1, x: 0, scale: 1 },
2896
2924
  transition: { duration: 0.2, ease: [0.16, 1, 0.3, 1] },
@@ -2938,15 +2966,22 @@ function DevToolsProvider(props) {
2938
2966
  ]
2939
2967
  }
2940
2968
  ),
2941
- /* @__PURE__ */ jsx9(AnimatePresence7, { initial: false, children: !collapsed && /* @__PURE__ */ jsxs9(
2969
+ /* @__PURE__ */ jsx9(
2942
2970
  motion9.div,
2943
2971
  {
2944
- style: { ...styles9.body, overflow: "hidden" },
2945
- initial: { height: 0, opacity: 0 },
2946
- animate: { height: "auto", opacity: 1 },
2947
- exit: { height: 0, opacity: 0 },
2948
- transition: springs.smooth,
2949
- children: [
2972
+ style: {
2973
+ ...styles9.body,
2974
+ overflow: "hidden",
2975
+ flex: collapsed ? "0 0 auto" : "1 1 auto"
2976
+ },
2977
+ initial: false,
2978
+ animate: { height: collapsed ? 0 : "auto", opacity: collapsed ? 0 : 1 },
2979
+ transition: {
2980
+ height: springs.smooth,
2981
+ opacity: { duration: 0.12 }
2982
+ },
2983
+ "aria-hidden": collapsed,
2984
+ children: /* @__PURE__ */ jsxs9("div", { style: { pointerEvents: collapsed ? "none" : "auto" }, children: [
2950
2985
  /* @__PURE__ */ jsx9(
2951
2986
  TabNav,
2952
2987
  {
@@ -2968,9 +3003,9 @@ function DevToolsProvider(props) {
2968
3003
  onExport: exportSteps
2969
3004
  }
2970
3005
  ) : /* @__PURE__ */ jsx9(FlowsTab, { container: shadowContainer })
2971
- ]
3006
+ ] })
2972
3007
  }
2973
- ) })
3008
+ )
2974
3009
  ]
2975
3010
  }
2976
3011
  ),
@@ -0,0 +1,29 @@
1
+ import type { ClientRectLike } from '../utils/dom';
2
+ export interface ConstrainedScrollLockOptions {
3
+ /**
4
+ * Whether scroll lock is enabled.
5
+ */
6
+ enabled: boolean;
7
+ /**
8
+ * The target element's bounding rect.
9
+ * If target is larger than viewport, scrolling is allowed within target bounds.
10
+ */
11
+ targetRect: ClientRectLike | null;
12
+ /**
13
+ * Viewport height. Used to determine if target exceeds viewport.
14
+ */
15
+ viewportHeight: number;
16
+ /**
17
+ * Additional padding around the target bounds (for highlight padding).
18
+ * Default: 0
19
+ */
20
+ padding?: number;
21
+ }
22
+ /**
23
+ * Enhanced scroll lock that allows constrained scrolling when target is larger than viewport.
24
+ *
25
+ * - If target fits in viewport: normal scroll lock (overflow: hidden)
26
+ * - If target > viewport: allow scrolling within target bounds only
27
+ */
28
+ export declare const useConstrainedScrollLock: ({ enabled, targetRect, viewportHeight, padding, }: ConstrainedScrollLockOptions) => void;
29
+ //# sourceMappingURL=useConstrainedScrollLock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConstrainedScrollLock.d.ts","sourceRoot":"","sources":["../../src/hooks/useConstrainedScrollLock.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAGlD,MAAM,WAAW,4BAA4B;IAC3C;;OAEG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,UAAU,EAAE,cAAc,GAAG,IAAI,CAAA;IACjC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAwBD;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,mDAKtC,4BAA4B,SA6D9B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"useTourHud.d.ts","sourceRoot":"","sources":["../../src/hooks/useTourHud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAA;IAC5C;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,uBAAuB,CAAA;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAClD,qBAAqB,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,YAAY,EAAE,wBAAwB,CAAA;IACtC,WAAW,EAAE,uBAAuB,CAAA;IACpC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAKD,eAAO,MAAM,UAAU,GACrB,UAAS,iBAAsB,KAC9B,gBA+FF,CAAA"}
1
+ {"version":3,"file":"useTourHud.d.ts","sourceRoot":"","sources":["../../src/hooks/useTourHud.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AAEtD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAA;IAC5C;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,uBAAuB,CAAA;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,cAAc,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAClD,qBAAqB,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,EAAE,oBAAoB,CAAA;IAC7B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,YAAY,EAAE,wBAAwB,CAAA;IACtC,WAAW,EAAE,uBAAuB,CAAA;IACpC,oBAAoB,EAAE,OAAO,CAAA;IAC7B,gBAAgB,EAAE,OAAO,CAAA;CAC1B;AAKD,eAAO,MAAM,UAAU,GACrB,UAAS,iBAAsB,KAC9B,gBAqGF,CAAA"}
package/dist/index.cjs CHANGED
@@ -2460,11 +2460,11 @@ var useHudShortcuts = (target, options) => {
2460
2460
  // src/hooks/useTourHud.ts
2461
2461
 
2462
2462
 
2463
- // src/hooks/useBodyScrollLock.ts
2463
+ // src/hooks/useConstrainedScrollLock.ts
2464
2464
 
2465
2465
  var lockCount = 0;
2466
2466
  var previousOverflow = null;
2467
- var acquireLock = () => {
2467
+ var acquireHardLock = () => {
2468
2468
  if (!_chunkD5LQLRSUcjs.isBrowser) return;
2469
2469
  if (lockCount === 0) {
2470
2470
  previousOverflow = document.body.style.overflow;
@@ -2472,7 +2472,7 @@ var acquireLock = () => {
2472
2472
  }
2473
2473
  lockCount += 1;
2474
2474
  };
2475
- var releaseLock = () => {
2475
+ var releaseHardLock = () => {
2476
2476
  if (!_chunkD5LQLRSUcjs.isBrowser) return;
2477
2477
  if (lockCount === 0) return;
2478
2478
  lockCount -= 1;
@@ -2481,14 +2481,51 @@ var releaseLock = () => {
2481
2481
  previousOverflow = null;
2482
2482
  }
2483
2483
  };
2484
- var useBodyScrollLock = (enabled) => {
2484
+ var useConstrainedScrollLock = ({
2485
+ enabled,
2486
+ targetRect,
2487
+ viewportHeight,
2488
+ padding = 0
2489
+ }) => {
2490
+ const isConstrainedModeRef = _react.useRef.call(void 0, false);
2491
+ const boundsRef = _react.useRef.call(void 0, { minY: 0, maxY: 0 });
2485
2492
  _react.useEffect.call(void 0, () => {
2486
- if (!enabled) return;
2487
- acquireLock();
2493
+ if (!enabled || !_chunkD5LQLRSUcjs.isBrowser) return;
2494
+ const targetHeight = targetRect ? targetRect.height + padding * 2 : 0;
2495
+ const targetExceedsViewport = targetRect && targetHeight > viewportHeight;
2496
+ if (!targetExceedsViewport) {
2497
+ acquireHardLock();
2498
+ isConstrainedModeRef.current = false;
2499
+ return () => {
2500
+ releaseHardLock();
2501
+ };
2502
+ }
2503
+ isConstrainedModeRef.current = true;
2504
+ const targetTop = targetRect.top - padding;
2505
+ const targetBottom = targetRect.bottom + padding;
2506
+ const currentScroll = window.scrollY;
2507
+ const minY = currentScroll + targetTop;
2508
+ const maxY = currentScroll + targetBottom - viewportHeight;
2509
+ boundsRef.current = {
2510
+ minY: Math.max(0, minY),
2511
+ maxY: Math.max(0, maxY)
2512
+ };
2513
+ const handleScroll = () => {
2514
+ const { minY: minY2, maxY: maxY2 } = boundsRef.current;
2515
+ const currentY = window.scrollY;
2516
+ if (currentY < minY2) {
2517
+ window.scrollTo({ top: minY2, behavior: "auto" });
2518
+ } else if (currentY > maxY2) {
2519
+ window.scrollTo({ top: maxY2, behavior: "auto" });
2520
+ }
2521
+ };
2522
+ handleScroll();
2523
+ window.addEventListener("scroll", handleScroll, { passive: false });
2488
2524
  return () => {
2489
- releaseLock();
2525
+ window.removeEventListener("scroll", handleScroll);
2526
+ isConstrainedModeRef.current = false;
2490
2527
  };
2491
- }, [enabled]);
2528
+ }, [enabled, targetRect, viewportHeight, padding]);
2492
2529
  };
2493
2530
 
2494
2531
  // src/hooks/useHudTargetIssue.ts
@@ -2571,10 +2608,16 @@ var useTourHud = (options = {}) => {
2571
2608
  fallbackAriaDescribedBy: _optionalChain([popoverOptions, 'optionalAccess', _100 => _100.ariaDescribedBy])
2572
2609
  });
2573
2610
  const targetIssue = useHudTargetIssue(hudState.hudTarget);
2611
+ const viewport = useViewportRect();
2574
2612
  const shouldLockBodyScroll = Boolean(
2575
2613
  bodyScrollLock && (_nullishCoalesce(_optionalChain([hudState, 'access', _101 => _101.flowHudOptions, 'optionalAccess', _102 => _102.behavior, 'optionalAccess', _103 => _103.lockBodyScroll]), () => ( lockBodyScroll))) && hudState.focusTrapActive
2576
2614
  );
2577
- useBodyScrollLock(shouldLockBodyScroll);
2615
+ useConstrainedScrollLock({
2616
+ enabled: shouldLockBodyScroll,
2617
+ targetRect: hudState.hudTarget.rect,
2618
+ viewportHeight: viewport.height,
2619
+ padding: _nullishCoalesce(overlayPadding, () => ( 12))
2620
+ });
2578
2621
  const shortcutOptions = typeof shortcuts === "object" ? shortcuts : {};
2579
2622
  const shortcutsEnabled = Boolean(
2580
2623
  (typeof shortcuts === "boolean" ? shortcuts : _nullishCoalesce(shortcuts.enabled, () => ( true))) && hudState.shouldRender
@@ -4501,6 +4544,38 @@ var useHudMotion = () => {
4501
4544
  }, [adapter]);
4502
4545
  };
4503
4546
 
4547
+ // src/hooks/useBodyScrollLock.ts
4548
+
4549
+ var lockCount2 = 0;
4550
+ var previousOverflow2 = null;
4551
+ var acquireLock = () => {
4552
+ if (!_chunkD5LQLRSUcjs.isBrowser) return;
4553
+ if (lockCount2 === 0) {
4554
+ previousOverflow2 = document.body.style.overflow;
4555
+ document.body.style.overflow = "hidden";
4556
+ }
4557
+ lockCount2 += 1;
4558
+ };
4559
+ var releaseLock = () => {
4560
+ if (!_chunkD5LQLRSUcjs.isBrowser) return;
4561
+ if (lockCount2 === 0) return;
4562
+ lockCount2 -= 1;
4563
+ if (lockCount2 === 0) {
4564
+ document.body.style.overflow = _nullishCoalesce(previousOverflow2, () => ( ""));
4565
+ previousOverflow2 = null;
4566
+ }
4567
+ };
4568
+ var useBodyScrollLock = (enabled) => {
4569
+ _react.useEffect.call(void 0, () => {
4570
+ if (!enabled) return;
4571
+ acquireLock();
4572
+ return () => {
4573
+ releaseLock();
4574
+ };
4575
+ }, [enabled]);
4576
+ };
4577
+
4578
+
4504
4579
 
4505
4580
 
4506
4581
 
@@ -4540,4 +4615,4 @@ var useHudMotion = () => {
4540
4615
 
4541
4616
 
4542
4617
 
4543
- exports.AnimationAdapterProvider = AnimationAdapterProvider; exports.DialogRegistryProvider = DialogRegistryProvider; exports.OverlayBackdrop = OverlayBackdrop; exports.TourFocusManager = TourFocusManager; exports.TourPopoverPortal = TourPopoverPortal; exports.TourProvider = TourProvider; exports.createPathString = _chunkD5LQLRSUcjs.createPathString; exports.createWaitForPredicateController = createWaitForPredicateController; exports.defaultAnimationAdapter = defaultAnimationAdapter; exports.defaultLabels = defaultLabels; exports.getCurrentRoutePath = _chunkD5LQLRSUcjs.getCurrentRoutePath; exports.notifyRouteChange = _chunkD5LQLRSUcjs.notifyRouteChange; exports.reducedMotionAnimationAdapter = reducedMotionAnimationAdapter; exports.subscribeToRouteChanges = _chunkD5LQLRSUcjs.subscribeToRouteChanges; exports.useAdvanceRules = useAdvanceRules; exports.useAnimationAdapter = useAnimationAdapter; exports.useBodyScrollLock = useBodyScrollLock; exports.useDelayAdvance = useDelayAdvance; exports.useDialogRegistry = useDialogRegistry; exports.useDialogRegistryOptional = useDialogRegistryOptional; exports.useHiddenTargetFallback = useHiddenTargetFallback; exports.useHudDescription = useHudDescription; exports.useHudMotion = useHudMotion; exports.useHudShortcuts = useHudShortcuts; exports.useHudState = useHudState; exports.useHudTargetIssue = useHudTargetIssue; exports.usePreferredAnimationAdapter = usePreferredAnimationAdapter; exports.useRadixDialogAdapter = useRadixDialogAdapter; exports.useRadixTourDialog = useRadixTourDialog; exports.useTour = useTour; exports.useTourControls = useTourControls; exports.useTourEvents = useTourEvents; exports.useTourFocusDominance = useTourFocusDominance; exports.useTourHud = useTourHud; exports.useTourLabels = useTourLabels; exports.useTourOverlay = useTourOverlay; exports.useTourTarget = useTourTarget; exports.useViewportRect = useViewportRect; exports.waitForDom = waitForDom;
4618
+ exports.AnimationAdapterProvider = AnimationAdapterProvider; exports.DialogRegistryProvider = DialogRegistryProvider; exports.OverlayBackdrop = OverlayBackdrop; exports.TourFocusManager = TourFocusManager; exports.TourPopoverPortal = TourPopoverPortal; exports.TourProvider = TourProvider; exports.createPathString = _chunkD5LQLRSUcjs.createPathString; exports.createWaitForPredicateController = createWaitForPredicateController; exports.defaultAnimationAdapter = defaultAnimationAdapter; exports.defaultLabels = defaultLabels; exports.getCurrentRoutePath = _chunkD5LQLRSUcjs.getCurrentRoutePath; exports.notifyRouteChange = _chunkD5LQLRSUcjs.notifyRouteChange; exports.reducedMotionAnimationAdapter = reducedMotionAnimationAdapter; exports.subscribeToRouteChanges = _chunkD5LQLRSUcjs.subscribeToRouteChanges; exports.useAdvanceRules = useAdvanceRules; exports.useAnimationAdapter = useAnimationAdapter; exports.useBodyScrollLock = useBodyScrollLock; exports.useConstrainedScrollLock = useConstrainedScrollLock; exports.useDelayAdvance = useDelayAdvance; exports.useDialogRegistry = useDialogRegistry; exports.useDialogRegistryOptional = useDialogRegistryOptional; exports.useHiddenTargetFallback = useHiddenTargetFallback; exports.useHudDescription = useHudDescription; exports.useHudMotion = useHudMotion; exports.useHudShortcuts = useHudShortcuts; exports.useHudState = useHudState; exports.useHudTargetIssue = useHudTargetIssue; exports.usePreferredAnimationAdapter = usePreferredAnimationAdapter; exports.useRadixDialogAdapter = useRadixDialogAdapter; exports.useRadixTourDialog = useRadixTourDialog; exports.useTour = useTour; exports.useTourControls = useTourControls; exports.useTourEvents = useTourEvents; exports.useTourFocusDominance = useTourFocusDominance; exports.useTourHud = useTourHud; exports.useTourLabels = useTourLabels; exports.useTourOverlay = useTourOverlay; exports.useTourTarget = useTourTarget; exports.useViewportRect = useViewportRect; exports.waitForDom = waitForDom;
package/dist/index.d.ts CHANGED
@@ -41,6 +41,8 @@ export { useHudMotion } from './motion/useHudMotion';
41
41
  export type { UseHudMotionResult } from './motion/useHudMotion';
42
42
  export { useAdvanceRules } from './hooks/useAdvanceRules';
43
43
  export { useBodyScrollLock } from './hooks/useBodyScrollLock';
44
+ export { useConstrainedScrollLock } from './hooks/useConstrainedScrollLock';
45
+ export type { ConstrainedScrollLockOptions } from './hooks/useConstrainedScrollLock';
44
46
  export { useHiddenTargetFallback } from './hooks/useHiddenTargetFallback';
45
47
  export type { UseHiddenTargetFallbackConfig, UseHiddenTargetFallbackResult, } from './hooks/useHiddenTargetFallback';
46
48
  export { useViewportRect } from './hooks/useViewportRect';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -2460,11 +2460,11 @@ var useHudShortcuts = (target, options) => {
2460
2460
  // src/hooks/useTourHud.ts
2461
2461
  import { useMemo as useMemo9, useState as useState9 } from "react";
2462
2462
 
2463
- // src/hooks/useBodyScrollLock.ts
2464
- import { useEffect as useEffect11 } from "react";
2463
+ // src/hooks/useConstrainedScrollLock.ts
2464
+ import { useEffect as useEffect11, useRef as useRef8 } from "react";
2465
2465
  var lockCount = 0;
2466
2466
  var previousOverflow = null;
2467
- var acquireLock = () => {
2467
+ var acquireHardLock = () => {
2468
2468
  if (!isBrowser) return;
2469
2469
  if (lockCount === 0) {
2470
2470
  previousOverflow = document.body.style.overflow;
@@ -2472,7 +2472,7 @@ var acquireLock = () => {
2472
2472
  }
2473
2473
  lockCount += 1;
2474
2474
  };
2475
- var releaseLock = () => {
2475
+ var releaseHardLock = () => {
2476
2476
  if (!isBrowser) return;
2477
2477
  if (lockCount === 0) return;
2478
2478
  lockCount -= 1;
@@ -2481,14 +2481,51 @@ var releaseLock = () => {
2481
2481
  previousOverflow = null;
2482
2482
  }
2483
2483
  };
2484
- var useBodyScrollLock = (enabled) => {
2484
+ var useConstrainedScrollLock = ({
2485
+ enabled,
2486
+ targetRect,
2487
+ viewportHeight,
2488
+ padding = 0
2489
+ }) => {
2490
+ const isConstrainedModeRef = useRef8(false);
2491
+ const boundsRef = useRef8({ minY: 0, maxY: 0 });
2485
2492
  useEffect11(() => {
2486
- if (!enabled) return;
2487
- acquireLock();
2493
+ if (!enabled || !isBrowser) return;
2494
+ const targetHeight = targetRect ? targetRect.height + padding * 2 : 0;
2495
+ const targetExceedsViewport = targetRect && targetHeight > viewportHeight;
2496
+ if (!targetExceedsViewport) {
2497
+ acquireHardLock();
2498
+ isConstrainedModeRef.current = false;
2499
+ return () => {
2500
+ releaseHardLock();
2501
+ };
2502
+ }
2503
+ isConstrainedModeRef.current = true;
2504
+ const targetTop = targetRect.top - padding;
2505
+ const targetBottom = targetRect.bottom + padding;
2506
+ const currentScroll = window.scrollY;
2507
+ const minY = currentScroll + targetTop;
2508
+ const maxY = currentScroll + targetBottom - viewportHeight;
2509
+ boundsRef.current = {
2510
+ minY: Math.max(0, minY),
2511
+ maxY: Math.max(0, maxY)
2512
+ };
2513
+ const handleScroll = () => {
2514
+ const { minY: minY2, maxY: maxY2 } = boundsRef.current;
2515
+ const currentY = window.scrollY;
2516
+ if (currentY < minY2) {
2517
+ window.scrollTo({ top: minY2, behavior: "auto" });
2518
+ } else if (currentY > maxY2) {
2519
+ window.scrollTo({ top: maxY2, behavior: "auto" });
2520
+ }
2521
+ };
2522
+ handleScroll();
2523
+ window.addEventListener("scroll", handleScroll, { passive: false });
2488
2524
  return () => {
2489
- releaseLock();
2525
+ window.removeEventListener("scroll", handleScroll);
2526
+ isConstrainedModeRef.current = false;
2490
2527
  };
2491
- }, [enabled]);
2528
+ }, [enabled, targetRect, viewportHeight, padding]);
2492
2529
  };
2493
2530
 
2494
2531
  // src/hooks/useHudTargetIssue.ts
@@ -2571,10 +2608,16 @@ var useTourHud = (options = {}) => {
2571
2608
  fallbackAriaDescribedBy: popoverOptions?.ariaDescribedBy
2572
2609
  });
2573
2610
  const targetIssue = useHudTargetIssue(hudState.hudTarget);
2611
+ const viewport = useViewportRect();
2574
2612
  const shouldLockBodyScroll = Boolean(
2575
2613
  bodyScrollLock && (hudState.flowHudOptions?.behavior?.lockBodyScroll ?? lockBodyScroll) && hudState.focusTrapActive
2576
2614
  );
2577
- useBodyScrollLock(shouldLockBodyScroll);
2615
+ useConstrainedScrollLock({
2616
+ enabled: shouldLockBodyScroll,
2617
+ targetRect: hudState.hudTarget.rect,
2618
+ viewportHeight: viewport.height,
2619
+ padding: overlayPadding ?? 12
2620
+ });
2578
2621
  const shortcutOptions = typeof shortcuts === "object" ? shortcuts : {};
2579
2622
  const shortcutsEnabled = Boolean(
2580
2623
  (typeof shortcuts === "boolean" ? shortcuts : shortcuts.enabled ?? true) && hudState.shouldRender
@@ -2636,7 +2679,7 @@ var useTourHud = (options = {}) => {
2636
2679
  };
2637
2680
 
2638
2681
  // src/hooks/useTourOverlay.ts
2639
- import { useEffect as useEffect13, useMemo as useMemo10, useRef as useRef8 } from "react";
2682
+ import { useEffect as useEffect13, useMemo as useMemo10, useRef as useRef9 } from "react";
2640
2683
  var DEFAULT_PADDING = 12;
2641
2684
  var DEFAULT_RADIUS = 12;
2642
2685
  var DEFAULT_EDGE_BUFFER = 0;
@@ -2649,8 +2692,8 @@ var useTourOverlay = (options) => {
2649
2692
  interactionMode = "passthrough",
2650
2693
  isInGracePeriod = false
2651
2694
  } = options;
2652
- const hasShownRef = useRef8(false);
2653
- const lastReadyTargetRef = useRef8(null);
2695
+ const hasShownRef = useRef9(false);
2696
+ const lastReadyTargetRef = useRef9(null);
2654
2697
  useEffect13(() => {
2655
2698
  if (!isBrowser) return;
2656
2699
  if (target.status === "ready") {
@@ -2892,7 +2935,7 @@ var waitForDom = () => new Promise(
2892
2935
  );
2893
2936
 
2894
2937
  // src/hooks/useRadixTourDialog.ts
2895
- import { useCallback as useCallback5, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef9, useState as useState10 } from "react";
2938
+ import { useCallback as useCallback5, useEffect as useEffect14, useMemo as useMemo11, useRef as useRef10, useState as useState10 } from "react";
2896
2939
  var resolveAutoOpen2 = (config) => {
2897
2940
  if (!config) return { onEnter: true, onResume: true };
2898
2941
  const { autoOpen } = config;
@@ -2911,8 +2954,8 @@ var useRadixTourDialog = (params) => {
2911
2954
  const registry = useDialogRegistryOptional();
2912
2955
  const { suspendExternalFocusTrap } = useTourFocusDominance();
2913
2956
  const [internalOpen, setInternalOpen] = useState10(false);
2914
- const lastStepIndexRef = useRef9(-1);
2915
- const isResumeRef = useRef9(false);
2957
+ const lastStepIndexRef = useRef10(-1);
2958
+ const isResumeRef = useRef10(false);
2916
2959
  const flow = activeFlowId ? flows.get(activeFlowId) : void 0;
2917
2960
  const dialogConfig = flow?.dialogs?.[dialogId];
2918
2961
  const currentStep = flow && state && state.stepIndex >= 0 ? flow.steps[state.stepIndex] : void 0;
@@ -3160,7 +3203,7 @@ var useDelayAdvance = () => {
3160
3203
  };
3161
3204
 
3162
3205
  // src/components/OverlayBackdrop.tsx
3163
- import { useEffect as useEffect16, useRef as useRef10 } from "react";
3206
+ import { useEffect as useEffect16, useRef as useRef11 } from "react";
3164
3207
  import { createPortal } from "react-dom";
3165
3208
  import { AnimatePresence } from "motion/react";
3166
3209
  import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -3249,7 +3292,7 @@ var OverlayBackdrop = ({
3249
3292
  viewport
3250
3293
  } = overlay;
3251
3294
  const hasHighlightBounds = Boolean(highlight.rect);
3252
- const prevScreenTargetRef = useRef10(null);
3295
+ const prevScreenTargetRef = useRef11(null);
3253
3296
  const shouldSnapHighlight = prevScreenTargetRef.current === true && !highlight.isScreen && hasHighlightBounds;
3254
3297
  useEffect16(() => {
3255
3298
  prevScreenTargetRef.current = highlight.isScreen;
@@ -3488,7 +3531,7 @@ var OverlayBackdrop = ({
3488
3531
  };
3489
3532
 
3490
3533
  // src/components/TourPopoverPortal.tsx
3491
- import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef11, useState as useState12 } from "react";
3534
+ import { useEffect as useEffect17, useLayoutEffect as useLayoutEffect2, useMemo as useMemo13, useRef as useRef12, useState as useState12 } from "react";
3492
3535
  import { createPortal as createPortal2 } from "react-dom";
3493
3536
  import {
3494
3537
  autoPlacement,
@@ -3556,11 +3599,11 @@ var TourPopoverPortal = ({
3556
3599
  const popoverContentTransition = transitionsOverride?.popoverContent ?? adapter.transitions.popoverContent ?? DEFAULT_POPOVER_CONTENT_TRANSITION;
3557
3600
  const viewport = useViewportRect();
3558
3601
  const prefersMobileLayout = viewport.width <= MOBILE_BREAKPOINT || viewport.height <= MOBILE_HEIGHT_BREAKPOINT;
3559
- const prefersMobileRef = useRef11(prefersMobileLayout);
3602
+ const prefersMobileRef = useRef12(prefersMobileLayout);
3560
3603
  useEffect17(() => {
3561
3604
  prefersMobileRef.current = prefersMobileLayout;
3562
3605
  }, [prefersMobileLayout]);
3563
- const lastReadyTargetRef = useRef11(null);
3606
+ const lastReadyTargetRef = useRef12(null);
3564
3607
  useEffect17(() => {
3565
3608
  if (target.status === "ready" && target.rect) {
3566
3609
  lastReadyTargetRef.current = {
@@ -3604,22 +3647,22 @@ var TourPopoverPortal = ({
3604
3647
  }),
3605
3648
  [viewport.height, viewport.width]
3606
3649
  );
3607
- const floatingRef = useRef11(null);
3608
- const cachedFloatingPositionRef = useRef11(null);
3609
- const appliedFloatingCacheRef = useRef11(null);
3610
- const deferredScreenSnapRef = useRef11(null);
3650
+ const floatingRef = useRef12(null);
3651
+ const cachedFloatingPositionRef = useRef12(null);
3652
+ const appliedFloatingCacheRef = useRef12(null);
3653
+ const deferredScreenSnapRef = useRef12(null);
3611
3654
  const [layoutMode, setLayoutMode] = useState12(
3612
3655
  () => prefersMobileLayout ? "mobile" : "floating"
3613
3656
  );
3614
3657
  const [floatingPosition, setFloatingPosition] = useState12(fallbackPosition);
3615
3658
  const [dragPosition, setDragPosition] = useState12(null);
3616
3659
  const [isDragging, setIsDragging] = useState12(false);
3617
- const dragStateRef = useRef11(null);
3618
- const overflowRetryRef = useRef11({
3660
+ const dragStateRef = useRef12(null);
3661
+ const overflowRetryRef = useRef12({
3619
3662
  stepId: null,
3620
3663
  attempts: 0
3621
3664
  });
3622
- const overflowRetryTimeoutRef = useRef11(null);
3665
+ const overflowRetryTimeoutRef = useRef12(null);
3623
3666
  useLayoutEffect2(() => {
3624
3667
  if (!isBrowser) return;
3625
3668
  const node = floatingRef.current;
@@ -4093,7 +4136,7 @@ var TourPopoverPortal = ({
4093
4136
  };
4094
4137
 
4095
4138
  // src/components/TourFocusManager.tsx
4096
- import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect3, useRef as useRef12, useState as useState13 } from "react";
4139
+ import { useEffect as useEffect18, useLayoutEffect as useLayoutEffect3, useRef as useRef13, useState as useState13 } from "react";
4097
4140
  import { createPortal as createPortal3 } from "react-dom";
4098
4141
 
4099
4142
  // src/utils/focus.ts
@@ -4170,15 +4213,15 @@ var TourFocusManager = ({
4170
4213
  highlightRect,
4171
4214
  guardElementFocusRing
4172
4215
  }) => {
4173
- const previousFocusRef = useRef12(null);
4174
- const guardNodesRef = useRef12({
4216
+ const previousFocusRef = useRef13(null);
4217
+ const guardNodesRef = useRef13({
4175
4218
  "target-start": null,
4176
4219
  "target-end": null,
4177
4220
  "popover-start": null,
4178
4221
  "popover-end": null
4179
4222
  });
4180
- const lastTabDirectionRef = useRef12("forward");
4181
- const suppressGuardHopRef = useRef12(null);
4223
+ const lastTabDirectionRef = useRef13("forward");
4224
+ const suppressGuardHopRef = useRef13(null);
4182
4225
  const [targetRingActive, setTargetRingActive] = useState13(false);
4183
4226
  const [popoverRingActive, setPopoverRingActive] = useState13(false);
4184
4227
  const [popoverRect, setPopoverRect] = useState13(null);
@@ -4500,6 +4543,37 @@ var useHudMotion = () => {
4500
4543
  };
4501
4544
  }, [adapter]);
4502
4545
  };
4546
+
4547
+ // src/hooks/useBodyScrollLock.ts
4548
+ import { useEffect as useEffect19 } from "react";
4549
+ var lockCount2 = 0;
4550
+ var previousOverflow2 = null;
4551
+ var acquireLock = () => {
4552
+ if (!isBrowser) return;
4553
+ if (lockCount2 === 0) {
4554
+ previousOverflow2 = document.body.style.overflow;
4555
+ document.body.style.overflow = "hidden";
4556
+ }
4557
+ lockCount2 += 1;
4558
+ };
4559
+ var releaseLock = () => {
4560
+ if (!isBrowser) return;
4561
+ if (lockCount2 === 0) return;
4562
+ lockCount2 -= 1;
4563
+ if (lockCount2 === 0) {
4564
+ document.body.style.overflow = previousOverflow2 ?? "";
4565
+ previousOverflow2 = null;
4566
+ }
4567
+ };
4568
+ var useBodyScrollLock = (enabled) => {
4569
+ useEffect19(() => {
4570
+ if (!enabled) return;
4571
+ acquireLock();
4572
+ return () => {
4573
+ releaseLock();
4574
+ };
4575
+ }, [enabled]);
4576
+ };
4503
4577
  export {
4504
4578
  AnimationAdapterProvider,
4505
4579
  DialogRegistryProvider,
@@ -4518,6 +4592,7 @@ export {
4518
4592
  useAdvanceRules,
4519
4593
  useAnimationAdapter,
4520
4594
  useBodyScrollLock,
4595
+ useConstrainedScrollLock,
4521
4596
  useDelayAdvance,
4522
4597
  useDialogRegistry,
4523
4598
  useDialogRegistryOptional,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowsterix/react",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "React bindings for Flowsterix - guided tours and onboarding flows",
5
5
  "license": "MIT",
6
6
  "repository": {