react-modal-sheet 5.2.1 → 5.2.3

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
@@ -1,5 +1,5 @@
1
1
  import { motion, useMotionValue, useTransform, useReducedMotion, animate } from 'motion/react';
2
- import React4, { createContext, forwardRef, useRef, useState, useImperativeHandle, useContext, useCallback, useEffect, useLayoutEffect } from 'react';
2
+ import React4, { createContext, forwardRef, useRef, useState, useImperativeHandle, useContext, useCallback, useMemo, useEffect, useLayoutEffect } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
  import useMeasure from 'react-use-measure';
5
5
  import { transform } from 'motion';
@@ -214,14 +214,14 @@ var SheetBackdrop = forwardRef(
214
214
  return /* @__PURE__ */ React4.createElement(
215
215
  Comp,
216
216
  {
217
- ...rest,
218
- ref,
219
- className: `react-modal-sheet-backdrop ${className}`,
220
- style: backdropStyle,
221
217
  initial: { opacity: 0 },
222
218
  animate: { opacity: 1 },
223
219
  exit: { opacity: 0 },
224
- transition: { duration: 1 }
220
+ transition: { duration: 1 },
221
+ ...rest,
222
+ ref,
223
+ className: `react-modal-sheet-backdrop ${className}`,
224
+ style: backdropStyle
225
225
  }
226
226
  );
227
227
  }
@@ -270,63 +270,88 @@ function useDragConstraints() {
270
270
  const onMeasure = useCallback(() => constraints, []);
271
271
  return { ref, onMeasure };
272
272
  }
273
+ var useIsomorphicLayoutEffect = IS_SSR ? useEffect : useLayoutEffect;
274
+
275
+ // src/hooks/use-stable-callback.ts
276
+ function useStableCallback(handler) {
277
+ const handlerRef = useRef(void 0);
278
+ useIsomorphicLayoutEffect(() => {
279
+ handlerRef.current = handler;
280
+ });
281
+ return useCallback((...args) => {
282
+ const fn = handlerRef.current;
283
+ return fn == null ? void 0 : fn(...args);
284
+ }, []);
285
+ }
286
+
287
+ // src/hooks/use-scroll-position.ts
273
288
  function useScrollPosition(options = {}) {
274
289
  const { debounceDelay = 32, isEnabled = true } = options;
290
+ const scrollTimeoutRef = useRef(null);
275
291
  const [element, setElement] = useState(null);
276
292
  const [scrollPosition, setScrollPosition] = useState(void 0);
277
- useEffect(() => {
278
- if (!element || !isEnabled) return;
279
- let scrollTimeout = null;
280
- function determineScrollPosition(element2) {
281
- const { scrollTop, scrollHeight, clientHeight } = element2;
282
- const isScrollable2 = scrollHeight > clientHeight;
283
- if (!isScrollable2) {
284
- if (scrollPosition) setScrollPosition(void 0);
285
- return;
286
- }
287
- const isAtTop = scrollTop <= 0;
288
- const isAtBottom = Math.ceil(scrollHeight) - Math.ceil(scrollTop) === Math.ceil(clientHeight);
289
- let position;
290
- if (isAtTop) {
291
- position = "top";
292
- } else if (isAtBottom) {
293
- position = "bottom";
294
- } else {
295
- position = "middle";
296
- }
297
- if (position === scrollPosition) return;
298
- setScrollPosition(position);
293
+ const scrollRef = useMemo(
294
+ () => (element2) => {
295
+ setElement(element2);
296
+ },
297
+ []
298
+ );
299
+ const determineScrollPosition = useStableCallback((element2) => {
300
+ const { scrollTop, scrollHeight, clientHeight } = element2;
301
+ const isScrollable2 = scrollHeight > clientHeight;
302
+ if (!isScrollable2) {
303
+ if (scrollPosition) setScrollPosition(void 0);
304
+ return;
299
305
  }
300
- function onScroll(event) {
301
- if (event.currentTarget instanceof HTMLElement) {
302
- const el = event.currentTarget;
303
- if (scrollTimeout) clearTimeout(scrollTimeout);
304
- if (debounceDelay === 0) {
305
- determineScrollPosition(el);
306
- } else {
307
- scrollTimeout = setTimeout(
308
- () => determineScrollPosition(el),
309
- debounceDelay
310
- );
311
- }
312
- }
306
+ const isAtTop = scrollTop <= 0;
307
+ const isAtBottom = Math.ceil(scrollHeight) - Math.ceil(scrollTop) === Math.ceil(clientHeight);
308
+ let position;
309
+ if (isAtTop) {
310
+ position = "top";
311
+ } else if (isAtBottom) {
312
+ position = "bottom";
313
+ } else {
314
+ position = "middle";
313
315
  }
314
- function onTouchStart(event) {
315
- if (event.currentTarget instanceof HTMLElement) {
316
- determineScrollPosition(event.currentTarget);
316
+ element2.style.touchAction = isAtTop ? "pan-down" : "";
317
+ if (position === scrollPosition) return;
318
+ setScrollPosition(position);
319
+ });
320
+ const onScroll = useStableCallback((event) => {
321
+ if (event.currentTarget instanceof HTMLElement) {
322
+ const el = event.currentTarget;
323
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
324
+ if (debounceDelay === 0) {
325
+ determineScrollPosition(el);
326
+ } else {
327
+ scrollTimeoutRef.current = setTimeout(
328
+ () => determineScrollPosition(el),
329
+ debounceDelay
330
+ );
317
331
  }
318
332
  }
333
+ });
334
+ const onTouchStart = useStableCallback((event) => {
335
+ if (event.currentTarget instanceof HTMLElement) {
336
+ const element2 = event.currentTarget;
337
+ requestAnimationFrame(() => {
338
+ determineScrollPosition(element2);
339
+ });
340
+ }
341
+ });
342
+ useEffect(() => {
343
+ if (!element || !isEnabled) return;
319
344
  determineScrollPosition(element);
320
345
  element.addEventListener("scroll", onScroll);
321
346
  element.addEventListener("touchstart", onTouchStart);
322
347
  return () => {
323
- if (scrollTimeout) clearTimeout(scrollTimeout);
348
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
324
349
  element.removeEventListener("scroll", onScroll);
325
350
  element.removeEventListener("touchstart", onTouchStart);
326
351
  };
327
352
  }, [element, isEnabled]);
328
353
  return {
329
- scrollRef: (element2) => setElement(element2),
354
+ scrollRef,
330
355
  scrollPosition
331
356
  };
332
357
  }
@@ -347,7 +372,9 @@ var SheetContent = forwardRef(
347
372
  }, ref) => {
348
373
  const sheetContext = useSheetContext();
349
374
  const dragConstraints = useDragConstraints();
350
- const scroll = useScrollPosition();
375
+ const scroll = useScrollPosition({
376
+ isEnabled: typeof disableScrollProp === "function" ? true : !disableScrollProp
377
+ });
351
378
  const disableScroll = typeof disableScrollProp === "function" ? disableScrollProp({
352
379
  scrollPosition: scroll.scrollPosition,
353
380
  currentSnap: sheetContext.currentSnap
@@ -371,6 +398,9 @@ var SheetContent = forwardRef(
371
398
  if (disableScroll) {
372
399
  scrollStyle.overflowY = "hidden";
373
400
  }
401
+ if (dragProps !== void 0) {
402
+ scrollStyle.touchAction = "pan-down";
403
+ }
374
404
  return /* @__PURE__ */ React4.createElement(
375
405
  motion.div,
376
406
  {
@@ -466,9 +496,6 @@ var SheetHeader = forwardRef(
466
496
  }
467
497
  );
468
498
  SheetHeader.displayName = "SheetHeader";
469
- var useIsomorphicLayoutEffect = IS_SSR ? useEffect : useLayoutEffect;
470
-
471
- // src/hooks/use-dimensions.ts
472
499
  function useDimensions() {
473
500
  const [dimensions, setDimensions] = useState(() => ({
474
501
  windowHeight: !IS_SSR ? window.innerHeight : 0,
@@ -829,18 +856,6 @@ function scrollIntoView(target) {
829
856
  function willOpenKeyboard(target) {
830
857
  return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
831
858
  }
832
- function useStableCallback(handler) {
833
- const handlerRef = useRef(void 0);
834
- useIsomorphicLayoutEffect(() => {
835
- handlerRef.current = handler;
836
- });
837
- return useCallback((...args) => {
838
- const fn = handlerRef.current;
839
- return fn == null ? void 0 : fn(...args);
840
- }, []);
841
- }
842
-
843
- // src/hooks/use-sheet-state.ts
844
859
  function useSheetState({
845
860
  isOpen,
846
861
  onClosed: _onClosed,