@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.
@@ -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;
@@ -26965,25 +26965,34 @@ var nonTextInputTypes = /* @__PURE__ */ new Set([
26965
26965
  "submit",
26966
26966
  "reset"
26967
26967
  ]);
26968
- var preventScrollCount = 0;
26969
- var restore;
26968
+ var activePreventScrollLocks = /* @__PURE__ */ new Set();
26969
+ var activePreventScrollRestore = null;
26970
+ function acquirePreventScrollLock(lockId) {
26971
+ activePreventScrollLocks.add(lockId);
26972
+ if (activePreventScrollLocks.size === 1 && isIOS()) {
26973
+ activePreventScrollRestore = preventScrollMobileSafari();
26974
+ }
26975
+ }
26976
+ function releasePreventScrollLock(lockId) {
26977
+ activePreventScrollLocks.delete(lockId);
26978
+ if (activePreventScrollLocks.size === 0) {
26979
+ activePreventScrollRestore?.();
26980
+ activePreventScrollRestore = null;
26981
+ }
26982
+ }
26970
26983
  function usePreventScroll(options = {}) {
26971
26984
  let { isDisabled } = options;
26985
+ const lockIdRef = (0, import_react3.useRef)();
26986
+ if (!lockIdRef.current) {
26987
+ lockIdRef.current = /* @__PURE__ */ Symbol("drawer-prevent-scroll-lock");
26988
+ }
26972
26989
  useIsomorphicLayoutEffect2(() => {
26973
26990
  if (isDisabled) {
26974
26991
  return;
26975
26992
  }
26976
- preventScrollCount++;
26977
- if (preventScrollCount === 1) {
26978
- if (isIOS()) {
26979
- restore = preventScrollMobileSafari();
26980
- }
26981
- }
26993
+ acquirePreventScrollLock(lockIdRef.current);
26982
26994
  return () => {
26983
- preventScrollCount--;
26984
- if (preventScrollCount === 0) {
26985
- restore?.();
26986
- }
26995
+ releasePreventScrollLock(lockIdRef.current);
26987
26996
  };
26988
26997
  }, [isDisabled]);
26989
26998
  }
@@ -27557,12 +27566,23 @@ function useScaleBackground() {
27557
27566
  const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext();
27558
27567
  const timeoutIdRef = import_react6.default.useRef(null);
27559
27568
  const initialBackgroundColor = (0, import_react6.useMemo)(() => document.body.style.backgroundColor, []);
27569
+ import_react6.default.useEffect(() => {
27570
+ return () => {
27571
+ if (timeoutIdRef.current !== null) {
27572
+ window.clearTimeout(timeoutIdRef.current);
27573
+ timeoutIdRef.current = null;
27574
+ }
27575
+ };
27576
+ }, []);
27560
27577
  function getScale() {
27561
27578
  return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
27562
27579
  }
27563
27580
  import_react6.default.useEffect(() => {
27564
27581
  if (isOpen && shouldScaleBackground) {
27565
- if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current);
27582
+ if (timeoutIdRef.current !== null) {
27583
+ clearTimeout(timeoutIdRef.current);
27584
+ timeoutIdRef.current = null;
27585
+ }
27566
27586
  const wrapper = document.querySelector("[data-drawer-wrapper]");
27567
27587
  if (!wrapper) return;
27568
27588
  chain(
@@ -27591,6 +27611,7 @@ function useScaleBackground() {
27591
27611
  } else {
27592
27612
  document.body.style.removeProperty("background");
27593
27613
  }
27614
+ timeoutIdRef.current = null;
27594
27615
  }, TRANSITIONS.DURATION * 1e3);
27595
27616
  };
27596
27617
  }
@@ -27600,6 +27621,14 @@ function useScaleBackground() {
27600
27621
  // src/use-position-fixed.ts
27601
27622
  var import_react7 = __toESM(require_react());
27602
27623
  var previousBodyPosition = null;
27624
+ var activeBodyPositionLocks = /* @__PURE__ */ new Set();
27625
+ var bodyPositionTimeoutId = null;
27626
+ function clearBodyPositionTimeout() {
27627
+ if (bodyPositionTimeoutId !== null) {
27628
+ window.clearTimeout(bodyPositionTimeoutId);
27629
+ bodyPositionTimeoutId = null;
27630
+ }
27631
+ }
27603
27632
  function usePositionFixed({
27604
27633
  isOpen,
27605
27634
  modal,
@@ -27610,8 +27639,17 @@ function usePositionFixed({
27610
27639
  }) {
27611
27640
  const [activeUrl, setActiveUrl] = import_react7.default.useState(() => typeof window !== "undefined" ? window.location.href : "");
27612
27641
  const scrollPos = import_react7.default.useRef(0);
27642
+ const lockIdRef = import_react7.default.useRef();
27643
+ if (!lockIdRef.current) {
27644
+ lockIdRef.current = /* @__PURE__ */ Symbol("drawer-body-position-lock");
27645
+ }
27613
27646
  const setPositionFixed = import_react7.default.useCallback(() => {
27614
27647
  if (!isSafari()) return;
27648
+ const lockId = lockIdRef.current;
27649
+ if (activeBodyPositionLocks.has(lockId)) {
27650
+ return;
27651
+ }
27652
+ activeBodyPositionLocks.add(lockId);
27615
27653
  if (previousBodyPosition === null && isOpen && !noBodyStyles) {
27616
27654
  previousBodyPosition = {
27617
27655
  position: document.body.style.position,
@@ -27628,7 +27666,8 @@ function usePositionFixed({
27628
27666
  right: "0px",
27629
27667
  height: "auto"
27630
27668
  });
27631
- window.setTimeout(
27669
+ clearBodyPositionTimeout();
27670
+ bodyPositionTimeoutId = window.setTimeout(
27632
27671
  () => window.requestAnimationFrame(() => {
27633
27672
  const bottomBarHeight = innerHeight - window.innerHeight;
27634
27673
  if (bottomBarHeight && scrollPos.current >= innerHeight) {
@@ -27638,10 +27677,16 @@ function usePositionFixed({
27638
27677
  300
27639
27678
  );
27640
27679
  }
27641
- }, [isOpen]);
27680
+ }, [isOpen, noBodyStyles]);
27642
27681
  const restorePositionSetting = import_react7.default.useCallback(() => {
27643
27682
  if (!isSafari()) return;
27683
+ const lockId = lockIdRef.current;
27684
+ activeBodyPositionLocks.delete(lockId);
27685
+ if (activeBodyPositionLocks.size > 0) {
27686
+ return;
27687
+ }
27644
27688
  if (previousBodyPosition !== null && !noBodyStyles) {
27689
+ clearBodyPositionTimeout();
27645
27690
  const y = -parseInt(document.body.style.top, 10);
27646
27691
  const x = -parseInt(document.body.style.left, 10);
27647
27692
  Object.assign(document.body.style, previousBodyPosition);
@@ -27654,7 +27699,7 @@ function usePositionFixed({
27654
27699
  });
27655
27700
  previousBodyPosition = null;
27656
27701
  }
27657
- }, [activeUrl]);
27702
+ }, [activeUrl, noBodyStyles, setActiveUrl]);
27658
27703
  import_react7.default.useEffect(() => {
27659
27704
  function onScroll() {
27660
27705
  scrollPos.current = window.scrollY;
@@ -27952,6 +27997,12 @@ function Root2({
27952
27997
  container,
27953
27998
  autoFocus = false
27954
27999
  }) {
28000
+ const animationEndTimeoutRef = import_react9.default.useRef(null);
28001
+ const nonModalPointerEventsRafRef = import_react9.default.useRef(null);
28002
+ const shouldAnimateRafRef = import_react9.default.useRef(null);
28003
+ const snapPointsResetTimeoutRef = import_react9.default.useRef(null);
28004
+ const justReleasedTimeoutRef = import_react9.default.useRef(null);
28005
+ const touchEndHandlerRef = import_react9.default.useRef(null);
27955
28006
  const [isOpen = false, setIsOpen] = useControllableState2({
27956
28007
  defaultProp: defaultOpen,
27957
28008
  prop: openProp,
@@ -27960,13 +28011,20 @@ function Root2({
27960
28011
  if (!o && !nested) {
27961
28012
  restorePositionSetting();
27962
28013
  }
27963
- setTimeout(() => {
28014
+ if (animationEndTimeoutRef.current !== null) {
28015
+ window.clearTimeout(animationEndTimeoutRef.current);
28016
+ }
28017
+ animationEndTimeoutRef.current = window.setTimeout(() => {
27964
28018
  onAnimationEnd?.(o);
27965
28019
  }, TRANSITIONS.DURATION * 1e3);
27966
28020
  if (o && !modal) {
27967
28021
  if (typeof window !== "undefined") {
27968
- window.requestAnimationFrame(() => {
28022
+ if (nonModalPointerEventsRafRef.current !== null) {
28023
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28024
+ }
28025
+ nonModalPointerEventsRafRef.current = window.requestAnimationFrame(() => {
27969
28026
  document.body.style.pointerEvents = "auto";
28027
+ nonModalPointerEventsRafRef.current = null;
27970
28028
  });
27971
28029
  }
27972
28030
  }
@@ -28075,7 +28133,15 @@ function Root2({
28075
28133
  setIsDragging(true);
28076
28134
  dragStartTime.current = /* @__PURE__ */ new Date();
28077
28135
  if (isIOS()) {
28078
- window.addEventListener("touchend", () => isAllowedToDrag.current = false, { once: true });
28136
+ if (touchEndHandlerRef.current) {
28137
+ window.removeEventListener("touchend", touchEndHandlerRef.current);
28138
+ }
28139
+ const handleTouchEnd = () => {
28140
+ isAllowedToDrag.current = false;
28141
+ touchEndHandlerRef.current = null;
28142
+ };
28143
+ touchEndHandlerRef.current = handleTouchEnd;
28144
+ window.addEventListener("touchend", handleTouchEnd, { once: true });
28079
28145
  }
28080
28146
  event.target.setPointerCapture(event.pointerId);
28081
28147
  pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
@@ -28182,9 +28248,15 @@ function Root2({
28182
28248
  }
28183
28249
  }
28184
28250
  import_react9.default.useEffect(() => {
28185
- window.requestAnimationFrame(() => {
28251
+ shouldAnimateRafRef.current = window.requestAnimationFrame(() => {
28186
28252
  shouldAnimate.current = true;
28187
28253
  });
28254
+ return () => {
28255
+ if (shouldAnimateRafRef.current !== null) {
28256
+ window.cancelAnimationFrame(shouldAnimateRafRef.current);
28257
+ shouldAnimateRafRef.current = null;
28258
+ }
28259
+ };
28188
28260
  }, []);
28189
28261
  import_react9.default.useEffect(() => {
28190
28262
  function onVisualViewportChange() {
@@ -28225,10 +28297,14 @@ function Root2({
28225
28297
  if (!fromWithin) {
28226
28298
  setIsOpen(false);
28227
28299
  }
28228
- setTimeout(() => {
28300
+ if (snapPointsResetTimeoutRef.current !== null) {
28301
+ window.clearTimeout(snapPointsResetTimeoutRef.current);
28302
+ }
28303
+ snapPointsResetTimeoutRef.current = window.setTimeout(() => {
28229
28304
  if (snapPoints) {
28230
28305
  setActiveSnapPoint(snapPoints[0]);
28231
28306
  }
28307
+ snapPointsResetTimeoutRef.current = null;
28232
28308
  }, TRANSITIONS.DURATION * 1e3);
28233
28309
  }
28234
28310
  function resetDrawer() {
@@ -28303,8 +28379,12 @@ function Root2({
28303
28379
  });
28304
28380
  if (releaseResult.shouldPreventFocus) {
28305
28381
  setJustReleased(true);
28306
- setTimeout(() => {
28382
+ if (justReleasedTimeoutRef.current !== null) {
28383
+ window.clearTimeout(justReleasedTimeoutRef.current);
28384
+ }
28385
+ justReleasedTimeoutRef.current = window.setTimeout(() => {
28307
28386
  setJustReleased(false);
28387
+ justReleasedTimeoutRef.current = null;
28308
28388
  }, 200);
28309
28389
  }
28310
28390
  if (releaseResult.action === "close") {
@@ -28378,11 +28458,44 @@ function Root2({
28378
28458
  });
28379
28459
  }
28380
28460
  }
28461
+ import_react9.default.useEffect(() => {
28462
+ return () => {
28463
+ if (animationEndTimeoutRef.current !== null) {
28464
+ window.clearTimeout(animationEndTimeoutRef.current);
28465
+ }
28466
+ if (nonModalPointerEventsRafRef.current !== null) {
28467
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28468
+ }
28469
+ if (snapPointsResetTimeoutRef.current !== null) {
28470
+ window.clearTimeout(snapPointsResetTimeoutRef.current);
28471
+ }
28472
+ if (justReleasedTimeoutRef.current !== null) {
28473
+ window.clearTimeout(justReleasedTimeoutRef.current);
28474
+ }
28475
+ if (nestedOpenChangeTimer.current) {
28476
+ window.clearTimeout(nestedOpenChangeTimer.current);
28477
+ }
28478
+ if (touchEndHandlerRef.current) {
28479
+ window.removeEventListener("touchend", touchEndHandlerRef.current);
28480
+ touchEndHandlerRef.current = null;
28481
+ }
28482
+ };
28483
+ }, []);
28381
28484
  import_react9.default.useEffect(() => {
28382
28485
  if (!modal) {
28383
- window.requestAnimationFrame(() => {
28486
+ if (nonModalPointerEventsRafRef.current !== null) {
28487
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28488
+ }
28489
+ nonModalPointerEventsRafRef.current = window.requestAnimationFrame(() => {
28384
28490
  document.body.style.pointerEvents = "auto";
28491
+ nonModalPointerEventsRafRef.current = null;
28385
28492
  });
28493
+ return () => {
28494
+ if (nonModalPointerEventsRafRef.current !== null) {
28495
+ window.cancelAnimationFrame(nonModalPointerEventsRafRef.current);
28496
+ nonModalPointerEventsRafRef.current = null;
28497
+ }
28498
+ };
28386
28499
  }
28387
28500
  }, [modal]);
28388
28501
  return /* @__PURE__ */ import_react9.default.createElement(
@@ -28489,15 +28602,23 @@ var Content2 = import_react9.default.forwardRef(function({ onPointerDownOutside,
28489
28602
  const pointerStartRef = import_react9.default.useRef(null);
28490
28603
  const lastKnownPointerEventRef = import_react9.default.useRef(null);
28491
28604
  const wasBeyondThePointRef = import_react9.default.useRef(false);
28605
+ const delayedSnapPointsRafRef = import_react9.default.useRef(null);
28492
28606
  const hasSnapPoints = snapPoints && snapPoints.length > 0;
28493
28607
  useScaleBackground();
28494
28608
  import_react9.default.useEffect(() => {
28495
28609
  if (hasSnapPoints) {
28496
- window.requestAnimationFrame(() => {
28610
+ delayedSnapPointsRafRef.current = window.requestAnimationFrame(() => {
28497
28611
  setDelayedSnapPoints(true);
28612
+ delayedSnapPointsRafRef.current = null;
28498
28613
  });
28499
28614
  }
28500
- }, []);
28615
+ return () => {
28616
+ if (delayedSnapPointsRafRef.current !== null) {
28617
+ window.cancelAnimationFrame(delayedSnapPointsRafRef.current);
28618
+ delayedSnapPointsRafRef.current = null;
28619
+ }
28620
+ };
28621
+ }, [hasSnapPoints]);
28501
28622
  function handleOnPointerUp(event) {
28502
28623
  pointerStartRef.current = null;
28503
28624
  wasBeyondThePointRef.current = false;
@@ -28606,13 +28727,14 @@ var Handle = import_react9.default.forwardRef(function({ preventCycle = false, c
28606
28727
  onDrag
28607
28728
  } = useDrawerContext();
28608
28729
  const closeTimeoutIdRef = import_react9.default.useRef(null);
28730
+ const cycleTimeoutIdRef = import_react9.default.useRef(null);
28609
28731
  const shouldCancelInteractionRef = import_react9.default.useRef(false);
28610
28732
  function handleStartCycle() {
28611
28733
  if (shouldCancelInteractionRef.current) {
28612
28734
  handleCancelInteraction();
28613
28735
  return;
28614
28736
  }
28615
- window.setTimeout(() => {
28737
+ cycleTimeoutIdRef.current = window.setTimeout(() => {
28616
28738
  handleCycleSnapPoints();
28617
28739
  }, DOUBLE_TAP_TIMEOUT);
28618
28740
  }
@@ -28643,9 +28765,19 @@ var Handle = import_react9.default.forwardRef(function({ preventCycle = false, c
28643
28765
  function handleCancelInteraction() {
28644
28766
  if (closeTimeoutIdRef.current) {
28645
28767
  window.clearTimeout(closeTimeoutIdRef.current);
28768
+ closeTimeoutIdRef.current = null;
28769
+ }
28770
+ if (cycleTimeoutIdRef.current) {
28771
+ window.clearTimeout(cycleTimeoutIdRef.current);
28772
+ cycleTimeoutIdRef.current = null;
28646
28773
  }
28647
28774
  shouldCancelInteractionRef.current = false;
28648
28775
  }
28776
+ import_react9.default.useEffect(() => {
28777
+ return () => {
28778
+ handleCancelInteraction();
28779
+ };
28780
+ }, []);
28649
28781
  return /* @__PURE__ */ import_react9.default.createElement(
28650
28782
  "div",
28651
28783
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@samline/drawer",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "A universal drawer package for React, Vue, Svelte, vanilla JS, and browser usage.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",