react-modal-sheet 5.5.0 → 5.6.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,82 @@ 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) => {
784
392
  if (!rootId) return;
785
- const root = document.querySelector(`#${rootId}`);
786
- if (!root) return;
787
- const removeStartListener = y.on("animationStart", () => {
788
- setupModalEffect(rootId);
789
- });
790
- 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
- }
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;
801
401
  }
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
- }
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;
809
409
  }
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`;
410
+ }
411
+ progress = Math.max(0, Math.min(1, progress));
412
+ const pageWidth = window.innerWidth;
413
+ updateModalEffect(rootId, {
414
+ scale: motion.transform(progress, [0, 1], [1, (pageWidth - 16) / pageWidth]),
415
+ translateY: motion.transform(progress, [0, 1], [0, 24 + insetTop]),
416
+ borderRadius: motion.transform(progress, [0, 1], [0, 10])
818
417
  });
819
- function onCompleted() {
820
- if (y.get() - 5 >= sheetHeight) {
821
- cleanupModalEffect(rootId);
822
- }
418
+ });
419
+ const handleYComplete = useStableCallback(() => {
420
+ if (!rootId) return;
421
+ if (y.get() + 5 >= sheetHeight) {
422
+ cleanupModalEffect(rootId);
823
423
  }
824
- const removeCompleteListener = y.on("animationComplete", onCompleted);
825
- const removeCancelListener = y.on("animationCancel", onCompleted);
424
+ });
425
+ React.useEffect(() => {
426
+ if (!rootId) return;
427
+ const removeStartListener = y.on("animationStart", () => {
428
+ if (rootId) setupModalEffect(rootId);
429
+ });
430
+ const removeChangeListener = y.on("change", (yValue) => {
431
+ handleYChange(yValue);
432
+ });
433
+ const removeCompleteListener = y.on("animationComplete", handleYComplete);
434
+ const removeCancelListener = y.on("animationCancel", handleYComplete);
826
435
  return () => {
436
+ if (rootId) cleanupModalEffect(rootId);
827
437
  removeStartListener();
828
438
  removeChangeListener();
829
439
  removeCompleteListener();
830
440
  removeCancelListener();
831
441
  };
832
- }, [y, rootId, insetTop, startThreshold, sheetHeight]);
442
+ }, [rootId]);
833
443
  }
834
444
  function setupModalEffect(rootId) {
835
445
  const root = document.querySelector(`#${rootId}`);
836
- const body = document.querySelector("body");
837
446
  if (!root) return;
838
- body.style.backgroundColor = "#000";
447
+ const body = document.querySelector("body");
448
+ body.style.backgroundColor = "#000000";
839
449
  root.style.overflow = "hidden";
840
450
  root.style.transitionTimingFunction = "cubic-bezier(0.32, 0.72, 0, 1)";
841
451
  root.style.transitionProperty = "transform, border-radius";
842
452
  root.style.transitionDuration = "0.5s";
843
453
  root.style.transformOrigin = "center top";
844
454
  }
455
+ function updateModalEffect(rootId, opts) {
456
+ const root = document.querySelector(`#${rootId}`);
457
+ if (!root) return;
458
+ const { scale, translateY, borderRadius } = opts;
459
+ root.style.transform = `scale(${scale}) translate3d(0, ${translateY}px, 0)`;
460
+ root.style.borderTopRightRadius = `${borderRadius}px`;
461
+ root.style.borderTopLeftRadius = `${borderRadius}px`;
462
+ }
845
463
  function cleanupModalEffect(rootId) {
846
464
  const root = document.querySelector(`#${rootId}`);
847
- const body = document.querySelector("body");
848
465
  if (!root) return;
466
+ const body = document.querySelector("body");
849
467
  body.style.removeProperty("background-color");
850
468
  root.style.removeProperty("overflow");
851
469
  root.style.removeProperty("transition-timing-function");
@@ -1065,19 +683,19 @@ function useSheetState({
1065
683
  onOpen: _onOpen,
1066
684
  onClosing: _onClosing
1067
685
  }) {
1068
- const [state, setState] = React4.useState(isOpen ? "opening" : "closed");
686
+ const [state, setState] = React.useState(isOpen ? "opening" : "closed");
1069
687
  const onClosed = useStableCallback(() => _onClosed == null ? void 0 : _onClosed());
1070
688
  const onOpening = useStableCallback(() => _onOpening == null ? void 0 : _onOpening());
1071
689
  const onOpen = useStableCallback(() => _onOpen == null ? void 0 : _onOpen());
1072
690
  const onClosing = useStableCallback(() => _onClosing == null ? void 0 : _onClosing());
1073
- React4.useEffect(() => {
691
+ React.useEffect(() => {
1074
692
  if (isOpen && state === "closed") {
1075
693
  setState("opening");
1076
694
  } else if (!isOpen && (state === "open" || state === "opening")) {
1077
695
  setState("closing");
1078
696
  }
1079
697
  }, [isOpen, state]);
1080
- React4.useEffect(() => {
698
+ React.useEffect(() => {
1081
699
  async function handle() {
1082
700
  switch (state) {
1083
701
  case "closed":
@@ -1157,9 +775,6 @@ function computeSnapPoints({
1157
775
  // Y value is inverted as `y = 0` means sheet is at the top
1158
776
  }));
1159
777
  }
1160
- function clamp(value, min, max) {
1161
- return Math.min(Math.max(value, min), max);
1162
- }
1163
778
  function sign(value) {
1164
779
  if (value > 0) return 1;
1165
780
  if (value < 0) return -1;
@@ -1299,48 +914,152 @@ function classifyDragEnd({
1299
914
  };
1300
915
  }
1301
916
 
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,
917
+ // src/styles.ts
918
+ var styles = {
919
+ root: {
920
+ base: {
921
+ position: "fixed",
922
+ top: 0,
923
+ bottom: 0,
924
+ left: 0,
925
+ right: 0,
926
+ overflow: "hidden",
927
+ pointerEvents: "none"
928
+ },
929
+ decorative: {}
930
+ },
931
+ backdrop: {
932
+ base: {
933
+ zIndex: 1,
934
+ position: "fixed",
935
+ top: 0,
936
+ left: 0,
937
+ width: "100%",
938
+ height: "100%",
939
+ touchAction: "none",
940
+ userSelect: "none"
941
+ },
942
+ decorative: {
943
+ backgroundColor: "rgba(0, 0, 0, 0.2)",
944
+ border: "none",
945
+ WebkitTapHighlightColor: "transparent"
946
+ }
947
+ },
948
+ container: {
949
+ base: {
950
+ zIndex: 2,
951
+ position: "absolute",
952
+ left: 0,
953
+ bottom: 0,
954
+ width: "100%",
955
+ pointerEvents: "auto",
956
+ display: "flex",
957
+ flexDirection: "column"
958
+ },
959
+ decorative: {
960
+ backgroundColor: "#fff",
961
+ borderTopRightRadius: "8px",
962
+ borderTopLeftRadius: "8px",
963
+ boxShadow: "0px -2px 16px rgba(0, 0, 0, 0.3)"
964
+ }
965
+ },
966
+ headerWrapper: {
967
+ base: {
968
+ width: "100%"
969
+ },
970
+ decorative: {}
971
+ },
972
+ header: {
973
+ base: {
974
+ width: "100%",
975
+ position: "relative"
976
+ },
977
+ decorative: {
978
+ height: "40px",
979
+ display: "flex",
980
+ alignItems: "center",
981
+ justifyContent: "center"
982
+ }
983
+ },
984
+ indicatorWrapper: {
985
+ base: {
986
+ display: "flex"
987
+ },
988
+ decorative: {}
989
+ },
990
+ indicator: {
991
+ base: {
992
+ display: "inline-block"
993
+ },
994
+ decorative: {
995
+ width: "18px",
996
+ height: "4px",
997
+ borderRadius: "99px",
998
+ backgroundColor: "#ddd"
999
+ }
1000
+ },
1001
+ content: {
1002
+ base: {
1003
+ minHeight: "0px",
1004
+ position: "relative",
1005
+ flexGrow: 1,
1006
+ display: "flex",
1007
+ flexDirection: "column"
1008
+ },
1009
+ decorative: {}
1010
+ },
1011
+ scroller: {
1012
+ base: {
1013
+ height: "100%",
1014
+ overflowY: "auto",
1015
+ overscrollBehaviorY: "none"
1016
+ },
1017
+ decorative: {}
1018
+ }
1019
+ };
1020
+
1021
+ // src/sheet.tsx
1022
+ var Sheet = React.forwardRef(
1023
+ ({
1024
+ avoidKeyboard = true,
1025
+ children,
1026
+ className = "",
1027
+ detent = "default",
1028
+ disableDismiss = false,
1029
+ disableDrag: disableDragProp = false,
1030
+ disableScrollLocking = false,
1031
+ dragCloseThreshold = DEFAULT_DRAG_CLOSE_THRESHOLD,
1032
+ dragVelocityThreshold = DEFAULT_DRAG_VELOCITY_THRESHOLD,
1033
+ initialSnap,
1034
+ isOpen,
1035
+ modalEffectRootId,
1036
+ modalEffectThreshold,
1037
+ mountPoint,
1038
+ prefersReducedMotion = false,
1039
+ snapPoints: snapPointsProp,
1040
+ style,
1041
+ tweenConfig = DEFAULT_TWEEN_CONFIG,
1042
+ unstyled = false,
1043
+ onOpenStart,
1044
+ onOpenEnd,
1045
+ onClose,
1046
+ onCloseStart,
1047
+ onCloseEnd,
1048
+ onSnap,
1049
+ onDrag: onDragProp,
1050
+ onDragStart: onDragStartProp,
1332
1051
  onDragEnd: onDragEndProp,
1333
1052
  ...rest
1334
1053
  }, ref) => {
1335
1054
  const [sheetBoundsRef, sheetBounds] = useMeasure__default.default();
1336
- const sheetRef = React4.useRef(null);
1055
+ const sheetRef = React.useRef(null);
1337
1056
  const sheetHeight = Math.round(sheetBounds.height);
1338
- const [currentSnap, setCurrentSnap] = React4.useState(initialSnap);
1339
- const snapPoints = snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
1057
+ const [currentSnap, setCurrentSnap] = React.useState(initialSnap);
1340
1058
  const { windowHeight } = useDimensions();
1341
1059
  const closedY = sheetHeight > 0 ? sheetHeight : windowHeight;
1342
1060
  const y = react.useMotionValue(closedY);
1343
1061
  const yInverted = react.useTransform(y, (val) => Math.max(sheetHeight - val, 0));
1062
+ const yProgress = react.useTransform(y, (val) => clamp(1 - val / closedY, 0, 1));
1344
1063
  const indicatorRotation = react.useMotionValue(0);
1345
1064
  const shouldReduceMotion = react.useReducedMotion();
1346
1065
  const reduceMotion = Boolean(prefersReducedMotion || shouldReduceMotion);
@@ -1356,6 +1075,9 @@ var Sheet = React4.forwardRef(
1356
1075
  y,
1357
1076
  (val) => val + 2 >= closedY ? "hidden" : "visible"
1358
1077
  );
1078
+ const snapPoints = React.useMemo(() => {
1079
+ return snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
1080
+ }, [sheetHeight, snapPointsProp == null ? void 0 : snapPointsProp.join("")]);
1359
1081
  const updateSnap = useStableCallback((snapIndex) => {
1360
1082
  setCurrentSnap(snapIndex);
1361
1083
  onSnap == null ? void 0 : onSnap(snapIndex);
@@ -1468,12 +1190,6 @@ var Sheet = React4.forwardRef(
1468
1190
  }
1469
1191
  indicatorRotation.set(0);
1470
1192
  });
1471
- React4.useImperativeHandle(ref, () => ({
1472
- y,
1473
- yInverted,
1474
- height: sheetHeight,
1475
- snapTo
1476
- }));
1477
1193
  useModalEffect({
1478
1194
  y,
1479
1195
  detent,
@@ -1493,9 +1209,7 @@ var Sheet = React4.forwardRef(
1493
1209
  const initialSnapPoint = initialSnap !== void 0 ? getSnapPoint(initialSnap) : null;
1494
1210
  const yTo = (initialSnapPoint == null ? void 0 : initialSnapPoint.snapValueY) ?? 0;
1495
1211
  await react.animate(y, yTo, animationOptions);
1496
- if (initialSnap !== void 0) {
1497
- updateSnap(initialSnap);
1498
- }
1212
+ if (initialSnap !== void 0) updateSnap(initialSnap);
1499
1213
  onOpenEnd == null ? void 0 : onOpenEnd();
1500
1214
  },
1501
1215
  onClosing: async () => {
@@ -1513,7 +1227,7 @@ var Sheet = React4.forwardRef(
1513
1227
  onDragStart,
1514
1228
  onDragEnd
1515
1229
  };
1516
- const context = {
1230
+ const internalContext = {
1517
1231
  currentSnap,
1518
1232
  detent,
1519
1233
  disableDrag,
@@ -1524,9 +1238,20 @@ var Sheet = React4.forwardRef(
1524
1238
  sheetBoundsRef,
1525
1239
  sheetRef,
1526
1240
  unstyled,
1241
+ yProgress,
1527
1242
  y
1528
1243
  };
1529
- const sheet = /* @__PURE__ */ React4__default.default.createElement(SheetContext.Provider, { value: context }, /* @__PURE__ */ React4__default.default.createElement(
1244
+ const exposedContext = {
1245
+ height: sheetHeight,
1246
+ currentSnap,
1247
+ snapPoints,
1248
+ snapTo,
1249
+ y,
1250
+ yInverted,
1251
+ yProgress
1252
+ };
1253
+ React.useImperativeHandle(ref, () => exposedContext);
1254
+ const sheet = /* @__PURE__ */ React__default.default.createElement(InternalSheetContext.Provider, { value: internalContext }, /* @__PURE__ */ React__default.default.createElement(
1530
1255
  react.motion.div,
1531
1256
  {
1532
1257
  ...rest,
@@ -1540,13 +1265,293 @@ var Sheet = React4.forwardRef(
1540
1265
  ...style
1541
1266
  }
1542
1267
  },
1543
- state !== "closed" ? children : null
1268
+ /* @__PURE__ */ React__default.default.createElement(ExposedSheetContext.Provider, { value: exposedContext }, state !== "closed" ? children : null)
1544
1269
  ));
1545
1270
  if (IS_SSR) return sheet;
1546
1271
  return reactDom.createPortal(sheet, mountPoint ?? document.body);
1547
1272
  }
1548
1273
  );
1549
1274
  Sheet.displayName = "Sheet";
1275
+ var isClickable = (props) => !!props.onClick || !!props.onTap;
1276
+ var SheetBackdrop = React.forwardRef(
1277
+ ({ style, className = "", unstyled, ...rest }, ref) => {
1278
+ const sheetContext = useInternalContext();
1279
+ const clickable = isClickable(rest);
1280
+ const Comp = clickable ? react.motion.button : react.motion.div;
1281
+ const pointerEvents = clickable ? "auto" : "none";
1282
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1283
+ const backdropStyle = {
1284
+ opacity: sheetContext.yProgress,
1285
+ ...applyStyles(styles.backdrop, isUnstyled),
1286
+ ...style,
1287
+ pointerEvents
1288
+ };
1289
+ return /* @__PURE__ */ React__default.default.createElement(
1290
+ Comp,
1291
+ {
1292
+ ...rest,
1293
+ ref,
1294
+ className: `react-modal-sheet-backdrop ${className}`,
1295
+ style: backdropStyle
1296
+ }
1297
+ );
1298
+ }
1299
+ );
1300
+ SheetBackdrop.displayName = "SheetBackdrop";
1301
+ var SheetContainer = React.forwardRef(
1302
+ ({ children, style, className = "", unstyled, ...rest }, ref) => {
1303
+ const sheetContext = useInternalContext();
1304
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1305
+ const containerStyle = {
1306
+ ...applyStyles(styles.container, isUnstyled),
1307
+ ...style,
1308
+ y: sheetContext.y
1309
+ };
1310
+ if (sheetContext.detent === "default") {
1311
+ containerStyle.height = DEFAULT_HEIGHT;
1312
+ }
1313
+ if (sheetContext.detent === "full") {
1314
+ containerStyle.height = "100%";
1315
+ containerStyle.maxHeight = "100%";
1316
+ }
1317
+ if (sheetContext.detent === "content") {
1318
+ containerStyle.height = "auto";
1319
+ containerStyle.maxHeight = DEFAULT_HEIGHT;
1320
+ }
1321
+ return /* @__PURE__ */ React__default.default.createElement(
1322
+ react.motion.div,
1323
+ {
1324
+ ...rest,
1325
+ ref: mergeRefs([
1326
+ ref,
1327
+ sheetContext.sheetRef,
1328
+ sheetContext.sheetBoundsRef
1329
+ ]),
1330
+ className: `react-modal-sheet-container ${className}`,
1331
+ style: containerStyle
1332
+ },
1333
+ children
1334
+ );
1335
+ }
1336
+ );
1337
+ SheetContainer.displayName = "SheetContainer";
1338
+ var constraints = { bottom: 0, top: 0, left: 0, right: 0 };
1339
+ function useDragConstraints() {
1340
+ const ref = React.useRef(null);
1341
+ const onMeasure = React.useCallback(() => constraints, []);
1342
+ return { ref, onMeasure };
1343
+ }
1344
+ function useScrollPosition(options = {}) {
1345
+ const { debounceDelay = 32, isEnabled = true } = options;
1346
+ const scrollTimeoutRef = React.useRef(null);
1347
+ const [element, setElement] = React.useState(null);
1348
+ const [scrollPosition, setScrollPosition] = React.useState(void 0);
1349
+ const scrollRef = React.useMemo(
1350
+ () => (element2) => {
1351
+ setElement(element2);
1352
+ },
1353
+ []
1354
+ );
1355
+ const determineScrollPosition = useStableCallback((element2) => {
1356
+ const { scrollTop, scrollHeight, clientHeight } = element2;
1357
+ const isScrollable2 = scrollHeight > clientHeight;
1358
+ if (!isScrollable2) {
1359
+ if (scrollPosition) setScrollPosition(void 0);
1360
+ return;
1361
+ }
1362
+ const isAtTop = scrollTop <= 0;
1363
+ const isAtBottom = Math.ceil(scrollHeight) - Math.ceil(scrollTop) === Math.ceil(clientHeight);
1364
+ let position;
1365
+ if (isAtTop) {
1366
+ position = "top";
1367
+ } else if (isAtBottom) {
1368
+ position = "bottom";
1369
+ } else {
1370
+ position = "middle";
1371
+ }
1372
+ element2.style.touchAction = isAtTop ? "pan-down" : "";
1373
+ if (position === scrollPosition) return;
1374
+ setScrollPosition(position);
1375
+ });
1376
+ const onScroll = useStableCallback((event) => {
1377
+ if (event.currentTarget instanceof HTMLElement) {
1378
+ const el = event.currentTarget;
1379
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
1380
+ if (debounceDelay === 0) {
1381
+ determineScrollPosition(el);
1382
+ } else {
1383
+ scrollTimeoutRef.current = setTimeout(
1384
+ () => determineScrollPosition(el),
1385
+ debounceDelay
1386
+ );
1387
+ }
1388
+ }
1389
+ });
1390
+ const onTouchStart = useStableCallback((event) => {
1391
+ if (event.currentTarget instanceof HTMLElement) {
1392
+ const element2 = event.currentTarget;
1393
+ requestAnimationFrame(() => {
1394
+ determineScrollPosition(element2);
1395
+ });
1396
+ }
1397
+ });
1398
+ React.useEffect(() => {
1399
+ if (!element || !isEnabled) return;
1400
+ determineScrollPosition(element);
1401
+ element.addEventListener("scroll", onScroll);
1402
+ element.addEventListener("touchstart", onTouchStart);
1403
+ return () => {
1404
+ if (scrollTimeoutRef.current) clearTimeout(scrollTimeoutRef.current);
1405
+ element.removeEventListener("scroll", onScroll);
1406
+ element.removeEventListener("touchstart", onTouchStart);
1407
+ };
1408
+ }, [element, isEnabled]);
1409
+ return {
1410
+ scrollRef,
1411
+ scrollPosition
1412
+ };
1413
+ }
1414
+
1415
+ // src/sheet-content.tsx
1416
+ var SheetContent = React.forwardRef(
1417
+ ({
1418
+ disableScroll: disableScrollProp,
1419
+ disableDrag: disableDragProp,
1420
+ children,
1421
+ style: styleProp,
1422
+ className = "",
1423
+ scrollClassName = "",
1424
+ scrollStyle: scrollStyleProp,
1425
+ scrollRef: scrollRefProp = null,
1426
+ unstyled,
1427
+ ...rest
1428
+ }, ref) => {
1429
+ const sheetContext = useInternalContext();
1430
+ const dragConstraints = useDragConstraints();
1431
+ const scroll = useScrollPosition({
1432
+ isEnabled: typeof disableScrollProp === "function" ? true : !disableScrollProp
1433
+ });
1434
+ const disableScroll = typeof disableScrollProp === "function" ? disableScrollProp({
1435
+ scrollPosition: scroll.scrollPosition,
1436
+ currentSnap: sheetContext.currentSnap
1437
+ }) : Boolean(disableScrollProp);
1438
+ const disableDragDueToScroll = !disableScroll && scroll.scrollPosition && scroll.scrollPosition !== "top";
1439
+ const disableDragDueToProp = typeof disableDragProp === "function" ? disableDragProp({
1440
+ scrollPosition: scroll.scrollPosition,
1441
+ currentSnap: sheetContext.currentSnap
1442
+ }) : Boolean(disableDragProp);
1443
+ const disableDrag = disableDragDueToProp || disableDragDueToScroll || sheetContext.disableDrag;
1444
+ const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
1445
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1446
+ const contentStyle = {
1447
+ ...applyStyles(styles.content, isUnstyled),
1448
+ ...styleProp
1449
+ };
1450
+ const scrollStyle = applyStyles(styles.scroller, isUnstyled);
1451
+ if (sheetContext.avoidKeyboard) {
1452
+ scrollStyle.paddingBottom = isHTTPS() ? "env(keyboard-inset-height, var(--keyboard-inset-height, 0px))" : "var(--keyboard-inset-height, 0px)";
1453
+ }
1454
+ if (disableScroll) {
1455
+ scrollStyle.overflowY = "clip";
1456
+ }
1457
+ if (dragProps !== void 0) {
1458
+ scrollStyle.touchAction = "pan-down";
1459
+ }
1460
+ return /* @__PURE__ */ React__default.default.createElement(
1461
+ react.motion.div,
1462
+ {
1463
+ ...rest,
1464
+ ref: mergeRefs([ref, dragConstraints.ref]),
1465
+ className: `react-modal-sheet-content ${className}`,
1466
+ style: contentStyle,
1467
+ ...dragProps,
1468
+ dragConstraints: dragConstraints.ref,
1469
+ onMeasureDragConstraints: dragConstraints.onMeasure
1470
+ },
1471
+ /* @__PURE__ */ React__default.default.createElement(
1472
+ react.motion.div,
1473
+ {
1474
+ ref: mergeRefs([scroll.scrollRef, scrollRefProp]),
1475
+ style: { ...scrollStyle, ...scrollStyleProp },
1476
+ className: `react-modal-sheet-content-scroller ${scrollClassName}`
1477
+ },
1478
+ children
1479
+ )
1480
+ );
1481
+ }
1482
+ );
1483
+ SheetContent.displayName = "SheetContent";
1484
+ function SheetDragIndicator({
1485
+ style,
1486
+ className = "",
1487
+ unstyled,
1488
+ ...rest
1489
+ }) {
1490
+ const sheetContext = useInternalContext();
1491
+ const indicator1Transform = react.useTransform(
1492
+ sheetContext.indicatorRotation,
1493
+ (r) => `translateX(2px) rotate(${r}deg)`
1494
+ );
1495
+ const indicator2Transform = react.useTransform(
1496
+ sheetContext.indicatorRotation,
1497
+ (r) => `translateX(-2px) rotate(${ -1 * r}deg)`
1498
+ );
1499
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1500
+ const indicatorWrapperStyle = {
1501
+ ...applyStyles(styles.indicatorWrapper, isUnstyled),
1502
+ ...style
1503
+ };
1504
+ const indicatorStyle = applyStyles(styles.indicator, isUnstyled);
1505
+ return /* @__PURE__ */ React__default.default.createElement(
1506
+ "div",
1507
+ {
1508
+ className: `react-modal-sheet-drag-indicator-container ${className}`,
1509
+ style: indicatorWrapperStyle,
1510
+ ...rest
1511
+ },
1512
+ /* @__PURE__ */ React__default.default.createElement(
1513
+ react.motion.span,
1514
+ {
1515
+ className: "react-modal-sheet-drag-indicator",
1516
+ style: { ...indicatorStyle, transform: indicator1Transform }
1517
+ }
1518
+ ),
1519
+ /* @__PURE__ */ React__default.default.createElement(
1520
+ react.motion.span,
1521
+ {
1522
+ className: "react-modal-sheet-drag-indicator",
1523
+ style: { ...indicatorStyle, transform: indicator2Transform }
1524
+ }
1525
+ )
1526
+ );
1527
+ }
1528
+ var SheetHeader = React.forwardRef(
1529
+ ({ children, style, disableDrag, unstyled, className = "", ...rest }, ref) => {
1530
+ const sheetContext = useInternalContext();
1531
+ const dragConstraints = useDragConstraints();
1532
+ const dragProps = disableDrag || sheetContext.disableDrag ? void 0 : sheetContext.dragProps;
1533
+ const isUnstyled = unstyled ?? sheetContext.unstyled;
1534
+ const headerWrapperStyle = {
1535
+ ...applyStyles(styles.headerWrapper, isUnstyled),
1536
+ ...style
1537
+ };
1538
+ const headerStyle = applyStyles(styles.header, isUnstyled);
1539
+ return /* @__PURE__ */ React__default.default.createElement(
1540
+ react.motion.div,
1541
+ {
1542
+ ...rest,
1543
+ ref: mergeRefs([ref, dragConstraints.ref]),
1544
+ style: headerWrapperStyle,
1545
+ className: `react-modal-sheet-header-container ${className}`,
1546
+ ...dragProps,
1547
+ dragConstraints: dragConstraints.ref,
1548
+ onMeasureDragConstraints: dragConstraints.onMeasure
1549
+ },
1550
+ children || /* @__PURE__ */ React__default.default.createElement("div", { className: "react-modal-sheet-header", style: headerStyle }, /* @__PURE__ */ React__default.default.createElement(SheetDragIndicator, null))
1551
+ );
1552
+ }
1553
+ );
1554
+ SheetHeader.displayName = "SheetHeader";
1550
1555
 
1551
1556
  // src/index.tsx
1552
1557
  var Sheet2 = Object.assign(Sheet, {
@@ -1554,7 +1559,8 @@ var Sheet2 = Object.assign(Sheet, {
1554
1559
  Header: SheetHeader,
1555
1560
  DragIndicator: SheetDragIndicator,
1556
1561
  Content: SheetContent,
1557
- Backdrop: SheetBackdrop
1562
+ Backdrop: SheetBackdrop,
1563
+ useContext: useExposedContext
1558
1564
  });
1559
1565
 
1560
1566
  exports.Sheet = Sheet2;