react-modal-sheet 5.4.1 → 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/README.md +263 -88
- package/dist/index.d.mts +16 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.js +668 -610
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +664 -606
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +1 -1
- package/src/context.tsx +16 -6
- package/src/hooks/use-modal-effect.ts +87 -82
- package/src/index.tsx +11 -16
- package/src/{SheetBackdrop.tsx → sheet-backdrop.tsx} +3 -12
- package/src/{SheetContainer.tsx → sheet-container.tsx} +2 -2
- package/src/{SheetContent.tsx → sheet-content.tsx} +9 -3
- package/src/{SheetDragIndicator.tsx → sheet-drag-indicator.tsx} +2 -2
- package/src/{SheetHeader.tsx → sheet-header.tsx} +3 -3
- package/src/sheet.tsx +58 -85
- package/src/snap.ts +202 -103
- package/src/types.tsx +13 -1
- package/src/utils.ts +4 -0
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
|
|
11
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
12
12
|
var useMeasure__default = /*#__PURE__*/_interopDefault(useMeasure);
|
|
13
13
|
|
|
14
|
-
// src/
|
|
15
|
-
var
|
|
16
|
-
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
|
|
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)";
|
|
@@ -137,7 +37,30 @@ var REDUCED_MOTION_TWEEN_CONFIG = {
|
|
|
137
37
|
duration: 0.01
|
|
138
38
|
};
|
|
139
39
|
var DEFAULT_DRAG_CLOSE_THRESHOLD = 0.6;
|
|
140
|
-
var DEFAULT_DRAG_VELOCITY_THRESHOLD =
|
|
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
|
-
|
|
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 =
|
|
150
|
+
const handlerRef = React.useRef(void 0);
|
|
305
151
|
useIsomorphicLayoutEffect(() => {
|
|
306
152
|
handlerRef.current = handler;
|
|
307
153
|
});
|
|
308
|
-
return
|
|
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
|
-
|
|
315
|
-
function
|
|
316
|
-
const {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
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
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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] =
|
|
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
|
-
|
|
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
|
-
|
|
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] =
|
|
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
|
-
|
|
779
|
-
return () => {
|
|
780
|
-
if (rootId) cleanupModalEffect(rootId);
|
|
781
|
-
};
|
|
782
|
-
}, []);
|
|
783
|
-
useIsomorphicLayoutEffect(() => {
|
|
391
|
+
const handleYChange = useStableCallback((yValue) => {
|
|
784
392
|
if (!rootId) return;
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
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
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
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
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
418
|
+
});
|
|
419
|
+
const handleYComplete = useStableCallback(() => {
|
|
420
|
+
if (!rootId) return;
|
|
421
|
+
if (y.get() + 5 >= sheetHeight) {
|
|
422
|
+
cleanupModalEffect(rootId);
|
|
823
423
|
}
|
|
824
|
-
|
|
825
|
-
|
|
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
|
-
}, [
|
|
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
|
|
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] =
|
|
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
|
-
|
|
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
|
-
|
|
698
|
+
React.useEffect(() => {
|
|
1081
699
|
async function handle() {
|
|
1082
700
|
switch (state) {
|
|
1083
701
|
case "closed":
|
|
@@ -1157,78 +775,251 @@ function computeSnapPoints({
|
|
|
1157
775
|
// Y value is inverted as `y = 0` means sheet is at the top
|
|
1158
776
|
}));
|
|
1159
777
|
}
|
|
1160
|
-
function
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
778
|
+
function sign(value) {
|
|
779
|
+
if (value > 0) return 1;
|
|
780
|
+
if (value < 0) return -1;
|
|
781
|
+
return 0;
|
|
782
|
+
}
|
|
783
|
+
function toAscendingYSnaps(snapPoints) {
|
|
784
|
+
return snapPoints.slice().sort((a, b) => a.snapValueY - b.snapValueY);
|
|
785
|
+
}
|
|
786
|
+
function findNearestSnapByY(snapPoints, y) {
|
|
1164
787
|
return snapPoints.reduce(
|
|
1165
|
-
(closest, snap) => Math.abs(snap.snapValueY -
|
|
788
|
+
(closest, snap) => Math.abs(snap.snapValueY - y) < Math.abs(closest.snapValueY - y) ? snap : closest
|
|
1166
789
|
);
|
|
1167
790
|
}
|
|
1168
|
-
function
|
|
791
|
+
function findNearestSnapAboveY(snapPoints, y) {
|
|
792
|
+
const snaps = toAscendingYSnaps(snapPoints);
|
|
793
|
+
for (let i = snaps.length - 1; i >= 0; i--) {
|
|
794
|
+
if (snaps[i].snapValueY < y) {
|
|
795
|
+
return snaps[i];
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return null;
|
|
799
|
+
}
|
|
800
|
+
function findNearestSnapBelowY(snapPoints, y) {
|
|
801
|
+
const snaps = toAscendingYSnaps(snapPoints);
|
|
802
|
+
for (let i = 0; i < snaps.length; i++) {
|
|
803
|
+
if (snaps[i].snapValueY > y) {
|
|
804
|
+
return snaps[i];
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
function resolveDirection({
|
|
810
|
+
offsetY,
|
|
811
|
+
velocityY,
|
|
812
|
+
deltaY
|
|
813
|
+
}) {
|
|
814
|
+
if (Math.abs(velocityY) > 50) return sign(velocityY);
|
|
815
|
+
const offsetDirection = sign(offsetY);
|
|
816
|
+
if (offsetDirection !== 0) return offsetDirection;
|
|
817
|
+
return sign(deltaY);
|
|
818
|
+
}
|
|
819
|
+
function classifyDragEnd({
|
|
1169
820
|
y,
|
|
821
|
+
info,
|
|
822
|
+
sheetHeight,
|
|
1170
823
|
snapPoints,
|
|
1171
|
-
|
|
824
|
+
dragVelocityThreshold,
|
|
825
|
+
dragCloseThreshold
|
|
1172
826
|
}) {
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
827
|
+
const flickVelocity = dragVelocityThreshold;
|
|
828
|
+
const strongFlickVelocity = Math.max(2e3, flickVelocity);
|
|
829
|
+
const distanceCommitRatio = 0.35;
|
|
830
|
+
const predictionTime = 0.2;
|
|
831
|
+
const minDragDistance = 20;
|
|
832
|
+
const snapStickiness = 24;
|
|
833
|
+
const minY = 0;
|
|
834
|
+
const maxY = sheetHeight;
|
|
835
|
+
const offsetY = info.offset.y;
|
|
836
|
+
const deltaY = info.delta.y;
|
|
837
|
+
const velocityY = info.velocity.y;
|
|
838
|
+
const predictedY = clamp(y + velocityY * predictionTime, minY, maxY);
|
|
839
|
+
const absVelocity = Math.abs(velocityY);
|
|
840
|
+
const direction = resolveDirection({ offsetY, velocityY, deltaY });
|
|
841
|
+
const isStrongFlick = absVelocity > strongFlickVelocity;
|
|
842
|
+
const isFlick = absVelocity > flickVelocity;
|
|
843
|
+
if (snapPoints.length === 0) {
|
|
844
|
+
if (isFlick) {
|
|
845
|
+
return {
|
|
846
|
+
yTo: direction < 0 ? minY : maxY,
|
|
847
|
+
snapIndex: void 0
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
const midpoint = minY + (maxY - minY) * dragCloseThreshold;
|
|
851
|
+
return {
|
|
852
|
+
yTo: predictedY < midpoint ? minY : maxY,
|
|
853
|
+
snapIndex: void 0
|
|
854
|
+
};
|
|
1177
855
|
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
dragDirection,
|
|
1181
|
-
snapPoints
|
|
1182
|
-
}) {
|
|
1183
|
-
const bottomSnapPoint = snapPoints[0];
|
|
1184
|
-
const topSnapPoint = snapPoints[snapPoints.length - 1];
|
|
1185
|
-
if (dragDirection === "down") {
|
|
856
|
+
const nearestSnap = findNearestSnapByY(snapPoints, y);
|
|
857
|
+
if (!isFlick && Math.abs(offsetY) < minDragDistance) {
|
|
1186
858
|
return {
|
|
1187
|
-
yTo:
|
|
1188
|
-
snapIndex:
|
|
859
|
+
yTo: nearestSnap.snapValueY,
|
|
860
|
+
snapIndex: nearestSnap.snapIndex
|
|
1189
861
|
};
|
|
1190
862
|
}
|
|
1191
|
-
|
|
1192
|
-
yTo: topSnapPoint.snapValueY,
|
|
1193
|
-
snapIndex: topSnapPoint.snapIndex
|
|
1194
|
-
};
|
|
1195
|
-
}
|
|
1196
|
-
function handleLowVelocityDrag({
|
|
1197
|
-
currentSnapPoint,
|
|
1198
|
-
currentY,
|
|
1199
|
-
dragDirection,
|
|
1200
|
-
snapPoints,
|
|
1201
|
-
velocity
|
|
1202
|
-
}) {
|
|
1203
|
-
const closestSnapRelativeToCurrentY = findClosestSnapPoint({
|
|
1204
|
-
snapPoints,
|
|
1205
|
-
currentY
|
|
1206
|
-
});
|
|
1207
|
-
if (Math.abs(velocity) < 20) {
|
|
863
|
+
if (!isFlick && Math.abs(y - nearestSnap.snapValueY) < snapStickiness) {
|
|
1208
864
|
return {
|
|
1209
|
-
yTo:
|
|
1210
|
-
snapIndex:
|
|
865
|
+
yTo: nearestSnap.snapValueY,
|
|
866
|
+
snapIndex: nearestSnap.snapIndex
|
|
1211
867
|
};
|
|
1212
868
|
}
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
snapPoints,
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
869
|
+
if (isStrongFlick) {
|
|
870
|
+
const target = direction < 0 ? minY : maxY;
|
|
871
|
+
const targetSnap = findNearestSnapByY(snapPoints, target);
|
|
872
|
+
return {
|
|
873
|
+
yTo: target,
|
|
874
|
+
snapIndex: targetSnap.snapIndex
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
if (isFlick) {
|
|
878
|
+
const nextSnap2 = direction < 0 ? findNearestSnapAboveY(snapPoints, y) : findNearestSnapBelowY(snapPoints, y);
|
|
879
|
+
const fallbackY = direction < 0 ? minY : maxY;
|
|
880
|
+
const fallbackSnap = findNearestSnapByY(snapPoints, fallbackY);
|
|
881
|
+
const targetSnap = nextSnap2 ?? fallbackSnap;
|
|
882
|
+
return {
|
|
883
|
+
yTo: targetSnap.snapValueY,
|
|
884
|
+
snapIndex: targetSnap.snapIndex
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
const firstSnap = toAscendingYSnaps(snapPoints)[0];
|
|
888
|
+
const lastSnap = toAscendingYSnaps(snapPoints)[snapPoints.length - 1];
|
|
889
|
+
const prevSnap = findNearestSnapAboveY(snapPoints, y) ?? firstSnap;
|
|
890
|
+
const nextSnap = findNearestSnapBelowY(snapPoints, y) ?? lastSnap;
|
|
891
|
+
if (prevSnap.snapIndex === nextSnap.snapIndex) {
|
|
1219
892
|
return {
|
|
1220
|
-
yTo:
|
|
1221
|
-
snapIndex:
|
|
893
|
+
yTo: prevSnap.snapValueY,
|
|
894
|
+
snapIndex: prevSnap.snapIndex
|
|
1222
895
|
};
|
|
1223
896
|
}
|
|
897
|
+
const range = nextSnap.snapValueY - prevSnap.snapValueY;
|
|
898
|
+
const progress = range > 0 ? (y - prevSnap.snapValueY) / range : 0;
|
|
899
|
+
let selectedSnap = nearestSnap;
|
|
900
|
+
if (direction > 0) {
|
|
901
|
+
selectedSnap = progress > distanceCommitRatio ? nextSnap : prevSnap;
|
|
902
|
+
} else if (direction < 0) {
|
|
903
|
+
selectedSnap = progress < 1 - distanceCommitRatio ? prevSnap : nextSnap;
|
|
904
|
+
}
|
|
905
|
+
if (absVelocity > 200) {
|
|
906
|
+
const predictedSnap = findNearestSnapByY(snapPoints, predictedY);
|
|
907
|
+
if (Math.abs(predictedSnap.snapValueY - y) < Math.abs(selectedSnap.snapValueY - y)) {
|
|
908
|
+
selectedSnap = predictedSnap;
|
|
909
|
+
}
|
|
910
|
+
}
|
|
1224
911
|
return {
|
|
1225
|
-
yTo:
|
|
1226
|
-
snapIndex:
|
|
912
|
+
yTo: selectedSnap.snapValueY,
|
|
913
|
+
snapIndex: selectedSnap.snapIndex
|
|
1227
914
|
};
|
|
1228
915
|
}
|
|
1229
916
|
|
|
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
|
+
|
|
1230
1021
|
// src/sheet.tsx
|
|
1231
|
-
var Sheet =
|
|
1022
|
+
var Sheet = React.forwardRef(
|
|
1232
1023
|
({
|
|
1233
1024
|
avoidKeyboard = true,
|
|
1234
1025
|
children,
|
|
@@ -1261,14 +1052,14 @@ var Sheet = React4.forwardRef(
|
|
|
1261
1052
|
...rest
|
|
1262
1053
|
}, ref) => {
|
|
1263
1054
|
const [sheetBoundsRef, sheetBounds] = useMeasure__default.default();
|
|
1264
|
-
const sheetRef =
|
|
1055
|
+
const sheetRef = React.useRef(null);
|
|
1265
1056
|
const sheetHeight = Math.round(sheetBounds.height);
|
|
1266
|
-
const [currentSnap, setCurrentSnap] =
|
|
1267
|
-
const snapPoints = snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
|
|
1057
|
+
const [currentSnap, setCurrentSnap] = React.useState(initialSnap);
|
|
1268
1058
|
const { windowHeight } = useDimensions();
|
|
1269
1059
|
const closedY = sheetHeight > 0 ? sheetHeight : windowHeight;
|
|
1270
1060
|
const y = react.useMotionValue(closedY);
|
|
1271
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));
|
|
1272
1063
|
const indicatorRotation = react.useMotionValue(0);
|
|
1273
1064
|
const shouldReduceMotion = react.useReducedMotion();
|
|
1274
1065
|
const reduceMotion = Boolean(prefersReducedMotion || shouldReduceMotion);
|
|
@@ -1284,6 +1075,9 @@ var Sheet = React4.forwardRef(
|
|
|
1284
1075
|
y,
|
|
1285
1076
|
(val) => val + 2 >= closedY ? "hidden" : "visible"
|
|
1286
1077
|
);
|
|
1078
|
+
const snapPoints = React.useMemo(() => {
|
|
1079
|
+
return snapPointsProp && sheetHeight > 0 ? computeSnapPoints({ sheetHeight, snapPointsProp }) : [];
|
|
1080
|
+
}, [sheetHeight, snapPointsProp == null ? void 0 : snapPointsProp.join("")]);
|
|
1287
1081
|
const updateSnap = useStableCallback((snapIndex) => {
|
|
1288
1082
|
setCurrentSnap(snapIndex);
|
|
1289
1083
|
onSnap == null ? void 0 : onSnap(snapIndex);
|
|
@@ -1370,45 +1164,25 @@ var Sheet = React4.forwardRef(
|
|
|
1370
1164
|
blurActiveInput();
|
|
1371
1165
|
onDragEndProp == null ? void 0 : onDragEndProp(event, info);
|
|
1372
1166
|
const currentY = y.get();
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
currentSnapPoint,
|
|
1388
|
-
currentY,
|
|
1389
|
-
dragDirection: dragOffsetDirection,
|
|
1390
|
-
snapPoints,
|
|
1391
|
-
velocity: info.velocity.y
|
|
1392
|
-
});
|
|
1393
|
-
}
|
|
1394
|
-
yTo = result.yTo;
|
|
1395
|
-
if (disableDismiss && yTo + 1 >= sheetHeight) {
|
|
1396
|
-
const bottomSnapPoint = snapPoints.find((s) => s.snapValue > 0);
|
|
1397
|
-
if (bottomSnapPoint) {
|
|
1398
|
-
yTo = bottomSnapPoint.snapValueY;
|
|
1399
|
-
updateSnap(bottomSnapPoint.snapIndex);
|
|
1400
|
-
} else {
|
|
1401
|
-
yTo = currentY;
|
|
1402
|
-
}
|
|
1403
|
-
} else if (result.snapIndex !== void 0) {
|
|
1404
|
-
updateSnap(result.snapIndex);
|
|
1405
|
-
}
|
|
1406
|
-
} else if (info.velocity.y > dragVelocityThreshold || currentY > sheetHeight * dragCloseThreshold) {
|
|
1407
|
-
if (disableDismiss) {
|
|
1408
|
-
yTo = 0;
|
|
1167
|
+
const result = classifyDragEnd({
|
|
1168
|
+
y: currentY,
|
|
1169
|
+
info,
|
|
1170
|
+
sheetHeight,
|
|
1171
|
+
dragCloseThreshold,
|
|
1172
|
+
snapPoints,
|
|
1173
|
+
dragVelocityThreshold
|
|
1174
|
+
});
|
|
1175
|
+
let yTo = result.yTo;
|
|
1176
|
+
if (disableDismiss && yTo + 1 >= sheetHeight) {
|
|
1177
|
+
const bottomSnapPoint = snapPoints.find((s) => s.snapValue > 0);
|
|
1178
|
+
if (bottomSnapPoint) {
|
|
1179
|
+
yTo = bottomSnapPoint.snapValueY;
|
|
1180
|
+
updateSnap(bottomSnapPoint.snapIndex);
|
|
1409
1181
|
} else {
|
|
1410
|
-
yTo =
|
|
1182
|
+
yTo = currentY;
|
|
1411
1183
|
}
|
|
1184
|
+
} else if (result.snapIndex !== void 0) {
|
|
1185
|
+
updateSnap(result.snapIndex);
|
|
1412
1186
|
}
|
|
1413
1187
|
react.animate(y, yTo, animationOptions);
|
|
1414
1188
|
if (yTo + 1 >= sheetHeight && !disableDismiss) {
|
|
@@ -1416,12 +1190,6 @@ var Sheet = React4.forwardRef(
|
|
|
1416
1190
|
}
|
|
1417
1191
|
indicatorRotation.set(0);
|
|
1418
1192
|
});
|
|
1419
|
-
React4.useImperativeHandle(ref, () => ({
|
|
1420
|
-
y,
|
|
1421
|
-
yInverted,
|
|
1422
|
-
height: sheetHeight,
|
|
1423
|
-
snapTo
|
|
1424
|
-
}));
|
|
1425
1193
|
useModalEffect({
|
|
1426
1194
|
y,
|
|
1427
1195
|
detent,
|
|
@@ -1441,9 +1209,7 @@ var Sheet = React4.forwardRef(
|
|
|
1441
1209
|
const initialSnapPoint = initialSnap !== void 0 ? getSnapPoint(initialSnap) : null;
|
|
1442
1210
|
const yTo = (initialSnapPoint == null ? void 0 : initialSnapPoint.snapValueY) ?? 0;
|
|
1443
1211
|
await react.animate(y, yTo, animationOptions);
|
|
1444
|
-
if (initialSnap !== void 0)
|
|
1445
|
-
updateSnap(initialSnap);
|
|
1446
|
-
}
|
|
1212
|
+
if (initialSnap !== void 0) updateSnap(initialSnap);
|
|
1447
1213
|
onOpenEnd == null ? void 0 : onOpenEnd();
|
|
1448
1214
|
},
|
|
1449
1215
|
onClosing: async () => {
|
|
@@ -1461,7 +1227,7 @@ var Sheet = React4.forwardRef(
|
|
|
1461
1227
|
onDragStart,
|
|
1462
1228
|
onDragEnd
|
|
1463
1229
|
};
|
|
1464
|
-
const
|
|
1230
|
+
const internalContext = {
|
|
1465
1231
|
currentSnap,
|
|
1466
1232
|
detent,
|
|
1467
1233
|
disableDrag,
|
|
@@ -1472,9 +1238,20 @@ var Sheet = React4.forwardRef(
|
|
|
1472
1238
|
sheetBoundsRef,
|
|
1473
1239
|
sheetRef,
|
|
1474
1240
|
unstyled,
|
|
1241
|
+
yProgress,
|
|
1475
1242
|
y
|
|
1476
1243
|
};
|
|
1477
|
-
const
|
|
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(
|
|
1478
1255
|
react.motion.div,
|
|
1479
1256
|
{
|
|
1480
1257
|
...rest,
|
|
@@ -1488,13 +1265,293 @@ var Sheet = React4.forwardRef(
|
|
|
1488
1265
|
...style
|
|
1489
1266
|
}
|
|
1490
1267
|
},
|
|
1491
|
-
state !== "closed" ? children : null
|
|
1268
|
+
/* @__PURE__ */ React__default.default.createElement(ExposedSheetContext.Provider, { value: exposedContext }, state !== "closed" ? children : null)
|
|
1492
1269
|
));
|
|
1493
1270
|
if (IS_SSR) return sheet;
|
|
1494
1271
|
return reactDom.createPortal(sheet, mountPoint ?? document.body);
|
|
1495
1272
|
}
|
|
1496
1273
|
);
|
|
1497
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";
|
|
1498
1555
|
|
|
1499
1556
|
// src/index.tsx
|
|
1500
1557
|
var Sheet2 = Object.assign(Sheet, {
|
|
@@ -1502,7 +1559,8 @@ var Sheet2 = Object.assign(Sheet, {
|
|
|
1502
1559
|
Header: SheetHeader,
|
|
1503
1560
|
DragIndicator: SheetDragIndicator,
|
|
1504
1561
|
Content: SheetContent,
|
|
1505
|
-
Backdrop: SheetBackdrop
|
|
1562
|
+
Backdrop: SheetBackdrop,
|
|
1563
|
+
useContext: useExposedContext
|
|
1506
1564
|
});
|
|
1507
1565
|
|
|
1508
1566
|
exports.Sheet = Sheet2;
|