@nexub/react 1.1.0 → 1.3.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.
@@ -0,0 +1,1639 @@
1
+ 'use client';
2
+ import {
3
+ glassSurfaceClass
4
+ } from "./chunk-ROZVVWPV.js";
5
+ import {
6
+ cn
7
+ } from "./chunk-AT6RPKU3.js";
8
+
9
+ // src/components/Drawer/Drawer.tsx
10
+ import * as React2 from "react";
11
+ import { Slot } from "@radix-ui/react-slot";
12
+
13
+ // ../../node_modules/.pnpm/vaul@1.1.2_@types+react-dom@19.2.3_@types+react@19.2.14__@types+react@19.2.14_react-dom_d9bfd38a4ee4f41de100e4d447baf4a5/node_modules/vaul/dist/index.mjs
14
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
15
+ import * as React from "react";
16
+ import React__default, { useLayoutEffect, useEffect, useMemo } from "react";
17
+ var DrawerContext = React__default.createContext({
18
+ drawerRef: {
19
+ current: null
20
+ },
21
+ overlayRef: {
22
+ current: null
23
+ },
24
+ onPress: () => {
25
+ },
26
+ onRelease: () => {
27
+ },
28
+ onDrag: () => {
29
+ },
30
+ onNestedDrag: () => {
31
+ },
32
+ onNestedOpenChange: () => {
33
+ },
34
+ onNestedRelease: () => {
35
+ },
36
+ openProp: void 0,
37
+ dismissible: false,
38
+ isOpen: false,
39
+ isDragging: false,
40
+ keyboardIsOpen: {
41
+ current: false
42
+ },
43
+ snapPointsOffset: null,
44
+ snapPoints: null,
45
+ handleOnly: false,
46
+ modal: false,
47
+ shouldFade: false,
48
+ activeSnapPoint: null,
49
+ onOpenChange: () => {
50
+ },
51
+ setActiveSnapPoint: () => {
52
+ },
53
+ closeDrawer: () => {
54
+ },
55
+ direction: "bottom",
56
+ shouldAnimate: {
57
+ current: true
58
+ },
59
+ shouldScaleBackground: false,
60
+ setBackgroundColorOnScale: true,
61
+ noBodyStyles: false,
62
+ container: null,
63
+ autoFocus: false
64
+ });
65
+ var useDrawerContext = () => {
66
+ const context = React__default.useContext(DrawerContext);
67
+ if (!context) {
68
+ throw new Error("useDrawerContext must be used within a Drawer.Root");
69
+ }
70
+ return context;
71
+ };
72
+ function isMobileFirefox() {
73
+ const userAgent = navigator.userAgent;
74
+ return typeof window !== "undefined" && (/Firefox/.test(userAgent) && /Mobile/.test(userAgent) || // Android Firefox
75
+ /FxiOS/.test(userAgent));
76
+ }
77
+ function isMac() {
78
+ return testPlatform(/^Mac/);
79
+ }
80
+ function isIPhone() {
81
+ return testPlatform(/^iPhone/);
82
+ }
83
+ function isSafari() {
84
+ return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
85
+ }
86
+ function isIPad() {
87
+ return testPlatform(/^iPad/) || // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
88
+ isMac() && navigator.maxTouchPoints > 1;
89
+ }
90
+ function isIOS() {
91
+ return isIPhone() || isIPad();
92
+ }
93
+ function testPlatform(re) {
94
+ return typeof window !== "undefined" && window.navigator != null ? re.test(window.navigator.platform) : void 0;
95
+ }
96
+ var KEYBOARD_BUFFER = 24;
97
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
98
+ function chain$1(...callbacks) {
99
+ return (...args) => {
100
+ for (let callback of callbacks) {
101
+ if (typeof callback === "function") {
102
+ callback(...args);
103
+ }
104
+ }
105
+ };
106
+ }
107
+ var visualViewport = typeof document !== "undefined" && window.visualViewport;
108
+ function isScrollable(node) {
109
+ let style = window.getComputedStyle(node);
110
+ return /(auto|scroll)/.test(style.overflow + style.overflowX + style.overflowY);
111
+ }
112
+ function getScrollParent(node) {
113
+ if (isScrollable(node)) {
114
+ node = node.parentElement;
115
+ }
116
+ while (node && !isScrollable(node)) {
117
+ node = node.parentElement;
118
+ }
119
+ return node || document.scrollingElement || document.documentElement;
120
+ }
121
+ var nonTextInputTypes = /* @__PURE__ */ new Set([
122
+ "checkbox",
123
+ "radio",
124
+ "range",
125
+ "color",
126
+ "file",
127
+ "image",
128
+ "button",
129
+ "submit",
130
+ "reset"
131
+ ]);
132
+ var preventScrollCount = 0;
133
+ var restore;
134
+ function usePreventScroll(options = {}) {
135
+ let { isDisabled } = options;
136
+ useIsomorphicLayoutEffect(() => {
137
+ if (isDisabled) {
138
+ return;
139
+ }
140
+ preventScrollCount++;
141
+ if (preventScrollCount === 1) {
142
+ if (isIOS()) {
143
+ restore = preventScrollMobileSafari();
144
+ }
145
+ }
146
+ return () => {
147
+ preventScrollCount--;
148
+ if (preventScrollCount === 0) {
149
+ restore == null ? void 0 : restore();
150
+ }
151
+ };
152
+ }, [
153
+ isDisabled
154
+ ]);
155
+ }
156
+ function preventScrollMobileSafari() {
157
+ let scrollable;
158
+ let lastY = 0;
159
+ let onTouchStart = (e) => {
160
+ scrollable = getScrollParent(e.target);
161
+ if (scrollable === document.documentElement && scrollable === document.body) {
162
+ return;
163
+ }
164
+ lastY = e.changedTouches[0].pageY;
165
+ };
166
+ let onTouchMove = (e) => {
167
+ if (!scrollable || scrollable === document.documentElement || scrollable === document.body) {
168
+ e.preventDefault();
169
+ return;
170
+ }
171
+ let y = e.changedTouches[0].pageY;
172
+ let scrollTop = scrollable.scrollTop;
173
+ let bottom = scrollable.scrollHeight - scrollable.clientHeight;
174
+ if (bottom === 0) {
175
+ return;
176
+ }
177
+ if (scrollTop <= 0 && y > lastY || scrollTop >= bottom && y < lastY) {
178
+ e.preventDefault();
179
+ }
180
+ lastY = y;
181
+ };
182
+ let onTouchEnd = (e) => {
183
+ let target = e.target;
184
+ if (isInput(target) && target !== document.activeElement) {
185
+ e.preventDefault();
186
+ target.style.transform = "translateY(-2000px)";
187
+ target.focus();
188
+ requestAnimationFrame(() => {
189
+ target.style.transform = "";
190
+ });
191
+ }
192
+ };
193
+ let onFocus = (e) => {
194
+ let target = e.target;
195
+ if (isInput(target)) {
196
+ target.style.transform = "translateY(-2000px)";
197
+ requestAnimationFrame(() => {
198
+ target.style.transform = "";
199
+ if (visualViewport) {
200
+ if (visualViewport.height < window.innerHeight) {
201
+ requestAnimationFrame(() => {
202
+ scrollIntoView(target);
203
+ });
204
+ } else {
205
+ visualViewport.addEventListener("resize", () => scrollIntoView(target), {
206
+ once: true
207
+ });
208
+ }
209
+ }
210
+ });
211
+ }
212
+ };
213
+ let onWindowScroll = () => {
214
+ window.scrollTo(0, 0);
215
+ };
216
+ let scrollX = window.pageXOffset;
217
+ let scrollY = window.pageYOffset;
218
+ let restoreStyles = chain$1(setStyle(document.documentElement, "paddingRight", `${window.innerWidth - document.documentElement.clientWidth}px`));
219
+ window.scrollTo(0, 0);
220
+ let removeEvents = chain$1(addEvent(document, "touchstart", onTouchStart, {
221
+ passive: false,
222
+ capture: true
223
+ }), addEvent(document, "touchmove", onTouchMove, {
224
+ passive: false,
225
+ capture: true
226
+ }), addEvent(document, "touchend", onTouchEnd, {
227
+ passive: false,
228
+ capture: true
229
+ }), addEvent(document, "focus", onFocus, true), addEvent(window, "scroll", onWindowScroll));
230
+ return () => {
231
+ restoreStyles();
232
+ removeEvents();
233
+ window.scrollTo(scrollX, scrollY);
234
+ };
235
+ }
236
+ function setStyle(element, style, value) {
237
+ let cur = element.style[style];
238
+ element.style[style] = value;
239
+ return () => {
240
+ element.style[style] = cur;
241
+ };
242
+ }
243
+ function addEvent(target, event, handler, options) {
244
+ target.addEventListener(event, handler, options);
245
+ return () => {
246
+ target.removeEventListener(event, handler, options);
247
+ };
248
+ }
249
+ function scrollIntoView(target) {
250
+ let root = document.scrollingElement || document.documentElement;
251
+ while (target && target !== root) {
252
+ let scrollable = getScrollParent(target);
253
+ if (scrollable !== document.documentElement && scrollable !== document.body && scrollable !== target) {
254
+ let scrollableTop = scrollable.getBoundingClientRect().top;
255
+ let targetTop = target.getBoundingClientRect().top;
256
+ let targetBottom = target.getBoundingClientRect().bottom;
257
+ const keyboardHeight = scrollable.getBoundingClientRect().bottom + KEYBOARD_BUFFER;
258
+ if (targetBottom > keyboardHeight) {
259
+ scrollable.scrollTop += targetTop - scrollableTop;
260
+ }
261
+ }
262
+ target = scrollable.parentElement;
263
+ }
264
+ }
265
+ function isInput(target) {
266
+ return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
267
+ }
268
+ function setRef(ref, value) {
269
+ if (typeof ref === "function") {
270
+ ref(value);
271
+ } else if (ref !== null && ref !== void 0) {
272
+ ref.current = value;
273
+ }
274
+ }
275
+ function composeRefs(...refs) {
276
+ return (node) => refs.forEach((ref) => setRef(ref, node));
277
+ }
278
+ function useComposedRefs(...refs) {
279
+ return React.useCallback(composeRefs(...refs), refs);
280
+ }
281
+ var cache = /* @__PURE__ */ new WeakMap();
282
+ function set(el, styles, ignoreCache = false) {
283
+ if (!el || !(el instanceof HTMLElement)) return;
284
+ let originalStyles = {};
285
+ Object.entries(styles).forEach(([key, value]) => {
286
+ if (key.startsWith("--")) {
287
+ el.style.setProperty(key, value);
288
+ return;
289
+ }
290
+ originalStyles[key] = el.style[key];
291
+ el.style[key] = value;
292
+ });
293
+ if (ignoreCache) return;
294
+ cache.set(el, originalStyles);
295
+ }
296
+ function reset(el, prop) {
297
+ if (!el || !(el instanceof HTMLElement)) return;
298
+ let originalStyles = cache.get(el);
299
+ if (!originalStyles) {
300
+ return;
301
+ }
302
+ {
303
+ el.style[prop] = originalStyles[prop];
304
+ }
305
+ }
306
+ var isVertical = (direction) => {
307
+ switch (direction) {
308
+ case "top":
309
+ case "bottom":
310
+ return true;
311
+ case "left":
312
+ case "right":
313
+ return false;
314
+ default:
315
+ return direction;
316
+ }
317
+ };
318
+ function getTranslate(element, direction) {
319
+ if (!element) {
320
+ return null;
321
+ }
322
+ const style = window.getComputedStyle(element);
323
+ const transform = (
324
+ // @ts-ignore
325
+ style.transform || style.webkitTransform || style.mozTransform
326
+ );
327
+ let mat = transform.match(/^matrix3d\((.+)\)$/);
328
+ if (mat) {
329
+ return parseFloat(mat[1].split(", ")[isVertical(direction) ? 13 : 12]);
330
+ }
331
+ mat = transform.match(/^matrix\((.+)\)$/);
332
+ return mat ? parseFloat(mat[1].split(", ")[isVertical(direction) ? 5 : 4]) : null;
333
+ }
334
+ function dampenValue(v) {
335
+ return 8 * (Math.log(v + 1) - 2);
336
+ }
337
+ function assignStyle(element, style) {
338
+ if (!element) return () => {
339
+ };
340
+ const prevStyle = element.style.cssText;
341
+ Object.assign(element.style, style);
342
+ return () => {
343
+ element.style.cssText = prevStyle;
344
+ };
345
+ }
346
+ function chain(...fns) {
347
+ return (...args) => {
348
+ for (const fn of fns) {
349
+ if (typeof fn === "function") {
350
+ fn(...args);
351
+ }
352
+ }
353
+ };
354
+ }
355
+ var TRANSITIONS = {
356
+ DURATION: 0.5,
357
+ EASE: [
358
+ 0.32,
359
+ 0.72,
360
+ 0,
361
+ 1
362
+ ]
363
+ };
364
+ var VELOCITY_THRESHOLD = 0.4;
365
+ var CLOSE_THRESHOLD = 0.25;
366
+ var SCROLL_LOCK_TIMEOUT = 100;
367
+ var BORDER_RADIUS = 8;
368
+ var NESTED_DISPLACEMENT = 16;
369
+ var WINDOW_TOP_OFFSET = 26;
370
+ var DRAG_CLASS = "vaul-dragging";
371
+ function useCallbackRef(callback) {
372
+ const callbackRef = React__default.useRef(callback);
373
+ React__default.useEffect(() => {
374
+ callbackRef.current = callback;
375
+ });
376
+ return React__default.useMemo(() => (...args) => callbackRef.current == null ? void 0 : callbackRef.current.call(callbackRef, ...args), []);
377
+ }
378
+ function useUncontrolledState({ defaultProp, onChange }) {
379
+ const uncontrolledState = React__default.useState(defaultProp);
380
+ const [value] = uncontrolledState;
381
+ const prevValueRef = React__default.useRef(value);
382
+ const handleChange = useCallbackRef(onChange);
383
+ React__default.useEffect(() => {
384
+ if (prevValueRef.current !== value) {
385
+ handleChange(value);
386
+ prevValueRef.current = value;
387
+ }
388
+ }, [
389
+ value,
390
+ prevValueRef,
391
+ handleChange
392
+ ]);
393
+ return uncontrolledState;
394
+ }
395
+ function useControllableState({ prop, defaultProp, onChange = () => {
396
+ } }) {
397
+ const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({
398
+ defaultProp,
399
+ onChange
400
+ });
401
+ const isControlled = prop !== void 0;
402
+ const value = isControlled ? prop : uncontrolledProp;
403
+ const handleChange = useCallbackRef(onChange);
404
+ const setValue = React__default.useCallback((nextValue) => {
405
+ if (isControlled) {
406
+ const setter = nextValue;
407
+ const value2 = typeof nextValue === "function" ? setter(prop) : nextValue;
408
+ if (value2 !== prop) handleChange(value2);
409
+ } else {
410
+ setUncontrolledProp(nextValue);
411
+ }
412
+ }, [
413
+ isControlled,
414
+ prop,
415
+ setUncontrolledProp,
416
+ handleChange
417
+ ]);
418
+ return [
419
+ value,
420
+ setValue
421
+ ];
422
+ }
423
+ function useSnapPoints({ activeSnapPointProp, setActiveSnapPointProp, snapPoints, drawerRef, overlayRef, fadeFromIndex, onSnapPointChange, direction = "bottom", container, snapToSequentialPoint }) {
424
+ const [activeSnapPoint, setActiveSnapPoint] = useControllableState({
425
+ prop: activeSnapPointProp,
426
+ defaultProp: snapPoints == null ? void 0 : snapPoints[0],
427
+ onChange: setActiveSnapPointProp
428
+ });
429
+ const [windowDimensions, setWindowDimensions] = React__default.useState(typeof window !== "undefined" ? {
430
+ innerWidth: window.innerWidth,
431
+ innerHeight: window.innerHeight
432
+ } : void 0);
433
+ React__default.useEffect(() => {
434
+ function onResize() {
435
+ setWindowDimensions({
436
+ innerWidth: window.innerWidth,
437
+ innerHeight: window.innerHeight
438
+ });
439
+ }
440
+ window.addEventListener("resize", onResize);
441
+ return () => window.removeEventListener("resize", onResize);
442
+ }, []);
443
+ const isLastSnapPoint = React__default.useMemo(() => activeSnapPoint === (snapPoints == null ? void 0 : snapPoints[snapPoints.length - 1]) || null, [
444
+ snapPoints,
445
+ activeSnapPoint
446
+ ]);
447
+ const activeSnapPointIndex = React__default.useMemo(() => {
448
+ var _snapPoints_findIndex;
449
+ return (_snapPoints_findIndex = snapPoints == null ? void 0 : snapPoints.findIndex((snapPoint) => snapPoint === activeSnapPoint)) != null ? _snapPoints_findIndex : null;
450
+ }, [
451
+ snapPoints,
452
+ activeSnapPoint
453
+ ]);
454
+ const shouldFade = snapPoints && snapPoints.length > 0 && (fadeFromIndex || fadeFromIndex === 0) && !Number.isNaN(fadeFromIndex) && snapPoints[fadeFromIndex] === activeSnapPoint || !snapPoints;
455
+ const snapPointsOffset = React__default.useMemo(() => {
456
+ const containerSize = container ? {
457
+ width: container.getBoundingClientRect().width,
458
+ height: container.getBoundingClientRect().height
459
+ } : typeof window !== "undefined" ? {
460
+ width: window.innerWidth,
461
+ height: window.innerHeight
462
+ } : {
463
+ width: 0,
464
+ height: 0
465
+ };
466
+ var _snapPoints_map;
467
+ return (_snapPoints_map = snapPoints == null ? void 0 : snapPoints.map((snapPoint) => {
468
+ const isPx = typeof snapPoint === "string";
469
+ let snapPointAsNumber = 0;
470
+ if (isPx) {
471
+ snapPointAsNumber = parseInt(snapPoint, 10);
472
+ }
473
+ if (isVertical(direction)) {
474
+ const height = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.height : 0;
475
+ if (windowDimensions) {
476
+ return direction === "bottom" ? containerSize.height - height : -containerSize.height + height;
477
+ }
478
+ return height;
479
+ }
480
+ const width = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.width : 0;
481
+ if (windowDimensions) {
482
+ return direction === "right" ? containerSize.width - width : -containerSize.width + width;
483
+ }
484
+ return width;
485
+ })) != null ? _snapPoints_map : [];
486
+ }, [
487
+ snapPoints,
488
+ windowDimensions,
489
+ container
490
+ ]);
491
+ const activeSnapPointOffset = React__default.useMemo(() => activeSnapPointIndex !== null ? snapPointsOffset == null ? void 0 : snapPointsOffset[activeSnapPointIndex] : null, [
492
+ snapPointsOffset,
493
+ activeSnapPointIndex
494
+ ]);
495
+ const snapToPoint = React__default.useCallback((dimension) => {
496
+ var _snapPointsOffset_findIndex;
497
+ const newSnapPointIndex = (_snapPointsOffset_findIndex = snapPointsOffset == null ? void 0 : snapPointsOffset.findIndex((snapPointDim) => snapPointDim === dimension)) != null ? _snapPointsOffset_findIndex : null;
498
+ onSnapPointChange(newSnapPointIndex);
499
+ set(drawerRef.current, {
500
+ transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
501
+ transform: isVertical(direction) ? `translate3d(0, ${dimension}px, 0)` : `translate3d(${dimension}px, 0, 0)`
502
+ });
503
+ if (snapPointsOffset && newSnapPointIndex !== snapPointsOffset.length - 1 && fadeFromIndex !== void 0 && newSnapPointIndex !== fadeFromIndex && newSnapPointIndex < fadeFromIndex) {
504
+ set(overlayRef.current, {
505
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
506
+ opacity: "0"
507
+ });
508
+ } else {
509
+ set(overlayRef.current, {
510
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
511
+ opacity: "1"
512
+ });
513
+ }
514
+ setActiveSnapPoint(snapPoints == null ? void 0 : snapPoints[Math.max(newSnapPointIndex, 0)]);
515
+ }, [
516
+ drawerRef.current,
517
+ snapPoints,
518
+ snapPointsOffset,
519
+ fadeFromIndex,
520
+ overlayRef,
521
+ setActiveSnapPoint
522
+ ]);
523
+ React__default.useEffect(() => {
524
+ if (activeSnapPoint || activeSnapPointProp) {
525
+ var _snapPoints_findIndex;
526
+ const newIndex = (_snapPoints_findIndex = snapPoints == null ? void 0 : snapPoints.findIndex((snapPoint) => snapPoint === activeSnapPointProp || snapPoint === activeSnapPoint)) != null ? _snapPoints_findIndex : -1;
527
+ if (snapPointsOffset && newIndex !== -1 && typeof snapPointsOffset[newIndex] === "number") {
528
+ snapToPoint(snapPointsOffset[newIndex]);
529
+ }
530
+ }
531
+ }, [
532
+ activeSnapPoint,
533
+ activeSnapPointProp,
534
+ snapPoints,
535
+ snapPointsOffset,
536
+ snapToPoint
537
+ ]);
538
+ function onRelease({ draggedDistance, closeDrawer, velocity, dismissible }) {
539
+ if (fadeFromIndex === void 0) return;
540
+ const currentPosition = direction === "bottom" || direction === "right" ? (activeSnapPointOffset != null ? activeSnapPointOffset : 0) - draggedDistance : (activeSnapPointOffset != null ? activeSnapPointOffset : 0) + draggedDistance;
541
+ const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
542
+ const isFirst = activeSnapPointIndex === 0;
543
+ const hasDraggedUp = draggedDistance > 0;
544
+ if (isOverlaySnapPoint) {
545
+ set(overlayRef.current, {
546
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`
547
+ });
548
+ }
549
+ if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) {
550
+ if (dismissible) closeDrawer();
551
+ else snapToPoint(snapPointsOffset[0]);
552
+ return;
553
+ }
554
+ if (!snapToSequentialPoint && velocity > 2 && hasDraggedUp && snapPointsOffset && snapPoints) {
555
+ snapToPoint(snapPointsOffset[snapPoints.length - 1]);
556
+ return;
557
+ }
558
+ const closestSnapPoint = snapPointsOffset == null ? void 0 : snapPointsOffset.reduce((prev, curr) => {
559
+ if (typeof prev !== "number" || typeof curr !== "number") return prev;
560
+ return Math.abs(curr - currentPosition) < Math.abs(prev - currentPosition) ? curr : prev;
561
+ });
562
+ const dim = isVertical(direction) ? window.innerHeight : window.innerWidth;
563
+ if (velocity > VELOCITY_THRESHOLD && Math.abs(draggedDistance) < dim * 0.4) {
564
+ const dragDirection = hasDraggedUp ? 1 : -1;
565
+ if (dragDirection > 0 && isLastSnapPoint && snapPoints) {
566
+ snapToPoint(snapPointsOffset[snapPoints.length - 1]);
567
+ return;
568
+ }
569
+ if (isFirst && dragDirection < 0 && dismissible) {
570
+ closeDrawer();
571
+ }
572
+ if (activeSnapPointIndex === null) return;
573
+ snapToPoint(snapPointsOffset[activeSnapPointIndex + dragDirection]);
574
+ return;
575
+ }
576
+ snapToPoint(closestSnapPoint);
577
+ }
578
+ function onDrag({ draggedDistance }) {
579
+ if (activeSnapPointOffset === null) return;
580
+ const newValue = direction === "bottom" || direction === "right" ? activeSnapPointOffset - draggedDistance : activeSnapPointOffset + draggedDistance;
581
+ if ((direction === "bottom" || direction === "right") && newValue < snapPointsOffset[snapPointsOffset.length - 1]) {
582
+ return;
583
+ }
584
+ if ((direction === "top" || direction === "left") && newValue > snapPointsOffset[snapPointsOffset.length - 1]) {
585
+ return;
586
+ }
587
+ set(drawerRef.current, {
588
+ transform: isVertical(direction) ? `translate3d(0, ${newValue}px, 0)` : `translate3d(${newValue}px, 0, 0)`
589
+ });
590
+ }
591
+ function getPercentageDragged(absDraggedDistance, isDraggingDown) {
592
+ if (!snapPoints || typeof activeSnapPointIndex !== "number" || !snapPointsOffset || fadeFromIndex === void 0) return null;
593
+ const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1;
594
+ const isOverlaySnapPointOrHigher = activeSnapPointIndex >= fadeFromIndex;
595
+ if (isOverlaySnapPointOrHigher && isDraggingDown) {
596
+ return 0;
597
+ }
598
+ if (isOverlaySnapPoint && !isDraggingDown) return 1;
599
+ if (!shouldFade && !isOverlaySnapPoint) return null;
600
+ const targetSnapPointIndex = isOverlaySnapPoint ? activeSnapPointIndex + 1 : activeSnapPointIndex - 1;
601
+ const snapPointDistance = isOverlaySnapPoint ? snapPointsOffset[targetSnapPointIndex] - snapPointsOffset[targetSnapPointIndex - 1] : snapPointsOffset[targetSnapPointIndex + 1] - snapPointsOffset[targetSnapPointIndex];
602
+ const percentageDragged = absDraggedDistance / Math.abs(snapPointDistance);
603
+ if (isOverlaySnapPoint) {
604
+ return 1 - percentageDragged;
605
+ } else {
606
+ return percentageDragged;
607
+ }
608
+ }
609
+ return {
610
+ isLastSnapPoint,
611
+ activeSnapPoint,
612
+ shouldFade,
613
+ getPercentageDragged,
614
+ setActiveSnapPoint,
615
+ activeSnapPointIndex,
616
+ onRelease,
617
+ onDrag,
618
+ snapPointsOffset
619
+ };
620
+ }
621
+ var noop = () => () => {
622
+ };
623
+ function useScaleBackground() {
624
+ const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext();
625
+ const timeoutIdRef = React__default.useRef(null);
626
+ const initialBackgroundColor = useMemo(() => document.body.style.backgroundColor, []);
627
+ function getScale() {
628
+ return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
629
+ }
630
+ React__default.useEffect(() => {
631
+ if (isOpen && shouldScaleBackground) {
632
+ if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current);
633
+ const wrapper = document.querySelector("[data-vaul-drawer-wrapper]") || document.querySelector("[vaul-drawer-wrapper]");
634
+ if (!wrapper) return;
635
+ chain(setBackgroundColorOnScale && !noBodyStyles ? assignStyle(document.body, {
636
+ background: "black"
637
+ }) : noop, assignStyle(wrapper, {
638
+ transformOrigin: isVertical(direction) ? "top" : "left",
639
+ transitionProperty: "transform, border-radius",
640
+ transitionDuration: `${TRANSITIONS.DURATION}s`,
641
+ transitionTimingFunction: `cubic-bezier(${TRANSITIONS.EASE.join(",")})`
642
+ }));
643
+ const wrapperStylesCleanup = assignStyle(wrapper, {
644
+ borderRadius: `${BORDER_RADIUS}px`,
645
+ overflow: "hidden",
646
+ ...isVertical(direction) ? {
647
+ transform: `scale(${getScale()}) translate3d(0, calc(env(safe-area-inset-top) + 14px), 0)`
648
+ } : {
649
+ transform: `scale(${getScale()}) translate3d(calc(env(safe-area-inset-top) + 14px), 0, 0)`
650
+ }
651
+ });
652
+ return () => {
653
+ wrapperStylesCleanup();
654
+ timeoutIdRef.current = window.setTimeout(() => {
655
+ if (initialBackgroundColor) {
656
+ document.body.style.background = initialBackgroundColor;
657
+ } else {
658
+ document.body.style.removeProperty("background");
659
+ }
660
+ }, TRANSITIONS.DURATION * 1e3);
661
+ };
662
+ }
663
+ }, [
664
+ isOpen,
665
+ shouldScaleBackground,
666
+ initialBackgroundColor
667
+ ]);
668
+ }
669
+ var previousBodyPosition = null;
670
+ function usePositionFixed({ isOpen, modal, nested, hasBeenOpened, preventScrollRestoration, noBodyStyles }) {
671
+ const [activeUrl, setActiveUrl] = React__default.useState(() => typeof window !== "undefined" ? window.location.href : "");
672
+ const scrollPos = React__default.useRef(0);
673
+ const setPositionFixed = React__default.useCallback(() => {
674
+ if (!isSafari()) return;
675
+ if (previousBodyPosition === null && isOpen && !noBodyStyles) {
676
+ previousBodyPosition = {
677
+ position: document.body.style.position,
678
+ top: document.body.style.top,
679
+ left: document.body.style.left,
680
+ height: document.body.style.height,
681
+ right: "unset"
682
+ };
683
+ const { scrollX, innerHeight } = window;
684
+ document.body.style.setProperty("position", "fixed", "important");
685
+ Object.assign(document.body.style, {
686
+ top: `${-scrollPos.current}px`,
687
+ left: `${-scrollX}px`,
688
+ right: "0px",
689
+ height: "auto"
690
+ });
691
+ window.setTimeout(() => window.requestAnimationFrame(() => {
692
+ const bottomBarHeight = innerHeight - window.innerHeight;
693
+ if (bottomBarHeight && scrollPos.current >= innerHeight) {
694
+ document.body.style.top = `${-(scrollPos.current + bottomBarHeight)}px`;
695
+ }
696
+ }), 300);
697
+ }
698
+ }, [
699
+ isOpen
700
+ ]);
701
+ const restorePositionSetting = React__default.useCallback(() => {
702
+ if (!isSafari()) return;
703
+ if (previousBodyPosition !== null && !noBodyStyles) {
704
+ const y = -parseInt(document.body.style.top, 10);
705
+ const x = -parseInt(document.body.style.left, 10);
706
+ Object.assign(document.body.style, previousBodyPosition);
707
+ window.requestAnimationFrame(() => {
708
+ if (preventScrollRestoration && activeUrl !== window.location.href) {
709
+ setActiveUrl(window.location.href);
710
+ return;
711
+ }
712
+ window.scrollTo(x, y);
713
+ });
714
+ previousBodyPosition = null;
715
+ }
716
+ }, [
717
+ activeUrl
718
+ ]);
719
+ React__default.useEffect(() => {
720
+ function onScroll() {
721
+ scrollPos.current = window.scrollY;
722
+ }
723
+ onScroll();
724
+ window.addEventListener("scroll", onScroll);
725
+ return () => {
726
+ window.removeEventListener("scroll", onScroll);
727
+ };
728
+ }, []);
729
+ React__default.useEffect(() => {
730
+ if (!modal) return;
731
+ return () => {
732
+ if (typeof document === "undefined") return;
733
+ const hasDrawerOpened = !!document.querySelector("[data-vaul-drawer]");
734
+ if (hasDrawerOpened) return;
735
+ restorePositionSetting();
736
+ };
737
+ }, [
738
+ modal,
739
+ restorePositionSetting
740
+ ]);
741
+ React__default.useEffect(() => {
742
+ if (nested || !hasBeenOpened) return;
743
+ if (isOpen) {
744
+ const isStandalone = window.matchMedia("(display-mode: standalone)").matches;
745
+ !isStandalone && setPositionFixed();
746
+ if (!modal) {
747
+ window.setTimeout(() => {
748
+ restorePositionSetting();
749
+ }, 500);
750
+ }
751
+ } else {
752
+ restorePositionSetting();
753
+ }
754
+ }, [
755
+ isOpen,
756
+ hasBeenOpened,
757
+ activeUrl,
758
+ modal,
759
+ nested,
760
+ setPositionFixed,
761
+ restorePositionSetting
762
+ ]);
763
+ return {
764
+ restorePositionSetting
765
+ };
766
+ }
767
+ function Root2({ 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 }) {
768
+ var _drawerRef_current, _drawerRef_current1;
769
+ const [isOpen = false, setIsOpen] = useControllableState({
770
+ defaultProp: defaultOpen,
771
+ prop: openProp,
772
+ onChange: (o) => {
773
+ onOpenChange == null ? void 0 : onOpenChange(o);
774
+ if (!o && !nested) {
775
+ restorePositionSetting();
776
+ }
777
+ setTimeout(() => {
778
+ onAnimationEnd == null ? void 0 : onAnimationEnd(o);
779
+ }, TRANSITIONS.DURATION * 1e3);
780
+ if (o && !modal) {
781
+ if (typeof window !== "undefined") {
782
+ window.requestAnimationFrame(() => {
783
+ document.body.style.pointerEvents = "auto";
784
+ });
785
+ }
786
+ }
787
+ if (!o) {
788
+ document.body.style.pointerEvents = "auto";
789
+ }
790
+ }
791
+ });
792
+ const [hasBeenOpened, setHasBeenOpened] = React__default.useState(false);
793
+ const [isDragging, setIsDragging] = React__default.useState(false);
794
+ const [justReleased, setJustReleased] = React__default.useState(false);
795
+ const overlayRef = React__default.useRef(null);
796
+ const openTime = React__default.useRef(null);
797
+ const dragStartTime = React__default.useRef(null);
798
+ const dragEndTime = React__default.useRef(null);
799
+ const lastTimeDragPrevented = React__default.useRef(null);
800
+ const isAllowedToDrag = React__default.useRef(false);
801
+ const nestedOpenChangeTimer = React__default.useRef(null);
802
+ const pointerStart = React__default.useRef(0);
803
+ const keyboardIsOpen = React__default.useRef(false);
804
+ const shouldAnimate = React__default.useRef(!defaultOpen);
805
+ const previousDiffFromInitial = React__default.useRef(0);
806
+ const drawerRef = React__default.useRef(null);
807
+ const drawerHeightRef = React__default.useRef(((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0);
808
+ const drawerWidthRef = React__default.useRef(((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0);
809
+ const initialDrawerHeight = React__default.useRef(0);
810
+ const onSnapPointChange = React__default.useCallback((activeSnapPointIndex2) => {
811
+ if (snapPoints && activeSnapPointIndex2 === snapPointsOffset.length - 1) openTime.current = /* @__PURE__ */ new Date();
812
+ }, []);
813
+ const { activeSnapPoint, activeSnapPointIndex, setActiveSnapPoint, onRelease: onReleaseSnapPoints, snapPointsOffset, onDrag: onDragSnapPoints, shouldFade, getPercentageDragged: getSnapPointsPercentageDragged } = useSnapPoints({
814
+ snapPoints,
815
+ activeSnapPointProp,
816
+ setActiveSnapPointProp,
817
+ drawerRef,
818
+ fadeFromIndex,
819
+ overlayRef,
820
+ onSnapPointChange,
821
+ direction,
822
+ container,
823
+ snapToSequentialPoint
824
+ });
825
+ usePreventScroll({
826
+ isDisabled: !isOpen || isDragging || !modal || justReleased || !hasBeenOpened || !repositionInputs || !disablePreventScroll
827
+ });
828
+ const { restorePositionSetting } = usePositionFixed({
829
+ isOpen,
830
+ modal,
831
+ nested: nested != null ? nested : false,
832
+ hasBeenOpened,
833
+ preventScrollRestoration,
834
+ noBodyStyles
835
+ });
836
+ function getScale() {
837
+ return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth;
838
+ }
839
+ function onPress(event) {
840
+ var _drawerRef_current2, _drawerRef_current12;
841
+ if (!dismissible && !snapPoints) return;
842
+ if (drawerRef.current && !drawerRef.current.contains(event.target)) return;
843
+ drawerHeightRef.current = ((_drawerRef_current2 = drawerRef.current) == null ? void 0 : _drawerRef_current2.getBoundingClientRect().height) || 0;
844
+ drawerWidthRef.current = ((_drawerRef_current12 = drawerRef.current) == null ? void 0 : _drawerRef_current12.getBoundingClientRect().width) || 0;
845
+ setIsDragging(true);
846
+ dragStartTime.current = /* @__PURE__ */ new Date();
847
+ if (isIOS()) {
848
+ window.addEventListener("touchend", () => isAllowedToDrag.current = false, {
849
+ once: true
850
+ });
851
+ }
852
+ event.target.setPointerCapture(event.pointerId);
853
+ pointerStart.current = isVertical(direction) ? event.pageY : event.pageX;
854
+ }
855
+ function shouldDrag(el, isDraggingInDirection) {
856
+ var _window_getSelection;
857
+ let element = el;
858
+ const highlightedText = (_window_getSelection = window.getSelection()) == null ? void 0 : _window_getSelection.toString();
859
+ const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null;
860
+ const date = /* @__PURE__ */ new Date();
861
+ if (element.tagName === "SELECT") {
862
+ return false;
863
+ }
864
+ if (element.hasAttribute("data-vaul-no-drag") || element.closest("[data-vaul-no-drag]")) {
865
+ return false;
866
+ }
867
+ if (direction === "right" || direction === "left") {
868
+ return true;
869
+ }
870
+ if (openTime.current && date.getTime() - openTime.current.getTime() < 500) {
871
+ return false;
872
+ }
873
+ if (swipeAmount !== null) {
874
+ if (direction === "bottom" ? swipeAmount > 0 : swipeAmount < 0) {
875
+ return true;
876
+ }
877
+ }
878
+ if (highlightedText && highlightedText.length > 0) {
879
+ return false;
880
+ }
881
+ if (lastTimeDragPrevented.current && date.getTime() - lastTimeDragPrevented.current.getTime() < scrollLockTimeout && swipeAmount === 0) {
882
+ lastTimeDragPrevented.current = date;
883
+ return false;
884
+ }
885
+ if (isDraggingInDirection) {
886
+ lastTimeDragPrevented.current = date;
887
+ return false;
888
+ }
889
+ while (element) {
890
+ if (element.scrollHeight > element.clientHeight) {
891
+ if (element.scrollTop !== 0) {
892
+ lastTimeDragPrevented.current = /* @__PURE__ */ new Date();
893
+ return false;
894
+ }
895
+ if (element.getAttribute("role") === "dialog") {
896
+ return true;
897
+ }
898
+ }
899
+ element = element.parentNode;
900
+ }
901
+ return true;
902
+ }
903
+ function onDrag(event) {
904
+ if (!drawerRef.current) {
905
+ return;
906
+ }
907
+ if (isDragging) {
908
+ const directionMultiplier = direction === "bottom" || direction === "right" ? 1 : -1;
909
+ const draggedDistance = (pointerStart.current - (isVertical(direction) ? event.pageY : event.pageX)) * directionMultiplier;
910
+ const isDraggingInDirection = draggedDistance > 0;
911
+ const noCloseSnapPointsPreCondition = snapPoints && !dismissible && !isDraggingInDirection;
912
+ if (noCloseSnapPointsPreCondition && activeSnapPointIndex === 0) return;
913
+ const absDraggedDistance = Math.abs(draggedDistance);
914
+ const wrapper = document.querySelector("[data-vaul-drawer-wrapper]");
915
+ const drawerDimension = direction === "bottom" || direction === "top" ? drawerHeightRef.current : drawerWidthRef.current;
916
+ let percentageDragged = absDraggedDistance / drawerDimension;
917
+ const snapPointPercentageDragged = getSnapPointsPercentageDragged(absDraggedDistance, isDraggingInDirection);
918
+ if (snapPointPercentageDragged !== null) {
919
+ percentageDragged = snapPointPercentageDragged;
920
+ }
921
+ if (noCloseSnapPointsPreCondition && percentageDragged >= 1) {
922
+ return;
923
+ }
924
+ if (!isAllowedToDrag.current && !shouldDrag(event.target, isDraggingInDirection)) return;
925
+ drawerRef.current.classList.add(DRAG_CLASS);
926
+ isAllowedToDrag.current = true;
927
+ set(drawerRef.current, {
928
+ transition: "none"
929
+ });
930
+ set(overlayRef.current, {
931
+ transition: "none"
932
+ });
933
+ if (snapPoints) {
934
+ onDragSnapPoints({
935
+ draggedDistance
936
+ });
937
+ }
938
+ if (isDraggingInDirection && !snapPoints) {
939
+ const dampenedDraggedDistance = dampenValue(draggedDistance);
940
+ const translateValue = Math.min(dampenedDraggedDistance * -1, 0) * directionMultiplier;
941
+ set(drawerRef.current, {
942
+ transform: isVertical(direction) ? `translate3d(0, ${translateValue}px, 0)` : `translate3d(${translateValue}px, 0, 0)`
943
+ });
944
+ return;
945
+ }
946
+ const opacityValue = 1 - percentageDragged;
947
+ if (shouldFade || fadeFromIndex && activeSnapPointIndex === fadeFromIndex - 1) {
948
+ onDragProp == null ? void 0 : onDragProp(event, percentageDragged);
949
+ set(overlayRef.current, {
950
+ opacity: `${opacityValue}`,
951
+ transition: "none"
952
+ }, true);
953
+ }
954
+ if (wrapper && overlayRef.current && shouldScaleBackground) {
955
+ const scaleValue = Math.min(getScale() + percentageDragged * (1 - getScale()), 1);
956
+ const borderRadiusValue = 8 - percentageDragged * 8;
957
+ const translateValue = Math.max(0, 14 - percentageDragged * 14);
958
+ set(wrapper, {
959
+ borderRadius: `${borderRadiusValue}px`,
960
+ transform: isVertical(direction) ? `scale(${scaleValue}) translate3d(0, ${translateValue}px, 0)` : `scale(${scaleValue}) translate3d(${translateValue}px, 0, 0)`,
961
+ transition: "none"
962
+ }, true);
963
+ }
964
+ if (!snapPoints) {
965
+ const translateValue = absDraggedDistance * directionMultiplier;
966
+ set(drawerRef.current, {
967
+ transform: isVertical(direction) ? `translate3d(0, ${translateValue}px, 0)` : `translate3d(${translateValue}px, 0, 0)`
968
+ });
969
+ }
970
+ }
971
+ }
972
+ React__default.useEffect(() => {
973
+ window.requestAnimationFrame(() => {
974
+ shouldAnimate.current = true;
975
+ });
976
+ }, []);
977
+ React__default.useEffect(() => {
978
+ var _window_visualViewport;
979
+ function onVisualViewportChange() {
980
+ if (!drawerRef.current || !repositionInputs) return;
981
+ const focusedElement = document.activeElement;
982
+ if (isInput(focusedElement) || keyboardIsOpen.current) {
983
+ var _window_visualViewport2;
984
+ const visualViewportHeight = ((_window_visualViewport2 = window.visualViewport) == null ? void 0 : _window_visualViewport2.height) || 0;
985
+ const totalHeight = window.innerHeight;
986
+ let diffFromInitial = totalHeight - visualViewportHeight;
987
+ const drawerHeight = drawerRef.current.getBoundingClientRect().height || 0;
988
+ const isTallEnough = drawerHeight > totalHeight * 0.8;
989
+ if (!initialDrawerHeight.current) {
990
+ initialDrawerHeight.current = drawerHeight;
991
+ }
992
+ const offsetFromTop = drawerRef.current.getBoundingClientRect().top;
993
+ if (Math.abs(previousDiffFromInitial.current - diffFromInitial) > 60) {
994
+ keyboardIsOpen.current = !keyboardIsOpen.current;
995
+ }
996
+ if (snapPoints && snapPoints.length > 0 && snapPointsOffset && activeSnapPointIndex) {
997
+ const activeSnapPointHeight = snapPointsOffset[activeSnapPointIndex] || 0;
998
+ diffFromInitial += activeSnapPointHeight;
999
+ }
1000
+ previousDiffFromInitial.current = diffFromInitial;
1001
+ if (drawerHeight > visualViewportHeight || keyboardIsOpen.current) {
1002
+ const height = drawerRef.current.getBoundingClientRect().height;
1003
+ let newDrawerHeight = height;
1004
+ if (height > visualViewportHeight) {
1005
+ newDrawerHeight = visualViewportHeight - (isTallEnough ? offsetFromTop : WINDOW_TOP_OFFSET);
1006
+ }
1007
+ if (fixed) {
1008
+ drawerRef.current.style.height = `${height - Math.max(diffFromInitial, 0)}px`;
1009
+ } else {
1010
+ drawerRef.current.style.height = `${Math.max(newDrawerHeight, visualViewportHeight - offsetFromTop)}px`;
1011
+ }
1012
+ } else if (!isMobileFirefox()) {
1013
+ drawerRef.current.style.height = `${initialDrawerHeight.current}px`;
1014
+ }
1015
+ if (snapPoints && snapPoints.length > 0 && !keyboardIsOpen.current) {
1016
+ drawerRef.current.style.bottom = `0px`;
1017
+ } else {
1018
+ drawerRef.current.style.bottom = `${Math.max(diffFromInitial, 0)}px`;
1019
+ }
1020
+ }
1021
+ }
1022
+ (_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.addEventListener("resize", onVisualViewportChange);
1023
+ return () => {
1024
+ var _window_visualViewport2;
1025
+ return (_window_visualViewport2 = window.visualViewport) == null ? void 0 : _window_visualViewport2.removeEventListener("resize", onVisualViewportChange);
1026
+ };
1027
+ }, [
1028
+ activeSnapPointIndex,
1029
+ snapPoints,
1030
+ snapPointsOffset
1031
+ ]);
1032
+ function closeDrawer(fromWithin) {
1033
+ cancelDrag();
1034
+ onClose == null ? void 0 : onClose();
1035
+ if (!fromWithin) {
1036
+ setIsOpen(false);
1037
+ }
1038
+ setTimeout(() => {
1039
+ if (snapPoints) {
1040
+ setActiveSnapPoint(snapPoints[0]);
1041
+ }
1042
+ }, TRANSITIONS.DURATION * 1e3);
1043
+ }
1044
+ function resetDrawer() {
1045
+ if (!drawerRef.current) return;
1046
+ const wrapper = document.querySelector("[data-vaul-drawer-wrapper]");
1047
+ const currentSwipeAmount = getTranslate(drawerRef.current, direction);
1048
+ set(drawerRef.current, {
1049
+ transform: "translate3d(0, 0, 0)",
1050
+ transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`
1051
+ });
1052
+ set(overlayRef.current, {
1053
+ transition: `opacity ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
1054
+ opacity: "1"
1055
+ });
1056
+ if (shouldScaleBackground && currentSwipeAmount && currentSwipeAmount > 0 && isOpen) {
1057
+ set(wrapper, {
1058
+ borderRadius: `${BORDER_RADIUS}px`,
1059
+ overflow: "hidden",
1060
+ ...isVertical(direction) ? {
1061
+ transform: `scale(${getScale()}) translate3d(0, calc(env(safe-area-inset-top) + 14px), 0)`,
1062
+ transformOrigin: "top"
1063
+ } : {
1064
+ transform: `scale(${getScale()}) translate3d(calc(env(safe-area-inset-top) + 14px), 0, 0)`,
1065
+ transformOrigin: "left"
1066
+ },
1067
+ transitionProperty: "transform, border-radius",
1068
+ transitionDuration: `${TRANSITIONS.DURATION}s`,
1069
+ transitionTimingFunction: `cubic-bezier(${TRANSITIONS.EASE.join(",")})`
1070
+ }, true);
1071
+ }
1072
+ }
1073
+ function cancelDrag() {
1074
+ if (!isDragging || !drawerRef.current) return;
1075
+ drawerRef.current.classList.remove(DRAG_CLASS);
1076
+ isAllowedToDrag.current = false;
1077
+ setIsDragging(false);
1078
+ dragEndTime.current = /* @__PURE__ */ new Date();
1079
+ }
1080
+ function onRelease(event) {
1081
+ if (!isDragging || !drawerRef.current) return;
1082
+ drawerRef.current.classList.remove(DRAG_CLASS);
1083
+ isAllowedToDrag.current = false;
1084
+ setIsDragging(false);
1085
+ dragEndTime.current = /* @__PURE__ */ new Date();
1086
+ const swipeAmount = getTranslate(drawerRef.current, direction);
1087
+ if (!event || !shouldDrag(event.target, false) || !swipeAmount || Number.isNaN(swipeAmount)) return;
1088
+ if (dragStartTime.current === null) return;
1089
+ const timeTaken = dragEndTime.current.getTime() - dragStartTime.current.getTime();
1090
+ const distMoved = pointerStart.current - (isVertical(direction) ? event.pageY : event.pageX);
1091
+ const velocity = Math.abs(distMoved) / timeTaken;
1092
+ if (velocity > 0.05) {
1093
+ setJustReleased(true);
1094
+ setTimeout(() => {
1095
+ setJustReleased(false);
1096
+ }, 200);
1097
+ }
1098
+ if (snapPoints) {
1099
+ const directionMultiplier = direction === "bottom" || direction === "right" ? 1 : -1;
1100
+ onReleaseSnapPoints({
1101
+ draggedDistance: distMoved * directionMultiplier,
1102
+ closeDrawer,
1103
+ velocity,
1104
+ dismissible
1105
+ });
1106
+ onReleaseProp == null ? void 0 : onReleaseProp(event, true);
1107
+ return;
1108
+ }
1109
+ if (direction === "bottom" || direction === "right" ? distMoved > 0 : distMoved < 0) {
1110
+ resetDrawer();
1111
+ onReleaseProp == null ? void 0 : onReleaseProp(event, true);
1112
+ return;
1113
+ }
1114
+ if (velocity > VELOCITY_THRESHOLD) {
1115
+ closeDrawer();
1116
+ onReleaseProp == null ? void 0 : onReleaseProp(event, false);
1117
+ return;
1118
+ }
1119
+ var _drawerRef_current_getBoundingClientRect_height;
1120
+ const visibleDrawerHeight = Math.min((_drawerRef_current_getBoundingClientRect_height = drawerRef.current.getBoundingClientRect().height) != null ? _drawerRef_current_getBoundingClientRect_height : 0, window.innerHeight);
1121
+ var _drawerRef_current_getBoundingClientRect_width;
1122
+ const visibleDrawerWidth = Math.min((_drawerRef_current_getBoundingClientRect_width = drawerRef.current.getBoundingClientRect().width) != null ? _drawerRef_current_getBoundingClientRect_width : 0, window.innerWidth);
1123
+ const isHorizontalSwipe = direction === "left" || direction === "right";
1124
+ if (Math.abs(swipeAmount) >= (isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold) {
1125
+ closeDrawer();
1126
+ onReleaseProp == null ? void 0 : onReleaseProp(event, false);
1127
+ return;
1128
+ }
1129
+ onReleaseProp == null ? void 0 : onReleaseProp(event, true);
1130
+ resetDrawer();
1131
+ }
1132
+ React__default.useEffect(() => {
1133
+ if (isOpen) {
1134
+ set(document.documentElement, {
1135
+ scrollBehavior: "auto"
1136
+ });
1137
+ openTime.current = /* @__PURE__ */ new Date();
1138
+ }
1139
+ return () => {
1140
+ reset(document.documentElement, "scrollBehavior");
1141
+ };
1142
+ }, [
1143
+ isOpen
1144
+ ]);
1145
+ function onNestedOpenChange(o) {
1146
+ const scale = o ? (window.innerWidth - NESTED_DISPLACEMENT) / window.innerWidth : 1;
1147
+ const initialTranslate = o ? -NESTED_DISPLACEMENT : 0;
1148
+ if (nestedOpenChangeTimer.current) {
1149
+ window.clearTimeout(nestedOpenChangeTimer.current);
1150
+ }
1151
+ set(drawerRef.current, {
1152
+ transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
1153
+ transform: isVertical(direction) ? `scale(${scale}) translate3d(0, ${initialTranslate}px, 0)` : `scale(${scale}) translate3d(${initialTranslate}px, 0, 0)`
1154
+ });
1155
+ if (!o && drawerRef.current) {
1156
+ nestedOpenChangeTimer.current = setTimeout(() => {
1157
+ const translateValue = getTranslate(drawerRef.current, direction);
1158
+ set(drawerRef.current, {
1159
+ transition: "none",
1160
+ transform: isVertical(direction) ? `translate3d(0, ${translateValue}px, 0)` : `translate3d(${translateValue}px, 0, 0)`
1161
+ });
1162
+ }, 500);
1163
+ }
1164
+ }
1165
+ function onNestedDrag(_event, percentageDragged) {
1166
+ if (percentageDragged < 0) return;
1167
+ const initialScale = (window.innerWidth - NESTED_DISPLACEMENT) / window.innerWidth;
1168
+ const newScale = initialScale + percentageDragged * (1 - initialScale);
1169
+ const newTranslate = -NESTED_DISPLACEMENT + percentageDragged * NESTED_DISPLACEMENT;
1170
+ set(drawerRef.current, {
1171
+ transform: isVertical(direction) ? `scale(${newScale}) translate3d(0, ${newTranslate}px, 0)` : `scale(${newScale}) translate3d(${newTranslate}px, 0, 0)`,
1172
+ transition: "none"
1173
+ });
1174
+ }
1175
+ function onNestedRelease(_event, o) {
1176
+ const dim = isVertical(direction) ? window.innerHeight : window.innerWidth;
1177
+ const scale = o ? (dim - NESTED_DISPLACEMENT) / dim : 1;
1178
+ const translate = o ? -NESTED_DISPLACEMENT : 0;
1179
+ if (o) {
1180
+ set(drawerRef.current, {
1181
+ transition: `transform ${TRANSITIONS.DURATION}s cubic-bezier(${TRANSITIONS.EASE.join(",")})`,
1182
+ transform: isVertical(direction) ? `scale(${scale}) translate3d(0, ${translate}px, 0)` : `scale(${scale}) translate3d(${translate}px, 0, 0)`
1183
+ });
1184
+ }
1185
+ }
1186
+ React__default.useEffect(() => {
1187
+ if (!modal) {
1188
+ window.requestAnimationFrame(() => {
1189
+ document.body.style.pointerEvents = "auto";
1190
+ });
1191
+ }
1192
+ }, [
1193
+ modal
1194
+ ]);
1195
+ return /* @__PURE__ */ React__default.createElement(DialogPrimitive.Root, {
1196
+ defaultOpen,
1197
+ onOpenChange: (open) => {
1198
+ if (!dismissible && !open) return;
1199
+ if (open) {
1200
+ setHasBeenOpened(true);
1201
+ } else {
1202
+ closeDrawer(true);
1203
+ }
1204
+ setIsOpen(open);
1205
+ },
1206
+ open: isOpen
1207
+ }, /* @__PURE__ */ React__default.createElement(DrawerContext.Provider, {
1208
+ value: {
1209
+ activeSnapPoint,
1210
+ snapPoints,
1211
+ setActiveSnapPoint,
1212
+ drawerRef,
1213
+ overlayRef,
1214
+ onOpenChange,
1215
+ onPress,
1216
+ onRelease,
1217
+ onDrag,
1218
+ dismissible,
1219
+ shouldAnimate,
1220
+ handleOnly,
1221
+ isOpen,
1222
+ isDragging,
1223
+ shouldFade,
1224
+ closeDrawer,
1225
+ onNestedDrag,
1226
+ onNestedOpenChange,
1227
+ onNestedRelease,
1228
+ keyboardIsOpen,
1229
+ modal,
1230
+ snapPointsOffset,
1231
+ activeSnapPointIndex,
1232
+ direction,
1233
+ shouldScaleBackground,
1234
+ setBackgroundColorOnScale,
1235
+ noBodyStyles,
1236
+ container,
1237
+ autoFocus
1238
+ }
1239
+ }, children));
1240
+ }
1241
+ var Overlay2 = /* @__PURE__ */ React__default.forwardRef(function({ ...rest }, ref) {
1242
+ const { overlayRef, snapPoints, onRelease, shouldFade, isOpen, modal, shouldAnimate } = useDrawerContext();
1243
+ const composedRef = useComposedRefs(ref, overlayRef);
1244
+ const hasSnapPoints = snapPoints && snapPoints.length > 0;
1245
+ if (!modal) {
1246
+ return null;
1247
+ }
1248
+ const onMouseUp = React__default.useCallback((event) => onRelease(event), [
1249
+ onRelease
1250
+ ]);
1251
+ return /* @__PURE__ */ React__default.createElement(DialogPrimitive.Overlay, {
1252
+ onMouseUp,
1253
+ ref: composedRef,
1254
+ "data-vaul-overlay": "",
1255
+ "data-vaul-snap-points": isOpen && hasSnapPoints ? "true" : "false",
1256
+ "data-vaul-snap-points-overlay": isOpen && shouldFade ? "true" : "false",
1257
+ "data-vaul-animate": (shouldAnimate == null ? void 0 : shouldAnimate.current) ? "true" : "false",
1258
+ ...rest
1259
+ });
1260
+ });
1261
+ Overlay2.displayName = "Drawer.Overlay";
1262
+ var Content2 = /* @__PURE__ */ React__default.forwardRef(function({ onPointerDownOutside, style, onOpenAutoFocus, ...rest }, ref) {
1263
+ const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, shouldAnimate, autoFocus } = useDrawerContext();
1264
+ const [delayedSnapPoints, setDelayedSnapPoints] = React__default.useState(false);
1265
+ const composedRef = useComposedRefs(ref, drawerRef);
1266
+ const pointerStartRef = React__default.useRef(null);
1267
+ const lastKnownPointerEventRef = React__default.useRef(null);
1268
+ const wasBeyondThePointRef = React__default.useRef(false);
1269
+ const hasSnapPoints = snapPoints && snapPoints.length > 0;
1270
+ useScaleBackground();
1271
+ const isDeltaInDirection = (delta, direction2, threshold = 0) => {
1272
+ if (wasBeyondThePointRef.current) return true;
1273
+ const deltaY = Math.abs(delta.y);
1274
+ const deltaX = Math.abs(delta.x);
1275
+ const isDeltaX = deltaX > deltaY;
1276
+ const dFactor = [
1277
+ "bottom",
1278
+ "right"
1279
+ ].includes(direction2) ? 1 : -1;
1280
+ if (direction2 === "left" || direction2 === "right") {
1281
+ const isReverseDirection = delta.x * dFactor < 0;
1282
+ if (!isReverseDirection && deltaX >= 0 && deltaX <= threshold) {
1283
+ return isDeltaX;
1284
+ }
1285
+ } else {
1286
+ const isReverseDirection = delta.y * dFactor < 0;
1287
+ if (!isReverseDirection && deltaY >= 0 && deltaY <= threshold) {
1288
+ return !isDeltaX;
1289
+ }
1290
+ }
1291
+ wasBeyondThePointRef.current = true;
1292
+ return true;
1293
+ };
1294
+ React__default.useEffect(() => {
1295
+ if (hasSnapPoints) {
1296
+ window.requestAnimationFrame(() => {
1297
+ setDelayedSnapPoints(true);
1298
+ });
1299
+ }
1300
+ }, []);
1301
+ function handleOnPointerUp(event) {
1302
+ pointerStartRef.current = null;
1303
+ wasBeyondThePointRef.current = false;
1304
+ onRelease(event);
1305
+ }
1306
+ return /* @__PURE__ */ React__default.createElement(DialogPrimitive.Content, {
1307
+ "data-vaul-drawer-direction": direction,
1308
+ "data-vaul-drawer": "",
1309
+ "data-vaul-delayed-snap-points": delayedSnapPoints ? "true" : "false",
1310
+ "data-vaul-snap-points": isOpen && hasSnapPoints ? "true" : "false",
1311
+ "data-vaul-custom-container": container ? "true" : "false",
1312
+ "data-vaul-animate": (shouldAnimate == null ? void 0 : shouldAnimate.current) ? "true" : "false",
1313
+ ...rest,
1314
+ ref: composedRef,
1315
+ style: snapPointsOffset && snapPointsOffset.length > 0 ? {
1316
+ "--snap-point-height": `${snapPointsOffset[activeSnapPointIndex != null ? activeSnapPointIndex : 0]}px`,
1317
+ ...style
1318
+ } : style,
1319
+ onPointerDown: (event) => {
1320
+ if (handleOnly) return;
1321
+ rest.onPointerDown == null ? void 0 : rest.onPointerDown.call(rest, event);
1322
+ pointerStartRef.current = {
1323
+ x: event.pageX,
1324
+ y: event.pageY
1325
+ };
1326
+ onPress(event);
1327
+ },
1328
+ onOpenAutoFocus: (e) => {
1329
+ onOpenAutoFocus == null ? void 0 : onOpenAutoFocus(e);
1330
+ if (!autoFocus) {
1331
+ e.preventDefault();
1332
+ }
1333
+ },
1334
+ onPointerDownOutside: (e) => {
1335
+ onPointerDownOutside == null ? void 0 : onPointerDownOutside(e);
1336
+ if (!modal || e.defaultPrevented) {
1337
+ e.preventDefault();
1338
+ return;
1339
+ }
1340
+ if (keyboardIsOpen.current) {
1341
+ keyboardIsOpen.current = false;
1342
+ }
1343
+ },
1344
+ onFocusOutside: (e) => {
1345
+ if (!modal) {
1346
+ e.preventDefault();
1347
+ return;
1348
+ }
1349
+ },
1350
+ onPointerMove: (event) => {
1351
+ lastKnownPointerEventRef.current = event;
1352
+ if (handleOnly) return;
1353
+ rest.onPointerMove == null ? void 0 : rest.onPointerMove.call(rest, event);
1354
+ if (!pointerStartRef.current) return;
1355
+ const yPosition = event.pageY - pointerStartRef.current.y;
1356
+ const xPosition = event.pageX - pointerStartRef.current.x;
1357
+ const swipeStartThreshold = event.pointerType === "touch" ? 10 : 2;
1358
+ const delta = {
1359
+ x: xPosition,
1360
+ y: yPosition
1361
+ };
1362
+ const isAllowedToSwipe = isDeltaInDirection(delta, direction, swipeStartThreshold);
1363
+ if (isAllowedToSwipe) onDrag(event);
1364
+ else if (Math.abs(xPosition) > swipeStartThreshold || Math.abs(yPosition) > swipeStartThreshold) {
1365
+ pointerStartRef.current = null;
1366
+ }
1367
+ },
1368
+ onPointerUp: (event) => {
1369
+ rest.onPointerUp == null ? void 0 : rest.onPointerUp.call(rest, event);
1370
+ pointerStartRef.current = null;
1371
+ wasBeyondThePointRef.current = false;
1372
+ onRelease(event);
1373
+ },
1374
+ onPointerOut: (event) => {
1375
+ rest.onPointerOut == null ? void 0 : rest.onPointerOut.call(rest, event);
1376
+ handleOnPointerUp(lastKnownPointerEventRef.current);
1377
+ },
1378
+ onContextMenu: (event) => {
1379
+ rest.onContextMenu == null ? void 0 : rest.onContextMenu.call(rest, event);
1380
+ if (lastKnownPointerEventRef.current) {
1381
+ handleOnPointerUp(lastKnownPointerEventRef.current);
1382
+ }
1383
+ }
1384
+ });
1385
+ });
1386
+ Content2.displayName = "Drawer.Content";
1387
+ var LONG_HANDLE_PRESS_TIMEOUT = 250;
1388
+ var DOUBLE_TAP_TIMEOUT = 120;
1389
+ var Handle = /* @__PURE__ */ React__default.forwardRef(function({ preventCycle = false, children, ...rest }, ref) {
1390
+ const { closeDrawer, isDragging, snapPoints, activeSnapPoint, setActiveSnapPoint, dismissible, handleOnly, isOpen, onPress, onDrag } = useDrawerContext();
1391
+ const closeTimeoutIdRef = React__default.useRef(null);
1392
+ const shouldCancelInteractionRef = React__default.useRef(false);
1393
+ function handleStartCycle() {
1394
+ if (shouldCancelInteractionRef.current) {
1395
+ handleCancelInteraction();
1396
+ return;
1397
+ }
1398
+ window.setTimeout(() => {
1399
+ handleCycleSnapPoints();
1400
+ }, DOUBLE_TAP_TIMEOUT);
1401
+ }
1402
+ function handleCycleSnapPoints() {
1403
+ if (isDragging || preventCycle || shouldCancelInteractionRef.current) {
1404
+ handleCancelInteraction();
1405
+ return;
1406
+ }
1407
+ handleCancelInteraction();
1408
+ if (!snapPoints || snapPoints.length === 0) {
1409
+ if (!dismissible) {
1410
+ closeDrawer();
1411
+ }
1412
+ return;
1413
+ }
1414
+ const isLastSnapPoint = activeSnapPoint === snapPoints[snapPoints.length - 1];
1415
+ if (isLastSnapPoint && dismissible) {
1416
+ closeDrawer();
1417
+ return;
1418
+ }
1419
+ const currentSnapIndex = snapPoints.findIndex((point) => point === activeSnapPoint);
1420
+ if (currentSnapIndex === -1) return;
1421
+ const nextSnapPoint = snapPoints[currentSnapIndex + 1];
1422
+ setActiveSnapPoint(nextSnapPoint);
1423
+ }
1424
+ function handleStartInteraction() {
1425
+ closeTimeoutIdRef.current = window.setTimeout(() => {
1426
+ shouldCancelInteractionRef.current = true;
1427
+ }, LONG_HANDLE_PRESS_TIMEOUT);
1428
+ }
1429
+ function handleCancelInteraction() {
1430
+ if (closeTimeoutIdRef.current) {
1431
+ window.clearTimeout(closeTimeoutIdRef.current);
1432
+ }
1433
+ shouldCancelInteractionRef.current = false;
1434
+ }
1435
+ return /* @__PURE__ */ React__default.createElement("div", {
1436
+ onClick: handleStartCycle,
1437
+ onPointerCancel: handleCancelInteraction,
1438
+ onPointerDown: (e) => {
1439
+ if (handleOnly) onPress(e);
1440
+ handleStartInteraction();
1441
+ },
1442
+ onPointerMove: (e) => {
1443
+ if (handleOnly) onDrag(e);
1444
+ },
1445
+ // onPointerUp is already handled by the content component
1446
+ ref,
1447
+ "data-vaul-drawer-visible": isOpen ? "true" : "false",
1448
+ "data-vaul-handle": "",
1449
+ "aria-hidden": "true",
1450
+ ...rest
1451
+ }, /* @__PURE__ */ React__default.createElement("span", {
1452
+ "data-vaul-handle-hitarea": "",
1453
+ "aria-hidden": "true"
1454
+ }, children));
1455
+ });
1456
+ Handle.displayName = "Drawer.Handle";
1457
+ function NestedRoot({ onDrag, onOpenChange, open: nestedIsOpen, ...rest }) {
1458
+ const { onNestedDrag, onNestedOpenChange, onNestedRelease } = useDrawerContext();
1459
+ if (!onNestedDrag) {
1460
+ throw new Error("Drawer.NestedRoot must be placed in another drawer");
1461
+ }
1462
+ return /* @__PURE__ */ React__default.createElement(Root2, {
1463
+ nested: true,
1464
+ open: nestedIsOpen,
1465
+ onClose: () => {
1466
+ onNestedOpenChange(false);
1467
+ },
1468
+ onDrag: (e, p) => {
1469
+ onNestedDrag(e, p);
1470
+ onDrag == null ? void 0 : onDrag(e, p);
1471
+ },
1472
+ onOpenChange: (o) => {
1473
+ if (o) {
1474
+ onNestedOpenChange(o);
1475
+ }
1476
+ onOpenChange == null ? void 0 : onOpenChange(o);
1477
+ },
1478
+ onRelease: onNestedRelease,
1479
+ ...rest
1480
+ });
1481
+ }
1482
+ function Portal2(props) {
1483
+ const context = useDrawerContext();
1484
+ const { container = context.container, ...portalProps } = props;
1485
+ return /* @__PURE__ */ React__default.createElement(DialogPrimitive.Portal, {
1486
+ container,
1487
+ ...portalProps
1488
+ });
1489
+ }
1490
+ var Drawer = {
1491
+ Root: Root2,
1492
+ NestedRoot,
1493
+ Content: Content2,
1494
+ Overlay: Overlay2,
1495
+ Trigger: DialogPrimitive.Trigger,
1496
+ Portal: Portal2,
1497
+ Handle,
1498
+ Close: DialogPrimitive.Close,
1499
+ Title: DialogPrimitive.Title,
1500
+ Description: DialogPrimitive.Description
1501
+ };
1502
+
1503
+ // src/components/Drawer/Drawer.tsx
1504
+ import { jsx, jsxs } from "react/jsx-runtime";
1505
+ var DrawerContext2 = React2.createContext({ scrollLock: "style", open: false, modal: true });
1506
+ function Root3({ scrollLock = "style", onOpenChange, ...props }) {
1507
+ const [uncontrolledOpen, setUncontrolledOpen] = React2.useState(props.defaultOpen ?? false);
1508
+ const open = props.open ?? uncontrolledOpen;
1509
+ return /* @__PURE__ */ jsx(DrawerContext2.Provider, { value: { scrollLock, open, modal: props.modal ?? true }, children: /* @__PURE__ */ jsx(
1510
+ Drawer.Root,
1511
+ {
1512
+ ...props,
1513
+ onOpenChange: (next) => {
1514
+ setUncontrolledOpen(next);
1515
+ onOpenChange?.(next);
1516
+ }
1517
+ }
1518
+ ) });
1519
+ }
1520
+ Root3.displayName = "Drawer.Root";
1521
+ var Trigger2 = Drawer.Trigger;
1522
+ var Close2 = Drawer.Close;
1523
+ var Portal3 = Drawer.Portal;
1524
+ var scrollLocks = 0;
1525
+ function useClassScrollLock() {
1526
+ React2.useEffect(() => {
1527
+ const html = document.documentElement;
1528
+ if (scrollLocks++ === 0) {
1529
+ html.classList.toggle("nexub-scroll-gutter", window.innerWidth > html.clientWidth);
1530
+ html.classList.add("nexub-scroll-lock");
1531
+ }
1532
+ return () => {
1533
+ if (--scrollLocks === 0) html.classList.remove("nexub-scroll-lock", "nexub-scroll-gutter");
1534
+ };
1535
+ }, []);
1536
+ }
1537
+ var ClassLockOverlay = React2.forwardRef(
1538
+ ({ asChild, forceMount: _forceMount, open, ...props }, ref) => {
1539
+ useClassScrollLock();
1540
+ const Comp = asChild ? Slot : "div";
1541
+ return /* @__PURE__ */ jsx(
1542
+ Comp,
1543
+ {
1544
+ ref,
1545
+ "data-vaul-overlay": "",
1546
+ "data-vaul-snap-points": "false",
1547
+ "data-state": open ? "open" : "closed",
1548
+ ...props
1549
+ }
1550
+ );
1551
+ }
1552
+ );
1553
+ var Overlay3 = React2.forwardRef(
1554
+ ({ className, ...props }, ref) => {
1555
+ const { scrollLock, open, modal } = React2.useContext(DrawerContext2);
1556
+ const classes = cn("fixed inset-0 z-[var(--z-modal)] bg-[var(--color-overlay)]", className);
1557
+ if (scrollLock === "class") {
1558
+ if (!modal) return null;
1559
+ return /* @__PURE__ */ jsx(ClassLockOverlay, { ref, open, className: cn("pointer-events-auto", classes), ...props });
1560
+ }
1561
+ return /* @__PURE__ */ jsx(Drawer.Overlay, { ref, className: classes, ...props });
1562
+ }
1563
+ );
1564
+ Overlay3.displayName = "Drawer.Overlay";
1565
+ var Content3 = React2.forwardRef(({ className, children, side = "right", surface = "solid", ...props }, ref) => {
1566
+ const sideMap = {
1567
+ right: "inset-y-0 right-0 h-full w-3/4 max-w-sm border-l overflow-x-hidden",
1568
+ left: "inset-y-0 left-0 h-full w-3/4 max-w-sm border-r overflow-x-hidden",
1569
+ top: "inset-x-0 top-0 w-full border-b",
1570
+ bottom: "inset-x-0 bottom-0 w-full border-t rounded-t-2xl"
1571
+ };
1572
+ return /* @__PURE__ */ jsxs(
1573
+ Drawer.Content,
1574
+ {
1575
+ ref,
1576
+ className: cn(
1577
+ "fixed z-[var(--z-modal)] flex flex-col bg-[var(--color-bg-default)] shadow-xl focus:outline-none",
1578
+ sideMap[side],
1579
+ surface === "glass" && glassSurfaceClass,
1580
+ className
1581
+ ),
1582
+ "data-material": surface === "glass" ? "glass" : void 0,
1583
+ ...props,
1584
+ children: [
1585
+ side === "bottom" && /* @__PURE__ */ jsx("div", { className: "mx-auto mt-4 h-2 w-20 rounded-full bg-[var(--color-border-default)]" }),
1586
+ children
1587
+ ]
1588
+ }
1589
+ );
1590
+ });
1591
+ Content3.displayName = "Drawer.Content";
1592
+ var Title2 = React2.forwardRef(
1593
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1594
+ Drawer.Title,
1595
+ {
1596
+ ref,
1597
+ className: cn("text-lg font-semibold text-[var(--color-text-primary)]", className),
1598
+ ...props
1599
+ }
1600
+ )
1601
+ );
1602
+ Title2.displayName = "Drawer.Title";
1603
+ var Description2 = React2.forwardRef(
1604
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
1605
+ Drawer.Description,
1606
+ {
1607
+ ref,
1608
+ className: cn("text-sm text-[var(--color-text-muted)]", className),
1609
+ ...props
1610
+ }
1611
+ )
1612
+ );
1613
+ Description2.displayName = "Drawer.Description";
1614
+ var Header = React2.forwardRef(
1615
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("flex flex-col gap-1.5 p-6", className), ...props })
1616
+ );
1617
+ Header.displayName = "Drawer.Header";
1618
+ var Footer = React2.forwardRef(
1619
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("mt-auto flex flex-col gap-2 p-6", className), ...props })
1620
+ );
1621
+ Footer.displayName = "Drawer.Footer";
1622
+ var Drawer2 = {
1623
+ Root: Root3,
1624
+ Trigger: Trigger2,
1625
+ Portal: Portal3,
1626
+ Overlay: Overlay3,
1627
+ Content: Content3,
1628
+ Close: Close2,
1629
+ Title: Title2,
1630
+ Description: Description2,
1631
+ Header,
1632
+ Footer
1633
+ };
1634
+ var Sheet = Drawer2;
1635
+
1636
+ export {
1637
+ Drawer2 as Drawer,
1638
+ Sheet
1639
+ };