1"use strict"; 2(self["webpackChunk_N_E"] = self["webpackChunk_N_E"] || []).push([["vendors-_app-pages-browser_node_modules_pnpm_lucide-react_0_479_0_react_19_0_0_node_modules_l-41fdb8"],{ 3 4/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/icons/chevron-left.js": 5/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 6 7/* harmony export */ __webpack_require__.d(__webpack_exports__, { 8/* harmony export */ A: () => (/* binding */ ChevronLeft) 9/* harmony export */ }); 10/* unused harmony export __iconNode */ 11/* harmony import */ var _createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/createLucideIcon.js"); 12/** 13 * @license lucide-react v0.479.0 - ISC 14 * 15 * This source code is licensed under the ISC license. 16 * See the LICENSE file in the root directory of this source tree. 17 */ 18const __iconNode = [ 19 [ 20 "path", 21 { 22 d: "m15 18-6-6 6-6", 23 key: "1wnfg3" 24 } 25 ] 26]; 27const ChevronLeft = (0,_createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)("ChevronLeft", __iconNode); 28 //# sourceMappingURL=chevron-left.js.map 29 30 31/***/ }), 32 33/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/icons/chevron-right.js": 34/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 35 36/* harmony export */ __webpack_require__.d(__webpack_exports__, { 37/* harmony export */ A: () => (/* binding */ ChevronRight) 38/* harmony export */ }); 39/* unused harmony export __iconNode */ 40/* harmony import */ var _createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/createLucideIcon.js"); 41/** 42 * @license lucide-react v0.479.0 - ISC 43 * 44 * This source code is licensed under the ISC license. 45 * See the LICENSE file in the root directory of this source tree. 46 */ 47const __iconNode = [ 48 [ 49 "path", 50 { 51 d: "m9 18 6-6-6-6", 52 key: "mthhwq" 53 } 54 ] 55]; 56const ChevronRight = (0,_createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)("ChevronRight", __iconNode); 57 //# sourceMappingURL=chevron-right.js.map 58 59 60/***/ }), 61 62/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/icons/chevron-up.js": 63/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 64 65/* harmony export */ __webpack_require__.d(__webpack_exports__, { 66/* harmony export */ A: () => (/* binding */ ChevronUp) 67/* harmony export */ }); 68/* unused harmony export __iconNode */ 69/* harmony import */ var _createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/createLucideIcon.js"); 70/** 71 * @license lucide-react v0.479.0 - ISC 72 * 73 * This source code is licensed under the ISC license. 74 * See the LICENSE file in the root directory of this source tree. 75 */ 76const __iconNode = [ 77 [ 78 "path", 79 { 80 d: "m18 15-6-6-6 6", 81 key: "153udz" 82 } 83 ] 84]; 85const ChevronUp = (0,_createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)("ChevronUp", __iconNode); 86 //# sourceMappingURL=chevron-up.js.map 87 88 89/***/ }), 90 91/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/icons/expand.js": 92/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 93 94/* harmony export */ __webpack_require__.d(__webpack_exports__, { 95/* harmony export */ A: () => (/* binding */ Expand) 96/* harmony export */ }); 97/* unused harmony export __iconNode */ 98/* harmony import */ var _createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/createLucideIcon.js"); 99/** 100 * @license lucide-react v0.479.0 - ISC 101 * 102 * This source code is licensed under the ISC license. 103 * See the LICENSE file in the root directory of this source tree. 104 */ 105const __iconNode = [ 106 [ 107 "path", 108 { 109 d: "m15 15 6 6", 110 key: "1s409w" 111 } 112 ], 113 [ 114 "path", 115 { 116 d: "m15 9 6-6", 117 key: "ko1vev" 118 } 119 ], 120 [ 121 "path", 122 { 123 d: "M21 16.2V21h-4.8", 124 key: "1hrera" 125 } 126 ], 127 [ 128 "path", 129 { 130 d: "M21 7.8V3h-4.8", 131 key: "ul1q53" 132 } 133 ], 134 [ 135 "path", 136 { 137 d: "M3 16.2V21h4.8", 138 key: "1x04uo" 139 } 140 ], 141 [ 142 "path", 143 { 144 d: "m3 21 6-6", 145 key: "wwnumi" 146 } 147 ], 148 [ 149 "path", 150 { 151 d: "M3 7.8V3h4.8", 152 key: "1ijppm" 153 } 154 ], 155 [ 156 "path", 157 { 158 d: "M9 9 3 3", 159 key: "v551iv" 160 } 161 ] 162]; 163const Expand = (0,_createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)("E
163xpand", __iconNode); 164 //# sourceMappingURL=expand.js.map 165 166 167/***/ }), 168 169/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/icons/info.js": 170/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 171 172/* harmony export */ __webpack_require__.d(__webpack_exports__, { 173/* harmony export */ A: () => (/* binding */ Info) 174/* harmony export */ }); 175/* unused harmony export __iconNode */ 176/* harmony import */ var _createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/lucide-react/dist/esm/createLucideIcon.js"); 177/** 178 * @license lucide-react v0.479.0 - ISC 179 * 180 * This source code is licensed under the ISC license. 181 * See the LICENSE file in the root directory of this source tree. 182 */ 183const __iconNode = [ 184 [ 185 "circle", 186 { 187 cx: "12", 188 cy: "12", 189 r: "10", 190 key: "1mglay" 191 } 192 ], 193 [ 194 "path", 195 { 196 d: "M12 16v-4", 197 key: "1dtifu" 198 } 199 ], 200 [ 201 "path", 202 { 203 d: "M12 8h.01", 204 key: "e9boi3" 205 } 206 ] 207]; 208const Info = (0,_createLucideIcon_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A)("Info", __iconNode); 209 //# sourceMappingURL=info.js.map 210 211 212/***/ }), 213 214/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]_@[email protected]_@[email protected]_react-dom@19._aa58729163ab3f130614a9ef27c9d411/node_modules/next-intl/dist/esm/production/react-client/index.js": 215/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 216 217/* harmony export */ __webpack_require__.d(__webpack_exports__, { 218/* harmony export */ c3: () => (/* binding */ e) 219/* harmony export */ }); 220/* unused harmony export useFormatter */ 221/* harmony import */ var use_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected][email protected]/node_modules/use-intl/dist/esm/production/react.js"); 222function o(r,t){return(...r)=>{try{return t(...r)}catch{throw new Error(void 0)}}}const e=o(0,use_intl__WEBPACK_IMPORTED_MODULE_0__/* .useTranslations */ .c3),n=o(0,use_intl__WEBPACK_IMPORTED_MODULE_0__/* .useFormatter */ .kc); 223 224 225/***/ }), 226 227/***/ "(app-pages-browser)/./node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]__@[email protected][email protected][email protected][email protected]/node_modules/vaul/dist/index.mjs": 228/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { 229 230/* harmony export */ __webpack_require__.d(__webpack_exports__, { 231/* harmony export */ _s: () => (/* binding */ Drawer) 232/* harmony export */ }); 233/* unused harmony exports Content, Handle, NestedRoot, Overlay, Portal, Root */ 234/* harmony import */ var _radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/@[email protected]_@[email protected]_@[email protected]__@types+react@_b2706bce2905070d80e023f4fbbae360/node_modules/@radix-ui/react-dialog/dist/index.mjs"); 235/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("(app-pages-browser)/./node_modules/.pnpm/[email protected]_@[email protected]_@[email protected][email protected][email protected][email protected][email protected]/node_modules/next/dist/compiled/react/index.js"); 236/* __next_internal_client_entry_do_not_use__ Content,Drawer,Handle,NestedRoot,Overlay,Portal,Root auto */ function __insertCSS(code) { 237 if (!code || typeof document == 'undefined') return; 238 let head = document.head || document.getElementsByTagName('head')[0]; 239 let style = document.createElement('style'); 240 style.type = 'text/css'; 241 head.appendChild(style); 242 style.styleSheet ? style.styleSheet.cssText = code : style.appendChild(document.createTextNode(code)); 243} 244 245 246 247const DrawerContext = /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createContext({ 248 drawerRef: { 249 current: null 250 }, 251 overlayRef: { 252 current: null 253 }, 254 onPress: ()=>{}, 255 onRelease: ()=>{}, 256 onDrag: ()=>{}, 257 onNestedDrag: ()=>{}, 258 onNestedOpenChange: ()=>{}, 259 onNestedRelease: ()=>{}, 260 openProp: undefined, 261 dismissible: false, 262 isOpen: false, 263 isDragging: false, 264 keyboardIsOpen: { 265 current: false 266 }, 267 snapPointsOffset: null, 268 snapPoints: null, 269 handleOnly: false, 270 modal: false, 271 shouldFade: false, 272 activeSnapPoint: null, 273 onOpenChange: ()=>{}, 274 setActiveSnapPoint: ()=>{}, 275 closeDrawer: ()=>{}, 276 direction: 'bottom', 277 shouldAnimate: { 278 current: true 279 },
280 shouldScaleBackground: false, 281 setBackgroundColorOnScale: true, 282 noBodyStyles: false, 283 container: null, 284 autoFocus: false 285}); 286const useDrawerContext = ()=>{ 287 const context = react__WEBPACK_IMPORTED_MODULE_0__.useContext(DrawerContext); 288 if (!context) { 289 throw new Error('useDrawerContext must be used within a Drawer.Root'); 290 } 291 return context; 292}; 293__insertCSS("[data-vaul-drawer]{touch-action:none;will-change:transform;transition:transform .5s cubic-bezier(.32, .72, 0, 1);animation-duration:.5s;animation-timing-function:cubic-bezier(0.32,0.72,0,1)}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=bottom][data-state=open]{animation-name:slideFromBottom}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=bottom][data-state=closed]{animation-name:slideToBottom}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=top][data-state=open]{animation-name:slideFromTop}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=top][data-state=closed]{animation-name:slideToTop}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=left][data-state=open]{animation-name:slideFromLeft}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=left][data-state=closed]{animation-name:slideToLeft}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=right][data-state=open]{animation-name:slideFromRight}[data-vaul-drawer][data-vaul-snap-points=false][data-vaul-drawer-direction=right][data-state=closed]{animation-name:slideToRight}[data-vaul-drawer][data-vaul-snap-points=true][data-vaul-drawer-direction=bottom]{transform:translate3d(0,var(--initial-transform,100%),0)}[data-vaul-drawer][data-vaul-snap-points=true][data-vaul-drawer-direction=top]{transform:translate3d(0,calc(var(--initial-transform,100%) * -1),0)}[data-vaul-drawer][data-vaul-snap-points=true][data-vaul-drawer-direction=left]{transform:translate3d(calc(var(--initial-transform,100%) * -1),0,0)}[data-vaul-drawer][data-vaul-snap-points=true][data-vaul-drawer-direction=right]{transform:translate3d(var(--initial-transform,100%),0,0)}[data-vaul-drawer][data-vaul-delayed-snap-points=true][data-vaul-drawer-direction=top]{transform:translate3d(0,var(--snap-point-height,0),0)}[data-vaul-drawer][data-vaul-delayed-snap-points=true][data-vaul-drawer-direction=bottom]{transform:translate3d(0,var(--snap-point-height,0),0)}[data-vaul-drawer][data-vaul-delayed-snap-points=true][data-vaul-drawer-direction=left]{transform:translate3d(var(--snap-point-height,0),0,0)}[data-vaul-drawer][data-vaul-delayed-snap-points=true][data-vaul-drawer-direction=right]{transform:translate3d(var(--snap-point-height,0),0,0)}[data-vaul-overlay][data-vaul-snap-points=false]{animation-duration:.5s;animation-timing-function:cubic-bezier(0.32,0.72,0,1)}[data-vaul-overlay][data-vaul-snap-points=false][data-state=open]{animation-name:fadeIn}[data-vaul-overlay][data-state=closed]{animation-name:fadeOut}[data-vaul-animate=false]{animation:none!important}[data-vaul-overlay][data-vaul-snap-points=true]{opacity:0;transition:opacity .5s cubic-bezier(.32, .72, 0, 1)}[data-vaul-overlay][data-vaul-snap-points=true]{opacity:1}[data-vaul-drawer]:not([data-vaul-custom-container=true])::after{content:'';position:absolute;background:inherit;background-color:inherit}[data-vaul-drawer][data-vaul-drawer-direction=top]::after{top:initial;bottom:100%;left:0;right:0;height:200%}[data-vaul-drawer][data-vaul-drawer-direction=bottom]::after{top:100%;bottom:initial;left:0;right:0;height:200%}[data-vaul-drawer][data-vaul-drawer-direction=left]::after{left:initial;right:100%;top:0;bottom:0;width:200%}[data-vaul-drawer][data-vaul-drawer-direction=right]::after{left:100%;right:initial;top:0;bottom:0;width:200%}[data-vaul-overlay][data-vaul-snap-points=true]:not([data-vaul-snap-points-overlay=true]):not(\n[data-state=closed]\n){opacity:0}
293[data-vaul-overlay][data-vaul-snap-points-overlay=true]{opacity:1}[data-vaul-handle]{display:block;position:relative;opacity:.7;background:#e2e2e4;margin-left:auto;margin-right:auto;height:5px;width:32px;border-radius:1rem;touch-action:pan-y}[data-vaul-handle]:active,[data-vaul-handle]:hover{opacity:1}[data-vaul-handle-hitarea]{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:max(100%,2.75rem);height:max(100%,2.75rem);touch-action:inherit}@media (hover:hover) and (pointer:fine){[data-vaul-drawer]{user-select:none}}@media (pointer:fine){[data-vaul-handle-hitarea]:{width:100%;height:100%}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeOut{to{opacity:0}}@keyframes slideFromBottom{from{transform:translate3d(0,var(--initial-transform,100%),0)}to{transform:translate3d(0,0,0)}}@keyframes slideToBottom{to{transform:translate3d(0,var(--initial-transform,100%),0)}}@keyframes slideFromTop{from{transform:translate3d(0,calc(var(--initial-transform,100%) * -1),0)}to{transform:translate3d(0,0,0)}}@keyframes slideToTop{to{transform:translate3d(0,calc(var(--initial-transform,100%) * -1),0)}}@keyframes slideFromLeft{from{transform:translate3d(calc(var(--initial-transform,100%) * -1),0,0)}to{transform:translate3d(0,0,0)}}@keyframes slideToLeft{to{transform:translate3d(calc(var(--initial-transform,100%) * -1),0,0)}}@keyframes slideFromRight{from{transform:translate3d(var(--initial-transform,100%),0,0)}to{transform:translate3d(0,0,0)}}@keyframes slideToRight{to{transform:translate3d(var(--initial-transform,100%),0,0)}}"); 294function isMobileFirefox() { 295 const userAgent = navigator.userAgent; 296 return typeof window !== 'undefined' && (/Firefox/.test(userAgent) && /Mobile/.test(userAgent) || // Android Firefox 297 /FxiOS/.test(userAgent) // iOS Firefox 298 ); 299} 300function isMac() { 301 return testPlatform(/^Mac/); 302} 303function isIPhone() { 304 return testPlatform(/^iPhone/); 305} 306function isSafari() { 307 return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 308} 309function isIPad() { 310 return testPlatform(/^iPad/) || // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support. 311 isMac() && navigator.maxTouchPoints > 1; 312} 313function isIOS() { 314 return isIPhone() || isIPad(); 315} 316function testPlatform(re) { 317 return typeof window !== 'undefined' && window.navigator != null ? re.test(window.navigator.platform) : undefined; 318} 319// This code comes from https://github.com/adobe/react-spectrum/blob/main/packages/%40react-aria/overlays/src/usePreventScroll.ts 320const KEYBOARD_BUFFER = 24; 321const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect : react__WEBPACK_IMPORTED_MODULE_0__.useEffect; 322function chain$1() { 323 for(var _len = arguments.length, callbacks = new Array(_len), _key = 0; _key < _len; _key++){ 324 callbacks[_key] = arguments[_key]; 325 } 326 return function() { 327 for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ 328 args[_key] = arguments[_key]; 329 } 330 for (let callback of callbacks){ 331 if (typeof callback === 'function') { 332 callback(...args); 333 } 334 } 335 }; 336} 337// @ts-ignore 338const visualViewport = typeof document !== 'undefined' && window.visualViewport; 339function isScrollable(node) { 340 let style = window.getComputedStyle(node); 341 return /(auto|scroll)/.test(style.overflow + style.overflowX + style.overflowY); 342} 343function getScrollParent(node) { 344 if (isScrollable(node)) { 345 node = node.parentElement; 346 } 347 while(node && !isScrollable(node)){ 348 node = node.parentElement; 349 } 350 return node || document.scrollingElement || document.documentElement; 351} 352// HTML input types that do not cause the software keyboard to appear. 353const nonTextInputTypes = new Set([ 354 'checkbox', 355 'radio', 356 'range', 357 'color', 358 'file', 359 'image', 360 'button', 361 'submit', 362 'reset' 363]); 364// The number of active usePreventScroll calls. Used to determine whether to revert back to the original page style/scroll position 365let preventScrollCount = 0; 366let restore; 367/** 368 * Prevents scrolling on the document body on mount, and 369 * restores it on unmount. Also ensures that content does not 370 * shift due to the scrollbars disappearing. 371 */ function usePreventScroll() { 372 let options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {}; 373 let { isDisabled } = options; 374 useIsomorphicLayoutEffect(()=>{ 375 if (isDisabled) { 376 return; 377 } 378 preventScrollCount++; 379 if (preventScrollCount === 1) { 380 if (isIOS()) { 381 restore = preventScrollMobileSafari(); 382 } 383 } 384 return ()=>{ 385 preventScrollCount--; 386 if (preventScrollCount === 0) {
387 restore == null ? void 0 : restore(); 388 } 389 }; 390 }, [ 391 isDisabled 392 ]); 393} 394// Mobile Safari is a whole different beast. Even with overflow: hidden, 395// it still scrolls the page in many situations: 396// 397// 1. When the bottom toolbar and address bar are collapsed, page scrolling is always allowed. 398// 2. When the keyboard is visible, the viewport does not resize. Instead, the keyboard covers part of 399// it, so it becomes scrollable. 400// 3. When tapping on an input, the page always scrolls so that the input is centered in the visual viewport. 401// This may cause even fixed position elements to scroll off the screen. 402// 4. When using the next/previous buttons in the keyboard to navigate between inputs, the whole page always 403// scrolls, even if the input is inside a nested scrollable element that could be scrolled instead. 404// 405// In order to work around these cases, and prevent scrolling without jankiness, we do a few things: 406// 407// 1. Prevent default on `touchmove` events that are not in a scrollable element. This prevents touch scrolling 408// on the window. 409// 2. Prevent default on `touchmove` events inside a scrollable element when the scroll position is at the 410// top or bottom. This avoids the whole page scrolling instead, but does prevent overscrolling. 411// 3. Prevent default on `touchend` events on input elements and handle focusing the element ourselves. 412// 4. When focusing an input, apply a transform to trick Safari into thinking the input is at the top 413// of the page, which prevents it from scrolling the page. After the input is focused, scroll the element 414// into view ourselves, without scrolling the whole page. 415// 5. Offset the body by the scroll position using a negative margin and scroll to the top. This should appear the 416// same visually, but makes the actual scroll position always zero. This is required to make all of the 417// above work or Safari will still try to scroll the page when focusing an input. 418// 6. As a last resort, handle window scroll events, and scroll back to the top. This can happen when attempting 419// to navigate to an input with the next/previous buttons that's outside a modal. 420function preventScrollMobileSafari() { 421 let scrollable; 422 let lastY = 0; 423 let onTouchStart = (e)=>{ 424 // Store the nearest scrollable parent element from the element that the user touched. 425 scrollable = getScrollParent(e.target); 426 if (scrollable === document.documentElement && scrollable === document.body) { 427 return; 428 } 429 lastY = e.changedTouches[0].pageY; 430 }; 431 let onTouchMove = (e)=>{ 432 // Prevent scrolling the window. 433 if (!scrollable || scrollable === document.documentElement || scrollable === document.body) { 434 e.preventDefault(); 435 return; 436 } 437 // Prevent scrolling up when at the top and scrolling down when at the bottom 438 // of a nested scrollable area, otherwise mobile Safari will start scrolling 439 // the window instead. Unfortunately, this disables bounce scrolling when at 440 // the top but it's the best we can do. 441 let y = e.changedTouches[0].pageY; 442 let scrollTop = scrollable.scrollTop; 443 let bottom = scrollable.scrollHeight - scrollable.clientHeight; 444 if (bottom === 0) { 445 return; 446 } 447 if (scrollTop <= 0 && y > lastY || scrollTop >= bottom && y < lastY) { 448 e.preventDefault(); 449 } 450 lastY = y; 451 }; 452 let onTouchEnd = (e)=>{ 453 let target = e.target; 454 // Apply this change if we're not already focused on the target element 455 if (isInput(target) && target !== document.activeElement) { 456 e.preventDefault(); 457 // Apply a transform to trick Safari into thinking the input is at the top of the page 458 // so it doesn't try to scroll it into view. When tapping on an input, this needs to 459 // be done before the "focus" event, so we have to focus the element ourselves. 460 target.style.transform = 'translateY(-2000px)';
461 target.focus(); 462 requestAnimationFrame(()=>{ 463 target.style.transform = ''; 464 }); 465 } 466 }; 467 let onFocus = (e)=>{ 468 let target = e.target; 469 if (isInput(target)) { 470 // Transform also needs to be applied in the focus event in cases where focus moves 471 // other than tapping on an input directly, e.g. the next/previous buttons in the 472 // software keyboard. In these cases, it seems applying the transform in the focus event 473 // is good enough, whereas when tapping an input, it must be done before the focus event. ð¤·ââï¸ 474 target.style.transform = 'translateY(-2000px)'; 475 requestAnimationFrame(()=>{ 476 target.style.transform = ''; 477 // This will have prevented the browser from scrolling the focused element into view, 478 // so we need to do this ourselves in a way that doesn't cause the whole page to scroll. 479 if (visualViewport) { 480 if (visualViewport.height < window.innerHeight) { 481 // If the keyboard is already visible, do this after one additional frame 482 // to wait for the transform to be removed. 483 requestAnimationFrame(()=>{ 484 scrollIntoView(target); 485 }); 486 } else { 487 // Otherwise, wait for the visual viewport to resize before scrolling so we can 488 // measure the correct position to scroll to. 489 visualViewport.addEventListener('resize', ()=>scrollIntoView(target), { 490 once: true 491 }); 492 } 493 } 494 }); 495 } 496 }; 497 let onWindowScroll = ()=>{ 498 // Last resort. If the window scrolled, scroll it back to the top. 499 // It should always be at the top because the body will have a negative margin (see below). 500 window.scrollTo(0, 0); 501 }; 502 // Record the original scroll position so we can restore it. 503 // Then apply a negative margin to the body to offset it by the scroll position. This will 504 // enable us to scroll the window to the top, which is required for the rest of this to work. 505 let scrollX = window.pageXOffset; 506 let scrollY = window.pageYOffset; 507 let restoreStyles = chain$1(setStyle(document.documentElement, 'paddingRight', "".concat(window.innerWidth - document.documentElement.clientWidth, "px"))); 508 // Scroll to the top. The negative margin on the body will make this appear the same. 509 window.scrollTo(0, 0); 510 let removeEvents = chain$1(addEvent(document, 'touchstart', onTouchStart, { 511 passive: false, 512 capture: true 513 }), addEvent(document, 'touchmove', onTouchMove, { 514 passive: false, 515 capture: true 516 }), addEvent(document, 'touchend', onTouchEnd, { 517 passive: false, 518 capture: true 519 }), addEvent(document, 'focus', onFocus, true), addEvent(window, 'scroll', onWindowScroll)); 520 return ()=>{ 521 // Restore styles and scroll the page back to where it was. 522 restoreStyles(); 523 removeEvents(); 524 window.scrollTo(scrollX, scrollY); 525 }; 526} 527// Sets a CSS property on an element, and returns a function to revert it to the previous value. 528function setStyle(element, style, value) { 529 // https://github.com/microsoft/TypeScript/issues/17827#issuecomment-391663310 530 // @ts-ignore 531 let cur = element.style[style]; 532 // @ts-ignore 533 element.style[style] = value; 534 return ()=>{ 535 // @ts-ignore 536 element.style[style] = cur; 537 }; 538} 539// Adds an event listener to an element, and returns a function to remove it. 540function addEvent(target, event, handler, options) { 541 // @ts-ignore 542 target.addEventListener(event, handler, options); 543 return ()=>{ 544 // @ts-ignore 545 target.removeEventListener(event, handler, options); 546 }; 547} 548function scrollIntoView(target) { 549 let root = document.scrollingElement || document.documentElement; 550 while(target && target !== root){ 551 // Find the parent scrollable element and adjust the scroll position if the target is not already in view. 552 let scrollable = getScrollParent(target); 553 if (scrollable !== document.documentElement && scrollable !== document.body && scrollable !== target) { 554 let scrollableTop = scrollable.getBoundingClientRect().top; 555 let targetTop = target.getBoundingClientRect().top; 556 let targetBottom = target.getBoundingClientRect().bottom; 557 // Buffer is needed for some edge cases
558 const keyboardHeight = scrollable.getBoundingClientRect().bottom + KEYBOARD_BUFFER; 559 if (targetBottom > keyboardHeight) { 560 scrollable.scrollTop += targetTop - scrollableTop; 561 } 562 } 563 // @ts-ignore 564 target = scrollable.parentElement; 565 } 566} 567function isInput(target) { 568 return target instanceof HTMLInputElement && !nonTextInputTypes.has(target.type) || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable; 569} 570// This code comes from https://github.com/radix-ui/primitives/tree/main/packages/react/compose-refs 571/** 572 * Set a given ref to a given value 573 * This utility takes care of different types of refs: callback refs and RefObject(s) 574 */ function setRef(ref, value) { 575 if (typeof ref === 'function') { 576 ref(value); 577 } else if (ref !== null && ref !== undefined) { 578 ref.current = value; 579 } 580} 581/** 582 * A utility to compose multiple refs together 583 * Accepts callback refs and RefObject(s) 584 */ function composeRefs() { 585 for(var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++){ 586 refs[_key] = arguments[_key]; 587 } 588 return (node)=>refs.forEach((ref)=>setRef(ref, node)); 589} 590/** 591 * A custom hook that composes multiple refs 592 * Accepts callback refs and RefObject(s) 593 */ function useComposedRefs() { 594 for(var _len = arguments.length, refs = new Array(_len), _key = 0; _key < _len; _key++){ 595 refs[_key] = arguments[_key]; 596 } 597 // eslint-disable-next-line react-hooks/exhaustive-deps 598 return react__WEBPACK_IMPORTED_MODULE_0__.useCallback(composeRefs(...refs), refs); 599} 600const cache = new WeakMap(); 601function set(el, styles) { 602 let ignoreCache = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : false; 603 if (!el || !(el instanceof HTMLElement)) return; 604 let originalStyles = {}; 605 Object.entries(styles).forEach((param)=>{ 606 let [key, value] = param; 607 if (key.startsWith('--')) { 608 el.style.setProperty(key, value); 609 return; 610 } 611 originalStyles[key] = el.style[key]; 612 el.style[key] = value; 613 }); 614 if (ignoreCache) return; 615 cache.set(el, originalStyles); 616} 617function reset(el, prop) { 618 if (!el || !(el instanceof HTMLElement)) return; 619 let originalStyles = cache.get(el); 620 if (!originalStyles) { 621 return; 622 } 623 { 624 el.style[prop] = originalStyles[prop]; 625 } 626} 627const isVertical = (direction)=>{ 628 switch(direction){ 629 case 'top': 630 case 'bottom': 631 return true; 632 case 'left': 633 case 'right': 634 return false; 635 default: 636 return direction; 637 } 638}; 639function getTranslate(element, direction) { 640 if (!element) { 641 return null; 642 } 643 const style = window.getComputedStyle(element); 644 const transform = style.transform || style.webkitTransform || style.mozTransform; 645 let mat = transform.match(/^matrix3d\((.+)\)$/); 646 if (mat) { 647 // https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix3d 648 return parseFloat(mat[1].split(', ')[isVertical(direction) ? 13 : 12]); 649 } 650 // https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/matrix 651 mat = transform.match(/^matrix\((.+)\)$/); 652 return mat ? parseFloat(mat[1].split(', ')[isVertical(direction) ? 5 : 4]) : null; 653} 654function dampenValue(v) { 655 return 8 * (Math.log(v + 1) - 2); 656} 657function assignStyle(element, style) { 658 if (!element) return ()=>{}; 659 const prevStyle = element.style.cssText; 660 Object.assign(element.style, style); 661 return ()=>{ 662 element.style.cssText = prevStyle; 663 }; 664} 665/** 666 * Receives functions as arguments and returns a new function that calls all. 667 */ function chain() { 668 for(var _len = arguments.length, fns = new Array(_len), _key = 0; _key < _len; _key++){ 669 fns[_key] = arguments[_key]; 670 } 671 return function() { 672 for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ 673 args[_key] = arguments[_key]; 674 } 675 for (const fn of fns){ 676 if (typeof fn === 'function') { 677 // @ts-ignore 678 fn(...args); 679 } 680 } 681 }; 682} 683const TRANSITIONS = { 684 DURATION: 0.5, 685 EASE: [ 686 0.32, 687 0.72, 688 0, 689 1 690 ] 691}; 692const VELOCITY_THRESHOLD = 0.4; 693const CLOSE_THRESHOLD = 0.25; 694const SCROLL_LOCK_TIMEOUT = 100; 695const BORDER_RADIUS = 8; 696const NESTED_DISPLACEMENT = 16; 697const WINDOW_TOP_OFFSET = 26; 698const DRAG_CLASS = 'vaul-dragging'; 699// This code comes from https://github.com/radix-ui/primitives/blob/main/packages/react/use-controllable-state/src/useControllableState.tsx 700function useCallbackRef(callback) { 701 const callbackRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(callback); 702 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 703 callbackRef.current = callback; 704 }); 705 // https://github.com/facebook/react/issues/19240 706 return react__WEBPACK_IMPORTED_MODULE_0__.useMemo(()=>function() { 707 for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){ 708 args[_key] = arguments[_key]; 709 } 710 return callbackRef.current == null ? void 0 : callbackRef.current.call(callbackRef, ...args); 711 }, []); 712} 713function useUncontrolledState(param) { 714 let { defaultProp, onChange } = param; 715 const uncontrolledState = react__WEBPACK_IMPORTED_MODULE_0__.useState(defaultProp); 716 const [value] = uncontrolledState; 717 const prevValueRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(value); 718 const handleChange = useCallbackRef(onChange); 719 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 720 if (prevValueRef.current !== value) { 721 handleChange(value); 722 prevValueRef.current = value; 723 } 724 }, [ 725 value, 726 prevValueRef, 727 handleChange 728 ]); 729 return uncontrolledState; 730} 731function useControllableState(param) { 732 let { prop, defaultProp, onChange = ()=>{} } = param; 733 const [uncontrolledProp, setUncontrolledProp] = useUncontrolledState({ 734 defaultProp, 735 onChange 736 }); 737 const isControlled = prop !== undefined; 738 const value = isControlled ? prop : uncontrolledProp; 739 const handleChange = useCallbackRef(onChange); 740 const setValue = react__WEBPACK_IMPORTED_MODULE_0__.useCallback((nextValue)=>{ 741 if (isControlled) { 742 const setter = nextValue; 743 const value = typeof nextValue === 'function' ? setter(prop) : nextValue; 744 if (value !== prop) handleChange(value); 745 } else { 746 setUncontrolledProp(nextValue); 747 } 748 }, [ 749 isControlled, 750 prop, 751 setUncontrolledProp, 752 handleChange 753 ]); 754 return [ 755 value, 756 setValue 757 ]; 758} 759function useSnapPoints(param) { 760 let { activeSnapPointProp, setActiveSnapPointProp, snapPoints, drawerRef, overlayRef, fadeFromIndex, onSnapPointChange, direction = 'bottom', container, snapToSequentialPoint } = param; 761 const [activeSnapPoint, setActiveSnapPoint] = useControllableState({ 762 prop: activeSnapPointProp, 763 defaultProp: snapPoints == null ? void 0 : snapPoints[0], 764 onChange: setActiveSnapPointProp 765 }); 766 const [windowDimensions, setWindowDimensions] = react__WEBPACK_IMPORTED_MODULE_0__.useState(typeof window !== 'undefined' ? { 767 innerWidth: window.innerWidth, 768 innerHeight: window.innerHeight 769 } : undefined); 770 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 771 function onResize() { 772 setWindowDimensions({ 773 innerWidth: window.innerWidth, 774 innerHeight: window.innerHeight 775 }); 776 } 777 window.addEventListener('resize', onResize); 778 return ()=>window.removeEventListener('resize', onResize); 779 }, []); 780 const isLastSnapPoint = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(()=>activeSnapPoint === (snapPoints == null ? void 0 : snapPoints[snapPoints.length - 1]) || null, [ 781 snapPoints, 782 activeSnapPoint 783 ]); 784 const activeSnapPointIndex = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(()=>{ 785 var _snapPoints_findIndex; 786 return (_snapPoints_findIndex = snapPoints == null ? void 0 : snapPoints.findIndex((snapPoint)=>snapPoint === activeSnapPoint)) != null ? _snapPoints_findIndex : null; 787 }, [ 788 snapPoints, 789 activeSnapPoint 790 ]); 791 const shouldFade = snapPoints && snapPoints.length > 0 && (fadeFromIndex || fadeFromIndex === 0) && !Number.isNaN(fadeFromIndex) && snapPoints[fadeFromIndex] === activeSnapPoint || !snapPoints; 792 const snapPointsOffset = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(()=>{ 793 const containerSize = container ? { 794 width: container.getBoundingClientRect().width, 795 height: container.getBoundingClientRect().height 796 } : typeof window !== 'undefined' ? { 797 width: window.innerWidth, 798 height: window.innerHeight 799 } : { 800 width: 0, 801 height: 0 802 }; 803 var _snapPoints_map; 804 return (_snapPoints_map = snapPoints == null ? void 0 : snapPoints.map((snapPoint)=>{ 805 const isPx = typeof snapPoint === 'string'; 806 let snapPointAsNumber = 0; 807 if (isPx) { 808 snapPointAsNumber = parseInt(snapPoint, 10); 809 } 810 if (isVertical(direction)) { 811 const height = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.height : 0; 812 if (windowDimensions) { 813 return direction === 'bottom' ? containerSize.height - height : -containerSize.height + height; 814 } 815 return height; 816 } 817 const width = isPx ? snapPointAsNumber : windowDimensions ? snapPoint * containerSize.width : 0; 818 if (windowDimensions) { 819 return direction === 'right' ? containerSize.width - width : -containerSize.width + width; 820 } 821 return width; 822 })) != null ? _snapPoints_map : []; 823 }, [ 824 snapPoints, 825 windowDimensions, 826 container 827 ]); 828 const activeSnapPointOffset = react__WEBPACK_IMPORTED_MODULE_0__.useMemo(()=>activeSnapPointIndex !== null ? snapPointsOffset == null ? void 0 : snapPointsOffset[activeSnapPointIndex] : null, [ 829 snapPointsOffset, 830 activeSnapPointIndex 831 ]); 832 const snapToPoint = react__WEBPACK_IMPORTED_MODULE_0__.useCallback((dimension)=>{ 833 var _snapPointsOffset_findIndex; 834 const newSnapPointIndex = (_snapPointsOffset_findIndex = snapPointsOffset == null ? void 0 : snapPointsOffset.findIndex((snapPointDim)=>snapPointDim === dimension)) != null ? _snapPointsOffset_findIndex : null; 835 onSnapPointChange(newSnapPointIndex); 836 set(drawerRef.current, { 837 transition: "transform ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 838 transform: isVertical(direction) ? "translate3d(0, ".concat(dimension, "px, 0)") : "translate3d(".concat(dimension, "px, 0, 0)") 839 }); 840 if (snapPointsOffset && newSnapPointIndex !== snapPointsOffset.length - 1 && fadeFromIndex !== undefined && newSnapPointIndex !== fadeFromIndex && newSnapPointIndex < fadeFromIndex) { 841 set(overlayRef.current, { 842 transition: "opacity ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 843 opacity: '0' 844 }); 845 } else { 846 set(overlayRef.current, { 847 transition: "opacity ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 848 opacity: '1' 849 }); 850 }
851 setActiveSnapPoint(snapPoints == null ? void 0 : snapPoints[Math.max(newSnapPointIndex, 0)]); 852 }, [ 853 drawerRef.current, 854 snapPoints, 855 snapPointsOffset, 856 fadeFromIndex, 857 overlayRef, 858 setActiveSnapPoint 859 ]); 860 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 861 if (activeSnapPoint || activeSnapPointProp) { 862 var _snapPoints_findIndex; 863 const newIndex = (_snapPoints_findIndex = snapPoints == null ? void 0 : snapPoints.findIndex((snapPoint)=>snapPoint === activeSnapPointProp || snapPoint === activeSnapPoint)) != null ? _snapPoints_findIndex : -1; 864 if (snapPointsOffset && newIndex !== -1 && typeof snapPointsOffset[newIndex] === 'number') { 865 snapToPoint(snapPointsOffset[newIndex]); 866 } 867 } 868 }, [ 869 activeSnapPoint, 870 activeSnapPointProp, 871 snapPoints, 872 snapPointsOffset, 873 snapToPoint 874 ]); 875 function onRelease(param) { 876 let { draggedDistance, closeDrawer, velocity, dismissible } = param; 877 if (fadeFromIndex === undefined) return; 878 const currentPosition = direction === 'bottom' || direction === 'right' ? (activeSnapPointOffset != null ? activeSnapPointOffset : 0) - draggedDistance : (activeSnapPointOffset != null ? activeSnapPointOffset : 0) + draggedDistance; 879 const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1; 880 const isFirst = activeSnapPointIndex === 0; 881 const hasDraggedUp = draggedDistance > 0; 882 if (isOverlaySnapPoint) { 883 set(overlayRef.current, { 884 transition: "opacity ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")") 885 }); 886 } 887 if (!snapToSequentialPoint && velocity > 2 && !hasDraggedUp) { 888 if (dismissible) closeDrawer(); 889 else snapToPoint(snapPointsOffset[0]); // snap to initial point 890 return; 891 } 892 if (!snapToSequentialPoint && velocity > 2 && hasDraggedUp && snapPointsOffset && snapPoints) { 893 snapToPoint(snapPointsOffset[snapPoints.length - 1]); 894 return; 895 } 896 // Find the closest snap point to the current position 897 const closestSnapPoint = snapPointsOffset == null ? void 0 : snapPointsOffset.reduce((prev, curr)=>{ 898 if (typeof prev !== 'number' || typeof curr !== 'number') return prev; 899 return Math.abs(curr - currentPosition) < Math.abs(prev - currentPosition) ? curr : prev; 900 }); 901 const dim = isVertical(direction) ? window.innerHeight : window.innerWidth; 902 if (velocity > VELOCITY_THRESHOLD && Math.abs(draggedDistance) < dim * 0.4) { 903 const dragDirection = hasDraggedUp ? 1 : -1; // 1 = up, -1 = down 904 // Don't do anything if we swipe upwards while being on the last snap point 905 if (dragDirection > 0 && isLastSnapPoint && snapPoints) { 906 snapToPoint(snapPointsOffset[snapPoints.length - 1]); 907 return; 908 } 909 if (isFirst && dragDirection < 0 && dismissible) { 910 closeDrawer(); 911 } 912 if (activeSnapPointIndex === null) return; 913 snapToPoint(snapPointsOffset[activeSnapPointIndex + dragDirection]); 914 return; 915 } 916 snapToPoint(closestSnapPoint); 917 } 918 function onDrag(param) { 919 let { draggedDistance } = param; 920 if (activeSnapPointOffset === null) return; 921 const newValue = direction === 'bottom' || direction === 'right' ? activeSnapPointOffset - draggedDistance : activeSnapPointOffset + draggedDistance; 922 // Don't do anything if we exceed the last(biggest) snap point 923 if ((direction === 'bottom' || direction === 'right') && newValue < snapPointsOffset[snapPointsOffset.length - 1]) { 924 return; 925 } 926 if ((direction === 'top' || direction === 'left') && newValue > snapPointsOffset[snapPointsOffset.length - 1]) { 927 return; 928 } 929 set(drawerRef.current, { 930 transform: isVertical(direction) ? "translate3d(0, ".concat(newValue, "px, 0)") : "translate3d(".concat(newValue, "px, 0, 0)") 931 }); 932 } 933 function getPercentageDragged(absDraggedDistance, isDraggingDown) { 934 if (!snapPoints || typeof activeSnapPointIndex !== 'number' || !snapPointsOffset || fadeFromIndex === undefined) return null; 935 // If this is true we are dragging to a snap point that is supposed to have an overlay 936 const isOverlaySnapPoint = activeSnapPointIndex === fadeFromIndex - 1; 937 const isOverlaySnapPointOrHigher = activeSnapPointIndex >= fadeFromIndex; 938 if (isOverlaySnapPointOrHigher && isDraggingDown) { 939 return 0; 940 } 941 // Don't animate, but still use this one if we are dragging away from the overlaySnapPoint 942 if (isOverlaySnapPoint && !isDraggingDown) return 1; 943 if (!shouldFade && !isOverlaySnapPoint) return null; 944 // Either fadeFrom index or the one before 945 const targetSnapPointIndex = isOverlaySnapPoint ? activeSnapPointIndex + 1 : activeSnapPointIndex - 1; 946 // Get the distance from overlaySnapPoint to the one before or vice-versa to calculate the opacity percentage accordingly 947 const snapPointDistance = isOverlaySnapPoint ? snapPointsOffset[targetSnapPointIndex] - snapPointsOffset[targetSnapPointIndex - 1] : snapPointsOffset[targetSnapPointIndex + 1] - snapPointsOffset[targetSnapPointIndex]; 948 const percentageDragged = absDraggedDistance / Math.abs(snapPointDistance); 949 if (isOverlaySnapPoint) { 950 return 1 - percentageDragged; 951 } else { 952 return percentageDragged; 953 } 954 } 955 return { 956 isLastSnapPoint, 957 activeSnapPoint, 958 shouldFade, 959 getPercentageDragged,
960 setActiveSnapPoint, 961 activeSnapPointIndex, 962 onRelease, 963 onDrag, 964 snapPointsOffset 965 }; 966} 967const noop = ()=>()=>{}; 968function useScaleBackground() { 969 const { direction, isOpen, shouldScaleBackground, setBackgroundColorOnScale, noBodyStyles } = useDrawerContext(); 970 const timeoutIdRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 971 const initialBackgroundColor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(()=>document.body.style.backgroundColor, []); 972 function getScale() { 973 return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth; 974 } 975 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 976 if (isOpen && shouldScaleBackground) { 977 if (timeoutIdRef.current) clearTimeout(timeoutIdRef.current); 978 const wrapper = document.querySelector('[data-vaul-drawer-wrapper]') || document.querySelector('[vaul-drawer-wrapper]'); 979 if (!wrapper) return; 980 chain(setBackgroundColorOnScale && !noBodyStyles ? assignStyle(document.body, { 981 background: 'black' 982 }) : noop, assignStyle(wrapper, { 983 transformOrigin: isVertical(direction) ? 'top' : 'left', 984 transitionProperty: 'transform, border-radius', 985 transitionDuration: "".concat(TRANSITIONS.DURATION, "s"), 986 transitionTimingFunction: "cubic-bezier(".concat(TRANSITIONS.EASE.join(','), ")") 987 })); 988 const wrapperStylesCleanup = assignStyle(wrapper, { 989 borderRadius: "".concat(BORDER_RADIUS, "px"), 990 overflow: 'hidden', 991 ...isVertical(direction) ? { 992 transform: "scale(".concat(getScale(), ") translate3d(0, calc(env(safe-area-inset-top) + 14px), 0)") 993 } : { 994 transform: "scale(".concat(getScale(), ") translate3d(calc(env(safe-area-inset-top) + 14px), 0, 0)") 995 } 996 }); 997 return ()=>{ 998 wrapperStylesCleanup(); 999 timeoutIdRef.current = window.setTimeout(()=>{ 1000 if (initialBackgroundColor) { 1001 document.body.style.background = initialBackgroundColor; 1002 } else { 1003 document.body.style.removeProperty('background'); 1004 } 1005 }, TRANSITIONS.DURATION * 1000); 1006 }; 1007 } 1008 }, [ 1009 isOpen, 1010 shouldScaleBackground, 1011 initialBackgroundColor 1012 ]); 1013} 1014let previousBodyPosition = null; 1015/** 1016 * This hook is necessary to prevent buggy behavior on iOS devices (need to test on Android). 1017 * I won't get into too much detail about what bugs it solves, but so far I've found that setting the body to `position: fixed` is the most reliable way to prevent those bugs. 1018 * Issues that this hook solves: 1019 * https://github.com/emilkowalski/vaul/issues/435 1020 * https://github.com/emilkowalski/vaul/issues/433 1021 * And more that I discovered, but were just not reported. 1022 */ function usePositionFixed(param) { 1023 let { isOpen, modal, nested, hasBeenOpened, preventScrollRestoration, noBodyStyles } = param; 1024 const [activeUrl, setActiveUrl] = react__WEBPACK_IMPORTED_MODULE_0__.useState(()=>typeof window !== 'undefined' ? window.location.href : ''); 1025 const scrollPos = react__WEBPACK_IMPORTED_MODULE_0__.useRef(0); 1026 const setPositionFixed = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(()=>{ 1027 // All browsers on iOS will return true here. 1028 if (!isSafari()) return; 1029 // If previousBodyPosition is already set, don't set it again. 1030 if (previousBodyPosition === null && isOpen && !noBodyStyles) { 1031 previousBodyPosition = { 1032 position: document.body.style.position, 1033 top: document.body.style.top, 1034 left: document.body.style.left, 1035 height: document.body.style.height, 1036 right: 'unset' 1037 }; 1038 // Update the dom inside an animation frame 1039 const { scrollX, innerHeight } = window; 1040 document.body.style.setProperty('position', 'fixed', 'important'); 1041 Object.assign(document.body.style, { 1042 top: "".concat(-scrollPos.current, "px"), 1043 left: "".concat(-scrollX, "px"), 1044 right: '0px', 1045 height: 'auto' 1046 }); 1047 window.setTimeout(()=>window.requestAnimationFrame(()=>{ 1048 // Attempt to check if the bottom bar appeared due to the position change
1049 const bottomBarHeight = innerHeight - window.innerHeight; 1050 if (bottomBarHeight && scrollPos.current >= innerHeight) { 1051 // Move the content further up so that the bottom bar doesn't hide it 1052 document.body.style.top = "".concat(-(scrollPos.current + bottomBarHeight), "px"); 1053 } 1054 }), 300); 1055 } 1056 }, [ 1057 isOpen 1058 ]); 1059 const restorePositionSetting = react__WEBPACK_IMPORTED_MODULE_0__.useCallback(()=>{ 1060 // All browsers on iOS will return true here. 1061 if (!isSafari()) return; 1062 if (previousBodyPosition !== null && !noBodyStyles) { 1063 // Convert the position from "px" to Int 1064 const y = -parseInt(document.body.style.top, 10); 1065 const x = -parseInt(document.body.style.left, 10); 1066 // Restore styles 1067 Object.assign(document.body.style, previousBodyPosition); 1068 window.requestAnimationFrame(()=>{ 1069 if (preventScrollRestoration && activeUrl !== window.location.href) {
1070 setActiveUrl(window.location.href); 1071 return; 1072 } 1073 window.scrollTo(x, y); 1074 }); 1075 previousBodyPosition = null; 1076 } 1077 }, [ 1078 activeUrl 1079 ]); 1080 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1081 function onScroll() { 1082 scrollPos.current = window.scrollY; 1083 } 1084 onScroll(); 1085 window.addEventListener('scroll', onScroll); 1086 return ()=>{ 1087 window.removeEventListener('scroll', onScroll); 1088 }; 1089 }, []); 1090 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1091 if (!modal) return; 1092 return ()=>{ 1093 if (typeof document === 'undefined') return; 1094 // Another drawer is opened, safe to ignore the execution 1095 const hasDrawerOpened = !!document.querySelector('[data-vaul-drawer]'); 1096 if (hasDrawerOpened) return; 1097 restorePositionSetting(); 1098 }; 1099 }, [ 1100 modal, 1101 restorePositionSetting 1102 ]); 1103 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1104 if (nested || !hasBeenOpened) return; 1105 // This is needed to force Safari toolbar to show **before** the drawer starts animating to prevent a gnarly shift from happening 1106 if (isOpen) { 1107 // avoid for standalone mode (PWA) 1108 const isStandalone = window.matchMedia('(display-mode: standalone)').matches; 1109 !isStandalone && setPositionFixed(); 1110 if (!modal) { 1111 window.setTimeout(()=>{ 1112 restorePositionSetting(); 1113 }, 500); 1114 } 1115 } else { 1116 restorePositionSetting(); 1117 } 1118 }, [ 1119 isOpen, 1120 hasBeenOpened, 1121 activeUrl, 1122 modal, 1123 nested, 1124 setPositionFixed, 1125 restorePositionSetting 1126 ]); 1127 return { 1128 restorePositionSetting 1129 }; 1130} 1131function Root(param) { 1132 let { 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 } = param; 1133 var _drawerRef_current, _drawerRef_current1; 1134 const [isOpen = false, setIsOpen] = useControllableState({ 1135 defaultProp: defaultOpen, 1136 prop: openProp, 1137 onChange: (o)=>{ 1138 onOpenChange == null ? void 0 : onOpenChange(o); 1139 if (!o && !nested) { 1140 restorePositionSetting(); 1141 } 1142 setTimeout(()=>{ 1143 onAnimationEnd == null ? void 0 : onAnimationEnd(o); 1144 }, TRANSITIONS.DURATION * 1000); 1145 if (o && !modal) { 1146 if (typeof window !== 'undefined') { 1147 window.requestAnimationFrame(()=>{ 1148 document.body.style.pointerEvents = 'auto'; 1149 }); 1150 } 1151 } 1152 if (!o) { 1153 // This will be removed when the exit animation ends (`500ms`) 1154 document.body.style.pointerEvents = 'auto'; 1155 } 1156 } 1157 }); 1158 const [hasBeenOpened, setHasBeenOpened] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false); 1159 const [isDragging, setIsDragging] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false); 1160 const [justReleased, setJustReleased] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false); 1161 const overlayRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1162 const openTime = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1163 const dragStartTime = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1164 const dragEndTime = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1165 const lastTimeDragPrevented = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1166 const isAllowedToDrag = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false); 1167 const nestedOpenChangeTimer = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1168 const pointerStart = react__WEBPACK_IMPORTED_MODULE_0__.useRef(0);
1169 const keyboardIsOpen = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false); 1170 const shouldAnimate = react__WEBPACK_IMPORTED_MODULE_0__.useRef(!defaultOpen); 1171 const previousDiffFromInitial = react__WEBPACK_IMPORTED_MODULE_0__.useRef(0); 1172 const drawerRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1173 const drawerHeightRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0); 1174 const drawerWidthRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0); 1175 const initialDrawerHeight = react__WEBPACK_IMPORTED_MODULE_0__.useRef(0); 1176 const onSnapPointChange = react__WEBPACK_IMPORTED_MODULE_0__.useCallback((activeSnapPointIndex)=>{ 1177 // Change openTime ref when we reach the last snap point to prevent dragging for 500ms incase it's scrollable. 1178 if (snapPoints && activeSnapPointIndex === snapPointsOffset.length - 1) openTime.current = new Date(); 1179 }, []); 1180 const { activeSnapPoint, activeSnapPointIndex, setActiveSnapPoint, onRelease: onReleaseSnapPoints, snapPointsOffset, onDrag: onDragSnapPoints, shouldFade, getPercentageDragged: getSnapPointsPercentageDragged } = useSnapPoints({ 1181 snapPoints, 1182 activeSnapPointProp, 1183 setActiveSnapPointProp, 1184 drawerRef, 1185 fadeFromIndex, 1186 overlayRef, 1187 onSnapPointChange, 1188 direction, 1189 container, 1190 snapToSequentialPoint 1191 }); 1192 usePreventScroll({ 1193 isDisabled: !isOpen || isDragging || !modal || justReleased || !hasBeenOpened || !repositionInputs || !disablePreventScroll 1194 }); 1195 const { restorePositionSetting } = usePositionFixed({ 1196 isOpen, 1197 modal, 1198 nested: nested != null ? nested : false, 1199 hasBeenOpened, 1200 preventScrollRestoration, 1201 noBodyStyles 1202 }); 1203 function getScale() { 1204 return (window.innerWidth - WINDOW_TOP_OFFSET) / window.innerWidth; 1205 } 1206 function onPress(event) { 1207 var _drawerRef_current, _drawerRef_current1; 1208 if (!dismissible && !snapPoints) return; 1209 if (drawerRef.current && !drawerRef.current.contains(event.target)) return; 1210 drawerHeightRef.current = ((_drawerRef_current = drawerRef.current) == null ? void 0 : _drawerRef_current.getBoundingClientRect().height) || 0; 1211 drawerWidthRef.current = ((_drawerRef_current1 = drawerRef.current) == null ? void 0 : _drawerRef_current1.getBoundingClientRect().width) || 0; 1212 setIsDragging(true); 1213 dragStartTime.current = new Date(); 1214 // iOS doesn't trigger mouseUp after scrolling so we need to listen to touched in order to disallow dragging 1215 if (isIOS()) { 1216 window.addEventListener('touchend', ()=>isAllowedToDrag.current = false, { 1217 once: true 1218 }); 1219 } 1220 // Ensure we maintain correct pointer capture even when going outside of the drawer 1221 event.target.setPointerCapture(event.pointerId); 1222 pointerStart.current = isVertical(direction) ? event.pageY : event.pageX; 1223 } 1224 function shouldDrag(el, isDraggingInDirection) { 1225 var _window_getSelection; 1226 let element = el; 1227 const highlightedText = (_window_getSelection = window.getSelection()) == null ? void 0 : _window_getSelection.toString(); 1228 const swipeAmount = drawerRef.current ? getTranslate(drawerRef.current, direction) : null; 1229 const date = new Date(); 1230 // Fixes https://github.com/emilkowalski/vaul/issues/483 1231 if (element.tagName === 'SELECT') { 1232 return false; 1233 } 1234 if (element.hasAttribute('data-vaul-no-drag') || element.closest('[data-vaul-no-drag]')) { 1235 return false; 1236 } 1237 if (direction === 'right' || direction === 'left') { 1238 return true; 1239 } 1240 // Allow scrolling when animating 1241 if (openTime.current && date.getTime() - openTime.current.getTime() < 500) { 1242 return false;
1243 } 1244 if (swipeAmount !== null) { 1245 if (direction === 'bottom' ? swipeAmount > 0 : swipeAmount < 0) { 1246 return true; 1247 } 1248 } 1249 // Don't drag if there's highlighted text 1250 if (highlightedText && highlightedText.length > 0) { 1251 return false; 1252 } 1253 // Disallow dragging if drawer was scrolled within `scrollLockTimeout` 1254 if (lastTimeDragPrevented.current && date.getTime() - lastTimeDragPrevented.current.getTime() < scrollLockTimeout && swipeAmount === 0) { 1255 lastTimeDragPrevented.current = date; 1256 return false; 1257 } 1258 if (isDraggingInDirection) { 1259 lastTimeDragPrevented.current = date; 1260 // We are dragging down so we should allow scrolling 1261 return false; 1262 } 1263 // Keep climbing up the DOM tree as long as there's a parent 1264 while(element){ 1265 // Check if the element is scrollable 1266 if (element.scrollHeight > element.clientHeight) { 1267 if (element.scrollTop !== 0) { 1268 lastTimeDragPrevented.current = new Date(); 1269 // The element is scrollable and not scrolled to the top, so don't drag 1270 return false; 1271 } 1272 if (element.getAttribute('role') === 'dialog') { 1273 return true; 1274 } 1275 } 1276 // Move up to the parent element 1277 element = element.parentNode; 1278 } 1279 // No scrollable parents not scrolled to the top found, so drag 1280 return true; 1281 } 1282 function onDrag(event) { 1283 if (!drawerRef.current) { 1284 return; 1285 } 1286 // We need to know how much of the drawer has been dragged in percentages so that we can transform background accordingly 1287 if (isDragging) { 1288 const directionMultiplier = direction === 'bottom' || direction === 'right' ? 1 : -1; 1289 const draggedDistance = (pointerStart.current - (isVertical(direction) ? event.pageY : event.pageX)) * directionMultiplier; 1290 const isDraggingInDirection = draggedDistance > 0; 1291 // Pre condition for disallowing dragging in the close direction. 1292 const noCloseSnapPointsPreCondition = snapPoints && !dismissible && !isDraggingInDirection; 1293 // Disallow dragging down to close when first snap point is the active one and dismissible prop is set to false. 1294 if (noCloseSnapPointsPreCondition && activeSnapPointIndex === 0) return; 1295 // We need to capture last time when drag with scroll was triggered and have a timeout between 1296 const absDraggedDistance = Math.abs(draggedDistance); 1297 const wrapper = document.querySelector('[data-vaul-drawer-wrapper]'); 1298 const drawerDimension = direction === 'bottom' || direction === 'top' ? drawerHeightRef.current : drawerWidthRef.current; 1299 // Calculate the percentage dragged, where 1 is the closed position 1300 let percentageDragged = absDraggedDistance / drawerDimension; 1301 const snapPointPercentageDragged = getSnapPointsPercentageDragged(absDraggedDistance, isDraggingInDirection); 1302 if (snapPointPercentageDragged !== null) { 1303 percentageDragged = snapPointPercentageDragged; 1304 } 1305 // Disallow close dragging beyond the smallest snap point. 1306 if (noCloseSnapPointsPreCondition && percentageDragged >= 1) { 1307 return; 1308 } 1309 if (!isAllowedToDrag.current && !shouldDrag(event.target, isDraggingInDirection)) return; 1310 drawerRef.current.classList.add(DRAG_CLASS); 1311 // 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 1312 isAllowedToDrag.current = true; 1313 set(drawerRef.current, { 1314 transition: 'none' 1315 }); 1316 set(overlayRef.current, { 1317 transition: 'none' 1318 }); 1319 if (snapPoints) { 1320 onDragSnapPoints({ 1321 draggedDistance 1322 }); 1323 } 1324 // Run this only if snapPoints are not defined or if we are at the last snap point (highest one) 1325 if (isDraggingInDirection && !snapPoints) { 1326 const dampenedDraggedDistance = dampenValue(draggedDistance); 1327 const translateValue = Math.min(dampenedDraggedDistance * -1, 0) * directionMultiplier; 1328 set(drawerRef.current, { 1329 transform: isVertical(direction) ? "translate3d(0, ".concat(translateValue, "px, 0)") : "translate3d(".concat(translateValue, "px, 0, 0)") 1330 }); 1331 return; 1332 } 1333 const opacityValue = 1 - percentageDragged; 1334 if (shouldFade || fadeFromIndex && activeSnapPointIndex === fadeFromIndex - 1) { 1335 onDragProp == null ? void 0 : onDragProp(event, percentageDragged); 1336 set(overlayRef.current, { 1337 opacity: "".concat(opacityValue), 1338 transition: 'none' 1339 }, true); 1340 } 1341 if (wrapper && overlayRef.current && shouldScaleBackgroun
1341d) { 1342 // Calculate percentageDragged as a fraction (0 to 1) 1343 const scaleValue = Math.min(getScale() + percentageDragged * (1 - getScale()), 1); 1344 const borderRadiusValue = 8 - percentageDragged * 8; 1345 const translateValue = Math.max(0, 14 - percentageDragged * 14); 1346 set(wrapper, { 1347 borderRadius: "".concat(borderRadiusValue, "px"), 1348 transform: isVertical(direction) ? "scale(".concat(scaleValue, ") translate3d(0, ").concat(translateValue, "px, 0)") : "scale(".concat(scaleValue, ") translate3d(").concat(translateValue, "px, 0, 0)"), 1349 transition: 'none' 1350 }, true); 1351 } 1352 if (!snapPoints) { 1353 const translateValue = absDraggedDistance * directionMultiplier; 1354 set(drawerRef.current, { 1355 transform: isVertical(direction) ? "translate3d(0, ".concat(translateValue, "px, 0)") : "translate3d(".concat(translateValue, "px, 0, 0)") 1356 }); 1357 } 1358 } 1359 } 1360 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1361 window.requestAnimationFrame(()=>{ 1362 shouldAnimate.current = true; 1363 }); 1364 }, []); 1365 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1366 var _window_visualViewport; 1367 function onVisualViewportChange() { 1368 if (!drawerRef.current || !repositionInputs) return; 1369 const focusedElement = document.activeElement; 1370 if (isInput(focusedElement) || keyboardIsOpen.current) { 1371 var _window_visualViewport; 1372 const visualViewportHeight = ((_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.height) || 0; 1373 const totalHeight = window.innerHeight; 1374 // This is the height of the keyboard
1375 let diffFromInitial = totalHeight - visualViewportHeight; 1376 const drawerHeight = drawerRef.current.getBoundingClientRect().height || 0; 1377 // Adjust drawer height only if it's tall enough 1378 const isTallEnough = drawerHeight > totalHeight * 0.8; 1379 if (!initialDrawerHeight.current) { 1380 initialDrawerHeight.current = drawerHeight; 1381 } 1382 const offsetFromTop = drawerRef.current.getBoundingClientRect().top; 1383 // visualViewport height may change due to somq e subtle changes to the keyboard. Checking if the height changed by 60 or more will make sure that they keyboard really changed its open state. 1384 if (Math.abs(previousDiffFromInitial.current - diffFromInitial) > 60) { 1385 keyboardIsOpen.current = !keyboardIsOpen.current; 1386 } 1387 if (snapPoints && snapPoints.length > 0 && snapPointsOffset && activeSnapPointIndex) { 1388 const activeSnapPointHeight = snapPointsOffset[activeSnapPointIndex] || 0; 1389 diffFromInitial += activeSnapPointHeight; 1390 } 1391 previousDiffFromInitial.current = diffFromInitial; 1392 // We don't have to change the height if the input is in view, when we are here we are in the opened keyboard state so we can correctly check if the input is in view 1393 if (drawerHeight > visualViewportHeight || keyboardIsOpen.current) { 1394 const height = drawerRef.current.getBoundingClientRect().height;
1395 let newDrawerHeight = height; 1396 if (height > visualViewportHeight) { 1397 newDrawerHeight = visualViewportHeight - (isTallEnough ? offsetFromTop : WINDOW_TOP_OFFSET); 1398 } 1399 // When fixed, don't move the drawer upwards if there's space, but rather only change it's height so it's fully scrollable when the keyboard is open 1400 if (fixed) { 1401 drawerRef.current.style.height = "".concat(height - Math.max(diffFromInitial, 0), "px"); 1402 } else { 1403 drawerRef.current.style.height = "".concat(Math.max(newDrawerHeight, visualViewportHeight - offsetFromTop), "px"); 1404 } 1405 } else if (!isMobileFirefox()) { 1406 drawerRef.current.style.height = "".concat(initialDrawerHeight.current, "px"); 1407 } 1408 if (snapPoints && snapPoints.length > 0 && !keyboardIsOpen.current) { 1409 drawerRef.current.style.bottom = "0px"; 1410 } else { 1411 // Negative bottom value would never make sense 1412 drawerRef.current.style.bottom = "".concat(Math.max(diffFromInitial, 0), "px"); 1413 } 1414 } 1415 } 1416 (_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.addEventListener('resize', onVisualViewportChange); 1417 return ()=>{ 1418 var _window_visualViewport; 1419 return (_window_visualViewport = window.visualViewport) == null ? void 0 : _window_visualViewport.removeEventListener('resize', onVisualViewportChange); 1420 }; 1421 }, [ 1422 activeSnapPointIndex, 1423 snapPoints, 1424 snapPointsOffset 1425 ]); 1426 function closeDrawer(fromWithin) { 1427 cancelDrag(); 1428 onClose == null ? void 0 : onClose(); 1429 if (!fromWithin) { 1430 setIsOpen(false); 1431 } 1432 setTimeout(()=>{ 1433 if (snapPoints) {
1434 setActiveSnapPoint(snapPoints[0]); 1435 } 1436 }, TRANSITIONS.DURATION * 1000); // seconds to ms 1437 } 1438 function resetDrawer() { 1439 if (!drawerRef.current) return; 1440 const wrapper = document.querySelector('[data-vaul-drawer-wrapper]'); 1441 const currentSwipeAmount = getTranslate(drawerRef.current, direction); 1442 set(drawerRef.current, { 1443 transform: 'translate3d(0, 0, 0)', 1444 transition: "transform ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")") 1445 }); 1446 set(overlayRef.current, { 1447 transition: "opacity ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 1448 opacity: '1' 1449 }); 1450 // Don't reset background if swiped upwards 1451 if (shouldScaleBackground && currentSwipeAmount && currentSwipeAmount > 0 && isOpen) { 1452 set(wrapper, { 1453 borderRadius: "".concat(BORDER_RADIUS, "px"), 1454 overflow: 'hidden', 1455 ...isVertical(direction) ? { 1456 transform: "scale(".concat(getScale(), ") translate3d(0, calc(env(safe-area-inset-top) + 14px), 0)"), 1457 transformOrigin: 'top' 1458 } : { 1459 transform: "scale(".concat(getScale(), ") translate3d(calc(env(safe-area-inset-top) + 14px), 0, 0)"), 1460 transformOrigin: 'left' 1461 }, 1462 transitionProperty: 'transform, border-radius', 1463 transitionDuration: "".concat(TRANSITIONS.DURATION, "s"), 1464 transitionTimingFunction: "cubic-bezier(".concat(TRANSITIONS.EASE.join(','), ")") 1465 }, true); 1466 } 1467 } 1468 function cancelDrag() { 1469 if (!isDragging || !drawerRef.current) return; 1470 drawerRef.current.classList.remove(DRAG_CLASS); 1471 isAllowedToDrag.current = false; 1472 setIsDragging(false); 1473 dragEndTime.current = new Date(); 1474 } 1475 function onRelease(event) { 1476 if (!isDragging || !drawerRef.current) return; 1477 drawerRef.current.classList.remove(DRAG_CLASS); 1478 isAllowedToDrag.current = false; 1479 setIsDragging(false); 1480 dragEndTime.current = new Date(); 1481 const swipeAmount = getTranslate(drawerRef.current, direction); 1482 if (!event || !shouldDrag(event.target, false) || !swipeAmount || Number.isNaN(swipeAmount)) return; 1483 if (dragStartTime.current === null) return; 1484 const timeTaken = dragEndTime.current.getTime() - dragStartTime.current.getTime(); 1485 const distMoved = pointerStart.current - (isVertical(direction) ? event.pageY : event.pageX); 1486 const velocity = Math.abs(distMoved) / timeTaken; 1487 if (velocity > 0.05) { 1488 // `justReleased` is needed to prevent the drawer from focusing on an input when the drag ends, as it's not the intent most of the time. 1489 setJustReleased(true); 1490 setTimeout(()=>{ 1491 setJustReleased(false); 1492 }, 200); 1493 } 1494 if (snapPoints) { 1495 const directionMultiplier = direction === 'bottom' || direction === 'right' ? 1 : -1; 1496 onReleaseSnapPoints({ 1497 draggedDistance: distMoved * directionMultiplier, 1498 closeDrawer, 1499 velocity, 1500 dismissible 1501 }); 1502 onReleaseProp == null ? void 0 : onReleaseProp(event, true); 1503 return; 1504 } 1505 // Moved upwards, don't do anything 1506 if (direction === 'bottom' || direction === 'right' ? distMoved > 0 : distMoved < 0) { 1507 resetDrawer(); 1508 onReleaseProp == null ? void 0 : onReleaseProp(event, true); 1509 return; 1510 } 1511 if (velocity > VELOCITY_THRESHOLD) { 1512 closeDrawer(); 1513 onReleaseProp == null ? void 0 : onReleaseProp(event, false); 1514 return; 1515 } 1516 var _drawerRef_current_getBoundingClientRect_height; 1517 const visibleDrawerHeight = Math.min((_drawerRef_current_getBoundingClientRect_height = drawerRef.current.getBoundingClientRect().height) != null ? _drawerRef_current_getBoundingClientRect_height : 0, window.innerHeight); 1518 var _drawerRef_current_getBoundingClientRect_width; 1519 const visibleDrawerWidth = Math.min((_drawerRef_current_getBoundingClientRect_width = drawerRef.current.getBoundingClientRect().width) != null ? _drawerRef_current_getBoundingClientRect_width : 0, window.innerWidth); 1520 const isHorizontalSwipe = direction === 'left' || direction === 'right'; 1521 if (Math.abs(swipeAmount) >= (isHorizontalSwipe ? visibleDrawerWidth : visibleDrawerHeight) * closeThreshold) { 1522 closeDrawer(); 1523 onReleaseProp == null ? void 0 : onReleaseProp(event, false); 1524 return; 1525 } 1526 onReleaseProp == null ? void 0 : onReleaseProp(event, true); 1527 resetDrawer(); 1528 } 1529 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1530 // Trigger enter animation without using CSS animation 1531 if (isOpen) { 1532 set(document.documentElement, { 1533 scrollBehavior: 'auto' 1534 }); 1535 openTime.current = new Date(); 1536 } 1537 return ()=>{ 1538 reset(document.documentElement, 'scrollBehavior'); 1539 }; 1540 }, [ 1541 isOpen 1542 ]); 1543 function onNestedOpenChange(o) {
1544 const scale = o ? (window.innerWidth - NESTED_DISPLACEMENT) / window.innerWidth : 1; 1545 const initialTranslate = o ? -NESTED_DISPLACEMENT : 0; 1546 if (nestedOpenChangeTimer.current) { 1547 window.clearTimeout(nestedOpenChangeTimer.current); 1548 } 1549 set(drawerRef.current, { 1550 transition: "transform ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 1551 transform: isVertical(direction) ? "scale(".concat(scale, ") translate3d(0, ").concat(initialTranslate, "px, 0)") : "scale(".concat(scale, ") translate3d(").concat(initialTranslate, "px, 0, 0)") 1552 }); 1553 if (!o && drawerRef.current) { 1554 nestedOpenChangeTimer.current = setTimeout(()=>{ 1555 const translateValue = getTranslate(drawerRef.current, direction); 1556 set(drawerRef.current, { 1557 transition: 'none', 1558 transform: isVertical(direction) ? "translate3d(0, ".concat(translateValue, "px, 0)") : "translate3d(".concat(translateValue, "px, 0, 0)") 1559 }); 1560 }, 500); 1561 } 1562 } 1563 function onNestedDrag(_event, percentageDragged) { 1564 if (percentageDragged < 0) return; 1565 const initialScale = (window.innerWidth - NESTED_DISPLACEMENT) / window.innerWidth; 1566 const newScale = initialScale + percentageDragged * (1 - initialScale); 1567 const newTranslate = -NESTED_DISPLACEMENT + percentageDragged * NESTED_DISPLACEMENT; 1568 set(drawerRef.current, { 1569 transform: isVertical(direction) ? "scale(".concat(newScale, ") translate3d(0, ").concat(newTranslate, "px, 0)") : "scale(".concat(newScale, ") translate3d(").concat(newTranslate, "px, 0, 0)"), 1570 transition: 'none' 1571 }); 1572 } 1573 function onNestedRelease(_event, o) { 1574 const dim = isVertical(direction) ? window.innerHeight : window.innerWidth; 1575 const scale = o ? (dim - NESTED_DISPLACEMENT) / dim : 1; 1576 const translate = o ? -NESTED_DISPLACEMENT : 0; 1577 if (o) { 1578 set(drawerRef.current, { 1579 transition: "transform ".concat(TRANSITIONS.DURATION, "s cubic-bezier(").concat(TRANSITIONS.EASE.join(','), ")"), 1580 transform: isVertical(direction) ? "scale(".concat(scale, ") translate3d(0, ").concat(translate, "px, 0)") : "scale(".concat(scale, ") translate3d(").concat(translate, "px, 0, 0)") 1581 }); 1582 } 1583 } 1584 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1585 if (!modal) { 1586 // Need to do this manually unfortunately 1587 window.requestAnimationFrame(()=>{ 1588 document.body.style.pointerEvents = 'auto'; 1589 }); 1590 } 1591 }, [ 1592 modal 1593 ]); 1594 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(_radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Root */ .bL, { 1595 defaultOpen: defaultOpen, 1596 onOpenChange: (open)=>{ 1597 if (!dismissible && !open) return; 1598 if (open) { 1599 setHasBeenOpened(true); 1600 } else { 1601 closeDrawer(true); 1602 } 1603 setIsOpen(open); 1604 }, 1605 open: isOpen 1606 }, /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(DrawerContext.Provider, { 1607 value: { 1608 activeSnapPoint, 1609 snapPoints,
1610 setActiveSnapPoint, 1611 drawerRef, 1612 overlayRef, 1613 onOpenChange, 1614 onPress, 1615 onRelease, 1616 onDrag, 1617 dismissible, 1618 shouldAnimate, 1619 handleOnly, 1620 isOpen, 1621 isDragging, 1622 shouldFade, 1623 closeDrawer, 1624 onNestedDrag, 1625 onNestedOpenChange, 1626 onNestedRelease, 1627 keyboardIsOpen, 1628 modal, 1629 snapPointsOffset, 1630 activeSnapPointIndex, 1631 direction, 1632 shouldScaleBackground, 1633 setBackgroundColorOnScale, 1634 noBodyStyles, 1635 container, 1636 autoFocus 1637 } 1638 }, children)); 1639} 1640const Overlay = /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function(param, ref) { 1641 let { ...rest } = param; 1642 const { overlayRef, snapPoints, onRelease, shouldFade, isOpen, modal, shouldAnimate } = useDrawerContext(); 1643 const composedRef = useComposedRefs(ref, overlayRef); 1644 const hasSnapPoints = snapPoints && snapPoints.length > 0; 1645 // Overlay is the component that is locking scroll, removing it will unlock the scroll without having to dig into Radix's Dialog library 1646 if (!modal) { 1647 return null; 1648 } 1649 const onMouseUp = react__WEBPACK_IMPORTED_MODULE_0__.useCallback((event)=>onRelease(event), [ 1650 onRelease 1651 ]); 1652 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(_radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Overlay */ .hJ, { 1653 onMouseUp: onMouseUp, 1654 ref: composedRef, 1655 "data-vaul-overlay": "", 1656 "data-vaul-snap-points": isOpen && hasSnapPoints ? 'true' : 'false', 1657 "data-vaul-snap-points-overlay": isOpen && shouldFade ? 'true' : 'false', 1658 "data-vaul-animate": (shouldAnimate == null ? void 0 : shouldAnimate.current) ? 'true' : 'false', 1659 ...rest 1660 }); 1661}); 1662Overlay.displayName = 'Drawer.Overlay'; 1663const Content = /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function(param, ref) { 1664 let { onPointerDownOutside, style, onOpenAutoFocus, ...rest } = param; 1665 const { drawerRef, onPress, onRelease, onDrag, keyboardIsOpen, snapPointsOffset, activeSnapPointIndex, modal, isOpen, direction, snapPoints, container, handleOnly, shouldAnimate, autoFocus } = useDrawerContext(); 1666 // Needed to use transition instead of animations 1667 const [delayedSnapPoints, setDelayedSnapPoints] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false); 1668 const composedRef = useComposedRefs(ref, drawerRef); 1669 const pointerStartRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1670 const lastKnownPointerEventRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1671 const wasBeyondThePointRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false); 1672 const hasSnapPoints = snapPoints && snapPoints.length > 0; 1673 useScaleBackground(); 1674 const isDeltaInDirection = function(delta, direction) { 1675 let threshold = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 0; 1676 if (wasBeyondThePointRef.current) return true; 1677 const deltaY = Math.abs(delta.y); 1678 const deltaX = Math.abs(delta.x); 1679 const isDeltaX = deltaX > deltaY; 1680 const dFactor = [ 1681 'bottom', 1682 'right' 1683 ].includes(direction) ? 1 : -1; 1684 if (direction === 'left' || direction === 'right') { 1685 const isReverseDirection = delta.x * dFactor < 0; 1686 if (!isReverseDirection && deltaX >= 0 && deltaX <= threshold) { 1687 return isDeltaX; 1688 } 1689 } else { 1690 const isReverseDirection = delta.y * dFactor < 0; 1691 if (!isReverseDirection && deltaY >= 0 && deltaY <= threshold) { 1692 return !isDeltaX; 1693 } 1694 } 1695 wasBeyondThePointRef.current = true; 1696 return true; 1697 }; 1698 react__WEBPACK_IMPORTED_MODULE_0__.useEffect(()=>{ 1699 if (hasSnapPoints) { 1700 window.requestAnimationFrame(()=>{ 1701 setDelayedSnapPoints(true); 1702 }); 1703 } 1704 }, []); 1705 function handleOnPointerUp(event) { 1706 pointerStartRef.current = null; 1707 wasBeyondThePointRef.current = false;
1708 onRelease(event); 1709 } 1710 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(_radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Content */ .UC, { 1711 "data-vaul-drawer-direction": direction, 1712 "data-vaul-drawer": "", 1713 "data-vaul-delayed-snap-points": delayedSnapPoints ? 'true' : 'false', 1714 "data-vaul-snap-points": isOpen && hasSnapPoints ? 'true' : 'false', 1715 "data-vaul-custom-container": container ? 'true' : 'false', 1716 "data-vaul-animate": (shouldAnimate == null ? void 0 : shouldAnimate.current) ? 'true' : 'false', 1717 ...rest, 1718 ref: composedRef, 1719 style: snapPointsOffset && snapPointsOffset.length > 0 ? { 1720 '--snap-point-height': "".concat(snapPointsOffset[activeSnapPointIndex != null ? activeSnapPointIndex : 0], "px"), 1721 ...style 1722 } : style, 1723 onPointerDown: (event)=>{ 1724 if (handleOnly) return; 1725 rest.onPointerDown == null ? void 0 : rest.onPointerDown.call(rest, event); 1726 pointerStartRef.current = { 1727 x: event.pageX, 1728 y: event.pageY 1729 }; 1730 onPress(event); 1731 }, 1732 onOpenAutoFocus: (e)=>{ 1733 onOpenAutoFocus == null ? void 0 : onOpenAutoFocus(e); 1734 if (!autoFocus) { 1735 e.preventDefault(); 1736 } 1737 }, 1738 onPointerDownOutside: (e)=>{ 1739 onPointerDownOutside == null ? void 0 : onPointerDownOutside(e); 1740 if (!modal || e.defaultPrevented) { 1741 e.preventDefault(); 1742 return; 1743 } 1744 if (keyboardIsOpen.current) { 1745 keyboardIsOpen.current = false; 1746 } 1747 }, 1748 onFocusOutside: (e)=>{ 1749 if (!modal) { 1750 e.preventDefault(); 1751 return; 1752 } 1753 }, 1754 onPointerMove: (event)=>{ 1755 lastKnownPointerEventRef.current = event; 1756 if (handleOnly) return; 1757 rest.onPointerMove == null ? void 0 : rest.onPointerMove.call(rest, event); 1758 if (!pointerStartRef.current) return; 1759 const yPosition = event.pageY - pointerStartRef.current.y; 1760 const xPosition = event.pageX - pointerStartRef.current.x; 1761 const swipeStartThreshold = event.pointerType === 'touch' ? 10 : 2; 1762 const delta = { 1763 x: xPosition, 1764 y: yPosition 1765 }; 1766 const isAllowedToSwipe = isDeltaInDirection(delta, direction, swipeStartThreshold); 1767 if (isAllowedToSwipe) onDrag(event); 1768 else if (Math.abs(xPosition) > swipeStartThreshold || Math.abs(yPosition) > swipeStartThreshold) { 1769 pointerStartRef.current = null; 1770 } 1771 }, 1772 onPointerUp: (event)=>{ 1773 rest.onPointerUp == null ? void 0 : rest.onPointerUp.call(rest, event); 1774 pointerStartRef.current = null; 1775 wasBeyondThePointRef.current = false; 1776 onRelease(event); 1777 }, 1778 onPointerOut: (event)=>{ 1779 rest.onPointerOut == null ? void 0 : rest.onPointerOut.call(rest, event); 1780 handleOnPointerUp(lastKnownPointerEventRef.current); 1781 }, 1782 onContextMenu: (event)=>{ 1783 rest.onContextMenu == null ? void 0 : rest.onContextMenu.call(rest, event); 1784 if (lastKnownPointerEventRef.current) { 1785 handleOnPointerUp(lastKnownPointerEventRef.current); 1786 } 1787 } 1788 }); 1789}); 1790Content.displayName = 'Drawer.Content'; 1791const LONG_HANDLE_PRESS_TIMEOUT = 250; 1792const DOUBLE_TAP_TIMEOUT = 120; 1793const Handle = /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(function(param, ref) { 1794 let { preventCycle = false, children, ...rest } = param; 1795 const { closeDrawer, isDragging, snapPoints, activeSnapPoint, setActiveSnapPoint, dismissible, handleOnly, isOpen, onPress, onDrag } = useDrawerContext(); 1796 const closeTimeoutIdRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null); 1797 const shouldCancelInteractionRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(false); 1798 function handleStartCycle() { 1799 // Stop if this is the second click of a double click 1800 if (shouldCancelInteractionRef.current) { 1801 handleCancelInteraction(); 1802 return; 1803 } 1804 window.setTimeout(()=>{ 1805 handleCycleSnapPoints(); 1806 }, DOUBLE_TAP_TIMEOUT); 1807 } 1808 function handleCycleSnapPoints() { 1809 // Prevent accidental taps while resizing drawer 1810 if (isDragging || preventCycle || shouldCancelInteractionRef.current) { 1811 handleCancelInteraction(); 1812 return; 1813 } 1814 // Make sure to clear the timeout id if the user releases the handle before the cancel timeout 1815 handleCancelInteraction(); 1816 if (!snapPoints || snapPoints.length === 0) { 1817 if (!dismissible) { 1818 closeDrawer(); 1819 } 1820 return; 1821 } 1822 const isLastSnapPoint = activeSnapPoint === snapPoints[snapPoints.length - 1]; 1823 if (isLastSnapPoint && dismissible) { 1824 closeDrawer(); 1825 return; 1826 } 1827 const currentSnapIndex = snapPoints.findIndex((point)=>point === activeSnapPoint); 1828 if (currentSnapIndex === -1) return; // activeSnapPoint not found in snapPoints 1829 const nextSnapPoint = snapPoints[currentSnapIndex + 1];
1830 setActiveSnapPoint(nextSnapPoint); 1831 } 1832 function handleStartInteraction() { 1833 closeTimeoutIdRef.current = window.setTimeout(()=>{ 1834 // Cancel click interaction on a long press 1835 shouldCancelInteractionRef.current = true; 1836 }, LONG_HANDLE_PRESS_TIMEOUT); 1837 } 1838 function handleCancelInteraction() { 1839 if (closeTimeoutIdRef.current) { 1840 window.clearTimeout(closeTimeoutIdRef.current); 1841 } 1842 shouldCancelInteractionRef.current = false; 1843 } 1844 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement("div", { 1845 onClick: handleStartCycle, 1846 onPointerCancel: handleCancelInteraction, 1847 onPointerDown: (e)=>{ 1848 if (handleOnly) onPress(e); 1849 handleStartInteraction(); 1850 }, 1851 onPointerMove: (e)=>{ 1852 if (handleOnly) onDrag(e); 1853 }, 1854 // onPointerUp is already handled by the content component 1855 ref: ref, 1856 "data-vaul-drawer-visible": isOpen ? 'true' : 'false', 1857 "data-vaul-handle": "", 1858 "aria-hidden": "true", 1859 ...rest 1860 }, /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement("span", { 1861 "data-vaul-handle-hitarea": "", 1862 "aria-hidden": "true" 1863 }, children)); 1864}); 1865Handle.displayName = 'Drawer.Handle'; 1866function NestedRoot(param) { 1867 let { onDrag, onOpenChange, open: nestedIsOpen, ...rest } = param; 1868 const { onNestedDrag, onNestedOpenChange, onNestedRelease } = useDrawerContext(); 1869 if (!onNestedDrag) { 1870 throw new Error('Drawer.NestedRoot must be placed in another drawer'); 1871 } 1872 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(Root, { 1873 nested: true, 1874 open: nestedIsOpen, 1875 onClose: ()=>{ 1876 onNestedOpenChange(false); 1877 }, 1878 onDrag: (e, p)=>{ 1879 onNestedDrag(e, p); 1880 onDrag == null ? void 0 : onDrag(e, p); 1881 }, 1882 onOpenChange: (o)=>{ 1883 if (o) { 1884 onNestedOpenChange(o); 1885 } 1886 onOpenChange == null ? void 0 : onOpenChange(o); 1887 }, 1888 onRelease: onNestedRelease, 1889 ...rest 1890 }); 1891} 1892function Portal(props) { 1893 const context = useDrawerContext(); 1894 const { container = context.container, ...portalProps } = props; 1895 return /*#__PURE__*/ react__WEBPACK_IMPORTED_MODULE_0__.createElement(_radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Portal */ .ZL, {
1896 container: container, 1897 ...portalProps 1898 }); 1899} 1900const Drawer = { 1901 Root, 1902 NestedRoot, 1903 Content, 1904 Overlay, 1905 Trigger: _radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Trigger */ .l9, 1906 Portal, 1907 Handle, 1908 Close: _radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Close */ .bm, 1909 Title: _radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Title */ .hE, 1910 Description: _radix_ui_react_dialog__WEBPACK_IMPORTED_MODULE_1__/* .Description */ .VY 1911}; 1912 1913 1914 1915/***/ }) 1916 1917}]); 1918//# sourceMappingURL=vendors-_app-pages-browser_node_modules_pnpm_lucide-react_0_479_0_react_19_0_0_node_modules_l-41fdb8-772eec4655541bb7.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.