react-modal-sheet 3.5.0 → 4.0.1
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 +37 -17
- package/dist/index.d.mts +5 -3
- package/dist/index.d.ts +5 -3
- package/dist/index.js +68 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +37 -48
- package/src/SheetBackdrop.tsx +3 -5
- package/src/SheetContainer.tsx +3 -5
- package/src/SheetContent.tsx +3 -5
- package/src/SheetHeader.tsx +3 -5
- package/src/SheetScroller.tsx +2 -4
- package/src/context.tsx +8 -3
- package/src/hooks.tsx +10 -11
- package/src/index.tsx +24 -16
- package/src/sheet.tsx +12 -12
- package/src/styles.ts +2 -3
- package/src/types.tsx +1 -1
- package/src/use-prevent-scroll.ts +0 -1
- package/src/utils.ts +2 -6
package/README.md
CHANGED
|
@@ -23,23 +23,37 @@
|
|
|
23
23
|
npm install react-modal-sheet
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
### Peer dependencies
|
|
27
|
+
|
|
28
|
+
The gestures and animations are handled by the excellent [Motion](https://motion.dev/) library so before you can start using this library you need to install `motion`:
|
|
27
29
|
|
|
28
30
|
```sh
|
|
29
|
-
|
|
31
|
+
npm install motion
|
|
30
32
|
```
|
|
31
33
|
|
|
32
|
-
|
|
34
|
+
> [!IMPORTANT]
|
|
35
|
+
> If you are still using the old `framer-motion` package you need to upgrade to `motion` as `react-modal-sheet` is now built on top of the new `motion` package. **Version `v3.5.0` and older are compatible with `framer-motion`**.
|
|
33
36
|
|
|
34
|
-
|
|
37
|
+
---
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
<details>
|
|
40
|
+
<summary><strong>📚 Table of contents</strong></summary>
|
|
41
|
+
|
|
42
|
+
- [Usage](#-usage)
|
|
43
|
+
- [Props](#%EF%B8%8F-props)
|
|
44
|
+
- [Methods and properties](#%EF%B8%8F-methods-and-properties)
|
|
45
|
+
- [Compound Components](#-compound-components)
|
|
46
|
+
- [Advanced usage](#-advanced-usage)
|
|
47
|
+
- [Customization](#-customization)
|
|
48
|
+
- [Accessibility](#%EF%B8%8F-accessibility)
|
|
49
|
+
- [Troubleshooting](#-troubleshooting)
|
|
50
|
+
</details>
|
|
51
|
+
|
|
52
|
+
---
|
|
39
53
|
|
|
40
54
|
## 💻 Usage
|
|
41
55
|
|
|
42
|
-
```
|
|
56
|
+
```tsx
|
|
43
57
|
import { Sheet } from 'react-modal-sheet';
|
|
44
58
|
import { useState } from 'react';
|
|
45
59
|
|
|
@@ -86,7 +100,7 @@ Also, by constructing the sheet from smaller pieces makes it easier to apply any
|
|
|
86
100
|
| `snapPoints` | no | | Eg. `[-50, 0.5, 100, 0]` - where positive values are pixels from the bottom of the screen and negative from the top. Values between 0-1 represent percentages, eg. `0.5` means 50% of window height from the bottom of the sceen. |
|
|
87
101
|
| `initialSnap` | no | 0 | Initial snap point when sheet is opened (index from `snapPoints`). |
|
|
88
102
|
| `rootId` | no | | The id of the element where the main app is mounted, eg. "root". Enables iOS modal effect. |
|
|
89
|
-
| `tweenConfig` | no | `{ ease: 'easeOut', duration: 0.2 }` | Overrides the config for the sheet [tween](https://
|
|
103
|
+
| `tweenConfig` | no | `{ ease: 'easeOut', duration: 0.2 }` | Overrides the config for the sheet [tween](https://motion.dev/docs/react-transitions#tween) transition when the sheet is opened, closed, or snapped to a point. |
|
|
90
104
|
| `mountPoint` | no | `document.body` | HTML element that should be used as the mount point for the sheet. |
|
|
91
105
|
| `prefersReducedMotion` | no | false | Skip sheet animations (sheet instantly snaps to desired location). |
|
|
92
106
|
| `dragVelocityThreshold` | no | 500 | How fast the sheet must be flicked down to close. Higher values make the sheet harder to close. |
|
|
@@ -104,7 +118,7 @@ import { useState, useRef } from 'react';
|
|
|
104
118
|
|
|
105
119
|
function Example() {
|
|
106
120
|
const [isOpen, setOpen] = useState(false);
|
|
107
|
-
const ref = useRef<SheetRef>();
|
|
121
|
+
const ref = useRef<SheetRef>(null);
|
|
108
122
|
const snapTo = (i: number) => ref.current?.snapTo(i);
|
|
109
123
|
|
|
110
124
|
return (
|
|
@@ -150,7 +164,7 @@ import { useState, useRef } from 'react';
|
|
|
150
164
|
|
|
151
165
|
function Example() {
|
|
152
166
|
const [isOpen, setOpen] = useState(false);
|
|
153
|
-
const ref = useRef<SheetRef>();
|
|
167
|
+
const ref = useRef<SheetRef>(null);
|
|
154
168
|
|
|
155
169
|
return (
|
|
156
170
|
<>
|
|
@@ -269,7 +283,7 @@ Sheet scroller can be used to make the whole sheet content or parts of it scroll
|
|
|
269
283
|
|
|
270
284
|
Sheet backdrop is a translucent overlay that helps to separate the sheet from it's background. By default the backdrop doesn't have any interaction attached to it but if you, for example, want to close the sheet when the backdrop is clicked you can provide tap handler to it which will change the rendered element from `div` to `button`.
|
|
271
285
|
|
|
272
|
-
**⚠️ Note:** as the element is a motion component you need to use [`onTap`](https://
|
|
286
|
+
**⚠️ Note:** as the element is a motion component you need to use [`onTap`](https://motion.dev/docs/react-gestures#tap) instead of `onClick` if you want to add a click handler to it.
|
|
273
287
|
|
|
274
288
|
> 🖥 Rendered element: `motion.div` or `motion.button`.
|
|
275
289
|
|
|
@@ -305,7 +319,7 @@ The scroller component is in-between these states when the user has scrolled onl
|
|
|
305
319
|
|
|
306
320
|
The default value for the `draggableAt` prop is `top` which should be a good default for most use cases. You shouldn't need `bottom` or `both` unless you have scrollable content inside a sheet that also has snap points.
|
|
307
321
|
|
|
308
|
-
```
|
|
322
|
+
```tsx
|
|
309
323
|
function ScrollableExample() {
|
|
310
324
|
return (
|
|
311
325
|
<Sheet>
|
|
@@ -330,7 +344,7 @@ In addition to the `Sheet.Backdrop` it's possible to apply a scaling effect to t
|
|
|
330
344
|
|
|
331
345
|
To enable this effect you can provide the id of the root element where your application is mounted:
|
|
332
346
|
|
|
333
|
-
```
|
|
347
|
+
```tsx
|
|
334
348
|
function Example() {
|
|
335
349
|
return <Sheet rootId="root">{/*...*/}</Sheet>;
|
|
336
350
|
}
|
|
@@ -346,7 +360,7 @@ The default styles for the `Sheet` component somewhat follows the styles of the
|
|
|
346
360
|
|
|
347
361
|
Adding a custom header is as simple as providing your own header as the child component to `Sheet.Header`:
|
|
348
362
|
|
|
349
|
-
```
|
|
363
|
+
```tsx
|
|
350
364
|
function Example() {
|
|
351
365
|
return (
|
|
352
366
|
<Sheet>
|
|
@@ -388,7 +402,7 @@ You can add your own styles or override the default sheet styles via the exposed
|
|
|
388
402
|
|
|
389
403
|
#### CSS-in-JS
|
|
390
404
|
|
|
391
|
-
```
|
|
405
|
+
```tsx
|
|
392
406
|
import { Sheet } from 'react-modal-sheet';
|
|
393
407
|
import { styled } from 'styled-components';
|
|
394
408
|
import { useState } from 'react';
|
|
@@ -438,7 +452,7 @@ The example below utilizes React Aria to achieve an accessible modal-like bottom
|
|
|
438
452
|
|
|
439
453
|
> ℹ️ The example was built by following the React Aria's [useDialog](https://react-spectrum.adobe.com/react-aria/useDialog.html) documentation.
|
|
440
454
|
|
|
441
|
-
```
|
|
455
|
+
```tsx
|
|
442
456
|
import { Sheet } from 'react-modal-sheet';
|
|
443
457
|
import { useRef } from 'react';
|
|
444
458
|
import { useOverlayTriggerState } from 'react-stately';
|
|
@@ -519,3 +533,9 @@ If you want to see a more real-world-like implementation you can take a look at
|
|
|
519
533
|
### 🔩 Building a reusable sheet
|
|
520
534
|
|
|
521
535
|
In your projects it might make sense to build a reusable bottom sheet that has all the accessibility features included and can then be easily used in various places in the project. Take a look at the [A11ySheet](example/components/a11y/A11ySheet.tsx) example to get some insight on how to build such a component. By incorporating all the accessibility features inside your own reusable component you don't need to repeat them every time you want to use a bottom sheet in your app.
|
|
536
|
+
|
|
537
|
+
## 🐛 Troubleshooting
|
|
538
|
+
|
|
539
|
+
### The sheet doesn't open when using `StrictMode`
|
|
540
|
+
|
|
541
|
+
If you are using React [StrictMode](https://react.dev/reference/react/StrictMode) the sheet animations might not work as expected. This seems to be an issue in the `motion` library and I haven't been able to find a good solution for it yet. You see all `motion` issues related to the `StrictMode` [here](https://github.com/motiondivision/motion/issues?q=is%3Aissue+StrictMode). Easiest solution is to just not to use `StrictMode` 🤷♂️
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { motion,
|
|
2
|
-
import {
|
|
1
|
+
import { motion, MotionProps, EasingDefinition, MotionValue } from 'motion/react';
|
|
2
|
+
import { ReactNode, ComponentPropsWithoutRef, HTMLAttributes, ForwardRefExoticComponent, RefAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
interface SheetEvents {
|
|
5
5
|
onOpenStart?: () => void;
|
|
@@ -62,5 +62,7 @@ interface SheetRef {
|
|
|
62
62
|
snapTo: (index: number) => void;
|
|
63
63
|
}
|
|
64
64
|
declare const Sheet: SheetCompound;
|
|
65
|
+
type SheetHeaderProps = SheetDraggableProps;
|
|
66
|
+
type SheetContentProps = SheetDraggableProps;
|
|
65
67
|
|
|
66
|
-
export { Sheet, type SheetRef };
|
|
68
|
+
export { Sheet, type SheetBackdropProps, type SheetContainerProps, type SheetContentProps, type SheetHeaderProps, type SheetProps, type SheetRef, type SheetScrollerProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { motion,
|
|
2
|
-
import {
|
|
1
|
+
import { motion, MotionProps, EasingDefinition, MotionValue } from 'motion/react';
|
|
2
|
+
import { ReactNode, ComponentPropsWithoutRef, HTMLAttributes, ForwardRefExoticComponent, RefAttributes } from 'react';
|
|
3
3
|
|
|
4
4
|
interface SheetEvents {
|
|
5
5
|
onOpenStart?: () => void;
|
|
@@ -62,5 +62,7 @@ interface SheetRef {
|
|
|
62
62
|
snapTo: (index: number) => void;
|
|
63
63
|
}
|
|
64
64
|
declare const Sheet: SheetCompound;
|
|
65
|
+
type SheetHeaderProps = SheetDraggableProps;
|
|
66
|
+
type SheetContentProps = SheetDraggableProps;
|
|
65
67
|
|
|
66
|
-
export { Sheet, type SheetRef };
|
|
68
|
+
export { Sheet, type SheetBackdropProps, type SheetContainerProps, type SheetContentProps, type SheetHeaderProps, type SheetProps, type SheetRef, type SheetScrollerProps };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var React2 = require('react');
|
|
4
4
|
var reactDom = require('react-dom');
|
|
5
|
-
var
|
|
5
|
+
var react = require('motion/react');
|
|
6
6
|
|
|
7
7
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
8
|
|
|
@@ -35,8 +35,7 @@ function useModalEffect({
|
|
|
35
35
|
function setup() {
|
|
36
36
|
const root = document.querySelector(`#${rootId}`);
|
|
37
37
|
const body = document.querySelector("body");
|
|
38
|
-
if (!root)
|
|
39
|
-
return;
|
|
38
|
+
if (!root) return;
|
|
40
39
|
body.style.backgroundColor = "#000";
|
|
41
40
|
root.style.overflow = "hidden";
|
|
42
41
|
root.style.transitionTimingFunction = "cubic-bezier(0.32, 0.72, 0, 1)";
|
|
@@ -47,8 +46,7 @@ function useModalEffect({
|
|
|
47
46
|
function cleanup() {
|
|
48
47
|
const root = document.querySelector(`#${rootId}`);
|
|
49
48
|
const body = document.querySelector("body");
|
|
50
|
-
if (!root)
|
|
51
|
-
return;
|
|
49
|
+
if (!root) return;
|
|
52
50
|
setTimeout(() => {
|
|
53
51
|
body.style.removeProperty("background-color");
|
|
54
52
|
root.style.removeProperty("overflow");
|
|
@@ -63,17 +61,14 @@ function useModalEffect({
|
|
|
63
61
|
}
|
|
64
62
|
useIsomorphicLayoutEffect(() => {
|
|
65
63
|
return () => {
|
|
66
|
-
if (rootId)
|
|
67
|
-
cleanup();
|
|
64
|
+
if (rootId) cleanup();
|
|
68
65
|
};
|
|
69
66
|
}, []);
|
|
70
67
|
React2.useEffect(() => {
|
|
71
68
|
const root = document.querySelector(`#${rootId}`);
|
|
72
|
-
if (!root)
|
|
73
|
-
return;
|
|
69
|
+
if (!root) return;
|
|
74
70
|
function onCompleted() {
|
|
75
|
-
if (y.get() - 10 >= heightRef.current)
|
|
76
|
-
cleanup();
|
|
71
|
+
if (y.get() - 10 >= heightRef.current) cleanup();
|
|
77
72
|
}
|
|
78
73
|
const removeStartListener = y.on("animationStart", () => {
|
|
79
74
|
var _a;
|
|
@@ -85,9 +80,9 @@ function useModalEffect({
|
|
|
85
80
|
const progress = Math.max(0, 1 - value / heightRef.current);
|
|
86
81
|
const pageWidth = window.innerWidth;
|
|
87
82
|
const scale = (pageWidth - 16) / pageWidth;
|
|
88
|
-
const ty =
|
|
89
|
-
const s =
|
|
90
|
-
const borderRadius =
|
|
83
|
+
const ty = react.transform(progress, [0, 1], [0, 24]);
|
|
84
|
+
const s = react.transform(progress, [0, 1], [1, scale]);
|
|
85
|
+
const borderRadius = react.transform(progress, [0, 1], [0, 10]);
|
|
91
86
|
const inset = "env(safe-area-inset-top)";
|
|
92
87
|
root.style.transform = `scale(${s}) translate3d(0, calc(${inset} + ${ty}px), 0)`;
|
|
93
88
|
root.style.borderTopRightRadius = `${borderRadius}px`;
|
|
@@ -148,14 +143,14 @@ function useDimensions() {
|
|
|
148
143
|
return dimensions;
|
|
149
144
|
}
|
|
150
145
|
function usePrevious(state) {
|
|
151
|
-
const ref = React2.useRef();
|
|
146
|
+
const ref = React2.useRef(void 0);
|
|
152
147
|
React2.useEffect(() => {
|
|
153
148
|
ref.current = state;
|
|
154
149
|
});
|
|
155
150
|
return ref.current;
|
|
156
151
|
}
|
|
157
152
|
function useEffectEvent(handler) {
|
|
158
|
-
const handlerRef = React2.useRef();
|
|
153
|
+
const handlerRef = React2.useRef(void 0);
|
|
159
154
|
useIsomorphicLayoutEffect(() => {
|
|
160
155
|
handlerRef.current = handler;
|
|
161
156
|
});
|
|
@@ -175,8 +170,7 @@ var SheetContext = React2.createContext(
|
|
|
175
170
|
);
|
|
176
171
|
var useSheetContext = () => {
|
|
177
172
|
const context = React2.useContext(SheetContext);
|
|
178
|
-
if (!context)
|
|
179
|
-
throw Error("Sheet context error");
|
|
173
|
+
if (!context) throw new Error("Sheet context error");
|
|
180
174
|
return context;
|
|
181
175
|
};
|
|
182
176
|
var SheetScrollerContext = React2.createContext(void 0);
|
|
@@ -186,12 +180,10 @@ function SheetScrollerContextProvider({
|
|
|
186
180
|
const sheetContext = useSheetContext();
|
|
187
181
|
const [disableDrag, setDisableDrag] = React2.useState(!!sheetContext.disableDrag);
|
|
188
182
|
function setDragEnabled() {
|
|
189
|
-
if (!sheetContext.disableDrag)
|
|
190
|
-
setDisableDrag(false);
|
|
183
|
+
if (!sheetContext.disableDrag) setDisableDrag(false);
|
|
191
184
|
}
|
|
192
185
|
function setDragDisabled() {
|
|
193
|
-
if (!disableDrag)
|
|
194
|
-
setDisableDrag(true);
|
|
186
|
+
if (!disableDrag) setDisableDrag(true);
|
|
195
187
|
}
|
|
196
188
|
return /* @__PURE__ */ React2__default.default.createElement(
|
|
197
189
|
SheetScrollerContext.Provider,
|
|
@@ -203,8 +195,7 @@ function SheetScrollerContextProvider({
|
|
|
203
195
|
}
|
|
204
196
|
var useSheetScrollerContext = () => {
|
|
205
197
|
const context = React2.useContext(SheetScrollerContext);
|
|
206
|
-
if (!context)
|
|
207
|
-
throw Error("Sheet scroller context error");
|
|
198
|
+
if (!context) throw new Error("Sheet scroller context error");
|
|
208
199
|
return context;
|
|
209
200
|
};
|
|
210
201
|
|
|
@@ -223,8 +214,7 @@ function getClosest(nums, goal) {
|
|
|
223
214
|
}
|
|
224
215
|
function inDescendingOrder(arr) {
|
|
225
216
|
for (let i = 0; i < arr.length; i++) {
|
|
226
|
-
if (arr[i + 1] > arr[i])
|
|
227
|
-
return false;
|
|
217
|
+
if (arr[i + 1] > arr[i]) return false;
|
|
228
218
|
}
|
|
229
219
|
return true;
|
|
230
220
|
}
|
|
@@ -251,16 +241,14 @@ function mergeRefs(refs) {
|
|
|
251
241
|
};
|
|
252
242
|
}
|
|
253
243
|
function isTouchDevice() {
|
|
254
|
-
if (typeof window === "undefined")
|
|
255
|
-
return false;
|
|
244
|
+
if (typeof window === "undefined") return false;
|
|
256
245
|
return "ontouchstart" in window || navigator.maxTouchPoints > 0;
|
|
257
246
|
}
|
|
258
247
|
function testPlatform(re) {
|
|
259
248
|
var _a;
|
|
260
249
|
return typeof window !== "undefined" && window.navigator != null ? re.test(
|
|
261
250
|
// @ts-expect-error
|
|
262
|
-
|
|
263
|
-
((_a = window.navigator["userAgentData"]) == null ? void 0 : _a.platform) || window.navigator.platform
|
|
251
|
+
((_a = window.navigator.userAgentData) == null ? void 0 : _a.platform) || window.navigator.platform
|
|
264
252
|
) : false;
|
|
265
253
|
}
|
|
266
254
|
function cached(fn) {
|
|
@@ -523,7 +511,8 @@ var styles = {
|
|
|
523
511
|
backgroundColor: "rgba(0, 0, 0, 0.2)",
|
|
524
512
|
touchAction: "none",
|
|
525
513
|
// Disable iOS body scrolling
|
|
526
|
-
border: "none"
|
|
514
|
+
border: "none",
|
|
515
|
+
WebkitTapHighlightColor: "transparent"
|
|
527
516
|
},
|
|
528
517
|
container: {
|
|
529
518
|
zIndex: 2,
|
|
@@ -568,7 +557,6 @@ var styles = {
|
|
|
568
557
|
overflowY: "auto"
|
|
569
558
|
}
|
|
570
559
|
};
|
|
571
|
-
var styles_default = styles;
|
|
572
560
|
|
|
573
561
|
// src/sheet.tsx
|
|
574
562
|
var Sheet = React2.forwardRef(
|
|
@@ -596,20 +584,20 @@ var Sheet = React2.forwardRef(
|
|
|
596
584
|
...rest
|
|
597
585
|
}, ref) => {
|
|
598
586
|
const sheetRef = React2.useRef(null);
|
|
599
|
-
const indicatorRotation =
|
|
587
|
+
const indicatorRotation = react.useMotionValue(0);
|
|
600
588
|
const { height: windowHeight } = useDimensions();
|
|
601
|
-
const shouldReduceMotion =
|
|
589
|
+
const shouldReduceMotion = react.useReducedMotion();
|
|
602
590
|
const reduceMotion = Boolean(prefersReducedMotion || shouldReduceMotion);
|
|
603
591
|
const animationOptions = {
|
|
604
592
|
type: "tween",
|
|
605
593
|
...reduceMotion ? REDUCED_MOTION_TWEEN_CONFIG : tweenConfig
|
|
606
594
|
};
|
|
607
|
-
const y =
|
|
608
|
-
const zIndex =
|
|
595
|
+
const y = react.useMotionValue(windowHeight);
|
|
596
|
+
const zIndex = react.useTransform(
|
|
609
597
|
y,
|
|
610
|
-
(value) => value + 2 >= windowHeight ? -1 :
|
|
598
|
+
(value) => value + 2 >= windowHeight ? -1 : (style == null ? void 0 : style.zIndex) ?? 9999
|
|
611
599
|
);
|
|
612
|
-
const visibility =
|
|
600
|
+
const visibility = react.useTransform(
|
|
613
601
|
y,
|
|
614
602
|
(value) => value + 2 >= windowHeight ? "hidden" : "visible"
|
|
615
603
|
);
|
|
@@ -630,8 +618,7 @@ var Sheet = React2.forwardRef(
|
|
|
630
618
|
let snapPoints = snapPointsProp;
|
|
631
619
|
if (snapPoints) {
|
|
632
620
|
snapPoints = snapPoints.map((point) => {
|
|
633
|
-
if (point > 0 && point <= 1)
|
|
634
|
-
return Math.round(point * windowHeight);
|
|
621
|
+
if (point > 0 && point <= 1) return Math.round(point * windowHeight);
|
|
635
622
|
return point < 0 ? windowHeight + point : point;
|
|
636
623
|
});
|
|
637
624
|
console.assert(
|
|
@@ -643,16 +630,13 @@ var Sheet = React2.forwardRef(
|
|
|
643
630
|
}
|
|
644
631
|
const onDrag = useEffectEvent((_, { delta }) => {
|
|
645
632
|
const velocity = y.getVelocity();
|
|
646
|
-
if (velocity > 0)
|
|
647
|
-
|
|
648
|
-
if (velocity < 0)
|
|
649
|
-
indicatorRotation.set(-10);
|
|
633
|
+
if (velocity > 0) indicatorRotation.set(10);
|
|
634
|
+
if (velocity < 0) indicatorRotation.set(-10);
|
|
650
635
|
y.set(Math.max(y.get() + delta.y, 0));
|
|
651
636
|
});
|
|
652
637
|
const onDragStart = useEffectEvent(() => {
|
|
653
638
|
const focusedElement = document.activeElement;
|
|
654
|
-
if (!focusedElement || !sheetRef.current)
|
|
655
|
-
return;
|
|
639
|
+
if (!focusedElement || !sheetRef.current) return;
|
|
656
640
|
const isInput = focusedElement.tagName === "INPUT" || focusedElement.tagName === "TEXTAREA";
|
|
657
641
|
if (isInput && sheetRef.current.contains(focusedElement)) {
|
|
658
642
|
focusedElement.blur();
|
|
@@ -677,22 +661,22 @@ var Sheet = React2.forwardRef(
|
|
|
677
661
|
snapTo = sheetHeight;
|
|
678
662
|
}
|
|
679
663
|
snapTo = validateSnapTo({ snapTo, sheetHeight });
|
|
680
|
-
|
|
664
|
+
react.animate(y, snapTo, animationOptions);
|
|
681
665
|
if (snapPoints && onSnap) {
|
|
682
666
|
const snapValue = Math.abs(Math.round(snapPoints[0] - snapTo));
|
|
683
|
-
const snapIndex = snapPoints.indexOf(
|
|
667
|
+
const snapIndex = snapPoints.indexOf(
|
|
668
|
+
getClosest(snapPoints, snapValue)
|
|
669
|
+
);
|
|
684
670
|
onSnap(snapIndex);
|
|
685
671
|
}
|
|
686
672
|
const roundedSheetHeight = Math.round(sheetHeight);
|
|
687
673
|
const shouldClose = snapTo + 2 >= roundedSheetHeight;
|
|
688
|
-
if (shouldClose)
|
|
689
|
-
onClose();
|
|
674
|
+
if (shouldClose) onClose();
|
|
690
675
|
}
|
|
691
676
|
indicatorRotation.set(0);
|
|
692
677
|
});
|
|
693
678
|
React2.useEffect(() => {
|
|
694
|
-
if (!snapPoints || !onSnap)
|
|
695
|
-
return;
|
|
679
|
+
if (!snapPoints || !onSnap) return;
|
|
696
680
|
const snapIndex = isOpen ? initialSnap : snapPoints.length - 1;
|
|
697
681
|
onSnap(snapIndex);
|
|
698
682
|
}, [isOpen]);
|
|
@@ -707,11 +691,9 @@ var Sheet = React2.forwardRef(
|
|
|
707
691
|
snapTo: sheetHeight - snapPoint,
|
|
708
692
|
sheetHeight
|
|
709
693
|
});
|
|
710
|
-
|
|
711
|
-
if (onSnap)
|
|
712
|
-
|
|
713
|
-
if (snapTo >= sheetHeight)
|
|
714
|
-
onClose();
|
|
694
|
+
react.animate(y, snapTo, animationOptions);
|
|
695
|
+
if (onSnap) onSnap(snapIndex);
|
|
696
|
+
if (snapTo >= sheetHeight) onClose();
|
|
715
697
|
}
|
|
716
698
|
}
|
|
717
699
|
}));
|
|
@@ -749,24 +731,22 @@ var Sheet = React2.forwardRef(
|
|
|
749
731
|
disableDrag
|
|
750
732
|
};
|
|
751
733
|
const sheet = /* @__PURE__ */ React2__default.default.createElement(SheetContext.Provider, { value: context }, /* @__PURE__ */ React2__default.default.createElement(
|
|
752
|
-
|
|
734
|
+
react.motion.div,
|
|
753
735
|
{
|
|
754
736
|
...rest,
|
|
755
737
|
ref,
|
|
756
|
-
style: { ...
|
|
738
|
+
style: { ...styles.wrapper, zIndex, visibility, ...style }
|
|
757
739
|
},
|
|
758
|
-
/* @__PURE__ */ React2__default.default.createElement(
|
|
740
|
+
/* @__PURE__ */ React2__default.default.createElement(react.AnimatePresence, null, isOpen ? /* @__PURE__ */ React2__default.default.createElement(SheetScrollerContextProvider, null, React2.Children.map(
|
|
759
741
|
children,
|
|
760
742
|
(child, i) => React2.cloneElement(child, { key: `sheet-child-${i}` })
|
|
761
743
|
)) : null)
|
|
762
744
|
));
|
|
763
|
-
if (IS_SSR)
|
|
764
|
-
return sheet;
|
|
745
|
+
if (IS_SSR) return sheet;
|
|
765
746
|
return reactDom.createPortal(sheet, mountPoint ?? document.body);
|
|
766
747
|
}
|
|
767
748
|
);
|
|
768
749
|
Sheet.displayName = "Sheet";
|
|
769
|
-
var sheet_default = Sheet;
|
|
770
750
|
var SheetContainer = React2.forwardRef(
|
|
771
751
|
({ children, style = {}, className = "", ...rest }, ref) => {
|
|
772
752
|
const {
|
|
@@ -786,13 +766,13 @@ var SheetContainer = React2.forwardRef(
|
|
|
786
766
|
const maxSnapHeight = snapPoints ? snapPoints[0] : null;
|
|
787
767
|
const height = maxSnapHeight !== null ? `min(${maxSnapHeight}px, ${MAX_HEIGHT})` : MAX_HEIGHT;
|
|
788
768
|
return /* @__PURE__ */ React2__default.default.createElement(
|
|
789
|
-
|
|
769
|
+
react.motion.div,
|
|
790
770
|
{
|
|
791
771
|
...rest,
|
|
792
772
|
ref: mergeRefs([sheetRef, ref]),
|
|
793
773
|
className: `react-modal-sheet-container ${className}`,
|
|
794
774
|
style: {
|
|
795
|
-
...
|
|
775
|
+
...styles.container,
|
|
796
776
|
...style,
|
|
797
777
|
...detent === "full-height" && { height },
|
|
798
778
|
...detent === "content-height" && { maxHeight: height },
|
|
@@ -808,7 +788,6 @@ var SheetContainer = React2.forwardRef(
|
|
|
808
788
|
}
|
|
809
789
|
);
|
|
810
790
|
SheetContainer.displayName = "SheetContainer";
|
|
811
|
-
var SheetContainer_default = SheetContainer;
|
|
812
791
|
var SheetContent = React2.forwardRef(
|
|
813
792
|
({ children, style, disableDrag, className = "", ...rest }, ref) => {
|
|
814
793
|
const sheetContext = useSheetContext();
|
|
@@ -816,12 +795,12 @@ var SheetContent = React2.forwardRef(
|
|
|
816
795
|
const { constraintsRef, onMeasureDragConstraints } = useDragConstraints();
|
|
817
796
|
const dragProps = disableDrag || sheetScrollerContext.disableDrag ? void 0 : sheetContext.dragProps;
|
|
818
797
|
return /* @__PURE__ */ React2__default.default.createElement(
|
|
819
|
-
|
|
798
|
+
react.motion.div,
|
|
820
799
|
{
|
|
821
800
|
...rest,
|
|
822
801
|
ref: mergeRefs([ref, constraintsRef]),
|
|
823
802
|
className: `react-modal-sheet-content ${className}`,
|
|
824
|
-
style: { ...
|
|
803
|
+
style: { ...styles.content, ...style },
|
|
825
804
|
...dragProps,
|
|
826
805
|
dragConstraints: constraintsRef,
|
|
827
806
|
onMeasureDragConstraints
|
|
@@ -831,52 +810,50 @@ var SheetContent = React2.forwardRef(
|
|
|
831
810
|
}
|
|
832
811
|
);
|
|
833
812
|
SheetContent.displayName = "SheetContent";
|
|
834
|
-
var SheetContent_default = SheetContent;
|
|
835
813
|
var SheetHeader = React2.forwardRef(
|
|
836
814
|
({ children, style, disableDrag, ...rest }, ref) => {
|
|
837
815
|
const { indicatorRotation, dragProps } = useSheetContext();
|
|
838
816
|
const { constraintsRef, onMeasureDragConstraints } = useDragConstraints();
|
|
839
817
|
const _dragProps = disableDrag ? void 0 : dragProps;
|
|
840
|
-
const indicator1Transform =
|
|
818
|
+
const indicator1Transform = react.useTransform(
|
|
841
819
|
indicatorRotation,
|
|
842
820
|
(r) => `translateX(2px) rotate(${r}deg)`
|
|
843
821
|
);
|
|
844
|
-
const indicator2Transform =
|
|
822
|
+
const indicator2Transform = react.useTransform(
|
|
845
823
|
indicatorRotation,
|
|
846
824
|
(r) => `translateX(-2px) rotate(${-1 * r}deg)`
|
|
847
825
|
);
|
|
848
826
|
return /* @__PURE__ */ React2__default.default.createElement(
|
|
849
|
-
|
|
827
|
+
react.motion.div,
|
|
850
828
|
{
|
|
851
829
|
...rest,
|
|
852
830
|
ref: mergeRefs([ref, constraintsRef]),
|
|
853
|
-
style: { ...
|
|
831
|
+
style: { ...styles.headerWrapper, ...style },
|
|
854
832
|
..._dragProps,
|
|
855
833
|
dragConstraints: constraintsRef,
|
|
856
834
|
onMeasureDragConstraints
|
|
857
835
|
},
|
|
858
|
-
children || /* @__PURE__ */ React2__default.default.createElement("div", { className: "react-modal-sheet-header", style:
|
|
859
|
-
|
|
836
|
+
children || /* @__PURE__ */ React2__default.default.createElement("div", { className: "react-modal-sheet-header", style: styles.header }, /* @__PURE__ */ React2__default.default.createElement(
|
|
837
|
+
react.motion.span,
|
|
860
838
|
{
|
|
861
839
|
className: "react-modal-sheet-drag-indicator",
|
|
862
|
-
style: { ...
|
|
840
|
+
style: { ...styles.indicator, transform: indicator1Transform }
|
|
863
841
|
}
|
|
864
842
|
), /* @__PURE__ */ React2__default.default.createElement(
|
|
865
|
-
|
|
843
|
+
react.motion.span,
|
|
866
844
|
{
|
|
867
845
|
className: "react-modal-sheet-drag-indicator",
|
|
868
|
-
style: { ...
|
|
846
|
+
style: { ...styles.indicator, transform: indicator2Transform }
|
|
869
847
|
}
|
|
870
848
|
))
|
|
871
849
|
);
|
|
872
850
|
}
|
|
873
851
|
);
|
|
874
852
|
SheetHeader.displayName = "SheetHeader";
|
|
875
|
-
var SheetHeader_default = SheetHeader;
|
|
876
853
|
var isClickable = (props) => !!props.onClick || !!props.onTap;
|
|
877
854
|
var SheetBackdrop = React2.forwardRef(
|
|
878
855
|
({ style = {}, className = "", ...rest }, ref) => {
|
|
879
|
-
const Comp = isClickable(rest) ?
|
|
856
|
+
const Comp = isClickable(rest) ? react.motion.button : react.motion.div;
|
|
880
857
|
const pointerEvents = isClickable(rest) ? "auto" : "none";
|
|
881
858
|
return /* @__PURE__ */ React2__default.default.createElement(
|
|
882
859
|
Comp,
|
|
@@ -884,7 +861,7 @@ var SheetBackdrop = React2.forwardRef(
|
|
|
884
861
|
...rest,
|
|
885
862
|
ref,
|
|
886
863
|
className: `react-modal-sheet-backdrop ${className}`,
|
|
887
|
-
style: { ...
|
|
864
|
+
style: { ...styles.backdrop, ...style, pointerEvents },
|
|
888
865
|
initial: { opacity: 0 },
|
|
889
866
|
animate: { opacity: 1 },
|
|
890
867
|
exit: { opacity: 0 }
|
|
@@ -893,15 +870,13 @@ var SheetBackdrop = React2.forwardRef(
|
|
|
893
870
|
}
|
|
894
871
|
);
|
|
895
872
|
SheetBackdrop.displayName = "SheetBackdrop";
|
|
896
|
-
var SheetBackdrop_default = SheetBackdrop;
|
|
897
873
|
var SheetScroller = React2.forwardRef(
|
|
898
874
|
({ draggableAt = "top", children, style, className = "", ...rest }, ref) => {
|
|
899
875
|
const sheetScrollerContext = useSheetScrollerContext();
|
|
900
876
|
function determineDragState(element) {
|
|
901
877
|
const { scrollTop, scrollHeight, clientHeight } = element;
|
|
902
878
|
const isScrollable2 = scrollHeight > clientHeight;
|
|
903
|
-
if (!isScrollable2)
|
|
904
|
-
return;
|
|
879
|
+
if (!isScrollable2) return;
|
|
905
880
|
const isAtTop = scrollTop <= 0;
|
|
906
881
|
const isAtBottom = scrollHeight - scrollTop === clientHeight;
|
|
907
882
|
const shouldEnable = draggableAt === "top" && isAtTop || draggableAt === "bottom" && isAtBottom || draggableAt === "both" && (isAtTop || isAtBottom);
|
|
@@ -930,7 +905,7 @@ var SheetScroller = React2.forwardRef(
|
|
|
930
905
|
...rest,
|
|
931
906
|
ref,
|
|
932
907
|
className: `react-modal-sheet-scroller ${className}`,
|
|
933
|
-
style: { ...
|
|
908
|
+
style: { ...styles.scroller, ...style },
|
|
934
909
|
...scrollProps
|
|
935
910
|
},
|
|
936
911
|
children
|
|
@@ -938,17 +913,16 @@ var SheetScroller = React2.forwardRef(
|
|
|
938
913
|
}
|
|
939
914
|
);
|
|
940
915
|
SheetScroller.displayName = "SheetScroller";
|
|
941
|
-
var SheetScroller_default = SheetScroller;
|
|
942
916
|
|
|
943
917
|
// src/index.tsx
|
|
944
|
-
var
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
918
|
+
var Sheet2 = Object.assign(Sheet, {
|
|
919
|
+
Container: SheetContainer,
|
|
920
|
+
Header: SheetHeader,
|
|
921
|
+
Content: SheetContent,
|
|
922
|
+
Backdrop: SheetBackdrop,
|
|
923
|
+
Scroller: SheetScroller
|
|
924
|
+
});
|
|
951
925
|
|
|
952
926
|
exports.Sheet = Sheet2;
|
|
953
|
-
//# sourceMappingURL=
|
|
927
|
+
//# sourceMappingURL=index.js.map
|
|
954
928
|
//# sourceMappingURL=index.js.map
|