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