react-modal-sheet 1.11.1 → 2.1.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 +81 -50
- package/dist/SheetBackdrop.d.ts +1 -1
- package/dist/SheetContainer.d.ts +1 -1
- package/dist/SheetContent.d.ts +1 -1
- package/dist/SheetHeader.d.ts +1 -1
- package/dist/SheetScroller.d.ts +5 -0
- package/dist/constants.d.ts +7 -4
- package/dist/context.d.ts +6 -1
- package/dist/hooks.d.ts +2 -2
- package/dist/react-modal-sheet.cjs.development.js +231 -238
- package/dist/react-modal-sheet.cjs.development.js.map +1 -1
- package/dist/react-modal-sheet.cjs.production.min.js +1 -1
- package/dist/react-modal-sheet.cjs.production.min.js.map +1 -1
- package/dist/react-modal-sheet.esm.js +232 -239
- package/dist/react-modal-sheet.esm.js.map +1 -1
- package/dist/sheet.d.ts +2 -1
- package/dist/types.d.ts +18 -2
- package/dist/utils.d.ts +1 -0
- package/package.json +2 -3
- package/src/SheetContent.tsx +9 -4
- package/src/SheetScroller.tsx +59 -0
- package/src/constants.ts +8 -4
- package/src/context.tsx +38 -1
- package/src/hooks.tsx +5 -5
- package/src/index.tsx +2 -0
- package/src/sheet.tsx +18 -11
- package/src/styles.ts +9 -3
- package/src/types.tsx +25 -3
- package/src/utils.ts +8 -23
|
@@ -1,47 +1,44 @@
|
|
|
1
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState, createContext, useContext, forwardRef, useImperativeHandle, useMemo,
|
|
1
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState, createContext, useContext, createElement, forwardRef, useImperativeHandle, useMemo, Children, cloneElement } from 'react';
|
|
2
2
|
import { createPortal } from 'react-dom';
|
|
3
3
|
import { useMotionValue, useReducedMotion, useTransform, animate, motion, AnimatePresence } from 'framer-motion';
|
|
4
4
|
import { useLayoutEffect as useLayoutEffect$1, isIOS, chain, getScrollParent } from '@react-aria/utils';
|
|
5
5
|
|
|
6
6
|
function _extends() {
|
|
7
|
-
_extends = Object.assign
|
|
7
|
+
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
8
8
|
for (var i = 1; i < arguments.length; i++) {
|
|
9
9
|
var source = arguments[i];
|
|
10
|
-
|
|
11
10
|
for (var key in source) {
|
|
12
11
|
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
13
12
|
target[key] = source[key];
|
|
14
13
|
}
|
|
15
14
|
}
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
return target;
|
|
19
17
|
};
|
|
20
|
-
|
|
21
18
|
return _extends.apply(this, arguments);
|
|
22
19
|
}
|
|
23
|
-
|
|
24
20
|
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
25
21
|
if (source == null) return {};
|
|
26
22
|
var target = {};
|
|
27
23
|
var sourceKeys = Object.keys(source);
|
|
28
24
|
var key, i;
|
|
29
|
-
|
|
30
25
|
for (i = 0; i < sourceKeys.length; i++) {
|
|
31
26
|
key = sourceKeys[i];
|
|
32
27
|
if (excluded.indexOf(key) >= 0) continue;
|
|
33
28
|
target[key] = source[key];
|
|
34
29
|
}
|
|
35
|
-
|
|
36
30
|
return target;
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
var MAX_HEIGHT = 'calc(100% - env(safe-area-inset-top) - 34px)';
|
|
40
34
|
var IS_SSR = typeof window === 'undefined';
|
|
41
|
-
var
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
35
|
+
var DEFAULT_TWEEN_CONFIG = {
|
|
36
|
+
ease: 'easeOut',
|
|
37
|
+
duration: 0.2
|
|
38
|
+
};
|
|
39
|
+
var REDUCED_MOTION_TWEEN_CONFIG = {
|
|
40
|
+
ease: 'linear',
|
|
41
|
+
duration: 0.01
|
|
45
42
|
};
|
|
46
43
|
var DRAG_CLOSE_THRESHOLD = 0.6;
|
|
47
44
|
var DRAG_VELOCITY_THRESHOLD = 500;
|
|
@@ -49,23 +46,18 @@ var DRAG_VELOCITY_THRESHOLD = 500;
|
|
|
49
46
|
function getClosest(nums, goal) {
|
|
50
47
|
var closest = nums[0];
|
|
51
48
|
var minDifference = Math.abs(nums[0] - goal);
|
|
52
|
-
|
|
53
49
|
for (var i = 1; i < nums.length; i++) {
|
|
54
50
|
var difference = Math.abs(nums[i] - goal);
|
|
55
|
-
|
|
56
51
|
if (difference < minDifference) {
|
|
57
52
|
closest = nums[i];
|
|
58
53
|
minDifference = difference;
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
|
-
|
|
62
56
|
return closest;
|
|
63
57
|
}
|
|
64
|
-
var highlightId = 'react-modal-sheet-highlight';
|
|
65
58
|
function applyRootStyles(rootId) {
|
|
66
59
|
var body = document.querySelector('body');
|
|
67
60
|
var root = document.querySelector("#" + rootId);
|
|
68
|
-
|
|
69
61
|
if (root) {
|
|
70
62
|
var p = 24;
|
|
71
63
|
var h = window.innerHeight;
|
|
@@ -73,52 +65,28 @@ function applyRootStyles(rootId) {
|
|
|
73
65
|
body.style.backgroundColor = '#000';
|
|
74
66
|
root.style.overflow = 'hidden';
|
|
75
67
|
root.style.willChange = 'transform';
|
|
76
|
-
root.style.transition = 'transform 200ms linear';
|
|
68
|
+
root.style.transition = 'transform 200ms ease-in-out, border-radius 200ms linear';
|
|
77
69
|
root.style.transform = "translateY(calc(env(safe-area-inset-top) + " + p / 2 + "px)) scale(" + s + ")"; // prettier-ignore
|
|
78
|
-
|
|
79
70
|
root.style.borderTopRightRadius = '10px';
|
|
80
|
-
root.style.borderTopLeftRadius = '10px';
|
|
81
|
-
|
|
82
|
-
var highlight = document.createElement('div');
|
|
83
|
-
highlight.setAttribute('aria-hidden', 'true');
|
|
84
|
-
highlight.id = highlightId;
|
|
85
|
-
highlight.style.position = 'absolute';
|
|
86
|
-
highlight.style.top = '0px';
|
|
87
|
-
highlight.style.left = '0px';
|
|
88
|
-
highlight.style.bottom = '0px';
|
|
89
|
-
highlight.style.right = '0px';
|
|
90
|
-
highlight.style.opacity = '0';
|
|
91
|
-
highlight.style.transition = 'opacity 200ms linear';
|
|
92
|
-
highlight.style.backgroundColor = 'rgba(150, 150, 150, 0.1)';
|
|
93
|
-
root.appendChild(highlight);
|
|
94
|
-
requestAnimationFrame(function () {
|
|
95
|
-
return highlight.style.opacity = '1';
|
|
96
|
-
});
|
|
71
|
+
root.style.borderTopLeftRadius = '10px';
|
|
97
72
|
}
|
|
98
73
|
}
|
|
99
74
|
function cleanupRootStyles(rootId) {
|
|
100
75
|
var body = document.querySelector('body');
|
|
101
76
|
var root = document.getElementById(rootId);
|
|
102
|
-
var highlight = document.getElementById(highlightId);
|
|
103
|
-
|
|
104
77
|
function onTransitionEnd() {
|
|
105
|
-
var _highlight$parentNode;
|
|
106
|
-
|
|
107
78
|
root.style.removeProperty('overflow');
|
|
108
79
|
root.style.removeProperty('will-change');
|
|
109
80
|
root.style.removeProperty('transition');
|
|
110
81
|
body.style.removeProperty('background-color');
|
|
111
82
|
root.removeEventListener('transitionend', onTransitionEnd);
|
|
112
|
-
(_highlight$parentNode = highlight.parentNode) == null ? void 0 : _highlight$parentNode.removeChild(highlight);
|
|
113
83
|
}
|
|
114
|
-
|
|
115
|
-
if (root && highlight) {
|
|
84
|
+
if (root) {
|
|
116
85
|
// Start animating back
|
|
117
86
|
root.style.removeProperty('border-top-right-radius');
|
|
118
87
|
root.style.removeProperty('border-top-left-radius');
|
|
119
88
|
root.style.removeProperty('transform');
|
|
120
|
-
|
|
121
|
-
|
|
89
|
+
// Remove temp properties after animation is finished
|
|
122
90
|
root.addEventListener('transitionend', onTransitionEnd);
|
|
123
91
|
}
|
|
124
92
|
}
|
|
@@ -126,17 +94,14 @@ function inDescendingOrder(arr) {
|
|
|
126
94
|
for (var i = 0; i < arr.length; i++) {
|
|
127
95
|
if (arr[i + 1] > arr[i]) return false;
|
|
128
96
|
}
|
|
129
|
-
|
|
130
97
|
return true;
|
|
131
98
|
}
|
|
132
99
|
function validateSnapTo(_ref) {
|
|
133
100
|
var snapTo = _ref.snapTo,
|
|
134
|
-
|
|
135
|
-
|
|
101
|
+
sheetHeight = _ref.sheetHeight;
|
|
136
102
|
if (snapTo < 0) {
|
|
137
103
|
console.warn("Snap point is out of bounds. Sheet height is " + sheetHeight + " but snap point is " + (sheetHeight + Math.abs(snapTo)) + ".");
|
|
138
104
|
}
|
|
139
|
-
|
|
140
105
|
return Math.max(Math.round(snapTo), 0);
|
|
141
106
|
}
|
|
142
107
|
function mergeRefs(refs) {
|
|
@@ -150,11 +115,15 @@ function mergeRefs(refs) {
|
|
|
150
115
|
});
|
|
151
116
|
};
|
|
152
117
|
}
|
|
118
|
+
function isTouchDevice() {
|
|
119
|
+
if (typeof window === 'undefined') return false;
|
|
120
|
+
return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
|
|
121
|
+
}
|
|
153
122
|
|
|
154
123
|
var useIsomorphicLayoutEffect = IS_SSR ? useEffect : useLayoutEffect;
|
|
155
|
-
|
|
156
|
-
var prevOpen = usePrevious(isOpen);
|
|
157
|
-
|
|
124
|
+
function useModalEffect(isOpen, rootId) {
|
|
125
|
+
var prevOpen = usePrevious(isOpen);
|
|
126
|
+
// Automatically apply the iOS modal effect to the body when sheet opens/closes
|
|
158
127
|
useEffect(function () {
|
|
159
128
|
if (rootId && !prevOpen && isOpen) {
|
|
160
129
|
applyRootStyles(rootId);
|
|
@@ -163,51 +132,47 @@ var useModalEffect = function useModalEffect(isOpen, rootId) {
|
|
|
163
132
|
}
|
|
164
133
|
}, [isOpen, prevOpen]); // eslint-disable-line
|
|
165
134
|
// Make sure to cleanup modal styles on unmount
|
|
166
|
-
|
|
167
135
|
useEffect(function () {
|
|
168
136
|
return function () {
|
|
169
137
|
if (rootId && isOpen) cleanupRootStyles(rootId);
|
|
170
138
|
};
|
|
171
139
|
}, [isOpen]); // eslint-disable-line
|
|
172
|
-
}
|
|
173
|
-
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function useEventCallbacks(isOpen, callbacks) {
|
|
174
143
|
var prevOpen = usePrevious(isOpen);
|
|
175
|
-
var didOpen = useRef(false);
|
|
144
|
+
var didOpen = useRef(false);
|
|
145
|
+
// Because of AnimatePrecence we don't have access to latest isOpen value
|
|
176
146
|
// so we need to read and write to a ref to determine if we are
|
|
177
147
|
// opening or closing the sheet
|
|
178
|
-
|
|
179
148
|
var handleAnimationComplete = useCallback(function () {
|
|
180
149
|
if (!didOpen.current) {
|
|
181
|
-
callbacks.current.onOpenEnd == null
|
|
150
|
+
callbacks.current.onOpenEnd == null || callbacks.current.onOpenEnd();
|
|
182
151
|
didOpen.current = true;
|
|
183
152
|
} else {
|
|
184
|
-
callbacks.current.onCloseEnd == null
|
|
153
|
+
callbacks.current.onCloseEnd == null || callbacks.current.onCloseEnd();
|
|
185
154
|
didOpen.current = false;
|
|
186
155
|
}
|
|
187
156
|
}, [isOpen, prevOpen]); // eslint-disable-line
|
|
188
|
-
|
|
189
157
|
useEffect(function () {
|
|
190
158
|
if (!prevOpen && isOpen) {
|
|
191
|
-
callbacks.current.onOpenStart == null
|
|
159
|
+
callbacks.current.onOpenStart == null || callbacks.current.onOpenStart();
|
|
192
160
|
} else if (!isOpen && prevOpen) {
|
|
193
|
-
callbacks.current.onCloseStart == null
|
|
161
|
+
callbacks.current.onCloseStart == null || callbacks.current.onCloseStart();
|
|
194
162
|
}
|
|
195
163
|
}, [isOpen, prevOpen]); // eslint-disable-line
|
|
196
|
-
|
|
197
164
|
return {
|
|
198
165
|
handleAnimationComplete: handleAnimationComplete
|
|
199
166
|
};
|
|
200
|
-
}
|
|
167
|
+
}
|
|
201
168
|
function useWindowHeight() {
|
|
202
169
|
var _React$useState = useState(0),
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
170
|
+
windowHeight = _React$useState[0],
|
|
171
|
+
setWindowHeight = _React$useState[1];
|
|
206
172
|
useIsomorphicLayoutEffect(function () {
|
|
207
173
|
var updateHeight = function updateHeight() {
|
|
208
174
|
return setWindowHeight(window.innerHeight);
|
|
209
175
|
};
|
|
210
|
-
|
|
211
176
|
window.addEventListener('resize', updateHeight);
|
|
212
177
|
updateHeight();
|
|
213
178
|
return function () {
|
|
@@ -222,9 +187,9 @@ function usePrevious(state) {
|
|
|
222
187
|
ref.current = state;
|
|
223
188
|
});
|
|
224
189
|
return ref.current;
|
|
225
|
-
}
|
|
190
|
+
}
|
|
191
|
+
// Userland version of the `useEvent` React hook:
|
|
226
192
|
// RFC: https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md
|
|
227
|
-
|
|
228
193
|
function useEvent(handler) {
|
|
229
194
|
var handlerRef = useRef();
|
|
230
195
|
useIsomorphicLayoutEffect(function () {
|
|
@@ -232,11 +197,9 @@ function useEvent(handler) {
|
|
|
232
197
|
});
|
|
233
198
|
return useCallback(function () {
|
|
234
199
|
var fn = handlerRef.current;
|
|
235
|
-
|
|
236
200
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
237
201
|
args[_key] = arguments[_key];
|
|
238
202
|
}
|
|
239
|
-
|
|
240
203
|
return fn == null ? void 0 : fn.apply(void 0, args);
|
|
241
204
|
}, []);
|
|
242
205
|
}
|
|
@@ -247,13 +210,39 @@ var useSheetContext = function useSheetContext() {
|
|
|
247
210
|
if (!context) throw Error('Sheet context error');
|
|
248
211
|
return context;
|
|
249
212
|
};
|
|
213
|
+
var SheetScrollerContext = /*#__PURE__*/createContext(undefined);
|
|
214
|
+
function SheetScrollerContextProvider(_ref) {
|
|
215
|
+
var children = _ref.children;
|
|
216
|
+
var sheetContext = useSheetContext();
|
|
217
|
+
var _React$useState = useState(!!sheetContext.disableDrag),
|
|
218
|
+
disableDrag = _React$useState[0],
|
|
219
|
+
setDisableDrag = _React$useState[1];
|
|
220
|
+
function setDragEnabled() {
|
|
221
|
+
if (!sheetContext.disableDrag) setDisableDrag(false);
|
|
222
|
+
}
|
|
223
|
+
function setDragDisabled() {
|
|
224
|
+
if (!disableDrag) setDisableDrag(true);
|
|
225
|
+
}
|
|
226
|
+
return createElement(SheetScrollerContext.Provider, {
|
|
227
|
+
value: {
|
|
228
|
+
disableDrag: disableDrag,
|
|
229
|
+
setDragEnabled: setDragEnabled,
|
|
230
|
+
setDragDisabled: setDragDisabled
|
|
231
|
+
}
|
|
232
|
+
}, children);
|
|
233
|
+
}
|
|
234
|
+
var useSheetScrollerContext = function useSheetScrollerContext() {
|
|
235
|
+
var context = useContext(SheetScrollerContext);
|
|
236
|
+
if (!context) throw Error('Sheet scroller context error');
|
|
237
|
+
return context;
|
|
238
|
+
};
|
|
250
239
|
|
|
251
240
|
// Source: https://github.com/adobe/react-spectrum/blob/main/packages/@react-aria/overlays/src/usePreventScroll.ts
|
|
252
|
-
|
|
253
|
-
var visualViewport = typeof window !== 'undefined' && window.visualViewport;
|
|
254
|
-
|
|
255
|
-
var nonTextInputTypes = /*#__PURE__*/new Set(['checkbox', 'radio', 'range', 'color', 'file', 'image', 'button', 'submit', 'reset']);
|
|
256
|
-
|
|
241
|
+
// @ts-ignore
|
|
242
|
+
var visualViewport = typeof window !== 'undefined' && window.visualViewport;
|
|
243
|
+
// HTML input types that do not cause the software keyboard to appear.
|
|
244
|
+
var nonTextInputTypes = /*#__PURE__*/new Set(['checkbox', 'radio', 'range', 'color', 'file', 'image', 'button', 'submit', 'reset']);
|
|
245
|
+
// The number of active usePreventScroll calls. Used to determine whether to revert back to the original page style/scroll position
|
|
257
246
|
var preventScrollCount = 0;
|
|
258
247
|
var restore;
|
|
259
248
|
/**
|
|
@@ -261,21 +250,17 @@ var restore;
|
|
|
261
250
|
* restores it on unmount. Also ensures that content does not
|
|
262
251
|
* shift due to the scrollbars disappearing.
|
|
263
252
|
*/
|
|
264
|
-
|
|
265
253
|
function usePreventScroll(options) {
|
|
266
254
|
if (options === void 0) {
|
|
267
255
|
options = {};
|
|
268
256
|
}
|
|
269
|
-
|
|
270
257
|
var _options = options,
|
|
271
|
-
|
|
258
|
+
isDisabled = _options.isDisabled;
|
|
272
259
|
useLayoutEffect$1(function () {
|
|
273
260
|
if (isDisabled) {
|
|
274
261
|
return;
|
|
275
262
|
}
|
|
276
|
-
|
|
277
263
|
preventScrollCount++;
|
|
278
|
-
|
|
279
264
|
if (preventScrollCount === 1) {
|
|
280
265
|
if (isIOS()) {
|
|
281
266
|
restore = preventScrollMobileSafari();
|
|
@@ -283,21 +268,20 @@ function usePreventScroll(options) {
|
|
|
283
268
|
restore = preventScrollStandard();
|
|
284
269
|
}
|
|
285
270
|
}
|
|
286
|
-
|
|
287
271
|
return function () {
|
|
288
272
|
preventScrollCount--;
|
|
289
|
-
|
|
290
273
|
if (preventScrollCount === 0) {
|
|
291
274
|
restore();
|
|
292
275
|
}
|
|
293
276
|
};
|
|
294
277
|
}, [isDisabled]);
|
|
295
|
-
}
|
|
278
|
+
}
|
|
279
|
+
// For most browsers, all we need to do is set `overflow: hidden` on the root element, and
|
|
296
280
|
// add some padding to prevent the page from shifting when the scrollbar is hidden.
|
|
297
|
-
|
|
298
281
|
function preventScrollStandard() {
|
|
299
282
|
return chain(setStyle(document.documentElement, 'paddingRight', window.innerWidth - document.documentElement.clientWidth + "px"), setStyle(document.documentElement, 'overflow', 'hidden'));
|
|
300
|
-
}
|
|
283
|
+
}
|
|
284
|
+
// Mobile Safari is a whole different beast. Even with overflow: hidden,
|
|
301
285
|
// it still scrolls the page in many situations:
|
|
302
286
|
//
|
|
303
287
|
// 1. When the bottom toolbar and address bar are collapsed, page scrolling is always allowed.
|
|
@@ -323,57 +307,47 @@ function preventScrollStandard() {
|
|
|
323
307
|
// above work or Safari will still try to scroll the page when focusing an input.
|
|
324
308
|
// 6. As a last resort, handle window scroll events, and scroll back to the top. This can happen when attempting
|
|
325
309
|
// to navigate to an input with the next/previous buttons that's outside a modal.
|
|
326
|
-
|
|
327
|
-
|
|
328
310
|
function preventScrollMobileSafari() {
|
|
329
311
|
var scrollable;
|
|
330
312
|
var lastY = 0;
|
|
331
|
-
|
|
332
313
|
var onTouchStart = function onTouchStart(e) {
|
|
333
314
|
// Store the nearest scrollable parent element from the element that the user touched.
|
|
334
315
|
scrollable = getScrollParent(e.target);
|
|
335
|
-
|
|
336
316
|
if (scrollable === document.documentElement && scrollable === document.body) {
|
|
337
317
|
return;
|
|
338
318
|
}
|
|
339
|
-
|
|
340
319
|
lastY = e.changedTouches[0].pageY;
|
|
341
320
|
};
|
|
342
|
-
|
|
343
321
|
var onTouchMove = function onTouchMove(e) {
|
|
344
322
|
// Prevent scrolling the window.
|
|
345
323
|
if (scrollable === document.documentElement || scrollable === document.body) {
|
|
346
324
|
e.preventDefault();
|
|
347
325
|
return;
|
|
348
|
-
}
|
|
326
|
+
}
|
|
327
|
+
// Prevent scrolling up when at the top and scrolling down when at the bottom
|
|
349
328
|
// of a nested scrollable area, otherwise mobile Safari will start scrolling
|
|
350
329
|
// the window instead. Unfortunately, this disables bounce scrolling when at
|
|
351
330
|
// the top but it's the best we can do.
|
|
352
|
-
|
|
353
|
-
|
|
354
331
|
var y = e.changedTouches[0].pageY;
|
|
355
332
|
var scrollTop = scrollable.scrollTop;
|
|
356
|
-
var bottom = scrollable.scrollHeight - scrollable.clientHeight;
|
|
357
|
-
|
|
333
|
+
var bottom = scrollable.scrollHeight - scrollable.clientHeight;
|
|
334
|
+
// Fix for: https://github.com/adobe/react-spectrum/pull/3780/files
|
|
358
335
|
if (bottom === 0) {
|
|
359
336
|
return;
|
|
360
337
|
}
|
|
361
|
-
|
|
362
338
|
if (scrollTop <= 0 && y > lastY || scrollTop >= bottom && y < lastY) {
|
|
363
339
|
e.preventDefault();
|
|
364
340
|
}
|
|
365
|
-
|
|
366
341
|
lastY = y;
|
|
367
342
|
};
|
|
368
|
-
|
|
369
343
|
var onTouchEnd = function onTouchEnd(e) {
|
|
370
|
-
var target = e.target;
|
|
371
|
-
|
|
344
|
+
var target = e.target;
|
|
345
|
+
// Apply this change if we're not already focused on the target element
|
|
372
346
|
if (willOpenKeyboard(target) && target !== document.activeElement) {
|
|
373
|
-
e.preventDefault();
|
|
347
|
+
e.preventDefault();
|
|
348
|
+
// Apply a transform to trick Safari into thinking the input is at the top of the page
|
|
374
349
|
// so it doesn't try to scroll it into view. When tapping on an input, this needs to
|
|
375
350
|
// be done before the "focus" event, so we have to focus the element ourselves.
|
|
376
|
-
|
|
377
351
|
target.style.transform = 'translateY(-2000px)';
|
|
378
352
|
target.focus();
|
|
379
353
|
requestAnimationFrame(function () {
|
|
@@ -381,10 +355,8 @@ function preventScrollMobileSafari() {
|
|
|
381
355
|
});
|
|
382
356
|
}
|
|
383
357
|
};
|
|
384
|
-
|
|
385
358
|
var onFocus = function onFocus(e) {
|
|
386
359
|
var target = e.target;
|
|
387
|
-
|
|
388
360
|
if (willOpenKeyboard(target)) {
|
|
389
361
|
// Transform also needs to be applied in the focus event in cases where focus moves
|
|
390
362
|
// other than tapping on an input directly, e.g. the next/previous buttons in the
|
|
@@ -392,9 +364,9 @@ function preventScrollMobileSafari() {
|
|
|
392
364
|
// is good enough, whereas when tapping an input, it must be done before the focus event. 🤷♂️
|
|
393
365
|
target.style.transform = 'translateY(-2000px)';
|
|
394
366
|
requestAnimationFrame(function () {
|
|
395
|
-
target.style.transform = '';
|
|
367
|
+
target.style.transform = '';
|
|
368
|
+
// This will have prevented the browser from scrolling the focused element into view,
|
|
396
369
|
// so we need to do this ourselves in a way that doesn't cause the whole page to scroll.
|
|
397
|
-
|
|
398
370
|
if (visualViewport) {
|
|
399
371
|
if (visualViewport.height < window.innerHeight) {
|
|
400
372
|
// If the keyboard is already visible, do this after one additional frame
|
|
@@ -415,20 +387,18 @@ function preventScrollMobileSafari() {
|
|
|
415
387
|
});
|
|
416
388
|
}
|
|
417
389
|
};
|
|
418
|
-
|
|
419
390
|
var onWindowScroll = function onWindowScroll() {
|
|
420
391
|
// Last resort. If the window scrolled, scroll it back to the top.
|
|
421
392
|
// It should always be at the top because the body will have a negative margin (see below).
|
|
422
393
|
window.scrollTo(0, 0);
|
|
423
|
-
};
|
|
394
|
+
};
|
|
395
|
+
// Record the original scroll position so we can restore it.
|
|
424
396
|
// Then apply a negative margin to the body to offset it by the scroll position. This will
|
|
425
397
|
// enable us to scroll the window to the top, which is required for the rest of this to work.
|
|
426
|
-
|
|
427
|
-
|
|
428
398
|
var scrollX = window.pageXOffset;
|
|
429
399
|
var scrollY = window.pageYOffset;
|
|
430
|
-
var restoreStyles = chain(setStyle(document.documentElement, 'paddingRight', window.innerWidth - document.documentElement.clientWidth + "px"), setStyle(document.documentElement, 'overflow', 'hidden'), setStyle(document.body, 'marginTop', "-" + scrollY + "px"));
|
|
431
|
-
|
|
400
|
+
var restoreStyles = chain(setStyle(document.documentElement, 'paddingRight', window.innerWidth - document.documentElement.clientWidth + "px"), setStyle(document.documentElement, 'overflow', 'hidden'), setStyle(document.body, 'marginTop', "-" + scrollY + "px"));
|
|
401
|
+
// Scroll to the top. The negative margin on the body will make this appear the same.
|
|
432
402
|
window.scrollTo(0, 0);
|
|
433
403
|
var removeEvents = chain(addEvent(document, 'touchstart', onTouchStart, {
|
|
434
404
|
passive: false,
|
|
@@ -446,45 +416,37 @@ function preventScrollMobileSafari() {
|
|
|
446
416
|
removeEvents();
|
|
447
417
|
window.scrollTo(scrollX, scrollY);
|
|
448
418
|
};
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
419
|
+
}
|
|
420
|
+
// Sets a CSS property on an element, and returns a function to revert it to the previous value.
|
|
452
421
|
function setStyle(element, style, value) {
|
|
453
422
|
var cur = element.style[style];
|
|
454
423
|
element.style[style] = value;
|
|
455
424
|
return function () {
|
|
456
425
|
element.style[style] = cur;
|
|
457
426
|
};
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
|
|
427
|
+
}
|
|
428
|
+
// Adds an event listener to an element, and returns a function to remove it.
|
|
461
429
|
function addEvent(target, event, handler, options) {
|
|
462
430
|
target.addEventListener(event, handler, options);
|
|
463
431
|
return function () {
|
|
464
432
|
target.removeEventListener(event, handler, options);
|
|
465
433
|
};
|
|
466
434
|
}
|
|
467
|
-
|
|
468
435
|
function scrollIntoView(target) {
|
|
469
436
|
var root = document.scrollingElement || document.documentElement;
|
|
470
|
-
|
|
471
437
|
while (target && target !== root) {
|
|
472
438
|
// Find the parent scrollable element and adjust the scroll position if the target is not already in view.
|
|
473
439
|
var scrollable = getScrollParent(target);
|
|
474
|
-
|
|
475
440
|
if (scrollable !== document.documentElement && scrollable !== document.body && scrollable !== target) {
|
|
476
441
|
var scrollableTop = scrollable.getBoundingClientRect().top;
|
|
477
442
|
var targetTop = target.getBoundingClientRect().top;
|
|
478
|
-
|
|
479
443
|
if (targetTop > scrollableTop + target.clientHeight) {
|
|
480
444
|
scrollable.scrollTop += targetTop - scrollableTop;
|
|
481
445
|
}
|
|
482
446
|
}
|
|
483
|
-
|
|
484
447
|
target = scrollable.parentElement;
|
|
485
448
|
}
|
|
486
449
|
}
|
|
487
|
-
|
|
488
450
|
function willOpenKeyboard(target) {
|
|
489
451
|
return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
490
452
|
}
|
|
@@ -506,7 +468,7 @@ var styles = {
|
|
|
506
468
|
left: 0,
|
|
507
469
|
width: '100%',
|
|
508
470
|
height: '100%',
|
|
509
|
-
backgroundColor: 'rgba(
|
|
471
|
+
backgroundColor: 'rgba(0, 0, 0, 0.2)',
|
|
510
472
|
touchAction: 'none',
|
|
511
473
|
border: 'none'
|
|
512
474
|
},
|
|
@@ -542,60 +504,65 @@ var styles = {
|
|
|
542
504
|
backgroundColor: '#ddd'
|
|
543
505
|
},
|
|
544
506
|
content: {
|
|
545
|
-
|
|
546
|
-
|
|
507
|
+
flexGrow: 1,
|
|
508
|
+
display: 'flex',
|
|
509
|
+
flexDirection: 'column',
|
|
510
|
+
minHeight: '0px',
|
|
547
511
|
position: 'relative'
|
|
512
|
+
},
|
|
513
|
+
scroller: {
|
|
514
|
+
height: '100%',
|
|
515
|
+
overflowY: 'auto'
|
|
548
516
|
}
|
|
549
517
|
};
|
|
550
518
|
|
|
519
|
+
var _excluded = ["onOpenStart", "onOpenEnd", "onClose", "onCloseStart", "onCloseEnd", "onSnap", "children", "disableScrollLocking", "isOpen", "snapPoints", "rootId", "mountPoint", "style", "detent", "initialSnap", "disableDrag", "prefersReducedMotion", "tweenConfig"];
|
|
551
520
|
var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
552
521
|
var onOpenStart = _ref.onOpenStart,
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
522
|
+
onOpenEnd = _ref.onOpenEnd,
|
|
523
|
+
onClose = _ref.onClose,
|
|
524
|
+
onCloseStart = _ref.onCloseStart,
|
|
525
|
+
onCloseEnd = _ref.onCloseEnd,
|
|
526
|
+
onSnap = _ref.onSnap,
|
|
527
|
+
children = _ref.children,
|
|
528
|
+
_ref$disableScrollLoc = _ref.disableScrollLocking,
|
|
529
|
+
disableScrollLocking = _ref$disableScrollLoc === void 0 ? false : _ref$disableScrollLoc,
|
|
530
|
+
isOpen = _ref.isOpen,
|
|
531
|
+
snapPoints = _ref.snapPoints,
|
|
532
|
+
rootId = _ref.rootId,
|
|
533
|
+
mountPoint = _ref.mountPoint,
|
|
534
|
+
style = _ref.style,
|
|
535
|
+
_ref$detent = _ref.detent,
|
|
536
|
+
detent = _ref$detent === void 0 ? 'full-height' : _ref$detent,
|
|
537
|
+
_ref$initialSnap = _ref.initialSnap,
|
|
538
|
+
initialSnap = _ref$initialSnap === void 0 ? 0 : _ref$initialSnap,
|
|
539
|
+
_ref$disableDrag = _ref.disableDrag,
|
|
540
|
+
disableDrag = _ref$disableDrag === void 0 ? false : _ref$disableDrag,
|
|
541
|
+
_ref$prefersReducedMo = _ref.prefersReducedMotion,
|
|
542
|
+
prefersReducedMotion = _ref$prefersReducedMo === void 0 ? false : _ref$prefersReducedMo,
|
|
543
|
+
_ref$tweenConfig = _ref.tweenConfig,
|
|
544
|
+
tweenConfig = _ref$tweenConfig === void 0 ? DEFAULT_TWEEN_CONFIG : _ref$tweenConfig,
|
|
545
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
576
546
|
var sheetRef = useRef(null);
|
|
577
547
|
var indicatorRotation = useMotionValue(0);
|
|
578
548
|
var windowHeight = useWindowHeight();
|
|
579
549
|
var shouldReduceMotion = useReducedMotion();
|
|
580
550
|
var reduceMotion = Boolean(prefersReducedMotion || shouldReduceMotion);
|
|
581
|
-
var animationOptions =
|
|
582
|
-
type: 'tween'
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
type: 'spring'
|
|
586
|
-
}, springConfig); // NOTE: the inital value for `y` doesn't matter since it is overwritten by
|
|
551
|
+
var animationOptions = _extends({
|
|
552
|
+
type: 'tween'
|
|
553
|
+
}, reduceMotion ? REDUCED_MOTION_TWEEN_CONFIG : tweenConfig);
|
|
554
|
+
// NOTE: the inital value for `y` doesn't matter since it is overwritten by
|
|
587
555
|
// the value driven by the `AnimatePresence` component when the sheet is opened
|
|
588
556
|
// and after that it is driven by the gestures and/or snapping
|
|
589
|
-
|
|
590
557
|
var y = useMotionValue(0);
|
|
591
558
|
var zIndex = useTransform(y, function (value) {
|
|
592
559
|
return value >= windowHeight ? -1 : 9999999;
|
|
593
560
|
});
|
|
594
561
|
var visibility = useTransform(y, function (value) {
|
|
595
562
|
return value >= windowHeight ? 'hidden' : 'visible';
|
|
596
|
-
});
|
|
563
|
+
});
|
|
564
|
+
// Keep the callback fns up-to-date so that they can be accessed inside
|
|
597
565
|
// the effect without including them to the dependencies array
|
|
598
|
-
|
|
599
566
|
var callbacks = useRef({
|
|
600
567
|
onOpenStart: onOpenStart,
|
|
601
568
|
onOpenEnd: onOpenEnd,
|
|
@@ -610,7 +577,6 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
610
577
|
onCloseEnd: onCloseEnd
|
|
611
578
|
};
|
|
612
579
|
});
|
|
613
|
-
|
|
614
580
|
if (snapPoints) {
|
|
615
581
|
// Convert negative / percentage snap points to absolute values
|
|
616
582
|
snapPoints = snapPoints.map(function (point) {
|
|
@@ -618,21 +584,20 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
618
584
|
if (point > 0 && point <= 1) return Math.round(point * windowHeight);
|
|
619
585
|
return point < 0 ? windowHeight + point : point; // negative values
|
|
620
586
|
});
|
|
587
|
+
|
|
621
588
|
console.assert(inDescendingOrder(snapPoints) || windowHeight === 0, "Snap points need to be in descending order got: [" + snapPoints + "]");
|
|
622
589
|
}
|
|
623
|
-
|
|
624
590
|
var onDrag = useEvent(function (_, _ref2) {
|
|
625
591
|
var delta = _ref2.delta;
|
|
626
592
|
// Update drag indicator rotation based on drag velocity
|
|
627
593
|
var velocity = y.getVelocity();
|
|
628
594
|
if (velocity > 0) indicatorRotation.set(10);
|
|
629
|
-
if (velocity < 0) indicatorRotation.set(-10);
|
|
630
|
-
|
|
595
|
+
if (velocity < 0) indicatorRotation.set(-10);
|
|
596
|
+
// Make sure user cannot drag beyond the top of the sheet
|
|
631
597
|
y.set(Math.max(y.get() + delta.y, 0));
|
|
632
598
|
});
|
|
633
599
|
var onDragEnd = useEvent(function (_, _ref3) {
|
|
634
600
|
var velocity = _ref3.velocity;
|
|
635
|
-
|
|
636
601
|
if (velocity.y > DRAG_VELOCITY_THRESHOLD) {
|
|
637
602
|
// User flicked the sheet down
|
|
638
603
|
onClose();
|
|
@@ -641,58 +606,49 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
641
606
|
var sheetHeight = sheetEl.getBoundingClientRect().height;
|
|
642
607
|
var currentY = y.get();
|
|
643
608
|
var snapTo = 0;
|
|
644
|
-
|
|
645
609
|
if (snapPoints) {
|
|
646
610
|
var snapToValues = snapPoints.map(function (p) {
|
|
647
611
|
return sheetHeight - Math.min(p, sheetHeight);
|
|
648
|
-
});
|
|
649
|
-
|
|
612
|
+
});
|
|
613
|
+
// Allow snapping to the top of the sheet if detent is set to `content-height`
|
|
650
614
|
if (detent === 'content-height' && !snapToValues.includes(0)) {
|
|
651
615
|
snapToValues.unshift(0);
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
|
|
616
|
+
}
|
|
617
|
+
// Get the closest snap point
|
|
655
618
|
snapTo = getClosest(snapToValues, currentY);
|
|
656
619
|
} else if (currentY / sheetHeight > DRAG_CLOSE_THRESHOLD) {
|
|
657
620
|
// Close if dragged over enough far
|
|
658
621
|
snapTo = sheetHeight;
|
|
659
622
|
}
|
|
660
|
-
|
|
661
623
|
snapTo = validateSnapTo({
|
|
662
624
|
snapTo: snapTo,
|
|
663
625
|
sheetHeight: sheetHeight
|
|
664
|
-
});
|
|
665
|
-
|
|
626
|
+
});
|
|
627
|
+
// Update the spring value so that the sheet is animated to the snap point
|
|
666
628
|
animate(y, snapTo, animationOptions);
|
|
667
|
-
|
|
668
629
|
if (snapPoints && onSnap) {
|
|
669
630
|
var snapValue = Math.abs(Math.round(snapPoints[0] - snapTo));
|
|
670
631
|
var snapIndex = snapPoints.indexOf(getClosest(snapPoints, snapValue)); // prettier-ignore
|
|
671
|
-
|
|
672
632
|
onSnap(snapIndex);
|
|
673
633
|
}
|
|
674
|
-
|
|
675
634
|
var roundedSheetHeight = Math.round(sheetHeight);
|
|
676
635
|
var shouldClose = snapTo >= roundedSheetHeight;
|
|
677
636
|
if (shouldClose) onClose();
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
|
|
637
|
+
}
|
|
638
|
+
// Reset indicator rotation after dragging
|
|
681
639
|
indicatorRotation.set(0);
|
|
682
|
-
});
|
|
683
|
-
|
|
640
|
+
});
|
|
641
|
+
// Trigger onSnap callback when sheet is opened or closed
|
|
684
642
|
useEffect(function () {
|
|
685
643
|
if (!snapPoints || !onSnap) return;
|
|
686
644
|
var snapIndex = isOpen ? initialSnap : snapPoints.length - 1;
|
|
687
645
|
onSnap(snapIndex);
|
|
688
646
|
}, [isOpen]); // eslint-disable-line
|
|
689
|
-
|
|
690
647
|
useImperativeHandle(ref, function () {
|
|
691
648
|
return {
|
|
692
649
|
y: y,
|
|
693
650
|
snapTo: function snapTo(snapIndex) {
|
|
694
651
|
var sheetEl = sheetRef.current;
|
|
695
|
-
|
|
696
652
|
if (snapPoints && snapPoints[snapIndex] !== undefined && sheetEl !== null) {
|
|
697
653
|
var sheetHeight = sheetEl.getBoundingClientRect().height;
|
|
698
654
|
var snapPoint = snapPoints[snapIndex];
|
|
@@ -707,11 +663,11 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
707
663
|
}
|
|
708
664
|
};
|
|
709
665
|
});
|
|
710
|
-
useModalEffect(isOpen, rootId);
|
|
666
|
+
useModalEffect(isOpen, rootId);
|
|
667
|
+
// Framer Motion should handle body scroll locking but it's not working
|
|
711
668
|
// properly on iOS. Scroll locking from React Aria seems to work much better.
|
|
712
|
-
|
|
713
669
|
usePreventScroll({
|
|
714
|
-
isDisabled: !isOpen
|
|
670
|
+
isDisabled: disableScrollLocking === true || !isOpen
|
|
715
671
|
});
|
|
716
672
|
var dragProps = useMemo(function () {
|
|
717
673
|
var dragProps = {
|
|
@@ -728,7 +684,6 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
728
684
|
};
|
|
729
685
|
return disableDrag ? undefined : dragProps;
|
|
730
686
|
}, [disableDrag]); // eslint-disable-line
|
|
731
|
-
|
|
732
687
|
var context = {
|
|
733
688
|
y: y,
|
|
734
689
|
sheetRef: sheetRef,
|
|
@@ -741,7 +696,8 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
741
696
|
dragProps: dragProps,
|
|
742
697
|
windowHeight: windowHeight,
|
|
743
698
|
animationOptions: animationOptions,
|
|
744
|
-
reduceMotion: reduceMotion
|
|
699
|
+
reduceMotion: reduceMotion,
|
|
700
|
+
disableDrag: disableDrag
|
|
745
701
|
};
|
|
746
702
|
var sheet = createElement(SheetContext.Provider, {
|
|
747
703
|
value: context
|
|
@@ -751,39 +707,37 @@ var Sheet = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
751
707
|
zIndex: zIndex,
|
|
752
708
|
visibility: visibility
|
|
753
709
|
}, style)
|
|
754
|
-
}), createElement(AnimatePresence, null, isOpen ? Children.map(children, function (child, i) {
|
|
710
|
+
}), createElement(AnimatePresence, null, isOpen ? createElement(SheetScrollerContextProvider, null, Children.map(children, function (child, i) {
|
|
755
711
|
return cloneElement(child, {
|
|
756
712
|
key: "sheet-child-" + i
|
|
757
713
|
});
|
|
758
|
-
}) : null)));
|
|
714
|
+
})) : null)));
|
|
759
715
|
if (IS_SSR) return sheet;
|
|
760
716
|
return createPortal(sheet, mountPoint != null ? mountPoint : document.body);
|
|
761
717
|
});
|
|
762
718
|
|
|
719
|
+
var _excluded$1 = ["children", "style", "className"];
|
|
763
720
|
var SheetContainer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
764
721
|
var children = _ref.children,
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
722
|
+
_ref$style = _ref.style,
|
|
723
|
+
style = _ref$style === void 0 ? {} : _ref$style,
|
|
724
|
+
_ref$className = _ref.className,
|
|
725
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
726
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$1);
|
|
771
727
|
var _useSheetContext = useSheetContext(),
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
728
|
+
y = _useSheetContext.y,
|
|
729
|
+
isOpen = _useSheetContext.isOpen,
|
|
730
|
+
callbacks = _useSheetContext.callbacks,
|
|
731
|
+
snapPoints = _useSheetContext.snapPoints,
|
|
732
|
+
_useSheetContext$init = _useSheetContext.initialSnap,
|
|
733
|
+
initialSnap = _useSheetContext$init === void 0 ? 0 : _useSheetContext$init,
|
|
734
|
+
sheetRef = _useSheetContext.sheetRef,
|
|
735
|
+
windowHeight = _useSheetContext.windowHeight,
|
|
736
|
+
detent = _useSheetContext.detent,
|
|
737
|
+
animationOptions = _useSheetContext.animationOptions,
|
|
738
|
+
reduceMotion = _useSheetContext.reduceMotion;
|
|
784
739
|
var _useEventCallbacks = useEventCallbacks(isOpen, callbacks),
|
|
785
|
-
|
|
786
|
-
|
|
740
|
+
handleAnimationComplete = _useEventCallbacks.handleAnimationComplete;
|
|
787
741
|
var initialY = snapPoints ? snapPoints[0] - snapPoints[initialSnap] : 0;
|
|
788
742
|
var maxSnapHeight = snapPoints ? snapPoints[0] : null;
|
|
789
743
|
var height = maxSnapHeight !== null ? "min(" + maxSnapHeight + "px, " + MAX_HEIGHT + ")" : MAX_HEIGHT;
|
|
@@ -812,38 +766,34 @@ var SheetContainer = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
812
766
|
}), children);
|
|
813
767
|
});
|
|
814
768
|
|
|
769
|
+
var _excluded$2 = ["children", "style", "disableDrag", "className"];
|
|
815
770
|
var SheetContent = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
816
771
|
var children = _ref.children,
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
var
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
var _dragProps = disableDrag ? undefined : dragProps;
|
|
827
|
-
|
|
772
|
+
style = _ref.style,
|
|
773
|
+
disableDrag = _ref.disableDrag,
|
|
774
|
+
_ref$className = _ref.className,
|
|
775
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
776
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$2);
|
|
777
|
+
var sheetContext = useSheetContext();
|
|
778
|
+
var sheetScrollerContext = useSheetScrollerContext();
|
|
779
|
+
var dragProps = disableDrag || sheetScrollerContext.disableDrag ? undefined : sheetContext.dragProps;
|
|
828
780
|
return createElement(motion.div, Object.assign({}, rest, {
|
|
829
781
|
ref: ref,
|
|
830
782
|
className: "react-modal-sheet-content " + className,
|
|
831
783
|
style: _extends({}, styles.content, style)
|
|
832
|
-
},
|
|
784
|
+
}, dragProps), children);
|
|
833
785
|
});
|
|
834
786
|
|
|
787
|
+
var _excluded$3 = ["children", "style", "disableDrag"];
|
|
835
788
|
var SheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
836
789
|
var children = _ref.children,
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
790
|
+
style = _ref.style,
|
|
791
|
+
disableDrag = _ref.disableDrag,
|
|
792
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$3);
|
|
841
793
|
var _useSheetContext = useSheetContext(),
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
794
|
+
indicatorRotation = _useSheetContext.indicatorRotation,
|
|
795
|
+
dragProps = _useSheetContext.dragProps;
|
|
845
796
|
var _dragProps = disableDrag ? undefined : dragProps;
|
|
846
|
-
|
|
847
797
|
var indicator1Transform = useTransform(indicatorRotation, function (r) {
|
|
848
798
|
return "translateX(2px) rotate(" + r + "deg)";
|
|
849
799
|
});
|
|
@@ -869,17 +819,16 @@ var SheetHeader = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
869
819
|
})));
|
|
870
820
|
});
|
|
871
821
|
|
|
822
|
+
var _excluded$4 = ["style", "className"];
|
|
872
823
|
var isClickable = function isClickable(props) {
|
|
873
824
|
return !!props.onClick || !!props.onTap;
|
|
874
825
|
};
|
|
875
|
-
|
|
876
826
|
var SheetBackdrop = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
877
827
|
var _ref$style = _ref.style,
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
828
|
+
style = _ref$style === void 0 ? {} : _ref$style,
|
|
829
|
+
_ref$className = _ref.className,
|
|
830
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
831
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$4);
|
|
883
832
|
var Comp = isClickable(rest) ? motion.button : motion.div;
|
|
884
833
|
var pointerEvents = isClickable(rest) ? 'auto' : 'none';
|
|
885
834
|
return createElement(Comp, Object.assign({}, rest, {
|
|
@@ -900,11 +849,55 @@ var SheetBackdrop = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
900
849
|
}));
|
|
901
850
|
});
|
|
902
851
|
|
|
852
|
+
var _excluded$5 = ["draggableAt", "children", "style", "className"];
|
|
853
|
+
var SheetScroller = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
854
|
+
var _ref$draggableAt = _ref.draggableAt,
|
|
855
|
+
draggableAt = _ref$draggableAt === void 0 ? 'top' : _ref$draggableAt,
|
|
856
|
+
children = _ref.children,
|
|
857
|
+
style = _ref.style,
|
|
858
|
+
_ref$className = _ref.className,
|
|
859
|
+
className = _ref$className === void 0 ? '' : _ref$className,
|
|
860
|
+
rest = _objectWithoutPropertiesLoose(_ref, _excluded$5);
|
|
861
|
+
var sheetScrollerContext = useSheetScrollerContext();
|
|
862
|
+
function determineDragState(element) {
|
|
863
|
+
var scrollTop = element.scrollTop,
|
|
864
|
+
scrollHeight = element.scrollHeight,
|
|
865
|
+
clientHeight = element.clientHeight;
|
|
866
|
+
var isScrollable = scrollHeight > clientHeight;
|
|
867
|
+
if (!isScrollable) return;
|
|
868
|
+
var isAtTop = scrollTop <= 0;
|
|
869
|
+
var isAtBottom = scrollHeight - scrollTop === clientHeight;
|
|
870
|
+
var shouldEnable = draggableAt === 'top' && isAtTop || draggableAt === 'bottom' && isAtBottom || draggableAt === 'both' && (isAtTop || isAtBottom);
|
|
871
|
+
if (shouldEnable) {
|
|
872
|
+
sheetScrollerContext.setDragEnabled();
|
|
873
|
+
} else {
|
|
874
|
+
sheetScrollerContext.setDragDisabled();
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function onScroll(e) {
|
|
878
|
+
determineDragState(e.currentTarget);
|
|
879
|
+
}
|
|
880
|
+
function onTouchStart(e) {
|
|
881
|
+
determineDragState(e.currentTarget);
|
|
882
|
+
}
|
|
883
|
+
var scrollProps = isTouchDevice() ? {
|
|
884
|
+
onScroll: onScroll,
|
|
885
|
+
onTouchStart: onTouchStart
|
|
886
|
+
} : undefined;
|
|
887
|
+
return createElement("div", Object.assign({}, rest, {
|
|
888
|
+
ref: ref,
|
|
889
|
+
className: "react-modal-sheet-scroller " + className,
|
|
890
|
+
style: _extends({}, styles.scroller, style)
|
|
891
|
+
}, scrollProps), children);
|
|
892
|
+
});
|
|
893
|
+
|
|
894
|
+
// HACK: this is needed to get the typing to work properly...
|
|
903
895
|
var _SheetCompound = Sheet;
|
|
904
896
|
_SheetCompound.Container = SheetContainer;
|
|
905
897
|
_SheetCompound.Header = SheetHeader;
|
|
906
898
|
_SheetCompound.Content = SheetContent;
|
|
907
899
|
_SheetCompound.Backdrop = SheetBackdrop;
|
|
900
|
+
_SheetCompound.Scroller = SheetScroller;
|
|
908
901
|
|
|
909
902
|
export default _SheetCompound;
|
|
910
903
|
//# sourceMappingURL=react-modal-sheet.esm.js.map
|