base-vaul 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +322 -355
- package/dist/index.mjs +259 -265
- package/package.json +27 -22
- package/style.css +254 -0
package/dist/index.mjs
CHANGED
|
@@ -8,10 +8,12 @@ function __insertCSS(code) {
|
|
|
8
8
|
;style.styleSheet ? (style.styleSheet.cssText = code) : style.appendChild(document.createTextNode(code))
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
import { jsx } from 'react/jsx-runtime';
|
|
11
12
|
import { Dialog } from '@base-ui/react';
|
|
12
13
|
import * as React from 'react';
|
|
13
14
|
import React__default, { useLayoutEffect, useEffect, useMemo } from 'react';
|
|
14
15
|
|
|
16
|
+
// @ts-nocheck [FIXME] See after monorepo migration
|
|
15
17
|
const DrawerContext = React__default.createContext({
|
|
16
18
|
drawerRef: {
|
|
17
19
|
current: null
|
|
@@ -41,7 +43,7 @@ const DrawerContext = React__default.createContext({
|
|
|
41
43
|
onOpenChange: ()=>{},
|
|
42
44
|
setActiveSnapPoint: ()=>{},
|
|
43
45
|
closeDrawer: ()=>{},
|
|
44
|
-
direction:
|
|
46
|
+
direction: "bottom",
|
|
45
47
|
shouldAnimate: {
|
|
46
48
|
current: true
|
|
47
49
|
},
|
|
@@ -54,7 +56,7 @@ const DrawerContext = React__default.createContext({
|
|
|
54
56
|
const useDrawerContext = ()=>{
|
|
55
57
|
const context = React__default.useContext(DrawerContext);
|
|
56
58
|
if (!context) {
|
|
57
|
-
throw new Error(
|
|
59
|
+
throw new Error("useDrawerContext must be used within a Drawer.Root");
|
|
58
60
|
}
|
|
59
61
|
return context;
|
|
60
62
|
};
|
|
@@ -87,22 +89,23 @@ function testPlatform(re) {
|
|
|
87
89
|
return typeof window !== 'undefined' && window.navigator != null ? re.test(window.navigator.platform) : undefined;
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
// @ts-nocheck [FIXME] See after monorepo migration
|
|
90
93
|
// This code comes from https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/overlays/src/usePreventScroll.ts
|
|
91
94
|
const KEYBOARD_BUFFER = 24;
|
|
92
|
-
const useIsomorphicLayoutEffect = typeof window !==
|
|
95
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
93
96
|
function chain$1(...callbacks) {
|
|
94
97
|
return (...args)=>{
|
|
95
|
-
for (
|
|
96
|
-
if (typeof callback ===
|
|
98
|
+
for (const callback of callbacks){
|
|
99
|
+
if (typeof callback === "function") {
|
|
97
100
|
callback(...args);
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
103
|
};
|
|
101
104
|
}
|
|
102
105
|
// @ts-ignore
|
|
103
|
-
const visualViewport = typeof document !==
|
|
106
|
+
const visualViewport = typeof document !== "undefined" && window.visualViewport;
|
|
104
107
|
function isScrollable(node) {
|
|
105
|
-
|
|
108
|
+
const style = window.getComputedStyle(node);
|
|
106
109
|
return /(auto|scroll)/.test(style.overflow + style.overflowX + style.overflowY);
|
|
107
110
|
}
|
|
108
111
|
function getScrollParent(node) {
|
|
@@ -116,15 +119,15 @@ function getScrollParent(node) {
|
|
|
116
119
|
}
|
|
117
120
|
// HTML input types that do not cause the software keyboard to appear.
|
|
118
121
|
const nonTextInputTypes = new Set([
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
"checkbox",
|
|
123
|
+
"radio",
|
|
124
|
+
"range",
|
|
125
|
+
"color",
|
|
126
|
+
"file",
|
|
127
|
+
"image",
|
|
128
|
+
"button",
|
|
129
|
+
"submit",
|
|
130
|
+
"reset"
|
|
128
131
|
]);
|
|
129
132
|
// The number of active usePreventScroll calls. Used to determine whether to revert back to the original page style/scroll position
|
|
130
133
|
let preventScrollCount = 0;
|
|
@@ -134,7 +137,7 @@ let restore;
|
|
|
134
137
|
* restores it on unmount. Also ensures that content does not
|
|
135
138
|
* shift due to the scrollbars disappearing.
|
|
136
139
|
*/ function usePreventScroll(options = {}) {
|
|
137
|
-
|
|
140
|
+
const { isDisabled } = options;
|
|
138
141
|
useIsomorphicLayoutEffect(()=>{
|
|
139
142
|
if (isDisabled) {
|
|
140
143
|
return;
|
|
@@ -148,7 +151,7 @@ let restore;
|
|
|
148
151
|
return ()=>{
|
|
149
152
|
preventScrollCount--;
|
|
150
153
|
if (preventScrollCount === 0) {
|
|
151
|
-
restore
|
|
154
|
+
restore?.();
|
|
152
155
|
}
|
|
153
156
|
};
|
|
154
157
|
}, [
|
|
@@ -184,7 +187,7 @@ let restore;
|
|
|
184
187
|
function preventScrollMobileSafari() {
|
|
185
188
|
let scrollable;
|
|
186
189
|
let lastY = 0;
|
|
187
|
-
|
|
190
|
+
const onTouchStart = (e)=>{
|
|
188
191
|
// Store the nearest scrollable parent element from the element that the user touched.
|
|
189
192
|
scrollable = getScrollParent(e.target);
|
|
190
193
|
if (scrollable === document.documentElement && scrollable === document.body) {
|
|
@@ -192,7 +195,7 @@ function preventScrollMobileSafari() {
|
|
|
192
195
|
}
|
|
193
196
|
lastY = e.changedTouches[0].pageY;
|
|
194
197
|
};
|
|
195
|
-
|
|
198
|
+
const onTouchMove = (e)=>{
|
|
196
199
|
// Prevent scrolling the window.
|
|
197
200
|
if (!scrollable || scrollable === document.documentElement || scrollable === document.body) {
|
|
198
201
|
e.preventDefault();
|
|
@@ -202,9 +205,9 @@ function preventScrollMobileSafari() {
|
|
|
202
205
|
// of a nested scrollable area, otherwise mobile Safari will start scrolling
|
|
203
206
|
// the window instead. Unfortunately, this disables bounce scrolling when at
|
|
204
207
|
// the top but it's the best we can do.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
const y = e.changedTouches[0].pageY;
|
|
209
|
+
const scrollTop = scrollable.scrollTop;
|
|
210
|
+
const bottom = scrollable.scrollHeight - scrollable.clientHeight;
|
|
208
211
|
if (bottom === 0) {
|
|
209
212
|
return;
|
|
210
213
|
}
|
|
@@ -213,31 +216,31 @@ function preventScrollMobileSafari() {
|
|
|
213
216
|
}
|
|
214
217
|
lastY = y;
|
|
215
218
|
};
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
const onTouchEnd = (e)=>{
|
|
220
|
+
const target = e.target;
|
|
218
221
|
// Apply this change if we're not already focused on the target element
|
|
219
222
|
if (isInput(target) && target !== document.activeElement) {
|
|
220
223
|
e.preventDefault();
|
|
221
224
|
// Apply a transform to trick Safari into thinking the input is at the top of the page
|
|
222
225
|
// so it doesn't try to scroll it into view. When tapping on an input, this needs to
|
|
223
226
|
// be done before the "focus" event, so we have to focus the element ourselves.
|
|
224
|
-
target.style.transform =
|
|
227
|
+
target.style.transform = "translateY(-2000px)";
|
|
225
228
|
target.focus();
|
|
226
229
|
requestAnimationFrame(()=>{
|
|
227
|
-
target.style.transform =
|
|
230
|
+
target.style.transform = "";
|
|
228
231
|
});
|
|
229
232
|
}
|
|
230
233
|
};
|
|
231
|
-
|
|
232
|
-
|
|
234
|
+
const onFocus = (e)=>{
|
|
235
|
+
const target = e.target;
|
|
233
236
|
if (isInput(target)) {
|
|
234
237
|
// Transform also needs to be applied in the focus event in cases where focus moves
|
|
235
238
|
// other than tapping on an input directly, e.g. the next/previous buttons in the
|
|
236
239
|
// software keyboard. In these cases, it seems applying the transform in the focus event
|
|
237
240
|
// is good enough, whereas when tapping an input, it must be done before the focus event. 🤷♂️
|
|
238
|
-
target.style.transform =
|
|
241
|
+
target.style.transform = "translateY(-2000px)";
|
|
239
242
|
requestAnimationFrame(()=>{
|
|
240
|
-
target.style.transform =
|
|
243
|
+
target.style.transform = "";
|
|
241
244
|
// This will have prevented the browser from scrolling the focused element into view,
|
|
242
245
|
// so we need to do this ourselves in a way that doesn't cause the whole page to scroll.
|
|
243
246
|
if (visualViewport) {
|
|
@@ -250,7 +253,7 @@ function preventScrollMobileSafari() {
|
|
|
250
253
|
} else {
|
|
251
254
|
// Otherwise, wait for the visual viewport to resize before scrolling so we can
|
|
252
255
|
// measure the correct position to scroll to.
|
|
253
|
-
visualViewport.addEventListener(
|
|
256
|
+
visualViewport.addEventListener("resize", ()=>scrollIntoView(target), {
|
|
254
257
|
once: true
|
|
255
258
|
});
|
|
256
259
|
}
|
|
@@ -258,7 +261,7 @@ function preventScrollMobileSafari() {
|
|
|
258
261
|
});
|
|
259
262
|
}
|
|
260
263
|
};
|
|
261
|
-
|
|
264
|
+
const onWindowScroll = ()=>{
|
|
262
265
|
// Last resort. If the window scrolled, scroll it back to the top.
|
|
263
266
|
// It should always be at the top because the body will have a negative margin (see below).
|
|
264
267
|
window.scrollTo(0, 0);
|
|
@@ -266,21 +269,21 @@ function preventScrollMobileSafari() {
|
|
|
266
269
|
// Record the original scroll position so we can restore it.
|
|
267
270
|
// Then apply a negative margin to the body to offset it by the scroll position. This will
|
|
268
271
|
// enable us to scroll the window to the top, which is required for the rest of this to work.
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
+
const scrollX = window.pageXOffset;
|
|
273
|
+
const scrollY = window.pageYOffset;
|
|
274
|
+
const restoreStyles = chain$1(setStyle(document.documentElement, "paddingRight", `${window.innerWidth - document.documentElement.clientWidth}px`));
|
|
272
275
|
// Scroll to the top. The negative margin on the body will make this appear the same.
|
|
273
276
|
window.scrollTo(0, 0);
|
|
274
|
-
|
|
277
|
+
const removeEvents = chain$1(addEvent(document, "touchstart", onTouchStart, {
|
|
275
278
|
passive: false,
|
|
276
279
|
capture: true
|
|
277
|
-
}), addEvent(document,
|
|
280
|
+
}), addEvent(document, "touchmove", onTouchMove, {
|
|
278
281
|
passive: false,
|
|
279
282
|
capture: true
|
|
280
|
-
}), addEvent(document,
|
|
283
|
+
}), addEvent(document, "touchend", onTouchEnd, {
|
|
281
284
|
passive: false,
|
|
282
285
|
capture: true
|
|
283
|
-
}), addEvent(document,
|
|
286
|
+
}), addEvent(document, "focus", onFocus, true), addEvent(window, "scroll", onWindowScroll));
|
|
284
287
|
return ()=>{
|
|
285
288
|
// Restore styles and scroll the page back to where it was.
|
|
286
289
|
restoreStyles();
|
|
@@ -292,7 +295,7 @@ function preventScrollMobileSafari() {
|
|
|
292
295
|
function setStyle(element, style, value) {
|
|
293
296
|
// https://github.com/microsoft/TypeScript/issues/17827#issuecomment-391663310
|
|
294
297
|
// @ts-ignore
|
|
295
|
-
|
|
298
|
+
const cur = element.style[style];
|
|
296
299
|
// @ts-ignore
|
|
297
300
|
element.style[style] = value;
|
|
298
301
|
return ()=>{
|
|
@@ -310,14 +313,14 @@ function addEvent(target, event, handler, options) {
|
|
|
310
313
|
};
|
|
311
314
|
}
|
|
312
315
|
function scrollIntoView(target) {
|
|
313
|
-
|
|
316
|
+
const root = document.scrollingElement || document.documentElement;
|
|
314
317
|
while(target && target !== root){
|
|
315
318
|
// Find the parent scrollable element and adjust the scroll position if the target is not already in view.
|
|
316
|
-
|
|
319
|
+
const scrollable = getScrollParent(target);
|
|
317
320
|
if (scrollable !== document.documentElement && scrollable !== document.body && scrollable !== target) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
+
const scrollableTop = scrollable.getBoundingClientRect().top;
|
|
322
|
+
const targetTop = target.getBoundingClientRect().top;
|
|
323
|
+
const targetBottom = target.getBoundingClientRect().bottom;
|
|
321
324
|
// Buffer is needed for some edge cases
|
|
322
325
|
const keyboardHeight = scrollable.getBoundingClientRect().bottom + KEYBOARD_BUFFER;
|
|
323
326
|
if (targetBottom > keyboardHeight) {
|
|
@@ -360,7 +363,7 @@ function isInput(target) {
|
|
|
360
363
|
const cache = new WeakMap();
|
|
361
364
|
function set(el, styles, ignoreCache = false) {
|
|
362
365
|
if (!el || !(el instanceof HTMLElement)) return;
|
|
363
|
-
|
|
366
|
+
const originalStyles = {};
|
|
364
367
|
Object.entries(styles).forEach(([key, value])=>{
|
|
365
368
|
if (key.startsWith('--')) {
|
|
366
369
|
el.style.setProperty(key, value);
|
|
@@ -374,7 +377,7 @@ function set(el, styles, ignoreCache = false) {
|
|
|
374
377
|
}
|
|
375
378
|
function reset(el, prop) {
|
|
376
379
|
if (!el || !(el instanceof HTMLElement)) return;
|
|
377
|
-
|
|
380
|
+
const originalStyles = cache.get(el);
|
|
378
381
|
if (!originalStyles) {
|
|
379
382
|
return;
|
|
380
383
|
}
|
|
@@ -458,7 +461,7 @@ function useCallbackRef(callback) {
|
|
|
458
461
|
callbackRef.current = callback;
|
|
459
462
|
});
|
|
460
463
|
// https://github.com/facebook/react/issues/19240
|
|
461
|
-
return React__default.useMemo(()=>(...args)=>callbackRef.current
|
|
464
|
+
return React__default.useMemo(()=>(...args)=>callbackRef.current?.(...args), []);
|
|
462
465
|
}
|
|
463
466
|
function useUncontrolledState({ defaultProp, onChange }) {
|
|
464
467
|
const uncontrolledState = React__default.useState(defaultProp);
|
|
@@ -505,13 +508,14 @@ function useControllableState({ prop, defaultProp, onChange = ()=>{} }) {
|
|
|
505
508
|
];
|
|
506
509
|
}
|
|
507
510
|
|
|
508
|
-
|
|
511
|
+
// @ts-nocheck [FIXME] See after monorepo migration
|
|
512
|
+
function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints, drawerRef, overlayRef, fadeFromIndex, onSnapPointChange, direction = "bottom", container, snapToSequentialPoint }) {
|
|
509
513
|
const [activeSnapPoint, setActiveSnapPoint] = useControllableState({
|
|
510
514
|
prop: activeSnapPointProp,
|
|
511
|
-
defaultProp: snapPoints
|
|
515
|
+
defaultProp: snapPoints?.[0],
|
|
512
516
|
onChange: setActiveSnapPointProp
|
|
513
517
|
});
|
|
514
|
-
const [windowDimensions, setWindowDimensions] = React__default.useState(typeof window !==
|
|
518
|
+
const [windowDimensions, setWindowDimensions] = React__default.useState(typeof window !== "undefined" ? {
|
|
515
519
|
innerWidth: window.innerWidth,
|
|
516
520
|
innerHeight: window.innerHeight
|
|
517
521
|
} : undefined);
|
|
@@ -522,17 +526,14 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
522
526
|
innerHeight: window.innerHeight
|
|
523
527
|
});
|
|
524
528
|
}
|
|
525
|
-
window.addEventListener(
|
|
526
|
-
return ()=>window.removeEventListener(
|
|
529
|
+
window.addEventListener("resize", onResize);
|
|
530
|
+
return ()=>window.removeEventListener("resize", onResize);
|
|
527
531
|
}, []);
|
|
528
|
-
const isLastSnapPoint = React__default.useMemo(()=>activeSnapPoint ===
|
|
532
|
+
const isLastSnapPoint = React__default.useMemo(()=>activeSnapPoint === snapPoints?.[snapPoints.length - 1] || null, [
|
|
529
533
|
snapPoints,
|
|
530
534
|
activeSnapPoint
|
|
531
535
|
]);
|
|
532
|
-
const activeSnapPointIndex = React__default.useMemo(()=>
|
|
533
|
-
var _snapPoints_findIndex;
|
|
534
|
-
return (_snapPoints_findIndex = snapPoints == null ? void 0 : snapPoints.findIndex((snapPoint)=>snapPoint === activeSnapPoint)) != null ? _snapPoints_findIndex : null;
|
|
535
|
-
}, [
|
|
536
|
+
const activeSnapPointIndex = React__default.useMemo(()=>snapPoints?.findIndex((snapPoint)=>snapPoint === activeSnapPoint) ?? null, [
|
|
536
537
|
snapPoints,
|
|
537
538
|
activeSnapPoint
|
|
538
539
|
]);
|
|
@@ -541,16 +542,15 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
541
542
|
const containerSize = container ? {
|
|
542
543
|
width: container.getBoundingClientRect().width,
|
|
543
544
|
height: container.getBoundingClientRect().height
|
|
544
|
-
} : typeof window !==
|
|
545
|
+
} : typeof window !== "undefined" ? {
|
|
545
546
|
width: window.innerWidth,
|
|
546
547
|
height: window.innerHeight
|
|
547
548
|
} : {
|
|
548
549
|
width: 0,
|
|
549
550
|
height: 0
|
|
550
551
|
};
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
const isPx = typeof snapPoint === 'string';
|
|
552
|
+
return snapPoints?.map((snapPoint)=>{
|
|
553
|
+
const isPx = typeof snapPoint === "string";
|
|
554
554
|
let snapPointAsNumber = 0;
|
|
555
555
|
if (isPx) {
|
|
556
556
|
snapPointAsNumber = parseInt(snapPoint, 10);
|
|
@@ -558,45 +558,44 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
558
558
|
if (isVertical(direction)) {
|
|
559
559
|
const height = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.height : 0;
|
|
560
560
|
if (windowDimensions) {
|
|
561
|
-
return direction ===
|
|
561
|
+
return direction === "bottom" ? containerSize.height - height : -containerSize.height + height;
|
|
562
562
|
}
|
|
563
563
|
return height;
|
|
564
564
|
}
|
|
565
565
|
const width = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.width : 0;
|
|
566
566
|
if (windowDimensions) {
|
|
567
|
-
return direction ===
|
|
567
|
+
return direction === "right" ? containerSize.width - width : -containerSize.width + width;
|
|
568
568
|
}
|
|
569
569
|
return width;
|
|
570
|
-
})
|
|
570
|
+
}) ?? [];
|
|
571
571
|
}, [
|
|
572
572
|
snapPoints,
|
|
573
573
|
windowDimensions,
|
|
574
574
|
container
|
|
575
575
|
]);
|
|
576
|
-
const activeSnapPointOffset = React__default.useMemo(()=>activeSnapPointIndex !== null ? snapPointsOffset
|
|
576
|
+
const activeSnapPointOffset = React__default.useMemo(()=>activeSnapPointIndex !== null ? snapPointsOffset?.[activeSnapPointIndex] : null, [
|
|
577
577
|
snapPointsOffset,
|
|
578
578
|
activeSnapPointIndex
|
|
579
579
|
]);
|
|
580
580
|
const snapToPoint = React__default.useCallback((dimension)=>{
|
|
581
|
-
|
|
582
|
-
const newSnapPointIndex = (_snapPointsOffset_findIndex = snapPointsOffset == null ? void 0 : snapPointsOffset.findIndex((snapPointDim)=>snapPointDim === dimension)) != null ? _snapPointsOffset_findIndex : null;
|
|
581
|
+
const newSnapPointIndex = snapPointsOffset?.findIndex((snapPointDim)=>snapPointDim === dimension) ?? null;
|
|
583
582
|
onSnapPointChange(newSnapPointIndex);
|
|
584
583
|
set(drawerRef.current, {
|
|
585
|
-
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
584
|
+
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
586
585
|
transform: isVertical(direction) ? `translate3d(0, ${dimension}px, 0)` : `translate3d(${dimension}px, 0, 0)`
|
|
587
586
|
});
|
|
588
587
|
if (snapPointsOffset && newSnapPointIndex !== snapPointsOffset.length - 1 && fadeFromIndex !== undefined && newSnapPointIndex !== fadeFromIndex && newSnapPointIndex < fadeFromIndex) {
|
|
589
588
|
set(overlayRef.current, {
|
|
590
|
-
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
591
|
-
opacity:
|
|
589
|
+
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
590
|
+
opacity: "0"
|
|
592
591
|
});
|
|
593
592
|
} else {
|
|
594
593
|
set(overlayRef.current, {
|
|
595
|
-
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
596
|
-
opacity:
|
|
594
|
+
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
595
|
+
opacity: "1"
|
|
597
596
|
});
|
|
598
597
|
}
|
|
599
|
-
setActiveSnapPoint(snapPoints
|
|
598
|
+
setActiveSnapPoint(snapPoints?.[Math.max(newSnapPointIndex, 0)]);
|
|
600
599
|
}, [
|
|
601
600
|
drawerRef.current,
|
|
602
601
|
snapPoints,
|
|
@@ -607,9 +606,8 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
607
606
|
]);
|
|
608
607
|
React__default.useEffect(()=>{
|
|
609
608
|
if (activeSnapPoint || activeSnapPointProp) {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
if (snapPointsOffset && newIndex !== -1 && typeof snapPointsOffset[newIndex] === 'number') {
|
|
609
|
+
const newIndex = snapPoints?.findIndex((snapPoint)=>snapPoint === activeSnapPointProp || snapPoint === activeSnapPoint) ?? -1;
|
|
610
|
+
if (snapPointsOffset && newIndex !== -1 && typeof snapPointsOffset[newIndex] === "number") {
|
|
613
611
|
snapToPoint(snapPointsOffset[newIndex]);
|
|
614
612
|
}
|
|
615
613
|
}
|
|
@@ -622,13 +620,13 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
622
620
|
]);
|
|
623
621
|
function onRelease({ draggedDistance, closeDrawer, velocity, dismissible }) {
|
|
624
622
|
if (fadeFromIndex === undefined) return;
|
|
625
|
-
const currentPosition = direction ===
|
|
623
|
+
const currentPosition = direction === "bottom" || direction === "right" ? (activeSnapPointOffset ?? 0) - draggedDistance : (activeSnapPointOffset ?? 0) + draggedDistance;
|
|
626
624
|
const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
|
|
627
625
|
const isFirst = activeSnapPointIndex === 0;
|
|
628
626
|
const hasDraggedUp = draggedDistance > 0;
|
|
629
627
|
if (isOverlaySnapPoint) {
|
|
630
628
|
set(overlayRef.current, {
|
|
631
|
-
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
629
|
+
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`
|
|
632
630
|
});
|
|
633
631
|
}
|
|
634
632
|
if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
|
|
@@ -641,8 +639,8 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
641
639
|
return;
|
|
642
640
|
}
|
|
643
641
|
// Find the closest snap point to the current position
|
|
644
|
-
const closestSnapPoint = snapPointsOffset
|
|
645
|
-
if (typeof prev !==
|
|
642
|
+
const closestSnapPoint = snapPointsOffset?.reduce((prev, curr)=>{
|
|
643
|
+
if (typeof prev !== "number" || typeof curr !== "number") return prev;
|
|
646
644
|
return Math.abs(curr - currentPosition) < Math.abs(prev - currentPosition) ? curr : prev;
|
|
647
645
|
});
|
|
648
646
|
const dim = isVertical(direction) ? window.innerHeight : window.innerWidth;
|
|
@@ -664,12 +662,12 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
664
662
|
}
|
|
665
663
|
function onDrag({ draggedDistance }) {
|
|
666
664
|
if (activeSnapPointOffset === null) return;
|
|
667
|
-
const newValue = direction ===
|
|
665
|
+
const newValue = direction === "bottom" || direction === "right" ? activeSnapPointOffset - draggedDistance : activeSnapPointOffset + draggedDistance;
|
|
668
666
|
// Don't do anything if we exceed the last(biggest) snap point
|
|
669
|
-
if ((direction ===
|
|
667
|
+
if ((direction === "bottom" || direction === "right") && newValue < snapPointsOffset[snapPointsOffset.length - 1]) {
|
|
670
668
|
return;
|
|
671
669
|
}
|
|
672
|
-
if ((direction ===
|
|
670
|
+
if ((direction === "top" || direction === "left") && newValue > snapPointsOffset[snapPointsOffset.length - 1]) {
|
|
673
671
|
return;
|
|
674
672
|
}
|
|
675
673
|
set(drawerRef.current, {
|
|
@@ -677,7 +675,7 @@ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints
|
|
|
677
675
|
});
|
|
678
676
|
}
|
|
679
677
|
function getPercentageDragged(absDraggedDistance, isDraggingDown) {
|
|
680
|
-
if (!snapPoints || typeof activeSnapPointIndex !==
|
|
678
|
+
if (!snapPoints || typeof activeSnapPointIndex !== "number" || !snapPointsOffset || fadeFromIndex === undefined) return null;
|
|
681
679
|
// If this is true we are dragging to a snap point that is supposed to have an overlay
|
|
682
680
|
const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
|
|
683
681
|
const isOverlaySnapPointOrHigher = activeSnapPointIndex >= fadeFromIndex;
|
|
@@ -876,29 +874,28 @@ let previousBodyPosition = null;
|
|
|
876
874
|
};
|
|
877
875
|
}
|
|
878
876
|
|
|
879
|
-
function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction =
|
|
880
|
-
var _drawerRef_current, _drawerRef_current1;
|
|
877
|
+
function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRelease: onReleaseProp, snapPoints, shouldScaleBackground = false, setBackgroundColorOnScale = true, closeThreshold = CLOSE_THRESHOLD, scrollLockTimeout = SCROLL_LOCK_TIMEOUT, dismissible = true, handleOnly = false, fadeFromIndex = snapPoints && snapPoints.length - 1, activeSnapPoint: activeSnapPointProp, setActiveSnapPoint: setActiveSnapPointProp, fixed, modal = true, onClose, nested, noBodyStyles = false, direction = "bottom", defaultOpen = false, disablePreventScroll = true, snapToSequentialPoint = false, preventScrollRestoration = false, repositionInputs = true, onAnimationEnd, container, autoFocus = false }) {
|
|
881
878
|
const [isOpen = false, setIsOpen] = useControllableState({
|
|
882
879
|
defaultProp: defaultOpen,
|
|
883
880
|
prop: openProp,
|
|
884
881
|
onChange: (o)=>{
|
|
885
|
-
onOpenChange
|
|
882
|
+
onOpenChange?.(o);
|
|
886
883
|
if (!o && !nested) {
|
|
887
884
|
restorePositionSetting();
|
|
888
885
|
}
|
|
889
886
|
setTimeout(()=>{
|
|
890
|
-
onAnimationEnd
|
|
887
|
+
onAnimationEnd?.(o);
|
|
891
888
|
}, TRANSITIONS.DURATION * 1000);
|
|
892
889
|
if (o && !modal) {
|
|
893
|
-
if (typeof window !==
|
|
890
|
+
if (typeof window !== "undefined") {
|
|
894
891
|
window.requestAnimationFrame(()=>{
|
|
895
|
-
document.body.style.pointerEvents =
|
|
892
|
+
document.body.style.pointerEvents = "auto";
|
|
896
893
|
});
|
|
897
894
|
}
|
|
898
895
|
}
|
|
899
896
|
if (!o) {
|
|
900
897
|
// This will be removed when the exit animation ends (`500ms`)
|
|
901
|
-
document.body.style.pointerEvents =
|
|
898
|
+
document.body.style.pointerEvents = "auto";
|
|
902
899
|
}
|
|
903
900
|
}
|
|
904
901
|
});
|
|
@@ -917,8 +914,8 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
917
914
|
const shouldAnimate = React__default.useRef(!defaultOpen);
|
|
918
915
|
const previousDiffFromInitial = React__default.useRef(0);
|
|
919
916
|
const drawerRef = React__default.useRef(null);
|
|
920
|
-
const drawerHeightRef = React__default.useRef(
|
|
921
|
-
const drawerWidthRef = React__default.useRef(
|
|
917
|
+
const drawerHeightRef = React__default.useRef(drawerRef.current?.getBoundingClientRect().height || 0);
|
|
918
|
+
const drawerWidthRef = React__default.useRef(drawerRef.current?.getBoundingClientRect().width || 0);
|
|
922
919
|
const initialDrawerHeight = React__default.useRef(0);
|
|
923
920
|
const onSnapPointChange = React__default.useCallback((activeSnapPointIndex)=>{
|
|
924
921
|
// Change openTime ref when we reach the last snap point to prevent dragging for 500ms incase it's scrollable.
|
|
@@ -942,7 +939,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
942
939
|
const { restorePositionSetting } = usePositionFixed({
|
|
943
940
|
isOpen,
|
|
944
941
|
modal,
|
|
945
|
-
nested: nested
|
|
942
|
+
nested: nested ?? false,
|
|
946
943
|
hasBeenOpened,
|
|
947
944
|
preventScrollRestoration,
|
|
948
945
|
noBodyStyles
|
|
@@ -951,16 +948,15 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
951
948
|
return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
|
|
952
949
|
}
|
|
953
950
|
function onPress(event) {
|
|
954
|
-
var _drawerRef_current, _drawerRef_current1;
|
|
955
951
|
if (!dismissible && !snapPoints) return;
|
|
956
952
|
if (drawerRef.current && !drawerRef.current.contains(event.target)) return;
|
|
957
|
-
drawerHeightRef.current =
|
|
958
|
-
drawerWidthRef.current =
|
|
953
|
+
drawerHeightRef.current = drawerRef.current?.getBoundingClientRect().height || 0;
|
|
954
|
+
drawerWidthRef.current = drawerRef.current?.getBoundingClientRect().width || 0;
|
|
959
955
|
setIsDragging(true);
|
|
960
956
|
dragStartTime.current = new Date();
|
|
961
957
|
// iOS doesn't trigger mouseUp after scrolling so we need to listen to touched in order to disallow dragging
|
|
962
958
|
if (isIOS()) {
|
|
963
|
-
window.addEventListener(
|
|
959
|
+
window.addEventListener("touchend", ()=>isAllowedToDrag.current = false, {
|
|
964
960
|
once: true
|
|
965
961
|
});
|
|
966
962
|
}
|
|
@@ -969,19 +965,18 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
969
965
|
pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
|
|
970
966
|
}
|
|
971
967
|
function shouldDrag(el, isDraggingInDirection) {
|
|
972
|
-
var _window_getSelection;
|
|
973
968
|
let element = el;
|
|
974
|
-
const highlightedText =
|
|
969
|
+
const highlightedText = window.getSelection()?.toString();
|
|
975
970
|
const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
|
|
976
971
|
const date = new Date();
|
|
977
972
|
// Fixes https://github.com/emilkowalski/vaul/issues/483
|
|
978
|
-
if (element.tagName ===
|
|
973
|
+
if (element.tagName === "SELECT") {
|
|
979
974
|
return false;
|
|
980
975
|
}
|
|
981
|
-
if (element.hasAttribute(
|
|
976
|
+
if (element.hasAttribute("data-vaul-no-drag") || element.closest("[data-vaul-no-drag]")) {
|
|
982
977
|
return false;
|
|
983
978
|
}
|
|
984
|
-
if (direction ===
|
|
979
|
+
if (direction === "right" || direction === "left") {
|
|
985
980
|
return true;
|
|
986
981
|
}
|
|
987
982
|
// Allow scrolling when animating
|
|
@@ -989,7 +984,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
989
984
|
return false;
|
|
990
985
|
}
|
|
991
986
|
if (swipeAmount !== null) {
|
|
992
|
-
if (direction ===
|
|
987
|
+
if (direction === "bottom" ? swipeAmount > 0 : swipeAmount < 0) {
|
|
993
988
|
return true;
|
|
994
989
|
}
|
|
995
990
|
}
|
|
@@ -1016,7 +1011,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1016
1011
|
// The element is scrollable and not scrolled to the top, so don't drag
|
|
1017
1012
|
return false;
|
|
1018
1013
|
}
|
|
1019
|
-
if (element.getAttribute(
|
|
1014
|
+
if (element.getAttribute("role") === "dialog") {
|
|
1020
1015
|
return true;
|
|
1021
1016
|
}
|
|
1022
1017
|
}
|
|
@@ -1032,7 +1027,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1032
1027
|
}
|
|
1033
1028
|
// We need to know how much of the drawer has been dragged in percentages so that we can transform background accordingly
|
|
1034
1029
|
if (isDragging) {
|
|
1035
|
-
const directionMultiplier = direction ===
|
|
1030
|
+
const directionMultiplier = direction === "bottom" || direction === "right" ? 1 : -1;
|
|
1036
1031
|
const draggedDistance = (pointerStart.current - (isVertical(direction) ? event.pageY : event.pageX)) * directionMultiplier;
|
|
1037
1032
|
const isDraggingInDirection = draggedDistance > 0;
|
|
1038
1033
|
// Pre condition for disallowing dragging in the close direction.
|
|
@@ -1041,8 +1036,8 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1041
1036
|
if (noCloseSnapPointsPreCondition && activeSnapPointIndex === 0) return;
|
|
1042
1037
|
// We need to capture last time when drag with scroll was triggered and have a timeout between
|
|
1043
1038
|
const absDraggedDistance = Math.abs(draggedDistance);
|
|
1044
|
-
const wrapper = document.querySelector(
|
|
1045
|
-
const drawerDimension = direction ===
|
|
1039
|
+
const wrapper = document.querySelector("[data-vaul-drawer-wrapper]");
|
|
1040
|
+
const drawerDimension = direction === "bottom" || direction === "top" ? drawerHeightRef.current : drawerWidthRef.current;
|
|
1046
1041
|
// Calculate the percentage dragged, where 1 is the closed position
|
|
1047
1042
|
let percentageDragged = absDraggedDistance / drawerDimension;
|
|
1048
1043
|
const snapPointPercentageDragged = getSnapPointsPercentageDragged(absDraggedDistance, isDraggingInDirection);
|
|
@@ -1058,10 +1053,10 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1058
1053
|
// If shouldDrag gave true once after pressing down on the drawer, we set isAllowedToDrag to true and it will remain true until we let go, there's no reason to disable dragging mid way, ever, and that's the solution to it
|
|
1059
1054
|
isAllowedToDrag.current = true;
|
|
1060
1055
|
set(drawerRef.current, {
|
|
1061
|
-
transition:
|
|
1056
|
+
transition: "none"
|
|
1062
1057
|
});
|
|
1063
1058
|
set(overlayRef.current, {
|
|
1064
|
-
transition:
|
|
1059
|
+
transition: "none"
|
|
1065
1060
|
});
|
|
1066
1061
|
if (snapPoints) {
|
|
1067
1062
|
onDragSnapPoints({
|
|
@@ -1079,10 +1074,10 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1079
1074
|
}
|
|
1080
1075
|
const opacityValue = 1 - percentageDragged;
|
|
1081
1076
|
if (shouldFade || fadeFromIndex && activeSnapPointIndex === fadeFromIndex - 1) {
|
|
1082
|
-
onDragProp
|
|
1077
|
+
onDragProp?.(event, percentageDragged);
|
|
1083
1078
|
set(overlayRef.current, {
|
|
1084
1079
|
opacity: `${opacityValue}`,
|
|
1085
|
-
transition:
|
|
1080
|
+
transition: "none"
|
|
1086
1081
|
}, true);
|
|
1087
1082
|
}
|
|
1088
1083
|
if (wrapper && overlayRef.current && shouldScaleBackground) {
|
|
@@ -1093,7 +1088,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1093
1088
|
set(wrapper, {
|
|
1094
1089
|
borderRadius: `${borderRadiusValue}px`,
|
|
1095
1090
|
transform: isVertical(direction) ? `scale(${scaleValue}) translate3d(0, ${translateValue}px, 0)` : `scale(${scaleValue}) translate3d(${translateValue}px, 0, 0)`,
|
|
1096
|
-
transition:
|
|
1091
|
+
transition: "none"
|
|
1097
1092
|
}, true);
|
|
1098
1093
|
}
|
|
1099
1094
|
if (!snapPoints) {
|
|
@@ -1110,13 +1105,11 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1110
1105
|
});
|
|
1111
1106
|
}, []);
|
|
1112
1107
|
React__default.useEffect(()=>{
|
|
1113
|
-
var _window_visualViewport;
|
|
1114
1108
|
function onVisualViewportChange() {
|
|
1115
1109
|
if (!drawerRef.current || !repositionInputs) return;
|
|
1116
1110
|
const focusedElement = document.activeElement;
|
|
1117
1111
|
if (isInput(focusedElement) || keyboardIsOpen.current) {
|
|
1118
|
-
|
|
1119
|
-
const visualViewportHeight = ((_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.height) || 0;
|
|
1112
|
+
const visualViewportHeight = window.visualViewport?.height || 0;
|
|
1120
1113
|
const totalHeight = window.innerHeight;
|
|
1121
1114
|
// This is the height of the keyboard
|
|
1122
1115
|
let diffFromInitial = totalHeight - visualViewportHeight;
|
|
@@ -1160,11 +1153,8 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1160
1153
|
}
|
|
1161
1154
|
}
|
|
1162
1155
|
}
|
|
1163
|
-
|
|
1164
|
-
return ()=>
|
|
1165
|
-
var _window_visualViewport;
|
|
1166
|
-
return (_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.removeEventListener('resize', onVisualViewportChange);
|
|
1167
|
-
};
|
|
1156
|
+
window.visualViewport?.addEventListener("resize", onVisualViewportChange);
|
|
1157
|
+
return ()=>window.visualViewport?.removeEventListener("resize", onVisualViewportChange);
|
|
1168
1158
|
}, [
|
|
1169
1159
|
activeSnapPointIndex,
|
|
1170
1160
|
snapPoints,
|
|
@@ -1172,7 +1162,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1172
1162
|
]);
|
|
1173
1163
|
function closeDrawer(fromWithin) {
|
|
1174
1164
|
cancelDrag();
|
|
1175
|
-
onClose
|
|
1165
|
+
onClose?.();
|
|
1176
1166
|
if (!fromWithin) {
|
|
1177
1167
|
setIsOpen(false);
|
|
1178
1168
|
}
|
|
@@ -1184,31 +1174,31 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1184
1174
|
}
|
|
1185
1175
|
function resetDrawer() {
|
|
1186
1176
|
if (!drawerRef.current) return;
|
|
1187
|
-
const wrapper = document.querySelector(
|
|
1177
|
+
const wrapper = document.querySelector("[data-vaul-drawer-wrapper]");
|
|
1188
1178
|
const currentSwipeAmount = getTranslate(drawerRef.current, direction);
|
|
1189
1179
|
set(drawerRef.current, {
|
|
1190
|
-
transform:
|
|
1191
|
-
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
1180
|
+
transform: "translate3d(0, 0, 0)",
|
|
1181
|
+
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`
|
|
1192
1182
|
});
|
|
1193
1183
|
set(overlayRef.current, {
|
|
1194
|
-
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
1195
|
-
opacity:
|
|
1184
|
+
transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
1185
|
+
opacity: "1"
|
|
1196
1186
|
});
|
|
1197
1187
|
// Don't reset background if swiped upwards
|
|
1198
1188
|
if (shouldScaleBackground && currentSwipeAmount && currentSwipeAmount > 0 && isOpen) {
|
|
1199
1189
|
set(wrapper, {
|
|
1200
1190
|
borderRadius: `${BORDER_RADIUS}px`,
|
|
1201
|
-
overflow:
|
|
1191
|
+
overflow: "hidden",
|
|
1202
1192
|
...isVertical(direction) ? {
|
|
1203
1193
|
transform: `scale(${getScale()}) translate3d(0, calc(env(safe-area-inset-top) + 14px), 0)`,
|
|
1204
|
-
transformOrigin:
|
|
1194
|
+
transformOrigin: "top"
|
|
1205
1195
|
} : {
|
|
1206
1196
|
transform: `scale(${getScale()}) translate3d(calc(env(safe-area-inset-top) + 14px), 0, 0)`,
|
|
1207
|
-
transformOrigin:
|
|
1197
|
+
transformOrigin: "left"
|
|
1208
1198
|
},
|
|
1209
|
-
transitionProperty:
|
|
1199
|
+
transitionProperty: "transform, border-radius",
|
|
1210
1200
|
transitionDuration: `${TRANSITIONS.DURATION}s`,
|
|
1211
|
-
transitionTimingFunction: `cubic-bezier(${TRANSITIONS.EASE.join(
|
|
1201
|
+
transitionTimingFunction: `cubic-bezier(${TRANSITIONS.EASE.join(",")})`
|
|
1212
1202
|
}, true);
|
|
1213
1203
|
}
|
|
1214
1204
|
}
|
|
@@ -1239,50 +1229,48 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1239
1229
|
}, 200);
|
|
1240
1230
|
}
|
|
1241
1231
|
if (snapPoints) {
|
|
1242
|
-
const directionMultiplier = direction ===
|
|
1232
|
+
const directionMultiplier = direction === "bottom" || direction === "right" ? 1 : -1;
|
|
1243
1233
|
onReleaseSnapPoints({
|
|
1244
1234
|
draggedDistance: distMoved * directionMultiplier,
|
|
1245
1235
|
closeDrawer,
|
|
1246
1236
|
velocity,
|
|
1247
1237
|
dismissible
|
|
1248
1238
|
});
|
|
1249
|
-
onReleaseProp
|
|
1239
|
+
onReleaseProp?.(event, true);
|
|
1250
1240
|
return;
|
|
1251
1241
|
}
|
|
1252
1242
|
// Moved upwards, don't do anything
|
|
1253
|
-
if (direction ===
|
|
1243
|
+
if (direction === "bottom" || direction === "right" ? distMoved > 0 : distMoved < 0) {
|
|
1254
1244
|
resetDrawer();
|
|
1255
|
-
onReleaseProp
|
|
1245
|
+
onReleaseProp?.(event, true);
|
|
1256
1246
|
return;
|
|
1257
1247
|
}
|
|
1258
1248
|
if (velocity > VELOCITY_THRESHOLD) {
|
|
1259
1249
|
closeDrawer();
|
|
1260
|
-
onReleaseProp
|
|
1250
|
+
onReleaseProp?.(event, false);
|
|
1261
1251
|
return;
|
|
1262
1252
|
}
|
|
1263
|
-
|
|
1264
|
-
const
|
|
1265
|
-
|
|
1266
|
-
const visibleDrawerWidth = Math.min((_drawerRef_current_getBoundingClientRect_width = drawerRef.current.getBoundingClientRect().width) != null ? _drawerRef_current_getBoundingClientRect_width : 0, window.innerWidth);
|
|
1267
|
-
const isHorizontalSwipe = direction === 'left' || direction === 'right';
|
|
1253
|
+
const visibleDrawerHeight = Math.min(drawerRef.current.getBoundingClientRect().height ?? 0, window.innerHeight);
|
|
1254
|
+
const visibleDrawerWidth = Math.min(drawerRef.current.getBoundingClientRect().width ?? 0, window.innerWidth);
|
|
1255
|
+
const isHorizontalSwipe = direction === "left" || direction === "right";
|
|
1268
1256
|
if (Math.abs(swipeAmount) >= (isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold) {
|
|
1269
1257
|
closeDrawer();
|
|
1270
|
-
onReleaseProp
|
|
1258
|
+
onReleaseProp?.(event, false);
|
|
1271
1259
|
return;
|
|
1272
1260
|
}
|
|
1273
|
-
onReleaseProp
|
|
1261
|
+
onReleaseProp?.(event, true);
|
|
1274
1262
|
resetDrawer();
|
|
1275
1263
|
}
|
|
1276
1264
|
React__default.useEffect(()=>{
|
|
1277
1265
|
// Trigger enter animation without using CSS animation
|
|
1278
1266
|
if (isOpen) {
|
|
1279
1267
|
set(document.documentElement, {
|
|
1280
|
-
scrollBehavior:
|
|
1268
|
+
scrollBehavior: "auto"
|
|
1281
1269
|
});
|
|
1282
1270
|
openTime.current = new Date();
|
|
1283
1271
|
}
|
|
1284
1272
|
return ()=>{
|
|
1285
|
-
reset(document.documentElement,
|
|
1273
|
+
reset(document.documentElement, "scrollBehavior");
|
|
1286
1274
|
};
|
|
1287
1275
|
}, [
|
|
1288
1276
|
isOpen
|
|
@@ -1294,14 +1282,14 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1294
1282
|
window.clearTimeout(nestedOpenChangeTimer.current);
|
|
1295
1283
|
}
|
|
1296
1284
|
set(drawerRef.current, {
|
|
1297
|
-
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
1285
|
+
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
1298
1286
|
transform: isVertical(direction) ? `scale(${scale}) translate3d(0, ${initialTranslate}px, 0)` : `scale(${scale}) translate3d(${initialTranslate}px, 0, 0)`
|
|
1299
1287
|
});
|
|
1300
1288
|
if (!o && drawerRef.current) {
|
|
1301
1289
|
nestedOpenChangeTimer.current = setTimeout(()=>{
|
|
1302
1290
|
const translateValue = getTranslate(drawerRef.current, direction);
|
|
1303
1291
|
set(drawerRef.current, {
|
|
1304
|
-
transition:
|
|
1292
|
+
transition: "none",
|
|
1305
1293
|
transform: isVertical(direction) ? `translate3d(0, ${translateValue}px, 0)` : `translate3d(${translateValue}px, 0, 0)`
|
|
1306
1294
|
});
|
|
1307
1295
|
}, 500);
|
|
@@ -1314,7 +1302,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1314
1302
|
const newTranslate = -NESTED_DISPLACEMENT + percentageDragged * NESTED_DISPLACEMENT;
|
|
1315
1303
|
set(drawerRef.current, {
|
|
1316
1304
|
transform: isVertical(direction) ? `scale(${newScale}) translate3d(0, ${newTranslate}px, 0)` : `scale(${newScale}) translate3d(${newTranslate}px, 0, 0)`,
|
|
1317
|
-
transition:
|
|
1305
|
+
transition: "none"
|
|
1318
1306
|
});
|
|
1319
1307
|
}
|
|
1320
1308
|
function onNestedRelease(_event, o) {
|
|
@@ -1323,7 +1311,7 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1323
1311
|
const translate = o ? -NESTED_DISPLACEMENT : 0;
|
|
1324
1312
|
if (o) {
|
|
1325
1313
|
set(drawerRef.current, {
|
|
1326
|
-
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(
|
|
1314
|
+
transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
|
|
1327
1315
|
transform: isVertical(direction) ? `scale(${scale}) translate3d(0, ${translate}px, 0)` : `scale(${scale}) translate3d(${translate}px, 0, 0)`
|
|
1328
1316
|
});
|
|
1329
1317
|
}
|
|
@@ -1332,13 +1320,13 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1332
1320
|
if (!modal) {
|
|
1333
1321
|
// Need to do this manually unfortunately
|
|
1334
1322
|
window.requestAnimationFrame(()=>{
|
|
1335
|
-
document.body.style.pointerEvents =
|
|
1323
|
+
document.body.style.pointerEvents = "auto";
|
|
1336
1324
|
});
|
|
1337
1325
|
}
|
|
1338
1326
|
}, [
|
|
1339
1327
|
modal
|
|
1340
1328
|
]);
|
|
1341
|
-
return /*#__PURE__*/
|
|
1329
|
+
return /*#__PURE__*/ jsx(Dialog.Root, {
|
|
1342
1330
|
defaultOpen: defaultOpen,
|
|
1343
1331
|
onOpenChange: (open)=>{
|
|
1344
1332
|
if (!dismissible && !open) return;
|
|
@@ -1350,40 +1338,42 @@ function Root({ open: openProp, onOpenChange, children, onDrag: onDragProp, onRe
|
|
|
1350
1338
|
setIsOpen(open);
|
|
1351
1339
|
},
|
|
1352
1340
|
open: isOpen,
|
|
1353
|
-
modal: modal
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1341
|
+
modal: modal,
|
|
1342
|
+
children: /*#__PURE__*/ jsx(DrawerContext.Provider, {
|
|
1343
|
+
value: {
|
|
1344
|
+
activeSnapPoint,
|
|
1345
|
+
snapPoints,
|
|
1346
|
+
setActiveSnapPoint,
|
|
1347
|
+
drawerRef,
|
|
1348
|
+
overlayRef,
|
|
1349
|
+
onOpenChange,
|
|
1350
|
+
onPress,
|
|
1351
|
+
onRelease,
|
|
1352
|
+
onDrag,
|
|
1353
|
+
dismissible,
|
|
1354
|
+
shouldAnimate,
|
|
1355
|
+
handleOnly,
|
|
1356
|
+
isOpen,
|
|
1357
|
+
isDragging,
|
|
1358
|
+
shouldFade,
|
|
1359
|
+
closeDrawer,
|
|
1360
|
+
onNestedDrag,
|
|
1361
|
+
onNestedOpenChange,
|
|
1362
|
+
onNestedRelease,
|
|
1363
|
+
keyboardIsOpen,
|
|
1364
|
+
modal,
|
|
1365
|
+
snapPointsOffset,
|
|
1366
|
+
activeSnapPointIndex,
|
|
1367
|
+
direction,
|
|
1368
|
+
shouldScaleBackground,
|
|
1369
|
+
setBackgroundColorOnScale,
|
|
1370
|
+
noBodyStyles,
|
|
1371
|
+
container,
|
|
1372
|
+
autoFocus
|
|
1373
|
+
},
|
|
1374
|
+
children: children
|
|
1375
|
+
})
|
|
1376
|
+
});
|
|
1387
1377
|
}
|
|
1388
1378
|
const Overlay = /*#__PURE__*/ React__default.forwardRef(function({ ...rest }, ref) {
|
|
1389
1379
|
const { overlayRef, snapPoints, onRelease, shouldFade, isOpen, modal, shouldAnimate } = useDrawerContext();
|
|
@@ -1396,17 +1386,17 @@ const Overlay = /*#__PURE__*/ React__default.forwardRef(function({ ...rest }, re
|
|
|
1396
1386
|
if (!modal) {
|
|
1397
1387
|
return null;
|
|
1398
1388
|
}
|
|
1399
|
-
return /*#__PURE__*/
|
|
1389
|
+
return /*#__PURE__*/ jsx(Dialog.Backdrop, {
|
|
1400
1390
|
onMouseUp: onMouseUp,
|
|
1401
1391
|
ref: composedRef,
|
|
1402
1392
|
"data-vaul-overlay": "",
|
|
1403
|
-
"data-vaul-snap-points": isOpen && hasSnapPoints ?
|
|
1404
|
-
"data-vaul-snap-points-overlay": isOpen && shouldFade ?
|
|
1405
|
-
"data-vaul-animate":
|
|
1393
|
+
"data-vaul-snap-points": isOpen && hasSnapPoints ? "true" : "false",
|
|
1394
|
+
"data-vaul-snap-points-overlay": isOpen && shouldFade ? "true" : "false",
|
|
1395
|
+
"data-vaul-animate": shouldAnimate?.current ? "true" : "false",
|
|
1406
1396
|
...rest
|
|
1407
1397
|
});
|
|
1408
1398
|
});
|
|
1409
|
-
Overlay.displayName =
|
|
1399
|
+
Overlay.displayName = "Drawer.Overlay";
|
|
1410
1400
|
const Content = /*#__PURE__*/ React__default.forwardRef(function({ style, ...rest }, ref) {
|
|
1411
1401
|
const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, shouldAnimate, autoFocus } = useDrawerContext();
|
|
1412
1402
|
// Needed to use transition instead of animations
|
|
@@ -1423,10 +1413,10 @@ const Content = /*#__PURE__*/ React__default.forwardRef(function({ style, ...res
|
|
|
1423
1413
|
const deltaX = Math.abs(delta.x);
|
|
1424
1414
|
const isDeltaX = deltaX > deltaY;
|
|
1425
1415
|
const dFactor = [
|
|
1426
|
-
|
|
1427
|
-
|
|
1416
|
+
"bottom",
|
|
1417
|
+
"right"
|
|
1428
1418
|
].includes(direction) ? 1 : -1;
|
|
1429
|
-
if (direction ===
|
|
1419
|
+
if (direction === "left" || direction === "right") {
|
|
1430
1420
|
const isReverseDirection = delta.x * dFactor < 0;
|
|
1431
1421
|
if (!isReverseDirection && deltaX >= 0 && deltaX <= threshold) {
|
|
1432
1422
|
return isDeltaX;
|
|
@@ -1452,66 +1442,68 @@ const Content = /*#__PURE__*/ React__default.forwardRef(function({ style, ...res
|
|
|
1452
1442
|
wasBeyondThePointRef.current = false;
|
|
1453
1443
|
onRelease(event);
|
|
1454
1444
|
}
|
|
1455
|
-
return /*#__PURE__*/
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1445
|
+
return /*#__PURE__*/ jsx(Dialog.Viewport, {
|
|
1446
|
+
children: /*#__PURE__*/ jsx(Dialog.Popup, {
|
|
1447
|
+
"data-vaul-drawer-direction": direction,
|
|
1448
|
+
"data-vaul-drawer": "",
|
|
1449
|
+
"data-vaul-delayed-snap-points": delayedSnapPoints ? "true" : "false",
|
|
1450
|
+
"data-vaul-snap-points": isOpen && hasSnapPoints ? "true" : "false",
|
|
1451
|
+
"data-vaul-custom-container": container ? "true" : "false",
|
|
1452
|
+
"data-vaul-animate": shouldAnimate?.current ? "true" : "false",
|
|
1453
|
+
...rest,
|
|
1454
|
+
ref: composedRef,
|
|
1455
|
+
style: snapPointsOffset && snapPointsOffset.length > 0 ? {
|
|
1456
|
+
// @ts-ignore This should not be an error
|
|
1457
|
+
"--snap-point-height": `${snapPointsOffset[activeSnapPointIndex ?? 0]}px`,
|
|
1458
|
+
...style
|
|
1459
|
+
} : style,
|
|
1460
|
+
onPointerDown: (event)=>{
|
|
1461
|
+
if (handleOnly) return;
|
|
1462
|
+
rest.onPointerDown?.(event);
|
|
1463
|
+
pointerStartRef.current = {
|
|
1464
|
+
x: event.pageX,
|
|
1465
|
+
y: event.pageY
|
|
1466
|
+
};
|
|
1467
|
+
onPress(event);
|
|
1468
|
+
},
|
|
1469
|
+
onPointerMove: (event)=>{
|
|
1470
|
+
lastKnownPointerEventRef.current = event;
|
|
1471
|
+
if (handleOnly) return;
|
|
1472
|
+
rest.onPointerMove?.(event);
|
|
1473
|
+
if (!pointerStartRef.current) return;
|
|
1474
|
+
const yPosition = event.pageY - pointerStartRef.current.y;
|
|
1475
|
+
const xPosition = event.pageX - pointerStartRef.current.x;
|
|
1476
|
+
const swipeStartThreshold = event.pointerType === "touch" ? 10 : 2;
|
|
1477
|
+
const delta = {
|
|
1478
|
+
x: xPosition,
|
|
1479
|
+
y: yPosition
|
|
1480
|
+
};
|
|
1481
|
+
const isAllowedToSwipe = isDeltaInDirection(delta, direction, swipeStartThreshold);
|
|
1482
|
+
if (isAllowedToSwipe) onDrag(event);
|
|
1483
|
+
else if (Math.abs(xPosition) > swipeStartThreshold || Math.abs(yPosition) > swipeStartThreshold) {
|
|
1484
|
+
pointerStartRef.current = null;
|
|
1485
|
+
}
|
|
1486
|
+
},
|
|
1487
|
+
onPointerUp: (event)=>{
|
|
1488
|
+
rest.onPointerUp?.(event);
|
|
1493
1489
|
pointerStartRef.current = null;
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
wasBeyondThePointRef.current = false;
|
|
1500
|
-
onRelease(event);
|
|
1501
|
-
},
|
|
1502
|
-
onPointerOut: (event)=>{
|
|
1503
|
-
rest.onPointerOut == null ? void 0 : rest.onPointerOut.call(rest, event);
|
|
1504
|
-
handleOnPointerUp(lastKnownPointerEventRef.current);
|
|
1505
|
-
},
|
|
1506
|
-
onContextMenu: (event)=>{
|
|
1507
|
-
rest.onContextMenu == null ? void 0 : rest.onContextMenu.call(rest, event);
|
|
1508
|
-
if (lastKnownPointerEventRef.current) {
|
|
1490
|
+
wasBeyondThePointRef.current = false;
|
|
1491
|
+
onRelease(event);
|
|
1492
|
+
},
|
|
1493
|
+
onPointerOut: (event)=>{
|
|
1494
|
+
rest.onPointerOut?.(event);
|
|
1509
1495
|
handleOnPointerUp(lastKnownPointerEventRef.current);
|
|
1496
|
+
},
|
|
1497
|
+
onContextMenu: (event)=>{
|
|
1498
|
+
rest.onContextMenu?.(event);
|
|
1499
|
+
if (lastKnownPointerEventRef.current) {
|
|
1500
|
+
handleOnPointerUp(lastKnownPointerEventRef.current);
|
|
1501
|
+
}
|
|
1510
1502
|
}
|
|
1511
|
-
}
|
|
1512
|
-
})
|
|
1503
|
+
})
|
|
1504
|
+
});
|
|
1513
1505
|
});
|
|
1514
|
-
Content.displayName =
|
|
1506
|
+
Content.displayName = "Drawer.Content";
|
|
1515
1507
|
const LONG_HANDLE_PRESS_TIMEOUT = 250;
|
|
1516
1508
|
const DOUBLE_TAP_TIMEOUT = 120;
|
|
1517
1509
|
const Handle = /*#__PURE__*/ React__default.forwardRef(function({ preventCycle = false, children, ...rest }, ref) {
|
|
@@ -1564,7 +1556,7 @@ const Handle = /*#__PURE__*/ React__default.forwardRef(function({ preventCycle =
|
|
|
1564
1556
|
}
|
|
1565
1557
|
shouldCancelInteractionRef.current = false;
|
|
1566
1558
|
}
|
|
1567
|
-
return /*#__PURE__*/
|
|
1559
|
+
return /*#__PURE__*/ jsx("div", {
|
|
1568
1560
|
onClick: handleStartCycle,
|
|
1569
1561
|
onPointerCancel: handleCancelInteraction,
|
|
1570
1562
|
onPointerDown: (e)=>{
|
|
@@ -1582,22 +1574,24 @@ const Handle = /*#__PURE__*/ React__default.forwardRef(function({ preventCycle =
|
|
|
1582
1574
|
},
|
|
1583
1575
|
// onPointerUp is already handled by the content component
|
|
1584
1576
|
ref: ref,
|
|
1585
|
-
"data-vaul-drawer-visible": isOpen ?
|
|
1577
|
+
"data-vaul-drawer-visible": isOpen ? "true" : "false",
|
|
1586
1578
|
"data-vaul-handle": "",
|
|
1587
1579
|
"aria-hidden": "true",
|
|
1588
|
-
...rest
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1580
|
+
...rest,
|
|
1581
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
1582
|
+
"data-vaul-handle-hitarea": "",
|
|
1583
|
+
"aria-hidden": "true",
|
|
1584
|
+
children: children
|
|
1585
|
+
})
|
|
1586
|
+
});
|
|
1593
1587
|
});
|
|
1594
|
-
Handle.displayName =
|
|
1588
|
+
Handle.displayName = "Drawer.Handle";
|
|
1595
1589
|
function NestedRoot({ onDrag, onOpenChange, open: nestedIsOpen, ...rest }) {
|
|
1596
1590
|
const { onNestedDrag, onNestedOpenChange, onNestedRelease } = useDrawerContext();
|
|
1597
1591
|
if (!onNestedDrag) {
|
|
1598
|
-
throw new Error(
|
|
1592
|
+
throw new Error("Drawer.NestedRoot must be placed in another drawer");
|
|
1599
1593
|
}
|
|
1600
|
-
return /*#__PURE__*/
|
|
1594
|
+
return /*#__PURE__*/ jsx(Root, {
|
|
1601
1595
|
nested: true,
|
|
1602
1596
|
open: nestedIsOpen,
|
|
1603
1597
|
onClose: ()=>{
|
|
@@ -1605,13 +1599,13 @@ function NestedRoot({ onDrag, onOpenChange, open: nestedIsOpen, ...rest }) {
|
|
|
1605
1599
|
},
|
|
1606
1600
|
onDrag: (e, p)=>{
|
|
1607
1601
|
onNestedDrag(e, p);
|
|
1608
|
-
onDrag
|
|
1602
|
+
onDrag?.(e, p);
|
|
1609
1603
|
},
|
|
1610
1604
|
onOpenChange: (o)=>{
|
|
1611
1605
|
if (o) {
|
|
1612
1606
|
onNestedOpenChange(o);
|
|
1613
1607
|
}
|
|
1614
|
-
onOpenChange
|
|
1608
|
+
onOpenChange?.(o);
|
|
1615
1609
|
},
|
|
1616
1610
|
onRelease: onNestedRelease,
|
|
1617
1611
|
...rest
|
|
@@ -1620,7 +1614,7 @@ function NestedRoot({ onDrag, onOpenChange, open: nestedIsOpen, ...rest }) {
|
|
|
1620
1614
|
function Portal(props) {
|
|
1621
1615
|
const context = useDrawerContext();
|
|
1622
1616
|
const { container = context.container, ...portalProps } = props;
|
|
1623
|
-
return /*#__PURE__*/
|
|
1617
|
+
return /*#__PURE__*/ jsx(Dialog.Portal, {
|
|
1624
1618
|
container: container,
|
|
1625
1619
|
...portalProps
|
|
1626
1620
|
});
|