react-modal-sheet 5.5.0 → 5.7.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.
package/dist/index.js CHANGED
@@ -1,129 +1,29 @@
1
1
  'use strict';
2
2
 
3
+ var React = require('react');
3
4
  var react = require('motion/react');
4
- var React4 = require('react');
5
5
  var reactDom = require('react-dom');
6
6
  var useMeasure = require('react-use-measure');
7
7
  var motion = require('motion');
8
8
 
9
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
10
 
11
- var React4__default = /*#__PURE__*/_interopDefault(React4);
11
+ var React__default = /*#__PURE__*/_interopDefault(React);
12
12
  var useMeasure__default = /*#__PURE__*/_interopDefault(useMeasure);
13
13
 
14
- // src/SheetBackdrop.tsx
15
- var SheetContext = React4.createContext(
16
- void 0
17
- );
18
- function useSheetContext() {
19
- const context = React4.useContext(SheetContext);
14
+ // src/context.tsx
15
+ var InternalSheetContext = React.createContext(void 0);
16
+ var ExposedSheetContext = React.createContext(void 0);
17
+ function useInternalContext() {
18
+ const context = React.useContext(InternalSheetContext);
19
+ if (!context) throw new Error("Sheet context error");
20
+ return context;
21
+ }
22
+ function useExposedContext() {
23
+ const context = React.useContext(ExposedSheetContext);
20
24
  if (!context) throw new Error("Sheet context error");
21
25
  return context;
22
26
  }
23
-
24
- // src/styles.ts
25
- var styles = {
26
- root: {
27
- base: {
28
- position: "fixed",
29
- top: 0,
30
- bottom: 0,
31
- left: 0,
32
- right: 0,
33
- overflow: "hidden",
34
- pointerEvents: "none"
35
- },
36
- decorative: {}
37
- },
38
- backdrop: {
39
- base: {
40
- zIndex: 1,
41
- position: "fixed",
42
- top: 0,
43
- left: 0,
44
- width: "100%",
45
- height: "100%",
46
- touchAction: "none",
47
- userSelect: "none"
48
- },
49
- decorative: {
50
- backgroundColor: "rgba(0, 0, 0, 0.2)",
51
- border: "none",
52
- WebkitTapHighlightColor: "transparent"
53
- }
54
- },
55
- container: {
56
- base: {
57
- zIndex: 2,
58
- position: "absolute",
59
- left: 0,
60
- bottom: 0,
61
- width: "100%",
62
- pointerEvents: "auto",
63
- display: "flex",
64
- flexDirection: "column"
65
- },
66
- decorative: {
67
- backgroundColor: "#fff",
68
- borderTopRightRadius: "8px",
69
- borderTopLeftRadius: "8px",
70
- boxShadow: "0px -2px 16px rgba(0, 0, 0, 0.3)"
71
- }
72
- },
73
- headerWrapper: {
74
- base: {
75
- width: "100%"
76
- },
77
- decorative: {}
78
- },
79
- header: {
80
- base: {
81
- width: "100%",
82
- position: "relative"
83
- },
84
- decorative: {
85
- height: "40px",
86
- display: "flex",
87
- alignItems: "center",
88
- justifyContent: "center"
89
- }
90
- },
91
- indicatorWrapper: {
92
- base: {
93
- display: "flex"
94
- },
95
- decorative: {}
96
- },
97
- indicator: {
98
- base: {
99
- display: "inline-block"
100
- },
101
- decorative: {
102
- width: "18px",
103
- height: "4px",
104
- borderRadius: "99px",
105
- backgroundColor: "#ddd"
106
- }
107
- },
108
- content: {
109
- base: {
110
- minHeight: "0px",
111
- position: "relative",
112
- flexGrow: 1,
113
- display: "flex",
114
- flexDirection: "column"
115
- },
116
- decorative: {}
117
- },
118
- scroller: {
119
- base: {
120
- height: "100%",
121
- overflowY: "auto",
122
- overscrollBehaviorY: "none"
123
- },
124
- decorative: {}
125
- }
126
- };
127
27
 
128
28
  // src/constants.ts
129
29
  var DEFAULT_HEIGHT = "calc(100% - env(safe-area-inset-top) - 34px)";
@@ -138,6 +38,29 @@ var REDUCED_MOTION_TWEEN_CONFIG = {
138
38
  };
139
39
  var DEFAULT_DRAG_CLOSE_THRESHOLD = 0.6;
140
40
  var DEFAULT_DRAG_VELOCITY_THRESHOLD = 1200;
41
+ var useIsomorphicLayoutEffect = IS_SSR ? React.useEffect : React.useLayoutEffect;
42
+
43
+ // src/hooks/use-dimensions.ts
44
+ function useDimensions() {
45
+ const [dimensions, setDimensions] = React.useState(() => ({
46
+ windowHeight: !IS_SSR ? window.innerHeight : 0,
47
+ windowWidth: !IS_SSR ? window.innerWidth : 0
48
+ }));
49
+ useIsomorphicLayoutEffect(() => {
50
+ function handler() {
51
+ setDimensions({
52
+ windowHeight: window.innerHeight,
53
+ windowWidth: window.innerWidth
54
+ });
55
+ }
56
+ handler();
57
+ window.addEventListener("resize", handler);
58
+ return () => {
59
+ window.removeEventListener("resize", handler);
60
+ };
61
+ }, []);
62
+ return dimensions;
63
+ }
141
64
 
142
65
  // src/utils.ts
143
66
  function applyStyles(styles2, unstyled) {
@@ -220,356 +143,46 @@ function willOpenKeyboard(target) {
220
143
  function isHTTPS() {
221
144
  return typeof window !== "undefined" && window.isSecureContext;
222
145
  }
223
-
224
- // src/SheetBackdrop.tsx
225
- var isClickable = (props) => !!props.onClick || !!props.onTap;
226
- var SheetBackdrop = React4.forwardRef(
227
- ({ style, className = "", unstyled, ...rest }, ref) => {
228
- const sheetContext = useSheetContext();
229
- const clickable = isClickable(rest);
230
- const Comp = clickable ? react.motion.button : react.motion.div;
231
- const pointerEvents = clickable ? "auto" : "none";
232
- const isUnstyled = unstyled ?? sheetContext.unstyled;
233
- const backdropStyle = {
234
- ...applyStyles(styles.backdrop, isUnstyled),
235
- ...style,
236
- pointerEvents
237
- };
238
- const animationProps = sheetContext.prefersReducedMotion ? {} : {
239
- initial: { opacity: 0 },
240
- animate: { opacity: 1 },
241
- exit: { opacity: 0 },
242
- transition: { duration: 1 }
243
- };
244
- return /* @__PURE__ */ React4__default.default.createElement(
245
- Comp,
246
- {
247
- ...animationProps,
248
- ...rest,
249
- ref,
250
- className: `react-modal-sheet-backdrop ${className}`,
251
- style: backdropStyle
252
- }
253
- );
254
- }
255
- );
256
- SheetBackdrop.displayName = "SheetBackdrop";
257
- var SheetContainer = React4.forwardRef(
258
- ({ children, style, className = "", unstyled, ...rest }, ref) => {
259
- const sheetContext = useSheetContext();
260
- const isUnstyled = unstyled ?? sheetContext.unstyled;
261
- const containerStyle = {
262
- ...applyStyles(styles.container, isUnstyled),
263
- ...style,
264
- y: sheetContext.y
265
- };
266
- if (sheetContext.detent === "default") {
267
- containerStyle.height = DEFAULT_HEIGHT;
268
- }
269
- if (sheetContext.detent === "full") {
270
- containerStyle.height = "100%";
271
- containerStyle.maxHeight = "100%";
272
- }
273
- if (sheetContext.detent === "content") {
274
- containerStyle.height = "auto";
275
- containerStyle.maxHeight = DEFAULT_HEIGHT;
276
- }
277
- return /* @__PURE__ */ React4__default.default.createElement(
278
- react.motion.div,
279
- {
280
- ...rest,
281
- ref: mergeRefs([
282
- ref,
283
- sheetContext.sheetRef,
284
- sheetContext.sheetBoundsRef
285
- ]),
286
- className: `react-modal-sheet-container ${className}`,
287
- style: containerStyle
288
- },
289
- children
290
- );
291
- }
292
- );
293
- SheetContainer.displayName = "SheetContainer";
294
- var constraints = { bottom: 0, top: 0, left: 0, right: 0 };
295
- function useDragConstraints() {
296
- const ref = React4.useRef(null);
297
- const onMeasure = React4.useCallback(() => constraints, []);
298
- return { ref, onMeasure };
146
+ function clamp(value, min, max) {
147
+ return Math.min(Math.max(value, min), max);
299
148
  }
300
- var useIsomorphicLayoutEffect = IS_SSR ? React4.useEffect : React4.useLayoutEffect;
301
-
302
- // src/hooks/use-stable-callback.ts
303
149
  function useStableCallback(handler) {
304
- const handlerRef = React4.useRef(void 0);
150
+ const handlerRef = React.useRef(void 0);
305
151
  useIsomorphicLayoutEffect(() => {
306
152
  handlerRef.current = handler;
307
153
  });
308
- return React4.useCallback((...args) => {
154
+ return React.useCallback((...args) => {
309
155
  const fn = handlerRef.current;
310
156
  return fn == null ? void 0 : fn(...args);
311
157
  }, []);
312
158
  }
313
-
314
- // src/hooks/use-scroll-position.ts
315
- function useScrollPosition(options = {}) {
316
- const { debounceDelay = 32, isEnabled = true } = options;
317
- const scrollTimeoutRef = React4.useRef(null);
318
- const [element, setElement] = React4.useState(null);
319
- const [scrollPosition, setScrollPosition] = React4.useState(void 0);
320
- const scrollRef = React4.useMemo(
321
- () => (element2) => {
322
- setElement(element2);
323
- },
324
- []
325
- );
326
- const determineScrollPosition = useStableCallback((element2) => {
327
- const { scrollTop, scrollHeight, clientHeight } = element2;
328
- const isScrollable2 = scrollHeight > clientHeight;
329
- if (!isScrollable2) {
330
- if (scrollPosition) setScrollPosition(void 0);
331
- return;
332
- }
333
- const isAtTop = scrollTop <= 0;
334
- const isAtBottom = Math.ceil(scrollHeight) - Math.ceil(scrollTop) === Math.ceil(clientHeight);
335
- let position;
336
- if (isAtTop) {
337
- position = "top";
338
- } else if (isAtBottom) {
339
- position = "bottom";
340
- } else {
341
- position = "middle";
342
- }
343
- element2.style.touchAction = isAtTop ? "pan-down" : "";
344
- if (position === scrollPosition) return;
345
- setScrollPosition(position);
159
+ var virtualKeyboardOverlayUsers = 0;
160
+ var initialVirtualKeyboardOverlaysContent = null;
161
+ function useVirtualKeyboard(options = {}) {
162
+ const {
163
+ containerRef,
164
+ isEnabled = true,
165
+ debounceDelay = 100,
166
+ visualViewportThreshold = 100
167
+ } = options;
168
+ const [state, setState] = React.useState({
169
+ isVisible: false,
170
+ height: 0
346
171
  });
347
- const onScroll = useStableCallback((event) => {
348
- if (event.currentTarget instanceof HTMLElement) {
349
- const el = event.currentTarget;
350
- if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
351
- if (debounceDelay === 0) {
352
- determineScrollPosition(el);
353
- } else {
354
- scrollTimeoutRef.current = setTimeout(
355
- () => determineScrollPosition(el),
356
- debounceDelay
172
+ const focusedElementRef = React.useRef(null);
173
+ const debounceTimer = React.useRef(null);
174
+ React.useEffect(() => {
175
+ const vv = window.visualViewport;
176
+ const vk = getVirtualKeyboardApi();
177
+ function setKeyboardInsetHeightEnv(height) {
178
+ const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
179
+ if (vk) {
180
+ element.style.setProperty(
181
+ "--keyboard-inset-height",
182
+ `env(keyboard-inset-height, ${height}px)`
357
183
  );
358
- }
359
- }
360
- });
361
- const onTouchStart = useStableCallback((event) => {
362
- if (event.currentTarget instanceof HTMLElement) {
363
- const element2 = event.currentTarget;
364
- requestAnimationFrame(() => {
365
- determineScrollPosition(element2);
366
- });
367
- }
368
- });
369
- React4.useEffect(() => {
370
- if (!element || !isEnabled) return;
371
- determineScrollPosition(element);
372
- element.addEventListener("scroll", onScroll);
373
- element.addEventListener("touchstart", onTouchStart);
374
- return () => {
375
- if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
376
- element.removeEventListener("scroll", onScroll);
377
- element.removeEventListener("touchstart", onTouchStart);
378
- };
379
- }, [element, isEnabled]);
380
- return {
381
- scrollRef,
382
- scrollPosition
383
- };
384
- }
385
-
386
- // src/SheetContent.tsx
387
- var SheetContent = React4.forwardRef(
388
- ({
389
- disableScroll: disableScrollProp,
390
- disableDrag: disableDragProp,
391
- children,
392
- style: styleProp,
393
- className = "",
394
- scrollClassName = "",
395
- scrollStyle: scrollStyleProp,
396
- scrollRef: scrollRefProp = null,
397
- unstyled,
398
- ...rest
399
- }, ref) => {
400
- const sheetContext = useSheetContext();
401
- const dragConstraints = useDragConstraints();
402
- const scroll = useScrollPosition({
403
- isEnabled: typeof disableScrollProp === "function" ? true : !disableScrollProp
404
- });
405
- const disableScroll = typeof disableScrollProp === "function" ? disableScrollProp({
406
- scrollPosition: scroll.scrollPosition,
407
- currentSnap: sheetContext.currentSnap
408
- }) : Boolean(disableScrollProp);
409
- const disableDragDueToScroll = !disableScroll && scroll.scrollPosition && scroll.scrollPosition !== "top";
410
- const disableDragDueToProp = typeof disableDragProp === "function" ? disableDragProp({
411
- scrollPosition: scroll.scrollPosition,
412
- currentSnap: sheetContext.currentSnap
413
- }) : Boolean(disableDragProp);
414
- const disableDrag = disableDragDueToProp || disableDragDueToScroll || sheetContext.disableDrag;
415
- const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
416
- const isUnstyled = unstyled ?? sheetContext.unstyled;
417
- const contentStyle = {
418
- ...applyStyles(styles.content, isUnstyled),
419
- ...styleProp
420
- };
421
- const scrollStyle = applyStyles(styles.scroller, isUnstyled);
422
- if (sheetContext.avoidKeyboard) {
423
- scrollStyle.paddingBottom = isHTTPS() ? "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))" : "var(--keyboard-inset-height, 0px)";
424
- }
425
- if (disableScroll) {
426
- scrollStyle.overflowY = "hidden";
427
- }
428
- if (dragProps !== void 0) {
429
- scrollStyle.touchAction = "pan-down";
430
- }
431
- return /* @__PURE__ */ React4__default.default.createElement(
432
- react.motion.div,
433
- {
434
- ...rest,
435
- ref: mergeRefs([ref, dragConstraints.ref]),
436
- className: `react-modal-sheet-content ${className}`,
437
- style: contentStyle,
438
- ...dragProps,
439
- dragConstraints: dragConstraints.ref,
440
- onMeasureDragConstraints: dragConstraints.onMeasure
441
- },
442
- /* @__PURE__ */ React4__default.default.createElement(
443
- react.motion.div,
444
- {
445
- ref: mergeRefs([scroll.scrollRef, scrollRefProp]),
446
- style: { ...scrollStyle, ...scrollStyleProp },
447
- className: `react-modal-sheet-content-scroller ${scrollClassName}`
448
- },
449
- children
450
- )
451
- );
452
- }
453
- );
454
- SheetContent.displayName = "SheetContent";
455
- function SheetDragIndicator({
456
- style,
457
- className = "",
458
- unstyled,
459
- ...rest
460
- }) {
461
- const sheetContext = useSheetContext();
462
- const indicator1Transform = react.useTransform(
463
- sheetContext.indicatorRotation,
464
- (r) => `translateX(2px) rotate(${r}deg)`
465
- );
466
- const indicator2Transform = react.useTransform(
467
- sheetContext.indicatorRotation,
468
- (r) => `translateX(-2px) rotate(${ -1 * r}deg)`
469
- );
470
- const isUnstyled = unstyled ?? sheetContext.unstyled;
471
- const indicatorWrapperStyle = {
472
- ...applyStyles(styles.indicatorWrapper, isUnstyled),
473
- ...style
474
- };
475
- const indicatorStyle = applyStyles(styles.indicator, isUnstyled);
476
- return /* @__PURE__ */ React4__default.default.createElement(
477
- "div",
478
- {
479
- className: `react-modal-sheet-drag-indicator-container ${className}`,
480
- style: indicatorWrapperStyle,
481
- ...rest
482
- },
483
- /* @__PURE__ */ React4__default.default.createElement(
484
- react.motion.span,
485
- {
486
- className: "react-modal-sheet-drag-indicator",
487
- style: { ...indicatorStyle, transform: indicator1Transform }
488
- }
489
- ),
490
- /* @__PURE__ */ React4__default.default.createElement(
491
- react.motion.span,
492
- {
493
- className: "react-modal-sheet-drag-indicator",
494
- style: { ...indicatorStyle, transform: indicator2Transform }
495
- }
496
- )
497
- );
498
- }
499
- var SheetHeader = React4.forwardRef(
500
- ({ children, style, disableDrag, unstyled, className = "", ...rest }, ref) => {
501
- const sheetContext = useSheetContext();
502
- const dragConstraints = useDragConstraints();
503
- const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
504
- const isUnstyled = unstyled ?? sheetContext.unstyled;
505
- const headerWrapperStyle = {
506
- ...applyStyles(styles.headerWrapper, isUnstyled),
507
- ...style
508
- };
509
- const headerStyle = applyStyles(styles.header, isUnstyled);
510
- return /* @__PURE__ */ React4__default.default.createElement(
511
- react.motion.div,
512
- {
513
- ...rest,
514
- ref: mergeRefs([ref, dragConstraints.ref]),
515
- style: headerWrapperStyle,
516
- className: `react-modal-sheet-header-container ${className}`,
517
- ...dragProps,
518
- dragConstraints: dragConstraints.ref,
519
- onMeasureDragConstraints: dragConstraints.onMeasure
520
- },
521
- children || /* @__PURE__ */ React4__default.default.createElement("div", { className: "react-modal-sheet-header", style: headerStyle }, /* @__PURE__ */ React4__default.default.createElement(SheetDragIndicator, null))
522
- );
523
- }
524
- );
525
- SheetHeader.displayName = "SheetHeader";
526
- function useDimensions() {
527
- const [dimensions, setDimensions] = React4.useState(() => ({
528
- windowHeight: !IS_SSR ? window.innerHeight : 0,
529
- windowWidth: !IS_SSR ? window.innerWidth : 0
530
- }));
531
- useIsomorphicLayoutEffect(() => {
532
- function handler() {
533
- setDimensions({
534
- windowHeight: window.innerHeight,
535
- windowWidth: window.innerWidth
536
- });
537
- }
538
- handler();
539
- window.addEventListener("resize", handler);
540
- return () => {
541
- window.removeEventListener("resize", handler);
542
- };
543
- }, []);
544
- return dimensions;
545
- }
546
- var virtualKeyboardOverlayUsers = 0;
547
- var initialVirtualKeyboardOverlaysContent = null;
548
- function useVirtualKeyboard(options = {}) {
549
- const {
550
- containerRef,
551
- isEnabled = true,
552
- debounceDelay = 100,
553
- visualViewportThreshold = 100
554
- } = options;
555
- const [state, setState] = React4.useState({
556
- isVisible: false,
557
- height: 0
558
- });
559
- const focusedElementRef = React4.useRef(null);
560
- const debounceTimer = React4.useRef(null);
561
- React4.useEffect(() => {
562
- const vv = window.visualViewport;
563
- const vk = getVirtualKeyboardApi();
564
- function setKeyboardInsetHeightEnv(height) {
565
- const element = (containerRef == null ? void 0 : containerRef.current) || document.documentElement;
566
- if (vk) {
567
- element.style.setProperty(
568
- "--keyboard-inset-height",
569
- `env(keyboard-inset-height, ${height}px)`
570
- );
571
- } else {
572
- element.style.setProperty("--keyboard-inset-height", `${height}px`);
184
+ } else {
185
+ element.style.setProperty("--keyboard-inset-height", `${height}px`);
573
186
  }
574
187
  }
575
188
  function setKeyboardState(nextState) {
@@ -691,7 +304,7 @@ function useKeyboardAvoidance({
691
304
  onWillOpenKeyboard,
692
305
  onDidOpenKeyboard
693
306
  }) {
694
- const [focusedElement, setFocusedElement] = React4.useState(
307
+ const [focusedElement, setFocusedElement] = React.useState(
695
308
  null
696
309
  );
697
310
  const keyboard = useVirtualKeyboard({
@@ -712,7 +325,7 @@ function useKeyboardAvoidance({
712
325
  setFocusedElement(null);
713
326
  }
714
327
  });
715
- React4.useEffect(() => {
328
+ React.useEffect(() => {
716
329
  if (!isEnabled) return;
717
330
  document.addEventListener("focusin", handleFocusIn);
718
331
  document.addEventListener("focusout", handleFocusOut);
@@ -721,7 +334,7 @@ function useKeyboardAvoidance({
721
334
  document.removeEventListener("focusout", handleFocusOut);
722
335
  };
723
336
  }, [isEnabled]);
724
- React4.useEffect(() => {
337
+ React.useEffect(() => {
725
338
  const containerElement = containerRef.current;
726
339
  if (!isEnabled || !focusedElement || !containerElement || !keyboard.isKeyboardOpen) {
727
340
  return;
@@ -733,7 +346,7 @@ function useKeyboardAvoidance({
733
346
  return keyboard;
734
347
  }
735
348
  function useSafeAreaInsets() {
736
- const [insets] = React4.useState(() => {
349
+ const [insets] = React.useState(() => {
737
350
  const fallback = { top: 0, left: 0, right: 0, bottom: 0 };
738
351
  if (IS_SSR) return fallback;
739
352
  const root = document.querySelector(":root");
@@ -775,77 +388,109 @@ function useModalEffect({
775
388
  console.warn('Using "full" detent with modal effect is not supported.');
776
389
  rootId = void 0;
777
390
  }
778
- useIsomorphicLayoutEffect(() => {
779
- return () => {
780
- if (rootId) cleanupModalEffect(rootId);
781
- };
782
- }, []);
783
- useIsomorphicLayoutEffect(() => {
391
+ const handleYChange = useStableCallback((yValue) => {
392
+ if (!rootId) return;
393
+ let progress = Math.max(0, 1 - yValue / sheetHeight);
394
+ const snapThresholdPoint = snapPoints.length > 1 ? snapPoints[snapPoints.length - 2] : void 0;
395
+ if (snapThresholdPoint !== void 0) {
396
+ const snapThresholdValue = snapThresholdPoint.snapValueY;
397
+ if (yValue <= snapThresholdValue) {
398
+ progress = (snapThresholdValue - yValue) / snapThresholdValue;
399
+ } else {
400
+ progress = 0;
401
+ }
402
+ }
403
+ if (startThreshold !== void 0) {
404
+ const startThresholdValue = sheetHeight - Math.min(Math.floor(startThreshold * sheetHeight), sheetHeight);
405
+ if (yValue <= startThresholdValue) {
406
+ progress = (startThresholdValue - yValue) / startThresholdValue;
407
+ } else {
408
+ progress = 0;
409
+ }
410
+ }
411
+ progress = Math.max(0, Math.min(1, progress));
412
+ updateModalEffect(rootId, { progress, insetTop });
413
+ });
414
+ const handleYComplete = useStableCallback(() => {
415
+ if (!rootId) return;
416
+ if (y.get() + 5 >= sheetHeight) {
417
+ cleanupModalEffect(rootId);
418
+ }
419
+ });
420
+ React.useEffect(() => {
784
421
  if (!rootId) return;
785
- const root = document.querySelector(`#${rootId}`);
786
- if (!root) return;
787
422
  const removeStartListener = y.on("animationStart", () => {
788
- setupModalEffect(rootId);
423
+ if (rootId) setupModalEffect(rootId);
789
424
  });
790
425
  const removeChangeListener = y.on("change", (yValue) => {
791
- if (!root) return;
792
- let progress = Math.max(0, 1 - yValue / sheetHeight);
793
- const snapThresholdPoint = snapPoints.length > 1 ? snapPoints[snapPoints.length - 2] : void 0;
794
- if (snapThresholdPoint !== void 0) {
795
- const snapThresholdValue = snapThresholdPoint.snapValueY;
796
- if (yValue <= snapThresholdValue) {
797
- progress = (snapThresholdValue - yValue) / snapThresholdValue;
798
- } else {
799
- progress = 0;
800
- }
801
- }
802
- if (startThreshold !== void 0) {
803
- const startThresholdValue = sheetHeight - Math.min(Math.floor(startThreshold * sheetHeight), sheetHeight);
804
- if (yValue <= startThresholdValue) {
805
- progress = (startThresholdValue - yValue) / startThresholdValue;
806
- } else {
807
- progress = 0;
808
- }
809
- }
810
- progress = Math.max(0, Math.min(1, progress));
811
- const pageWidth = window.innerWidth;
812
- const ty = motion.transform(progress, [0, 1], [0, 24 + insetTop]);
813
- const s = motion.transform(progress, [0, 1], [1, (pageWidth - 16) / pageWidth]);
814
- const borderRadius = motion.transform(progress, [0, 1], [0, 10]);
815
- root.style.transform = `scale(${s}) translate3d(0, ${ty}px, 0)`;
816
- root.style.borderTopRightRadius = `${borderRadius}px`;
817
- root.style.borderTopLeftRadius = `${borderRadius}px`;
426
+ handleYChange(yValue);
818
427
  });
819
- function onCompleted() {
820
- if (y.get() - 5 >= sheetHeight) {
821
- cleanupModalEffect(rootId);
822
- }
823
- }
824
- const removeCompleteListener = y.on("animationComplete", onCompleted);
825
- const removeCancelListener = y.on("animationCancel", onCompleted);
428
+ const removeCompleteListener = y.on("animationComplete", handleYComplete);
429
+ const removeCancelListener = y.on("animationCancel", handleYComplete);
826
430
  return () => {
431
+ if (rootId) cleanupModalEffect(rootId);
827
432
  removeStartListener();
828
433
  removeChangeListener();
829
434
  removeCompleteListener();
830
435
  removeCancelListener();
831
436
  };
832
- }, [y, rootId, insetTop, startThreshold, sheetHeight]);
437
+ }, [rootId]);
833
438
  }
834
439
  function setupModalEffect(rootId) {
835
- const root = document.querySelector(`#${rootId}`);
440
+ const target = getModalEffectTarget(rootId);
441
+ if (!target) return;
442
+ if (target.type === "sheet") {
443
+ const sheet = target.element;
444
+ sheet.style.transformOrigin = "center top";
445
+ return;
446
+ }
447
+ const root = target.element;
836
448
  const body = document.querySelector("body");
837
- if (!root) return;
838
- body.style.backgroundColor = "#000";
449
+ body.style.backgroundColor = "#000000";
839
450
  root.style.overflow = "hidden";
840
451
  root.style.transitionTimingFunction = "cubic-bezier(0.32, 0.72, 0, 1)";
841
452
  root.style.transitionProperty = "transform, border-radius";
842
453
  root.style.transitionDuration = "0.5s";
843
454
  root.style.transformOrigin = "center top";
844
455
  }
456
+ function updateModalEffect(rootId, opts) {
457
+ const target = getModalEffectTarget(rootId);
458
+ if (!target) return;
459
+ const { progress, insetTop } = opts;
460
+ if (target.type === "sheet") {
461
+ const sheet = target.element;
462
+ const sheetWidth = sheet.offsetWidth;
463
+ const sheetTop = sheet.offsetTop;
464
+ const scaleEnd2 = (sheetWidth - 16) / sheetWidth;
465
+ const scale2 = motion.transform(progress, [0, 1], [1, scaleEnd2]);
466
+ const translateYEnd = clamp(scaleEnd2 * (24 + insetTop) - sheetTop, -10, 0);
467
+ const translateY2 = motion.transform(progress, [0, 1], [0, translateYEnd]);
468
+ sheet.style.scale = `${scale2}`;
469
+ sheet.style.translate = `0 ${translateY2}px`;
470
+ return;
471
+ }
472
+ const root = target.element;
473
+ const pageWidth = window.innerWidth;
474
+ const scaleEnd = (pageWidth - 16) / pageWidth;
475
+ const scale = motion.transform(progress, [0, 1], [1, scaleEnd]);
476
+ const translateY = motion.transform(progress, [0, 1], [0, 24 + insetTop]);
477
+ const borderRadius = motion.transform(progress, [0, 1], [0, 10]);
478
+ root.style.transform = `scale(${scale}) translate3d(0, ${translateY}px, 0)`;
479
+ root.style.borderTopRightRadius = `${borderRadius}px`;
480
+ root.style.borderTopLeftRadius = `${borderRadius}px`;
481
+ }
845
482
  function cleanupModalEffect(rootId) {
846
- const root = document.querySelector(`#${rootId}`);
483
+ const target = getModalEffectTarget(rootId);
484
+ if (!target) return;
485
+ if (target.type === "sheet") {
486
+ const sheet = target.element;
487
+ sheet.style.removeProperty("transform-origin");
488
+ sheet.style.removeProperty("scale");
489
+ sheet.style.removeProperty("translate");
490
+ return;
491
+ }
492
+ const root = target.element;
847
493
  const body = document.querySelector("body");
848
- if (!root) return;
849
494
  body.style.removeProperty("background-color");
850
495
  root.style.removeProperty("overflow");
851
496
  root.style.removeProperty("transition-timing-function");
@@ -856,6 +501,19 @@ function cleanupModalEffect(rootId) {
856
501
  root.style.removeProperty("border-top-right-radius");
857
502
  root.style.removeProperty("border-top-left-radius");
858
503
  }
504
+ function getModalEffectTarget(rootId) {
505
+ const root = document.getElementById(rootId);
506
+ if (!root) return null;
507
+ const sheetRoot = root.closest(".react-modal-sheet-root");
508
+ if (sheetRoot) {
509
+ const container = sheetRoot.querySelector(
510
+ ".react-modal-sheet-container"
511
+ );
512
+ if (!container) return null;
513
+ return { type: "sheet", element: container };
514
+ }
515
+ return { type: "root", element: root };
516
+ }
859
517
 
860
518
  // src/hooks/use-prevent-scroll.ts
861
519
  var KEYBOARD_BUFFER = 24;
@@ -1065,19 +723,19 @@ function useSheetState({
1065
723
  onOpen: _onOpen,
1066
724
  onClosing: _onClosing
1067
725
  }) {
1068
- const [state, setState] = React4.useState(isOpen ? "opening" : "closed");
726
+ const [state, setState] = React.useState(isOpen ? "opening" : "closed");
1069
727
  const onClosed = useStableCallback(() => _onClosed == null ? void 0 : _onClosed());
1070
728
  const onOpening = useStableCallback(() => _onOpening == null ? void 0 : _onOpening());
1071
729
  const onOpen = useStableCallback(() => _onOpen == null ? void 0 : _onOpen());
1072
730
  const onClosing = useStableCallback(() => _onClosing == null ? void 0 : _onClosing());
1073
- React4.useEffect(() => {
731
+ React.useEffect(() => {
1074
732
  if (isOpen && state === "closed") {
1075
733
  setState("opening");
1076
734
  } else if (!isOpen && (state === "open" || state === "opening")) {
1077
735
  setState("closing");
1078
736
  }
1079
737
  }, [isOpen, state]);
1080
- React4.useEffect(() => {
738
+ React.useEffect(() => {
1081
739
  async function handle() {
1082
740
  switch (state) {
1083
741
  case "closed":
@@ -1157,9 +815,6 @@ function computeSnapPoints({
1157
815
  // Y value is inverted as `y = 0` means sheet is at the top
1158
816
  }));
1159
817
  }
1160
- function clamp(value, min, max) {
1161
- return Math.min(Math.max(value, min), max);
1162
- }
1163
818
  function sign(value) {
1164
819
  if (value > 0) return 1;
1165
820
  if (value < 0) return -1;
@@ -1299,48 +954,152 @@ function classifyDragEnd({
1299
954
  };
1300
955
  }
1301
956
 
1302
- // src/sheet.tsx
1303
- var Sheet = React4.forwardRef(
1304
- ({
1305
- avoidKeyboard = true,
1306
- children,
1307
- className = "",
1308
- detent = "default",
1309
- disableDismiss = false,
1310
- disableDrag: disableDragProp = false,
1311
- disableScrollLocking = false,
1312
- dragCloseThreshold = DEFAULT_DRAG_CLOSE_THRESHOLD,
1313
- dragVelocityThreshold = DEFAULT_DRAG_VELOCITY_THRESHOLD,
1314
- initialSnap,
1315
- isOpen,
1316
- modalEffectRootId,
1317
- modalEffectThreshold,
1318
- mountPoint,
1319
- prefersReducedMotion = false,
1320
- snapPoints: snapPointsProp,
1321
- style,
1322
- tweenConfig = DEFAULT_TWEEN_CONFIG,
1323
- unstyled = false,
1324
- onOpenStart,
1325
- onOpenEnd,
1326
- onClose,
1327
- onCloseStart,
1328
- onCloseEnd,
1329
- onSnap,
1330
- onDrag: onDragProp,
1331
- onDragStart: onDragStartProp,
1332
- onDragEnd: onDragEndProp,
957
+ // src/styles.ts
958
+ var styles = {
959
+ root: {
960
+ base: {
961
+ position: "fixed",
962
+ top: 0,
963
+ bottom: 0,
964
+ left: 0,
965
+ right: 0,
966
+ overflow: "hidden",
967
+ pointerEvents: "none"
968
+ },
969
+ decorative: {}
970
+ },
971
+ backdrop: {
972
+ base: {
973
+ zIndex: 1,
974
+ position: "fixed",
975
+ top: 0,
976
+ left: 0,
977
+ width: "100%",
978
+ height: "100%",
979
+ touchAction: "none",
980
+ userSelect: "none"
981
+ },
982
+ decorative: {
983
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
984
+ border: "none",
985
+ WebkitTapHighlightColor: "transparent"
986
+ }
987
+ },
988
+ container: {
989
+ base: {
990
+ zIndex: 2,
991
+ position: "absolute",
992
+ left: 0,
993
+ bottom: 0,
994
+ width: "100%",
995
+ pointerEvents: "auto",
996
+ display: "flex",
997
+ flexDirection: "column"
998
+ },
999
+ decorative: {
1000
+ backgroundColor: "#fff",
1001
+ borderTopRightRadius: "8px",
1002
+ borderTopLeftRadius: "8px",
1003
+ boxShadow: "0px -2px 16px rgba(0, 0, 0, 0.3)"
1004
+ }
1005
+ },
1006
+ headerWrapper: {
1007
+ base: {
1008
+ width: "100%"
1009
+ },
1010
+ decorative: {}
1011
+ },
1012
+ header: {
1013
+ base: {
1014
+ width: "100%",
1015
+ position: "relative"
1016
+ },
1017
+ decorative: {
1018
+ height: "40px",
1019
+ display: "flex",
1020
+ alignItems: "center",
1021
+ justifyContent: "center"
1022
+ }
1023
+ },
1024
+ indicatorWrapper: {
1025
+ base: {
1026
+ display: "flex"
1027
+ },
1028
+ decorative: {}
1029
+ },
1030
+ indicator: {
1031
+ base: {
1032
+ display: "inline-block"
1033
+ },
1034
+ decorative: {
1035
+ width: "18px",
1036
+ height: "4px",
1037
+ borderRadius: "99px",
1038
+ backgroundColor: "#ddd"
1039
+ }
1040
+ },
1041
+ content: {
1042
+ base: {
1043
+ minHeight: "0px",
1044
+ position: "relative",
1045
+ flexGrow: 1,
1046
+ display: "flex",
1047
+ flexDirection: "column"
1048
+ },
1049
+ decorative: {}
1050
+ },
1051
+ scroller: {
1052
+ base: {
1053
+ height: "100%",
1054
+ overflowY: "auto",
1055
+ overscrollBehaviorY: "none"
1056
+ },
1057
+ decorative: {}
1058
+ }
1059
+ };
1060
+
1061
+ // src/sheet.tsx
1062
+ var Sheet = React.forwardRef(
1063
+ ({
1064
+ avoidKeyboard = true,
1065
+ children,
1066
+ className = "",
1067
+ detent = "default",
1068
+ disableDismiss = false,
1069
+ disableDrag: disableDragProp = false,
1070
+ disableScrollLocking = false,
1071
+ dragCloseThreshold = DEFAULT_DRAG_CLOSE_THRESHOLD,
1072
+ dragVelocityThreshold = DEFAULT_DRAG_VELOCITY_THRESHOLD,
1073
+ initialSnap,
1074
+ isOpen,
1075
+ modalEffectRootId,
1076
+ modalEffectThreshold,
1077
+ mountPoint,
1078
+ prefersReducedMotion = false,
1079
+ snapPoints: snapPointsProp,
1080
+ style,
1081
+ tweenConfig = DEFAULT_TWEEN_CONFIG,
1082
+ unstyled = false,
1083
+ onOpenStart,
1084
+ onOpenEnd,
1085
+ onClose,
1086
+ onCloseStart,
1087
+ onCloseEnd,
1088
+ onSnap,
1089
+ onDrag: onDragProp,
1090
+ onDragStart: onDragStartProp,
1091
+ onDragEnd: onDragEndProp,
1333
1092
  ...rest
1334
1093
  }, ref) => {
1335
- const [sheetBoundsRef, sheetBounds] = useMeasure__default.default();
1336
- const sheetRef = React4.useRef(null);
1094
+ const [sheetBoundsRef, sheetBounds] = useMeasure__default.default({ offsetSize: true });
1095
+ const sheetRef = React.useRef(null);
1337
1096
  const sheetHeight = Math.round(sheetBounds.height);
1338
- const [currentSnap, setCurrentSnap] = React4.useState(initialSnap);
1339
- const snapPoints = snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
1097
+ const [currentSnap, setCurrentSnap] = React.useState(initialSnap);
1340
1098
  const { windowHeight } = useDimensions();
1341
1099
  const closedY = sheetHeight > 0 ? sheetHeight : windowHeight;
1342
1100
  const y = react.useMotionValue(closedY);
1343
1101
  const yInverted = react.useTransform(y, (val) => Math.max(sheetHeight - val, 0));
1102
+ const yProgress = react.useTransform(y, (val) => clamp(1 - val / closedY, 0, 1));
1344
1103
  const indicatorRotation = react.useMotionValue(0);
1345
1104
  const shouldReduceMotion = react.useReducedMotion();
1346
1105
  const reduceMotion = Boolean(prefersReducedMotion || shouldReduceMotion);
@@ -1356,6 +1115,9 @@ var Sheet = React4.forwardRef(
1356
1115
  y,
1357
1116
  (val) => val + 2 >= closedY ? "hidden" : "visible"
1358
1117
  );
1118
+ const snapPoints = React.useMemo(() => {
1119
+ return snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
1120
+ }, [sheetHeight, snapPointsProp == null ? void 0 : snapPointsProp.join("")]);
1359
1121
  const updateSnap = useStableCallback((snapIndex) => {
1360
1122
  setCurrentSnap(snapIndex);
1361
1123
  onSnap == null ? void 0 : onSnap(snapIndex);
@@ -1468,12 +1230,6 @@ var Sheet = React4.forwardRef(
1468
1230
  }
1469
1231
  indicatorRotation.set(0);
1470
1232
  });
1471
- React4.useImperativeHandle(ref, () => ({
1472
- y,
1473
- yInverted,
1474
- height: sheetHeight,
1475
- snapTo
1476
- }));
1477
1233
  useModalEffect({
1478
1234
  y,
1479
1235
  detent,
@@ -1493,9 +1249,7 @@ var Sheet = React4.forwardRef(
1493
1249
  const initialSnapPoint = initialSnap !== void 0 ? getSnapPoint(initialSnap) : null;
1494
1250
  const yTo = (initialSnapPoint == null ? void 0 : initialSnapPoint.snapValueY) ?? 0;
1495
1251
  await react.animate(y, yTo, animationOptions);
1496
- if (initialSnap !== void 0) {
1497
- updateSnap(initialSnap);
1498
- }
1252
+ if (initialSnap !== void 0) updateSnap(initialSnap);
1499
1253
  onOpenEnd == null ? void 0 : onOpenEnd();
1500
1254
  },
1501
1255
  onClosing: async () => {
@@ -1513,7 +1267,7 @@ var Sheet = React4.forwardRef(
1513
1267
  onDragStart,
1514
1268
  onDragEnd
1515
1269
  };
1516
- const context = {
1270
+ const internalContext = {
1517
1271
  currentSnap,
1518
1272
  detent,
1519
1273
  disableDrag,
@@ -1524,9 +1278,20 @@ var Sheet = React4.forwardRef(
1524
1278
  sheetBoundsRef,
1525
1279
  sheetRef,
1526
1280
  unstyled,
1281
+ yProgress,
1527
1282
  y
1528
1283
  };
1529
- const sheet = /* @__PURE__ */ React4__default.default.createElement(SheetContext.Provider, { value: context }, /* @__PURE__ */ React4__default.default.createElement(
1284
+ const exposedContext = {
1285
+ height: sheetHeight,
1286
+ currentSnap,
1287
+ snapPoints,
1288
+ snapTo,
1289
+ y,
1290
+ yInverted,
1291
+ yProgress
1292
+ };
1293
+ React.useImperativeHandle(ref, () => exposedContext);
1294
+ const sheet = /* @__PURE__ */ React__default.default.createElement(InternalSheetContext.Provider, { value: internalContext }, /* @__PURE__ */ React__default.default.createElement(
1530
1295
  react.motion.div,
1531
1296
  {
1532
1297
  ...rest,
@@ -1540,13 +1305,293 @@ var Sheet = React4.forwardRef(
1540
1305
  ...style
1541
1306
  }
1542
1307
  },
1543
- state !== "closed" ? children : null
1308
+ /* @__PURE__ */ React__default.default.createElement(ExposedSheetContext.Provider, { value: exposedContext }, state !== "closed" ? children : null)
1544
1309
  ));
1545
1310
  if (IS_SSR) return sheet;
1546
1311
  return reactDom.createPortal(sheet, mountPoint ?? document.body);
1547
1312
  }
1548
1313
  );
1549
1314
  Sheet.displayName = "Sheet";
1315
+ var isClickable = (props) => !!props.onClick || !!props.onTap;
1316
+ var SheetBackdrop = React.forwardRef(
1317
+ ({ style, className = "", unstyled, ...rest }, ref) => {
1318
+ const sheetContext = useInternalContext();
1319
+ const clickable = isClickable(rest);
1320
+ const Comp = clickable ? react.motion.button : react.motion.div;
1321
+ const pointerEvents = clickable ? "auto" : "none";
1322
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1323
+ const backdropStyle = {
1324
+ opacity: sheetContext.yProgress,
1325
+ ...applyStyles(styles.backdrop, isUnstyled),
1326
+ ...style,
1327
+ pointerEvents
1328
+ };
1329
+ return /* @__PURE__ */ React__default.default.createElement(
1330
+ Comp,
1331
+ {
1332
+ ...rest,
1333
+ ref,
1334
+ className: `react-modal-sheet-backdrop ${className}`,
1335
+ style: backdropStyle
1336
+ }
1337
+ );
1338
+ }
1339
+ );
1340
+ SheetBackdrop.displayName = "SheetBackdrop";
1341
+ var SheetContainer = React.forwardRef(
1342
+ ({ children, style, className = "", unstyled, ...rest }, ref) => {
1343
+ const sheetContext = useInternalContext();
1344
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1345
+ const containerStyle = {
1346
+ ...applyStyles(styles.container, isUnstyled),
1347
+ ...style,
1348
+ y: sheetContext.y
1349
+ };
1350
+ if (sheetContext.detent === "default") {
1351
+ containerStyle.height = DEFAULT_HEIGHT;
1352
+ }
1353
+ if (sheetContext.detent === "full") {
1354
+ containerStyle.height = "100%";
1355
+ containerStyle.maxHeight = "100%";
1356
+ }
1357
+ if (sheetContext.detent === "content") {
1358
+ containerStyle.height = "auto";
1359
+ containerStyle.maxHeight = DEFAULT_HEIGHT;
1360
+ }
1361
+ return /* @__PURE__ */ React__default.default.createElement(
1362
+ react.motion.div,
1363
+ {
1364
+ ...rest,
1365
+ ref: mergeRefs([
1366
+ ref,
1367
+ sheetContext.sheetRef,
1368
+ sheetContext.sheetBoundsRef
1369
+ ]),
1370
+ className: `react-modal-sheet-container ${className}`,
1371
+ style: containerStyle
1372
+ },
1373
+ children
1374
+ );
1375
+ }
1376
+ );
1377
+ SheetContainer.displayName = "SheetContainer";
1378
+ var constraints = { bottom: 0, top: 0, left: 0, right: 0 };
1379
+ function useDragConstraints() {
1380
+ const ref = React.useRef(null);
1381
+ const onMeasure = React.useCallback(() => constraints, []);
1382
+ return { ref, onMeasure };
1383
+ }
1384
+ function useScrollPosition(options = {}) {
1385
+ const { debounceDelay = 32, isEnabled = true } = options;
1386
+ const scrollTimeoutRef = React.useRef(null);
1387
+ const [element, setElement] = React.useState(null);
1388
+ const [scrollPosition, setScrollPosition] = React.useState(void 0);
1389
+ const scrollRef = React.useMemo(
1390
+ () => (element2) => {
1391
+ setElement(element2);
1392
+ },
1393
+ []
1394
+ );
1395
+ const determineScrollPosition = useStableCallback((element2) => {
1396
+ const { scrollTop, scrollHeight, clientHeight } = element2;
1397
+ const isScrollable2 = scrollHeight > clientHeight;
1398
+ if (!isScrollable2) {
1399
+ if (scrollPosition) setScrollPosition(void 0);
1400
+ return;
1401
+ }
1402
+ const isAtTop = scrollTop <= 0;
1403
+ const isAtBottom = Math.ceil(scrollHeight) - Math.ceil(scrollTop) === Math.ceil(clientHeight);
1404
+ let position;
1405
+ if (isAtTop) {
1406
+ position = "top";
1407
+ } else if (isAtBottom) {
1408
+ position = "bottom";
1409
+ } else {
1410
+ position = "middle";
1411
+ }
1412
+ element2.style.touchAction = isAtTop ? "pan-down" : "";
1413
+ if (position === scrollPosition) return;
1414
+ setScrollPosition(position);
1415
+ });
1416
+ const onScroll = useStableCallback((event) => {
1417
+ if (event.currentTarget instanceof HTMLElement) {
1418
+ const el = event.currentTarget;
1419
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
1420
+ if (debounceDelay === 0) {
1421
+ determineScrollPosition(el);
1422
+ } else {
1423
+ scrollTimeoutRef.current = setTimeout(
1424
+ () => determineScrollPosition(el),
1425
+ debounceDelay
1426
+ );
1427
+ }
1428
+ }
1429
+ });
1430
+ const onTouchStart = useStableCallback((event) => {
1431
+ if (event.currentTarget instanceof HTMLElement) {
1432
+ const element2 = event.currentTarget;
1433
+ requestAnimationFrame(() => {
1434
+ determineScrollPosition(element2);
1435
+ });
1436
+ }
1437
+ });
1438
+ React.useEffect(() => {
1439
+ if (!element || !isEnabled) return;
1440
+ determineScrollPosition(element);
1441
+ element.addEventListener("scroll", onScroll);
1442
+ element.addEventListener("touchstart", onTouchStart);
1443
+ return () => {
1444
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
1445
+ element.removeEventListener("scroll", onScroll);
1446
+ element.removeEventListener("touchstart", onTouchStart);
1447
+ };
1448
+ }, [element, isEnabled]);
1449
+ return {
1450
+ scrollRef,
1451
+ scrollPosition
1452
+ };
1453
+ }
1454
+
1455
+ // src/sheet-content.tsx
1456
+ var SheetContent = React.forwardRef(
1457
+ ({
1458
+ disableScroll: disableScrollProp,
1459
+ disableDrag: disableDragProp,
1460
+ children,
1461
+ style: styleProp,
1462
+ className = "",
1463
+ scrollClassName = "",
1464
+ scrollStyle: scrollStyleProp,
1465
+ scrollRef: scrollRefProp = null,
1466
+ unstyled,
1467
+ ...rest
1468
+ }, ref) => {
1469
+ const sheetContext = useInternalContext();
1470
+ const dragConstraints = useDragConstraints();
1471
+ const scroll = useScrollPosition({
1472
+ isEnabled: typeof disableScrollProp === "function" ? true : !disableScrollProp
1473
+ });
1474
+ const disableScroll = typeof disableScrollProp === "function" ? disableScrollProp({
1475
+ scrollPosition: scroll.scrollPosition,
1476
+ currentSnap: sheetContext.currentSnap
1477
+ }) : Boolean(disableScrollProp);
1478
+ const disableDragDueToScroll = !disableScroll && scroll.scrollPosition && scroll.scrollPosition !== "top";
1479
+ const disableDragDueToProp = typeof disableDragProp === "function" ? disableDragProp({
1480
+ scrollPosition: scroll.scrollPosition,
1481
+ currentSnap: sheetContext.currentSnap
1482
+ }) : Boolean(disableDragProp);
1483
+ const disableDrag = disableDragDueToProp || disableDragDueToScroll || sheetContext.disableDrag;
1484
+ const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
1485
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1486
+ const contentStyle = {
1487
+ ...applyStyles(styles.content, isUnstyled),
1488
+ ...styleProp
1489
+ };
1490
+ const scrollStyle = applyStyles(styles.scroller, isUnstyled);
1491
+ if (sheetContext.avoidKeyboard) {
1492
+ scrollStyle.paddingBottom = isHTTPS() ? "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))" : "var(--keyboard-inset-height, 0px)";
1493
+ }
1494
+ if (disableScroll) {
1495
+ scrollStyle.overflowY = "clip";
1496
+ }
1497
+ if (dragProps !== void 0) {
1498
+ scrollStyle.touchAction = "pan-down";
1499
+ }
1500
+ return /* @__PURE__ */ React__default.default.createElement(
1501
+ react.motion.div,
1502
+ {
1503
+ ...rest,
1504
+ ref: mergeRefs([ref, dragConstraints.ref]),
1505
+ className: `react-modal-sheet-content ${className}`,
1506
+ style: contentStyle,
1507
+ ...dragProps,
1508
+ dragConstraints: dragConstraints.ref,
1509
+ onMeasureDragConstraints: dragConstraints.onMeasure
1510
+ },
1511
+ /* @__PURE__ */ React__default.default.createElement(
1512
+ react.motion.div,
1513
+ {
1514
+ ref: mergeRefs([scroll.scrollRef, scrollRefProp]),
1515
+ style: { ...scrollStyle, ...scrollStyleProp },
1516
+ className: `react-modal-sheet-content-scroller ${scrollClassName}`
1517
+ },
1518
+ children
1519
+ )
1520
+ );
1521
+ }
1522
+ );
1523
+ SheetContent.displayName = "SheetContent";
1524
+ function SheetDragIndicator({
1525
+ style,
1526
+ className = "",
1527
+ unstyled,
1528
+ ...rest
1529
+ }) {
1530
+ const sheetContext = useInternalContext();
1531
+ const indicator1Transform = react.useTransform(
1532
+ sheetContext.indicatorRotation,
1533
+ (r) => `translateX(2px) rotate(${r}deg)`
1534
+ );
1535
+ const indicator2Transform = react.useTransform(
1536
+ sheetContext.indicatorRotation,
1537
+ (r) => `translateX(-2px) rotate(${ -1 * r}deg)`
1538
+ );
1539
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1540
+ const indicatorWrapperStyle = {
1541
+ ...applyStyles(styles.indicatorWrapper, isUnstyled),
1542
+ ...style
1543
+ };
1544
+ const indicatorStyle = applyStyles(styles.indicator, isUnstyled);
1545
+ return /* @__PURE__ */ React__default.default.createElement(
1546
+ "div",
1547
+ {
1548
+ className: `react-modal-sheet-drag-indicator-container ${className}`,
1549
+ style: indicatorWrapperStyle,
1550
+ ...rest
1551
+ },
1552
+ /* @__PURE__ */ React__default.default.createElement(
1553
+ react.motion.span,
1554
+ {
1555
+ className: "react-modal-sheet-drag-indicator",
1556
+ style: { ...indicatorStyle, transform: indicator1Transform }
1557
+ }
1558
+ ),
1559
+ /* @__PURE__ */ React__default.default.createElement(
1560
+ react.motion.span,
1561
+ {
1562
+ className: "react-modal-sheet-drag-indicator",
1563
+ style: { ...indicatorStyle, transform: indicator2Transform }
1564
+ }
1565
+ )
1566
+ );
1567
+ }
1568
+ var SheetHeader = React.forwardRef(
1569
+ ({ children, style, disableDrag, unstyled, className = "", ...rest }, ref) => {
1570
+ const sheetContext = useInternalContext();
1571
+ const dragConstraints = useDragConstraints();
1572
+ const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
1573
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1574
+ const headerWrapperStyle = {
1575
+ ...applyStyles(styles.headerWrapper, isUnstyled),
1576
+ ...style
1577
+ };
1578
+ const headerStyle = applyStyles(styles.header, isUnstyled);
1579
+ return /* @__PURE__ */ React__default.default.createElement(
1580
+ react.motion.div,
1581
+ {
1582
+ ...rest,
1583
+ ref: mergeRefs([ref, dragConstraints.ref]),
1584
+ style: headerWrapperStyle,
1585
+ className: `react-modal-sheet-header-container ${className}`,
1586
+ ...dragProps,
1587
+ dragConstraints: dragConstraints.ref,
1588
+ onMeasureDragConstraints: dragConstraints.onMeasure
1589
+ },
1590
+ children || /* @__PURE__ */ React__default.default.createElement("div", { className: "react-modal-sheet-header", style: headerStyle }, /* @__PURE__ */ React__default.default.createElement(SheetDragIndicator, null))
1591
+ );
1592
+ }
1593
+ );
1594
+ SheetHeader.displayName = "SheetHeader";
1550
1595
 
1551
1596
  // src/index.tsx
1552
1597
  var Sheet2 = Object.assign(Sheet, {
@@ -1554,7 +1599,8 @@ var Sheet2 = Object.assign(Sheet, {
1554
1599
  Header: SheetHeader,
1555
1600
  DragIndicator: SheetDragIndicator,
1556
1601
  Content: SheetContent,
1557
- Backdrop: SheetBackdrop
1602
+ Backdrop: SheetBackdrop,
1603
+ useContext: useExposedContext
1558
1604
  });
1559
1605
 
1560
1606
  exports.Sheet = Sheet2;