@samline/drawer 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1099,7 +1099,7 @@ var require_react_development = __commonJS({
1099
1099
  var dispatcher = resolveDispatcher();
1100
1100
  return dispatcher.useReducer(reducer, initialArg, init);
1101
1101
  }
1102
- function useRef10(initialValue) {
1102
+ function useRef11(initialValue) {
1103
1103
  var dispatcher = resolveDispatcher();
1104
1104
  return dispatcher.useRef(initialValue);
1105
1105
  }
@@ -1893,7 +1893,7 @@ var require_react_development = __commonJS({
1893
1893
  exports.useLayoutEffect = useLayoutEffect5;
1894
1894
  exports.useMemo = useMemo6;
1895
1895
  exports.useReducer = useReducer3;
1896
- exports.useRef = useRef10;
1896
+ exports.useRef = useRef11;
1897
1897
  exports.useState = useState10;
1898
1898
  exports.useSyncExternalStore = useSyncExternalStore;
1899
1899
  exports.useTransition = useTransition;
@@ -26962,25 +26962,34 @@ var nonTextInputTypes = /* @__PURE__ */ new Set([
26962
26962
  "submit",
26963
26963
  "reset"
26964
26964
  ]);
26965
- var preventScrollCount = 0;
26966
- var restore;
26965
+ var activePreventScrollLocks = /* @__PURE__ */ new Set();
26966
+ var activePreventScrollRestore = null;
26967
+ function acquirePreventScrollLock(lockId) {
26968
+ activePreventScrollLocks.add(lockId);
26969
+ if (activePreventScrollLocks.size === 1 && isIOS()) {
26970
+ activePreventScrollRestore = preventScrollMobileSafari();
26971
+ }
26972
+ }
26973
+ function releasePreventScrollLock(lockId) {
26974
+ activePreventScrollLocks.delete(lockId);
26975
+ if (activePreventScrollLocks.size === 0) {
26976
+ activePreventScrollRestore?.();
26977
+ activePreventScrollRestore = null;
26978
+ }
26979
+ }
26967
26980
  function usePreventScroll(options = {}) {
26968
26981
  let { isDisabled } = options;
26982
+ const lockIdRef = (0, import_react3.useRef)();
26983
+ if (!lockIdRef.current) {
26984
+ lockIdRef.current = /* @__PURE__ */ Symbol("drawer-prevent-scroll-lock");
26985
+ }
26969
26986
  useIsomorphicLayoutEffect2(() => {
26970
26987
  if (isDisabled) {
26971
26988
  return;
26972
26989
  }
26973
- preventScrollCount++;
26974
- if (preventScrollCount === 1) {
26975
- if (isIOS()) {
26976
- restore = preventScrollMobileSafari();
26977
- }
26978
- }
26990
+ acquirePreventScrollLock(lockIdRef.current);
26979
26991
  return () => {
26980
- preventScrollCount--;
26981
- if (preventScrollCount === 0) {
26982
- restore?.();
26983
- }
26992
+ releasePreventScrollLock(lockIdRef.current);
26984
26993
  };
26985
26994
  }, [isDisabled]);
26986
26995
  }
@@ -27554,12 +27563,23 @@ function useScaleBackground() {
27554
27563
  const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext();
27555
27564
  const timeoutIdRef = import_react6.default.useRef(null);
27556
27565
  const initialBackgroundColor = (0, import_react6.useMemo)(() => document.body.style.backgroundColor, []);
27566
+ import_react6.default.useEffect(() => {
27567
+ return () => {
27568
+ if (timeoutIdRef.current !== null) {
27569
+ window.clearTimeout(timeoutIdRef.current);
27570
+ timeoutIdRef.current = null;
27571
+ }
27572
+ };
27573
+ }, []);
27557
27574
  function getScale() {
27558
27575
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
27559
27576
  }
27560
27577
  import_react6.default.useEffect(() => {
27561
27578
  if (isOpen && shouldScaleBackground) {
27562
- if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current);
27579
+ if (timeoutIdRef.current !== null) {
27580
+ clearTimeout(timeoutIdRef.current);
27581
+ timeoutIdRef.current = null;
27582
+ }
27563
27583
  const wrapper = document.querySelector("[data-drawer-wrapper]");
27564
27584
  if (!wrapper) return;
27565
27585
  chain(
@@ -27588,6 +27608,7 @@ function useScaleBackground() {
27588
27608
  } else {
27589
27609
  document.body.style.removeProperty("background");
27590
27610
  }
27611
+ timeoutIdRef.current = null;
27591
27612
  }, TRANSITIONS.DURATION * 1e3);
27592
27613
  };
27593
27614
  }
@@ -27597,6 +27618,14 @@ function useScaleBackground() {
27597
27618
  // src/use-position-fixed.ts
27598
27619
  var import_react7 = __toESM(require_react());
27599
27620
  var previousBodyPosition = null;
27621
+ var activeBodyPositionLocks = /* @__PURE__ */ new Set();
27622
+ var bodyPositionTimeoutId = null;
27623
+ function clearBodyPositionTimeout() {
27624
+ if (bodyPositionTimeoutId !== null) {
27625
+ window.clearTimeout(bodyPositionTimeoutId);
27626
+ bodyPositionTimeoutId = null;
27627
+ }
27628
+ }
27600
27629
  function usePositionFixed({
27601
27630
  isOpen,
27602
27631
  modal,
@@ -27607,8 +27636,17 @@ function usePositionFixed({
27607
27636
  }) {
27608
27637
  const [activeUrl, setActiveUrl] = import_react7.default.useState(() => typeof window !== "undefined" ? window.location.href : "");
27609
27638
  const scrollPos = import_react7.default.useRef(0);
27639
+ const lockIdRef = import_react7.default.useRef();
27640
+ if (!lockIdRef.current) {
27641
+ lockIdRef.current = /* @__PURE__ */ Symbol("drawer-body-position-lock");
27642
+ }
27610
27643
  const setPositionFixed = import_react7.default.useCallback(() => {
27611
27644
  if (!isSafari()) return;
27645
+ const lockId = lockIdRef.current;
27646
+ if (activeBodyPositionLocks.has(lockId)) {
27647
+ return;
27648
+ }
27649
+ activeBodyPositionLocks.add(lockId);
27612
27650
  if (previousBodyPosition === null && isOpen && !noBodyStyles) {
27613
27651
  previousBodyPosition = {
27614
27652
  position: document.body.style.position,
@@ -27625,7 +27663,8 @@ function usePositionFixed({
27625
27663
  right: "0px",
27626
27664
  height: "auto"
27627
27665
  });
27628
- window.setTimeout(
27666
+ clearBodyPositionTimeout();
27667
+ bodyPositionTimeoutId = window.setTimeout(
27629
27668
  () => window.requestAnimationFrame(() => {
27630
27669
  const bottomBarHeight = innerHeight - window.innerHeight;
27631
27670
  if (bottomBarHeight && scrollPos.current >= innerHeight) {
@@ -27635,10 +27674,16 @@ function usePositionFixed({
27635
27674
  300
27636
27675
  );
27637
27676
  }
27638
- }, [isOpen]);
27677
+ }, [isOpen, noBodyStyles]);
27639
27678
  const restorePositionSetting = import_react7.default.useCallback(() => {
27640
27679
  if (!isSafari()) return;
27680
+ const lockId = lockIdRef.current;
27681
+ activeBodyPositionLocks.delete(lockId);
27682
+ if (activeBodyPositionLocks.size > 0) {
27683
+ return;
27684
+ }
27641
27685
  if (previousBodyPosition !== null && !noBodyStyles) {
27686
+ clearBodyPositionTimeout();
27642
27687
  const y = -parseInt(document.body.style.top, 10);
27643
27688
  const x = -parseInt(document.body.style.left, 10);
27644
27689
  Object.assign(document.body.style, previousBodyPosition);
@@ -27651,7 +27696,7 @@ function usePositionFixed({
27651
27696
  });
27652
27697
  previousBodyPosition = null;
27653
27698
  }
27654
- }, [activeUrl]);
27699
+ }, [activeUrl, noBodyStyles, setActiveUrl]);
27655
27700
  import_react7.default.useEffect(() => {
27656
27701
  function onScroll() {
27657
27702
  scrollPos.current = window.scrollY;
@@ -27949,6 +27994,12 @@ function Root2({
27949
27994
  container,
27950
27995
  autoFocus = false
27951
27996
  }) {
27997
+ const animationEndTimeoutRef = import_react9.default.useRef(null);
27998
+ const nonModalPointerEventsRafRef = import_react9.default.useRef(null);
27999
+ const shouldAnimateRafRef = import_react9.default.useRef(null);
28000
+ const snapPointsResetTimeoutRef = import_react9.default.useRef(null);
28001
+ const justReleasedTimeoutRef = import_react9.default.useRef(null);
28002
+ const touchEndHandlerRef = import_react9.default.useRef(null);
27952
28003
  const [isOpen = false, setIsOpen] = useControllableState2({
27953
28004
  defaultProp: defaultOpen,
27954
28005
  prop: openProp,
@@ -27957,13 +28008,20 @@ function Root2({
27957
28008
  if (!o && !nested) {
27958
28009
  restorePositionSetting();
27959
28010
  }
27960
- setTimeout(() => {
28011
+ if (animationEndTimeoutRef.current !== null) {
28012
+ window.clearTimeout(animationEndTimeoutRef.current);
28013
+ }
28014
+ animationEndTimeoutRef.current = window.setTimeout(() => {
27961
28015
  onAnimationEnd?.(o);
27962
28016
  }, TRANSITIONS.DURATION * 1e3);
27963
28017
  if (o && !modal) {
27964
28018
  if (typeof window !== "undefined") {
27965
- window.requestAnimationFrame(() => {
28019
+ if (nonModalPointerEventsRafRef.current !== null) {
28020
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28021
+ }
28022
+ nonModalPointerEventsRafRef.current = window.requestAnimationFrame(() => {
27966
28023
  document.body.style.pointerEvents = "auto";
28024
+ nonModalPointerEventsRafRef.current = null;
27967
28025
  });
27968
28026
  }
27969
28027
  }
@@ -28072,7 +28130,15 @@ function Root2({
28072
28130
  setIsDragging(true);
28073
28131
  dragStartTime.current = /* @__PURE__ */ new Date();
28074
28132
  if (isIOS()) {
28075
- window.addEventListener("touchend", () => isAllowedToDrag.current = false, { once: true });
28133
+ if (touchEndHandlerRef.current) {
28134
+ window.removeEventListener("touchend", touchEndHandlerRef.current);
28135
+ }
28136
+ const handleTouchEnd = () => {
28137
+ isAllowedToDrag.current = false;
28138
+ touchEndHandlerRef.current = null;
28139
+ };
28140
+ touchEndHandlerRef.current = handleTouchEnd;
28141
+ window.addEventListener("touchend", handleTouchEnd, { once: true });
28076
28142
  }
28077
28143
  event.target.setPointerCapture(event.pointerId);
28078
28144
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
@@ -28179,9 +28245,15 @@ function Root2({
28179
28245
  }
28180
28246
  }
28181
28247
  import_react9.default.useEffect(() => {
28182
- window.requestAnimationFrame(() => {
28248
+ shouldAnimateRafRef.current = window.requestAnimationFrame(() => {
28183
28249
  shouldAnimate.current = true;
28184
28250
  });
28251
+ return () => {
28252
+ if (shouldAnimateRafRef.current !== null) {
28253
+ window.cancelAnimationFrame(shouldAnimateRafRef.current);
28254
+ shouldAnimateRafRef.current = null;
28255
+ }
28256
+ };
28185
28257
  }, []);
28186
28258
  import_react9.default.useEffect(() => {
28187
28259
  function onVisualViewportChange() {
@@ -28222,10 +28294,14 @@ function Root2({
28222
28294
  if (!fromWithin) {
28223
28295
  setIsOpen(false);
28224
28296
  }
28225
- setTimeout(() => {
28297
+ if (snapPointsResetTimeoutRef.current !== null) {
28298
+ window.clearTimeout(snapPointsResetTimeoutRef.current);
28299
+ }
28300
+ snapPointsResetTimeoutRef.current = window.setTimeout(() => {
28226
28301
  if (snapPoints) {
28227
28302
  setActiveSnapPoint(snapPoints[0]);
28228
28303
  }
28304
+ snapPointsResetTimeoutRef.current = null;
28229
28305
  }, TRANSITIONS.DURATION * 1e3);
28230
28306
  }
28231
28307
  function resetDrawer() {
@@ -28300,8 +28376,12 @@ function Root2({
28300
28376
  });
28301
28377
  if (releaseResult.shouldPreventFocus) {
28302
28378
  setJustReleased(true);
28303
- setTimeout(() => {
28379
+ if (justReleasedTimeoutRef.current !== null) {
28380
+ window.clearTimeout(justReleasedTimeoutRef.current);
28381
+ }
28382
+ justReleasedTimeoutRef.current = window.setTimeout(() => {
28304
28383
  setJustReleased(false);
28384
+ justReleasedTimeoutRef.current = null;
28305
28385
  }, 200);
28306
28386
  }
28307
28387
  if (releaseResult.action === "close") {
@@ -28375,11 +28455,44 @@ function Root2({
28375
28455
  });
28376
28456
  }
28377
28457
  }
28458
+ import_react9.default.useEffect(() => {
28459
+ return () => {
28460
+ if (animationEndTimeoutRef.current !== null) {
28461
+ window.clearTimeout(animationEndTimeoutRef.current);
28462
+ }
28463
+ if (nonModalPointerEventsRafRef.current !== null) {
28464
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28465
+ }
28466
+ if (snapPointsResetTimeoutRef.current !== null) {
28467
+ window.clearTimeout(snapPointsResetTimeoutRef.current);
28468
+ }
28469
+ if (justReleasedTimeoutRef.current !== null) {
28470
+ window.clearTimeout(justReleasedTimeoutRef.current);
28471
+ }
28472
+ if (nestedOpenChangeTimer.current) {
28473
+ window.clearTimeout(nestedOpenChangeTimer.current);
28474
+ }
28475
+ if (touchEndHandlerRef.current) {
28476
+ window.removeEventListener("touchend", touchEndHandlerRef.current);
28477
+ touchEndHandlerRef.current = null;
28478
+ }
28479
+ };
28480
+ }, []);
28378
28481
  import_react9.default.useEffect(() => {
28379
28482
  if (!modal) {
28380
- window.requestAnimationFrame(() => {
28483
+ if (nonModalPointerEventsRafRef.current !== null) {
28484
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28485
+ }
28486
+ nonModalPointerEventsRafRef.current = window.requestAnimationFrame(() => {
28381
28487
  document.body.style.pointerEvents = "auto";
28488
+ nonModalPointerEventsRafRef.current = null;
28382
28489
  });
28490
+ return () => {
28491
+ if (nonModalPointerEventsRafRef.current !== null) {
28492
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28493
+ nonModalPointerEventsRafRef.current = null;
28494
+ }
28495
+ };
28383
28496
  }
28384
28497
  }, [modal]);
28385
28498
  return /* @__PURE__ */ import_react9.default.createElement(
@@ -28486,15 +28599,23 @@ var Content2 = import_react9.default.forwardRef(function({ onPointerDownOutside,
28486
28599
  const pointerStartRef = import_react9.default.useRef(null);
28487
28600
  const lastKnownPointerEventRef = import_react9.default.useRef(null);
28488
28601
  const wasBeyondThePointRef = import_react9.default.useRef(false);
28602
+ const delayedSnapPointsRafRef = import_react9.default.useRef(null);
28489
28603
  const hasSnapPoints = snapPoints && snapPoints.length > 0;
28490
28604
  useScaleBackground();
28491
28605
  import_react9.default.useEffect(() => {
28492
28606
  if (hasSnapPoints) {
28493
- window.requestAnimationFrame(() => {
28607
+ delayedSnapPointsRafRef.current = window.requestAnimationFrame(() => {
28494
28608
  setDelayedSnapPoints(true);
28609
+ delayedSnapPointsRafRef.current = null;
28495
28610
  });
28496
28611
  }
28497
- }, []);
28612
+ return () => {
28613
+ if (delayedSnapPointsRafRef.current !== null) {
28614
+ window.cancelAnimationFrame(delayedSnapPointsRafRef.current);
28615
+ delayedSnapPointsRafRef.current = null;
28616
+ }
28617
+ };
28618
+ }, [hasSnapPoints]);
28498
28619
  function handleOnPointerUp(event) {
28499
28620
  pointerStartRef.current = null;
28500
28621
  wasBeyondThePointRef.current = false;
@@ -28603,13 +28724,14 @@ var Handle = import_react9.default.forwardRef(function({ preventCycle = false, c
28603
28724
  onDrag
28604
28725
  } = useDrawerContext();
28605
28726
  const closeTimeoutIdRef = import_react9.default.useRef(null);
28727
+ const cycleTimeoutIdRef = import_react9.default.useRef(null);
28606
28728
  const shouldCancelInteractionRef = import_react9.default.useRef(false);
28607
28729
  function handleStartCycle() {
28608
28730
  if (shouldCancelInteractionRef.current) {
28609
28731
  handleCancelInteraction();
28610
28732
  return;
28611
28733
  }
28612
- window.setTimeout(() => {
28734
+ cycleTimeoutIdRef.current = window.setTimeout(() => {
28613
28735
  handleCycleSnapPoints();
28614
28736
  }, DOUBLE_TAP_TIMEOUT);
28615
28737
  }
@@ -28640,9 +28762,19 @@ var Handle = import_react9.default.forwardRef(function({ preventCycle = false, c
28640
28762
  function handleCancelInteraction() {
28641
28763
  if (closeTimeoutIdRef.current) {
28642
28764
  window.clearTimeout(closeTimeoutIdRef.current);
28765
+ closeTimeoutIdRef.current = null;
28766
+ }
28767
+ if (cycleTimeoutIdRef.current) {
28768
+ window.clearTimeout(cycleTimeoutIdRef.current);
28769
+ cycleTimeoutIdRef.current = null;
28643
28770
  }
28644
28771
  shouldCancelInteractionRef.current = false;
28645
28772
  }
28773
+ import_react9.default.useEffect(() => {
28774
+ return () => {
28775
+ handleCancelInteraction();
28776
+ };
28777
+ }, []);
28646
28778
  return /* @__PURE__ */ import_react9.default.createElement(
28647
28779
  "div",
28648
28780
  {