@surdeddd/bottom-sheet 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -1
- package/dist/{BottomSheetEngine-D6oiEfZ4.d.cts → BottomSheetCore-CsIjyq7C.d.cts} +60 -5
- package/dist/{BottomSheetEngine-Dhy0X_e9.d.ts → BottomSheetCore-D16lsa6g.d.ts} +60 -5
- package/dist/BottomSheetEngine-BYjAVrmd.d.cts +7 -0
- package/dist/BottomSheetEngine-YuCNugZn.d.ts +7 -0
- package/dist/core.cjs +3476 -0
- package/dist/core.d.cts +3 -0
- package/dist/core.d.ts +3 -0
- package/dist/core.js +3474 -0
- package/dist/debug.cjs +109 -0
- package/dist/debug.d.cts +22 -0
- package/dist/debug.d.ts +22 -0
- package/dist/debug.js +107 -0
- package/dist/element.cjs +972 -685
- package/dist/element.d.cts +2 -1
- package/dist/element.d.ts +2 -1
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +972 -685
- package/dist/features.cjs +533 -0
- package/dist/features.d.cts +13 -0
- package/dist/features.d.ts +13 -0
- package/dist/features.js +526 -0
- package/dist/index-DdYLOIIT.d.ts +15 -0
- package/dist/index-dfrzw-lI.d.cts +15 -0
- package/dist/index.cjs +805 -534
- package/dist/index.d.cts +6 -15
- package/dist/index.d.ts +6 -15
- package/dist/index.js +799 -535
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +6 -5
- package/dist/overlay.js +6 -5
- package/dist/preact.d.cts +2 -1
- package/dist/preact.d.ts +2 -1
- package/dist/qwik-lib/index.qwik.cjs +4267 -0
- package/dist/qwik-lib/index.qwik.mjs +4267 -0
- package/dist/qwik.cjs +798 -534
- package/dist/qwik.d.cts +2 -2
- package/dist/qwik.d.ts +2 -2
- package/dist/qwik.js +798 -534
- package/dist/react.cjs +798 -534
- package/dist/react.d.cts +3 -2
- package/dist/react.d.ts +3 -2
- package/dist/react.js +798 -534
- package/dist/solid.cjs +798 -534
- package/dist/solid.d.cts +63 -4
- package/dist/solid.d.ts +63 -4
- package/dist/solid.js +798 -534
- package/dist/solid.source.jsx +798 -534
- package/dist/svelte-core.cjs +798 -534
- package/dist/svelte-core.js +798 -534
- package/dist/svelte.cjs +798 -534
- package/dist/svelte.js +798 -534
- package/dist/vue.cjs +909 -637
- package/dist/vue.js +909 -637
- package/package.json +63 -11
package/dist/index.cjs
CHANGED
|
@@ -354,74 +354,6 @@ var SnapResolver = class {
|
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
356
|
|
|
357
|
-
// src/core/features/persist.ts
|
|
358
|
-
function readPersistedId(key) {
|
|
359
|
-
if (!key) return null;
|
|
360
|
-
if (typeof window === "undefined") return null;
|
|
361
|
-
if (typeof localStorage === "undefined") return null;
|
|
362
|
-
try {
|
|
363
|
-
return localStorage.getItem(key);
|
|
364
|
-
} catch {
|
|
365
|
-
return null;
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
function installPersist(engine, key) {
|
|
369
|
-
const unsubscribe = engine.on("snap", ({ id }) => {
|
|
370
|
-
if (typeof window === "undefined") return;
|
|
371
|
-
if (typeof localStorage === "undefined") return;
|
|
372
|
-
try {
|
|
373
|
-
localStorage.setItem(key, id);
|
|
374
|
-
} catch {
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
return unsubscribe;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
// src/core/features/auto-collapse.ts
|
|
381
|
-
function installAutoCollapse(deps) {
|
|
382
|
-
const { ms } = deps;
|
|
383
|
-
if (ms === void 0 || ms <= 0) {
|
|
384
|
-
return () => {
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
let timer = null;
|
|
388
|
-
const clearTimer = () => {
|
|
389
|
-
if (timer !== null) {
|
|
390
|
-
clearTimeout(timer);
|
|
391
|
-
timer = null;
|
|
392
|
-
}
|
|
393
|
-
};
|
|
394
|
-
const fire = () => {
|
|
395
|
-
if (deps.isDestroyed()) return;
|
|
396
|
-
if (deps.isDragging()) return;
|
|
397
|
-
const active = deps.resolveSnap(deps.getActiveId());
|
|
398
|
-
if (!active || active.size === 0) return;
|
|
399
|
-
let target = null;
|
|
400
|
-
for (const id of deps.getAllowedIds()) {
|
|
401
|
-
const snap = deps.resolveSnap(id);
|
|
402
|
-
if (!snap || snap.size <= 0) continue;
|
|
403
|
-
if (!target || snap.size < target.size) target = snap;
|
|
404
|
-
}
|
|
405
|
-
if (!target) return;
|
|
406
|
-
if (target.id === active.id || target.size >= active.size) return;
|
|
407
|
-
deps.snapTo(target.id);
|
|
408
|
-
};
|
|
409
|
-
const reset = () => {
|
|
410
|
-
clearTimer();
|
|
411
|
-
if (deps.isDestroyed()) return;
|
|
412
|
-
timer = setTimeout(() => {
|
|
413
|
-
timer = null;
|
|
414
|
-
fire();
|
|
415
|
-
}, ms);
|
|
416
|
-
};
|
|
417
|
-
const unsubscribe = deps.on("snap", () => reset());
|
|
418
|
-
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset();
|
|
419
|
-
return () => {
|
|
420
|
-
clearTimer();
|
|
421
|
-
unsubscribe();
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
|
|
425
357
|
// src/core/features/linked-sheets.ts
|
|
426
358
|
function notifyLinkedSheets(sheets, self) {
|
|
427
359
|
if (sheets.length === 0) return;
|
|
@@ -444,394 +376,65 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
444
376
|
}
|
|
445
377
|
}
|
|
446
378
|
|
|
447
|
-
// src/core/features/
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
var pendingRebrand = null;
|
|
453
|
-
var listenerInstalled = false;
|
|
454
|
-
var patchInstalled = false;
|
|
455
|
-
var origPushState = null;
|
|
456
|
-
var origReplaceState = null;
|
|
457
|
-
var patchedPushState = null;
|
|
458
|
-
var patchedReplaceState = null;
|
|
459
|
-
var hasWindow = () => typeof window !== "undefined";
|
|
460
|
-
var hasHistory = () => typeof history !== "undefined";
|
|
461
|
-
var brandMarker = (surface) => ({
|
|
462
|
-
...surface.markerState(),
|
|
463
|
-
__bs: true
|
|
464
|
-
});
|
|
465
|
-
var runInternal = (fn) => {
|
|
466
|
-
internalDepth += 1;
|
|
467
|
-
try {
|
|
468
|
-
fn();
|
|
469
|
-
} finally {
|
|
470
|
-
internalDepth -= 1;
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
var notifyRouteChange = () => {
|
|
474
|
-
const snapshot = Array.from(subscribers);
|
|
475
|
-
for (const fn of snapshot) fn();
|
|
476
|
-
};
|
|
477
|
-
var ensureListener = () => {
|
|
478
|
-
if (listenerInstalled || !hasWindow()) return;
|
|
479
|
-
window.addEventListener("popstate", onPopState);
|
|
480
|
-
listenerInstalled = true;
|
|
481
|
-
};
|
|
482
|
-
var maybeTeardownListener = () => {
|
|
483
|
-
if (!listenerInstalled) return;
|
|
484
|
-
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
485
|
-
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
486
|
-
listenerInstalled = false;
|
|
487
|
-
};
|
|
488
|
-
var installPatch = () => {
|
|
489
|
-
if (patchInstalled || !hasHistory()) return;
|
|
490
|
-
origPushState = history.pushState;
|
|
491
|
-
origReplaceState = history.replaceState;
|
|
492
|
-
patchedPushState = function(...args) {
|
|
493
|
-
origPushState.apply(this, args);
|
|
494
|
-
if (internalDepth === 0) notifyRouteChange();
|
|
495
|
-
};
|
|
496
|
-
patchedReplaceState = function(...args) {
|
|
497
|
-
origReplaceState.apply(this, args);
|
|
498
|
-
if (internalDepth === 0) notifyRouteChange();
|
|
499
|
-
};
|
|
500
|
-
history.pushState = patchedPushState;
|
|
501
|
-
history.replaceState = patchedReplaceState;
|
|
502
|
-
patchInstalled = true;
|
|
503
|
-
};
|
|
504
|
-
var removePatch = () => {
|
|
505
|
-
if (!patchInstalled) return;
|
|
506
|
-
if (history.pushState === patchedPushState && origPushState) {
|
|
507
|
-
history.pushState = origPushState;
|
|
508
|
-
}
|
|
509
|
-
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
510
|
-
history.replaceState = origReplaceState;
|
|
511
|
-
}
|
|
512
|
-
origPushState = null;
|
|
513
|
-
origReplaceState = null;
|
|
514
|
-
patchedPushState = null;
|
|
515
|
-
patchedReplaceState = null;
|
|
516
|
-
patchInstalled = false;
|
|
517
|
-
};
|
|
518
|
-
function onPopState() {
|
|
519
|
-
if (suppress > 0) {
|
|
520
|
-
suppress -= 1;
|
|
521
|
-
const rebrand = pendingRebrand;
|
|
522
|
-
pendingRebrand = null;
|
|
523
|
-
if (rebrand) rebrand();
|
|
524
|
-
maybeTeardownListener();
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (entries.length === 0) {
|
|
528
|
-
notifyRouteChange();
|
|
529
|
-
maybeTeardownListener();
|
|
530
|
-
return;
|
|
379
|
+
// src/core/features/resize-observer.ts
|
|
380
|
+
function installResizeObserver(deps) {
|
|
381
|
+
if (typeof window === "undefined") {
|
|
382
|
+
return () => {
|
|
383
|
+
};
|
|
531
384
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
385
|
+
const onResize = () => {
|
|
386
|
+
if (deps.isDestroyed()) return;
|
|
387
|
+
deps.recomputeSnaps();
|
|
388
|
+
const mode = deps.getMode();
|
|
389
|
+
const isVerticalAxis = mode === "bottom" || mode === "top";
|
|
390
|
+
const viewportSize2 = isVerticalAxis ? window.innerHeight : window.innerWidth;
|
|
391
|
+
const max = deps.getMaxAxisSize();
|
|
392
|
+
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
393
|
+
deps.setMaxAxisSize(viewportSize2);
|
|
540
394
|
}
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
395
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
396
|
+
deps.cancelInFlight();
|
|
397
|
+
deps.newCycle();
|
|
398
|
+
const current = deps.resolveActiveSnap();
|
|
399
|
+
const newMax = deps.getMaxAxisSize();
|
|
400
|
+
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
401
|
+
deps.setSize(targetSize);
|
|
402
|
+
if (current && !deps.isDragging()) {
|
|
403
|
+
deps.applySize(targetSize);
|
|
404
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
545
405
|
}
|
|
406
|
+
};
|
|
407
|
+
let resizeObserver = null;
|
|
408
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
409
|
+
resizeObserver = new ResizeObserver(onResize);
|
|
410
|
+
resizeObserver.observe(document.documentElement);
|
|
411
|
+
} else {
|
|
412
|
+
window.addEventListener("resize", onResize);
|
|
546
413
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
if (
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
}
|
|
559
|
-
maybeTeardownListener();
|
|
414
|
+
window.addEventListener("orientationchange", onResize);
|
|
415
|
+
const onVisibility = () => {
|
|
416
|
+
if (deps.isDestroyed()) return;
|
|
417
|
+
if (document.hidden) deps.cancelInFlight();
|
|
418
|
+
};
|
|
419
|
+
document.addEventListener("visibilitychange", onVisibility);
|
|
420
|
+
return () => {
|
|
421
|
+
resizeObserver?.disconnect();
|
|
422
|
+
window.removeEventListener("resize", onResize);
|
|
423
|
+
window.removeEventListener("orientationchange", onResize);
|
|
424
|
+
document.removeEventListener("visibilitychange", onVisibility);
|
|
425
|
+
};
|
|
560
426
|
}
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
entries.push(entry);
|
|
573
|
-
ensureListener();
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
function pushBackMarker(surface) {
|
|
577
|
-
const entry = { surface, priorUrl: void 0, live: false };
|
|
578
|
-
if (!hasWindow() || !hasHistory()) {
|
|
579
|
-
return entry;
|
|
580
|
-
}
|
|
581
|
-
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
582
|
-
runInternal(() => {
|
|
583
|
-
try {
|
|
584
|
-
history.pushState(brandMarker(surface), "", surface.url);
|
|
585
|
-
entry.live = true;
|
|
586
|
-
} catch {
|
|
587
|
-
entry.live = false;
|
|
588
|
-
}
|
|
589
|
-
});
|
|
590
|
-
if (entry.live) {
|
|
591
|
-
entries.push(entry);
|
|
592
|
-
ensureListener();
|
|
593
|
-
}
|
|
594
|
-
return entry;
|
|
595
|
-
}
|
|
596
|
-
function popBackMarker(handle) {
|
|
597
|
-
if (!hasWindow() || !hasHistory()) return;
|
|
598
|
-
const entry = handle;
|
|
599
|
-
const idx = entries.indexOf(entry);
|
|
600
|
-
if (idx === -1 || !entry.live) return;
|
|
601
|
-
const last = entries.length - 1;
|
|
602
|
-
entry.live = false;
|
|
603
|
-
entries.splice(idx, 1);
|
|
604
|
-
if (idx !== last) {
|
|
605
|
-
const rebrandSurface = entries[entries.length - 1].surface;
|
|
606
|
-
const rebrandUrl = entry.priorUrl;
|
|
607
|
-
pendingRebrand = () => {
|
|
608
|
-
runInternal(() => {
|
|
609
|
-
history.replaceState(
|
|
610
|
-
brandMarker(rebrandSurface),
|
|
611
|
-
"",
|
|
612
|
-
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
613
|
-
);
|
|
614
|
-
});
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
suppress += 1;
|
|
618
|
-
runInternal(() => {
|
|
619
|
-
try {
|
|
620
|
-
history.back();
|
|
621
|
-
} catch {
|
|
622
|
-
suppress = Math.max(0, suppress - 1);
|
|
623
|
-
pendingRebrand = null;
|
|
624
|
-
}
|
|
625
|
-
});
|
|
626
|
-
maybeTeardownListener();
|
|
627
|
-
}
|
|
628
|
-
function subscribeRouteChange(fn) {
|
|
629
|
-
if (!hasWindow() || !hasHistory()) return () => {
|
|
630
|
-
};
|
|
631
|
-
subscribers.add(fn);
|
|
632
|
-
if (subscribers.size === 1) installPatch();
|
|
633
|
-
ensureListener();
|
|
634
|
-
return () => {
|
|
635
|
-
if (!subscribers.has(fn)) return;
|
|
636
|
-
subscribers.delete(fn);
|
|
637
|
-
if (subscribers.size === 0) removePatch();
|
|
638
|
-
maybeTeardownListener();
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// src/core/features/route.ts
|
|
643
|
-
function installRoute(deps) {
|
|
644
|
-
if (typeof window === "undefined") {
|
|
645
|
-
return () => {
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
if (!deps.routedTo && !deps.closeOnBack) {
|
|
649
|
-
return () => {
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
let handle = null;
|
|
653
|
-
const onOpen = () => {
|
|
654
|
-
if (handle) return;
|
|
655
|
-
handle = pushBackMarker({
|
|
656
|
-
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
657
|
-
isTop: deps.isTopSheet,
|
|
658
|
-
close: deps.close,
|
|
659
|
-
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
660
|
-
url: deps.routedTo
|
|
661
|
-
});
|
|
662
|
-
};
|
|
663
|
-
const onClose = () => {
|
|
664
|
-
if (!handle) return;
|
|
665
|
-
popBackMarker(handle);
|
|
666
|
-
handle = null;
|
|
667
|
-
};
|
|
668
|
-
const unsubscribeOpen = deps.on("open", onOpen);
|
|
669
|
-
const unsubscribeClose = deps.on("close", onClose);
|
|
670
|
-
if (deps.getSize() > 0) onOpen();
|
|
671
|
-
return () => {
|
|
672
|
-
unsubscribeOpen();
|
|
673
|
-
unsubscribeClose();
|
|
674
|
-
if (handle) {
|
|
675
|
-
popBackMarker(handle);
|
|
676
|
-
handle = null;
|
|
677
|
-
}
|
|
678
|
-
};
|
|
679
|
-
}
|
|
680
|
-
function installRouteChange(deps) {
|
|
681
|
-
return subscribeRouteChange(() => {
|
|
682
|
-
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
683
|
-
void deps.close();
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
// src/core/features/content-swipe.ts
|
|
688
|
-
var CONTENT_PULL_THRESHOLD = 60;
|
|
689
|
-
function installContentSwipe(deps) {
|
|
690
|
-
const { container } = deps;
|
|
691
|
-
let startY = 0;
|
|
692
|
-
let startScrollTop = 0;
|
|
693
|
-
let moved = false;
|
|
694
|
-
const onTouchStart = (e) => {
|
|
695
|
-
const t = e.touches[0];
|
|
696
|
-
if (!t) return;
|
|
697
|
-
startY = t.clientY;
|
|
698
|
-
startScrollTop = container.scrollTop;
|
|
699
|
-
moved = false;
|
|
700
|
-
};
|
|
701
|
-
const onTouchMove = (e) => {
|
|
702
|
-
const t = e.touches[0];
|
|
703
|
-
if (!t) return;
|
|
704
|
-
if (Math.abs(t.clientY - startY) > CONTENT_PULL_THRESHOLD) moved = true;
|
|
705
|
-
};
|
|
706
|
-
const onTouchEnd = (e) => {
|
|
707
|
-
if (!moved) return;
|
|
708
|
-
if (deps.isDragging() || deps.isAnimating()) return;
|
|
709
|
-
if (container.scrollTop !== startScrollTop) return;
|
|
710
|
-
const t = e.changedTouches[0];
|
|
711
|
-
if (!t) return;
|
|
712
|
-
const deltaY = t.clientY - startY;
|
|
713
|
-
const atTop = container.scrollTop <= 0;
|
|
714
|
-
const allowed = deps.getAllowedIds();
|
|
715
|
-
const idx = allowed.indexOf(deps.getActiveId());
|
|
716
|
-
if (idx === -1) return;
|
|
717
|
-
if (atTop && deltaY > CONTENT_PULL_THRESHOLD && idx > 0) {
|
|
718
|
-
deps.snapTo(allowed[idx - 1]);
|
|
719
|
-
} else if (deltaY < -CONTENT_PULL_THRESHOLD && idx < allowed.length - 1) {
|
|
720
|
-
deps.snapTo(allowed[idx + 1]);
|
|
721
|
-
}
|
|
722
|
-
};
|
|
723
|
-
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
724
|
-
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
725
|
-
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
726
|
-
return () => {
|
|
727
|
-
container.removeEventListener("touchstart", onTouchStart);
|
|
728
|
-
container.removeEventListener("touchmove", onTouchMove);
|
|
729
|
-
container.removeEventListener("touchend", onTouchEnd);
|
|
730
|
-
};
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
// src/core/features/visual-viewport.ts
|
|
734
|
-
var SAFETY_PAD = 8;
|
|
735
|
-
function installVisualViewport(deps) {
|
|
736
|
-
if (typeof window === "undefined" || !window.visualViewport) {
|
|
737
|
-
return () => {
|
|
738
|
-
};
|
|
739
|
-
}
|
|
740
|
-
const vv = window.visualViewport;
|
|
741
|
-
let rafId = null;
|
|
742
|
-
const onResize = () => {
|
|
743
|
-
if (rafId !== null) return;
|
|
744
|
-
rafId = requestAnimationFrame(() => {
|
|
745
|
-
rafId = null;
|
|
746
|
-
if (deps.isDestroyed()) return;
|
|
747
|
-
deps.recomputeSnaps();
|
|
748
|
-
const isVertical = deps.isVerticalAxis();
|
|
749
|
-
const visible = isVertical ? vv.height : vv.width;
|
|
750
|
-
const windowSize = isVertical ? window.innerHeight : window.innerWidth;
|
|
751
|
-
const clamp = Math.max(0, Math.min(windowSize, visible) - SAFETY_PAD);
|
|
752
|
-
if (clamp < deps.getMaxAxisSize()) {
|
|
753
|
-
deps.setMaxAxisSize(clamp);
|
|
754
|
-
}
|
|
755
|
-
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
756
|
-
deps.cancelInFlight();
|
|
757
|
-
deps.newCycle();
|
|
758
|
-
const max = deps.getMaxAxisSize();
|
|
759
|
-
deps.setSize(Math.min(deps.getSize(), max));
|
|
760
|
-
const current = deps.resolveActiveSnap();
|
|
761
|
-
if (current && !deps.isDragging()) {
|
|
762
|
-
deps.applySize(Math.min(current.size, max));
|
|
763
|
-
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
764
|
-
} else {
|
|
765
|
-
deps.applySize(deps.getSize());
|
|
766
|
-
}
|
|
767
|
-
});
|
|
768
|
-
};
|
|
769
|
-
vv.addEventListener("resize", onResize);
|
|
770
|
-
return () => {
|
|
771
|
-
vv.removeEventListener("resize", onResize);
|
|
772
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
773
|
-
};
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
// src/core/features/resize-observer.ts
|
|
777
|
-
function installResizeObserver(deps) {
|
|
778
|
-
if (typeof window === "undefined") {
|
|
779
|
-
return () => {
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
const onResize = () => {
|
|
783
|
-
if (deps.isDestroyed()) return;
|
|
784
|
-
deps.recomputeSnaps();
|
|
785
|
-
const mode = deps.getMode();
|
|
786
|
-
const isVerticalAxis = mode === "bottom" || mode === "top";
|
|
787
|
-
const viewportSize2 = isVerticalAxis ? window.innerHeight : window.innerWidth;
|
|
788
|
-
const max = deps.getMaxAxisSize();
|
|
789
|
-
if (viewportSize2 > 0 && viewportSize2 < max) {
|
|
790
|
-
deps.setMaxAxisSize(viewportSize2);
|
|
791
|
-
}
|
|
792
|
-
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
793
|
-
deps.cancelInFlight();
|
|
794
|
-
deps.newCycle();
|
|
795
|
-
const current = deps.resolveActiveSnap();
|
|
796
|
-
const newMax = deps.getMaxAxisSize();
|
|
797
|
-
const targetSize = current ? Math.min(current.size, newMax) : Math.min(deps.getSize(), newMax);
|
|
798
|
-
deps.setSize(targetSize);
|
|
799
|
-
if (current && !deps.isDragging()) {
|
|
800
|
-
deps.applySize(targetSize);
|
|
801
|
-
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
802
|
-
}
|
|
803
|
-
};
|
|
804
|
-
let resizeObserver = null;
|
|
805
|
-
if (typeof ResizeObserver !== "undefined") {
|
|
806
|
-
resizeObserver = new ResizeObserver(onResize);
|
|
807
|
-
resizeObserver.observe(document.documentElement);
|
|
808
|
-
} else {
|
|
809
|
-
window.addEventListener("resize", onResize);
|
|
810
|
-
}
|
|
811
|
-
window.addEventListener("orientationchange", onResize);
|
|
812
|
-
const onVisibility = () => {
|
|
813
|
-
if (deps.isDestroyed()) return;
|
|
814
|
-
if (document.hidden) deps.cancelInFlight();
|
|
815
|
-
};
|
|
816
|
-
document.addEventListener("visibilitychange", onVisibility);
|
|
817
|
-
return () => {
|
|
818
|
-
resizeObserver?.disconnect();
|
|
819
|
-
window.removeEventListener("resize", onResize);
|
|
820
|
-
window.removeEventListener("orientationchange", onResize);
|
|
821
|
-
document.removeEventListener("visibilitychange", onVisibility);
|
|
822
|
-
};
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// src/core/features/fit-observer.ts
|
|
826
|
-
var contentTargets = (scroller) => {
|
|
827
|
-
if (!scroller) return [];
|
|
828
|
-
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
829
|
-
const out = [];
|
|
830
|
-
for (const child of Array.from(scroller.children)) {
|
|
831
|
-
if (hasSlot && child instanceof HTMLSlotElement) {
|
|
832
|
-
for (const el of child.assignedElements()) out.push(el);
|
|
833
|
-
} else {
|
|
834
|
-
out.push(child);
|
|
427
|
+
|
|
428
|
+
// src/core/features/fit-observer.ts
|
|
429
|
+
var contentTargets = (scroller) => {
|
|
430
|
+
if (!scroller) return [];
|
|
431
|
+
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
432
|
+
const out = [];
|
|
433
|
+
for (const child of Array.from(scroller.children)) {
|
|
434
|
+
if (hasSlot && child instanceof HTMLSlotElement) {
|
|
435
|
+
for (const el of child.assignedElements()) out.push(el);
|
|
436
|
+
} else {
|
|
437
|
+
out.push(child);
|
|
835
438
|
}
|
|
836
439
|
}
|
|
837
440
|
return out;
|
|
@@ -1673,6 +1276,52 @@ function resolveAnimationPreset(animation) {
|
|
|
1673
1276
|
}
|
|
1674
1277
|
}
|
|
1675
1278
|
|
|
1279
|
+
// src/core/animation/waapi-settle.ts
|
|
1280
|
+
var SIM_HZ = 240;
|
|
1281
|
+
var SAMPLE_STRIDE = 4;
|
|
1282
|
+
var MAX_SIM_MS = 3e3;
|
|
1283
|
+
function sampleSpringSettle(from, to, velocityPxPerS, config) {
|
|
1284
|
+
const cfg = { ...DEFAULT_SPRING, ...config };
|
|
1285
|
+
const subDt = 1 / SIM_HZ;
|
|
1286
|
+
const stepMs = SAMPLE_STRIDE / SIM_HZ * 1e3;
|
|
1287
|
+
const maxSteps = Math.ceil(MAX_SIM_MS / 1e3 * SIM_HZ);
|
|
1288
|
+
const values = [from];
|
|
1289
|
+
let x = from;
|
|
1290
|
+
let v = velocityPxPerS;
|
|
1291
|
+
for (let i = 1; i <= maxSteps; i += 1) {
|
|
1292
|
+
const force = -cfg.stiffness * (x - to) - cfg.damping * v;
|
|
1293
|
+
v += force / cfg.mass * subDt;
|
|
1294
|
+
x += v * subDt;
|
|
1295
|
+
if (!Number.isFinite(x) || !Number.isFinite(v)) {
|
|
1296
|
+
values.push(to);
|
|
1297
|
+
break;
|
|
1298
|
+
}
|
|
1299
|
+
if (i % SAMPLE_STRIDE === 0) values.push(x);
|
|
1300
|
+
const atRest = Math.abs(to - x) < (cfg.restDelta ?? 0.5) && Math.abs(v) < (cfg.restSpeed ?? 0.5);
|
|
1301
|
+
if (atRest) break;
|
|
1302
|
+
}
|
|
1303
|
+
if (values[values.length - 1] !== to) values.push(to);
|
|
1304
|
+
return {
|
|
1305
|
+
values,
|
|
1306
|
+
stepMs,
|
|
1307
|
+
durationMs: (values.length - 1) * stepMs
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
function sampleTweenSettle(from, to, durationMs, easing) {
|
|
1311
|
+
const count = Math.max(2, Math.min(60, Math.round(durationMs / 16)));
|
|
1312
|
+
const values = [];
|
|
1313
|
+
for (let i = 0; i <= count; i += 1) {
|
|
1314
|
+
const t = i / count;
|
|
1315
|
+
values.push(from + (to - from) * easing(t));
|
|
1316
|
+
}
|
|
1317
|
+
values[values.length - 1] = to;
|
|
1318
|
+
return {
|
|
1319
|
+
values,
|
|
1320
|
+
stepMs: durationMs / count,
|
|
1321
|
+
durationMs
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1676
1325
|
// src/core/controllers/animation-runner.ts
|
|
1677
1326
|
var DEFAULT_DURATION2 = 220;
|
|
1678
1327
|
var VELOCITY_PX_PER_S = 1e3;
|
|
@@ -1683,6 +1332,10 @@ var AnimationRunner = class {
|
|
|
1683
1332
|
__publicField(this, "applySizeFn");
|
|
1684
1333
|
__publicField(this, "getSize");
|
|
1685
1334
|
__publicField(this, "isDragging");
|
|
1335
|
+
__publicField(this, "applyAux");
|
|
1336
|
+
__publicField(this, "getTransformFor");
|
|
1337
|
+
__publicField(this, "settleWaapi");
|
|
1338
|
+
__publicField(this, "currentWaapi", null);
|
|
1686
1339
|
__publicField(this, "animationKind");
|
|
1687
1340
|
__publicField(this, "springConfig");
|
|
1688
1341
|
__publicField(this, "duration");
|
|
@@ -1698,6 +1351,9 @@ var AnimationRunner = class {
|
|
|
1698
1351
|
this.applySizeFn = deps.applySize;
|
|
1699
1352
|
this.getSize = deps.getSize;
|
|
1700
1353
|
this.isDragging = deps.isDragging;
|
|
1354
|
+
this.applyAux = deps.applyAux;
|
|
1355
|
+
this.getTransformFor = deps.getTransformFor;
|
|
1356
|
+
this.settleWaapi = opts.settleAnimation === "waapi";
|
|
1701
1357
|
const preset = resolveAnimationPreset(opts.animation);
|
|
1702
1358
|
this.animationKind = preset.kind;
|
|
1703
1359
|
this.duration = opts.duration ?? preset.duration ?? DEFAULT_DURATION2;
|
|
@@ -1722,13 +1378,22 @@ var AnimationRunner = class {
|
|
|
1722
1378
|
}
|
|
1723
1379
|
}
|
|
1724
1380
|
get isAnimating() {
|
|
1725
|
-
return this.currentTween !== null || this.currentSpring !== null;
|
|
1381
|
+
return this.currentTween !== null || this.currentSpring !== null || this.currentWaapi !== null;
|
|
1726
1382
|
}
|
|
1727
1383
|
cancel() {
|
|
1728
1384
|
this.currentTween?.cancel();
|
|
1729
1385
|
this.currentSpring?.cancel();
|
|
1730
|
-
|
|
1731
|
-
|
|
1386
|
+
if (this.currentWaapi) {
|
|
1387
|
+
const entry = this.currentWaapi;
|
|
1388
|
+
this.currentWaapi = null;
|
|
1389
|
+
entry.stop();
|
|
1390
|
+
try {
|
|
1391
|
+
entry.anim.cancel();
|
|
1392
|
+
} catch {
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
async animateTo(target, velocityPxPerMs) {
|
|
1732
1397
|
if (target === this.getSize()) {
|
|
1733
1398
|
if (!this.isAnimating && !this.isDragging()) {
|
|
1734
1399
|
this.element.style.willChange = "";
|
|
@@ -1745,6 +1410,27 @@ var AnimationRunner = class {
|
|
|
1745
1410
|
if (!this.isDragging()) this.element.style.willChange = "";
|
|
1746
1411
|
return;
|
|
1747
1412
|
}
|
|
1413
|
+
if (this.settleWaapi && this.applyAux && this.getTransformFor && typeof this.element.animate === "function") {
|
|
1414
|
+
const samples = this.animationKind === "spring" ? sampleSpringSettle(
|
|
1415
|
+
this.getSize(),
|
|
1416
|
+
target,
|
|
1417
|
+
velocityPxPerMs * VELOCITY_PX_PER_S,
|
|
1418
|
+
this.springConfig
|
|
1419
|
+
) : sampleTweenSettle(
|
|
1420
|
+
this.getSize(),
|
|
1421
|
+
target,
|
|
1422
|
+
this.duration,
|
|
1423
|
+
this.easing
|
|
1424
|
+
);
|
|
1425
|
+
if (samples.values.length >= 2 && samples.durationMs > 0) {
|
|
1426
|
+
await this.runWaapiSettle(samples, target);
|
|
1427
|
+
if (!this.isAnimating) {
|
|
1428
|
+
this.getRootEl()?.removeAttribute("data-animating");
|
|
1429
|
+
if (!this.isDragging()) this.element.style.willChange = "";
|
|
1430
|
+
}
|
|
1431
|
+
return;
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1748
1434
|
if (this.animationKind === "spring") {
|
|
1749
1435
|
const spring = runSpring({
|
|
1750
1436
|
from: this.getSize(),
|
|
@@ -1773,11 +1459,66 @@ var AnimationRunner = class {
|
|
|
1773
1459
|
if (!this.isDragging()) this.element.style.willChange = "";
|
|
1774
1460
|
}
|
|
1775
1461
|
}
|
|
1462
|
+
async runWaapiSettle(samples, target) {
|
|
1463
|
+
const applyAux = this.applyAux;
|
|
1464
|
+
const getTransformFor = this.getTransformFor;
|
|
1465
|
+
const frames = samples.values.map((v) => ({
|
|
1466
|
+
transform: getTransformFor(v)
|
|
1467
|
+
}));
|
|
1468
|
+
const anim = this.element.animate(frames, {
|
|
1469
|
+
duration: samples.durationMs,
|
|
1470
|
+
easing: "linear",
|
|
1471
|
+
fill: "forwards"
|
|
1472
|
+
});
|
|
1473
|
+
let stopped = false;
|
|
1474
|
+
let auxRaf = 0;
|
|
1475
|
+
const start = performance.now();
|
|
1476
|
+
const lastIdx = samples.values.length - 1;
|
|
1477
|
+
const auxTick = () => {
|
|
1478
|
+
if (stopped) return;
|
|
1479
|
+
const elapsed = performance.now() - start;
|
|
1480
|
+
const idx = Math.min(Math.floor(elapsed / samples.stepMs), lastIdx);
|
|
1481
|
+
applyAux(samples.values[idx]);
|
|
1482
|
+
auxRaf = requestAnimationFrame(auxTick);
|
|
1483
|
+
};
|
|
1484
|
+
auxRaf = requestAnimationFrame(auxTick);
|
|
1485
|
+
const entry = {
|
|
1486
|
+
anim,
|
|
1487
|
+
stop: () => {
|
|
1488
|
+
stopped = true;
|
|
1489
|
+
cancelAnimationFrame(auxRaf);
|
|
1490
|
+
}
|
|
1491
|
+
};
|
|
1492
|
+
this.currentWaapi = entry;
|
|
1493
|
+
try {
|
|
1494
|
+
await anim.finished;
|
|
1495
|
+
} catch {
|
|
1496
|
+
}
|
|
1497
|
+
entry.stop();
|
|
1498
|
+
const wasCurrent = this.currentWaapi === entry;
|
|
1499
|
+
if (wasCurrent) this.currentWaapi = null;
|
|
1500
|
+
if (wasCurrent && anim.playState === "finished") {
|
|
1501
|
+
this.applySizeFn(target);
|
|
1502
|
+
try {
|
|
1503
|
+
anim.cancel();
|
|
1504
|
+
} catch {
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1776
1508
|
destroy() {
|
|
1777
1509
|
this.detachReducedMotion?.();
|
|
1778
1510
|
this.detachReducedMotion = null;
|
|
1779
1511
|
this.currentTween = null;
|
|
1780
1512
|
this.currentSpring = null;
|
|
1513
|
+
if (this.currentWaapi) {
|
|
1514
|
+
const entry = this.currentWaapi;
|
|
1515
|
+
this.currentWaapi = null;
|
|
1516
|
+
entry.stop();
|
|
1517
|
+
try {
|
|
1518
|
+
entry.anim.cancel();
|
|
1519
|
+
} catch {
|
|
1520
|
+
}
|
|
1521
|
+
}
|
|
1781
1522
|
}
|
|
1782
1523
|
};
|
|
1783
1524
|
|
|
@@ -2635,7 +2376,7 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2635
2376
|
const initialAllowed = opts.allowed ?? opts.snapPoints.map((p) => p.id);
|
|
2636
2377
|
let initialId = opts.initial ?? initialAllowed[0] ?? opts.snapPoints[0]?.id ?? "default";
|
|
2637
2378
|
if (opts.persistKey) {
|
|
2638
|
-
const restored =
|
|
2379
|
+
const restored = readPersistedIdSafe(opts.persistKey);
|
|
2639
2380
|
if (restored && initialAllowed.includes(restored)) {
|
|
2640
2381
|
initialId = restored;
|
|
2641
2382
|
}
|
|
@@ -2666,6 +2407,7 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2666
2407
|
},
|
|
2667
2408
|
animation: {
|
|
2668
2409
|
animation: opts.animation,
|
|
2410
|
+
settleAnimation: opts.settleAnimation,
|
|
2669
2411
|
duration: opts.duration,
|
|
2670
2412
|
easing: opts.easing,
|
|
2671
2413
|
spring: opts.spring,
|
|
@@ -2683,6 +2425,15 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2683
2425
|
}
|
|
2684
2426
|
};
|
|
2685
2427
|
}
|
|
2428
|
+
var readPersistedIdSafe = (key) => {
|
|
2429
|
+
if (typeof window === "undefined") return null;
|
|
2430
|
+
if (typeof localStorage === "undefined") return null;
|
|
2431
|
+
try {
|
|
2432
|
+
return localStorage.getItem(key);
|
|
2433
|
+
} catch {
|
|
2434
|
+
return null;
|
|
2435
|
+
}
|
|
2436
|
+
};
|
|
2686
2437
|
|
|
2687
2438
|
// src/core/primitives/teardown-stack.ts
|
|
2688
2439
|
var TeardownStack = class {
|
|
@@ -2705,9 +2456,9 @@ var TeardownStack = class {
|
|
|
2705
2456
|
}
|
|
2706
2457
|
};
|
|
2707
2458
|
|
|
2708
|
-
// src/core/
|
|
2459
|
+
// src/core/BottomSheetCore.ts
|
|
2709
2460
|
var HAPTIC_DURATION_MS = 8;
|
|
2710
|
-
var
|
|
2461
|
+
var BottomSheetCore = class {
|
|
2711
2462
|
constructor(opts) {
|
|
2712
2463
|
__publicField(this, "id", nextInstanceId("bs"));
|
|
2713
2464
|
__publicField(this, "element");
|
|
@@ -2768,6 +2519,8 @@ var BottomSheetEngine = class {
|
|
|
2768
2519
|
__publicField(this, "stackEffectPrimed", false);
|
|
2769
2520
|
__publicField(this, "fitDeps");
|
|
2770
2521
|
__publicField(this, "transformTemplate");
|
|
2522
|
+
__publicField(this, "featureList", []);
|
|
2523
|
+
__publicField(this, "featureCtx");
|
|
2771
2524
|
const resolved = resolveEngineOptions(opts, {
|
|
2772
2525
|
shouldApplyInertSiblings: () => {
|
|
2773
2526
|
if (typeof document === "undefined") return false;
|
|
@@ -2814,7 +2567,9 @@ var BottomSheetEngine = class {
|
|
|
2814
2567
|
getRootEl: () => this.rootEl,
|
|
2815
2568
|
applySize: (size) => this.applySize(size),
|
|
2816
2569
|
getSize: () => this.size,
|
|
2817
|
-
isDragging: () => this.gesture?.isDragging ?? false
|
|
2570
|
+
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2571
|
+
applyAux: (size) => this.applySize(size, true),
|
|
2572
|
+
getTransformFor: (size) => this.transformTemplate(this.snaps.getMaxAxisSize() - size)
|
|
2818
2573
|
},
|
|
2819
2574
|
resolved.animation
|
|
2820
2575
|
);
|
|
@@ -2837,6 +2592,11 @@ var BottomSheetEngine = class {
|
|
|
2837
2592
|
if (opts.linkedSheets) {
|
|
2838
2593
|
this.linkedSheets = opts.linkedSheets;
|
|
2839
2594
|
}
|
|
2595
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2596
|
+
for (const feature of opts.features ?? []) {
|
|
2597
|
+
byName.set(feature.name, feature);
|
|
2598
|
+
}
|
|
2599
|
+
this.featureList = Array.from(byName.values());
|
|
2840
2600
|
this.activeId = resolved.initialId;
|
|
2841
2601
|
auditVhUsage(this.snapPointsRaw);
|
|
2842
2602
|
this.auditDuplicateSnapIds(this.snapPointsRaw);
|
|
@@ -2873,6 +2633,7 @@ var BottomSheetEngine = class {
|
|
|
2873
2633
|
scrollContainer: this.scrollContainer,
|
|
2874
2634
|
getMaxAxisSize: () => this.snaps.getMaxAxisSize()
|
|
2875
2635
|
});
|
|
2636
|
+
this.featureCtx = this.buildFeatureContext(opts.autoCollapseAfter);
|
|
2876
2637
|
this.attach();
|
|
2877
2638
|
this.registerInStack();
|
|
2878
2639
|
if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
|
|
@@ -2904,46 +2665,77 @@ var BottomSheetEngine = class {
|
|
|
2904
2665
|
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2905
2666
|
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2906
2667
|
this.applyAutoAriaLabelledBy();
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
getSize: () => this.size,
|
|
2912
|
-
close: () => this.close()
|
|
2913
|
-
})
|
|
2914
|
-
);
|
|
2915
|
-
}
|
|
2916
|
-
if (this.persistKey) {
|
|
2917
|
-
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2668
|
+
this.runFeatureStage("post");
|
|
2669
|
+
this.warnOrphanFeatureOptions();
|
|
2670
|
+
if (this.size > 0) {
|
|
2671
|
+
this.handleOpen();
|
|
2918
2672
|
}
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
resolveSnap: (id) => this.snaps.findById(id),
|
|
2927
|
-
snapTo: (id) => {
|
|
2928
|
-
void this.snapTo(id);
|
|
2929
|
-
},
|
|
2930
|
-
on: (event, fn) => this.on(event, fn)
|
|
2931
|
-
})
|
|
2932
|
-
);
|
|
2933
|
-
this.teardowns.add(
|
|
2934
|
-
installRoute({
|
|
2673
|
+
}
|
|
2674
|
+
buildFeatureContext(autoCollapseAfter) {
|
|
2675
|
+
return {
|
|
2676
|
+
element: this.element,
|
|
2677
|
+
scrollContainer: this.scrollContainer,
|
|
2678
|
+
sheetId: this.id,
|
|
2679
|
+
options: {
|
|
2935
2680
|
routedTo: this.routedTo,
|
|
2936
2681
|
closeOnBack: this.closeOnBack,
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
this.
|
|
2682
|
+
closeOnRouteChange: this.closeOnRouteChange,
|
|
2683
|
+
persistKey: this.persistKey,
|
|
2684
|
+
autoCollapseAfter
|
|
2685
|
+
},
|
|
2686
|
+
isDestroyed: () => this.destroyed,
|
|
2687
|
+
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2688
|
+
isAnimating: () => this.animation.isAnimating,
|
|
2689
|
+
isTopSheet: () => this.isTopSheet,
|
|
2690
|
+
isVerticalAxis: () => this.mode === "bottom" || this.mode === "top",
|
|
2691
|
+
getSize: () => this.size,
|
|
2692
|
+
getActiveId: () => this.activeId,
|
|
2693
|
+
getAllowedIds: () => this.snaps.getAllowedIds().slice(),
|
|
2694
|
+
allowedIdsBySize: () => this.allowedIdsBySize(),
|
|
2695
|
+
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
2696
|
+
resolveSnap: (id) => this.snaps.findById(id),
|
|
2697
|
+
resolveActiveSnap: () => this.snaps.findById(this.activeId),
|
|
2698
|
+
setSize: (size) => {
|
|
2699
|
+
this.size = size;
|
|
2700
|
+
},
|
|
2701
|
+
setMaxAxisSize: (size) => {
|
|
2702
|
+
this.snaps.setMaxAxisSize(size);
|
|
2703
|
+
},
|
|
2704
|
+
applySize: (size) => this.applySize(size),
|
|
2705
|
+
recomputeSnaps: () => this.recomputeSnaps(),
|
|
2706
|
+
newCycle: () => {
|
|
2707
|
+
this.newCycle();
|
|
2708
|
+
},
|
|
2709
|
+
cancelInFlight: () => {
|
|
2710
|
+
this.animation.cancel();
|
|
2711
|
+
},
|
|
2712
|
+
resyncAfterResize: () => this.resyncAfterResize(),
|
|
2713
|
+
snapTo: (id) => {
|
|
2714
|
+
void this.snapTo(id);
|
|
2715
|
+
},
|
|
2716
|
+
close: (reason) => this.close(reason),
|
|
2717
|
+
on: (event, fn) => this.on(event, fn),
|
|
2718
|
+
addTeardown: (fn) => this.teardowns.add(fn)
|
|
2719
|
+
};
|
|
2720
|
+
}
|
|
2721
|
+
runFeatureStage(stage) {
|
|
2722
|
+
for (const feature of this.featureList) {
|
|
2723
|
+
if ((feature.stage ?? "post") !== stage) continue;
|
|
2724
|
+
const teardown = feature.install(this.featureCtx);
|
|
2725
|
+
if (teardown) this.teardowns.add(teardown);
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
warnOrphanFeatureOptions() {
|
|
2729
|
+
const names = new Set(this.featureList.map((f) => f.name));
|
|
2730
|
+
if ((this.closeOnBack || this.routedTo !== void 0 || this.closeOnRouteChange) && !names.has("route")) {
|
|
2731
|
+
devWarn(
|
|
2732
|
+
"[BottomSheet] closeOnBack/routedTo/closeOnRouteChange need routeFeature() \u2014 option ignored"
|
|
2733
|
+
);
|
|
2734
|
+
}
|
|
2735
|
+
if (this.persistKey && !names.has("persist")) {
|
|
2736
|
+
devWarn(
|
|
2737
|
+
"[BottomSheet] persistKey needs persistFeature() \u2014 snaps will not be saved"
|
|
2738
|
+
);
|
|
2947
2739
|
}
|
|
2948
2740
|
}
|
|
2949
2741
|
get state() {
|
|
@@ -3486,18 +3278,7 @@ var BottomSheetEngine = class {
|
|
|
3486
3278
|
}
|
|
3487
3279
|
}
|
|
3488
3280
|
attachFeatures() {
|
|
3489
|
-
|
|
3490
|
-
this.teardowns.add(installContentSwipe({
|
|
3491
|
-
container: this.scrollContainer,
|
|
3492
|
-
isDragging: () => this.gesture?.isDragging ?? false,
|
|
3493
|
-
isAnimating: () => this.animation.isAnimating,
|
|
3494
|
-
getAllowedIds: () => this.allowedIdsBySize(),
|
|
3495
|
-
getActiveId: () => this.activeId,
|
|
3496
|
-
snapTo: (id) => {
|
|
3497
|
-
void this.snapTo(id);
|
|
3498
|
-
}
|
|
3499
|
-
}));
|
|
3500
|
-
}
|
|
3281
|
+
this.runFeatureStage("attach");
|
|
3501
3282
|
if (typeof window !== "undefined") {
|
|
3502
3283
|
this.teardowns.add(installResizeObserver({
|
|
3503
3284
|
element: this.element,
|
|
@@ -3537,31 +3318,6 @@ var BottomSheetEngine = class {
|
|
|
3537
3318
|
() => document.removeEventListener("keydown", onKey)
|
|
3538
3319
|
);
|
|
3539
3320
|
}
|
|
3540
|
-
this.teardowns.add(installVisualViewport({
|
|
3541
|
-
element: this.element,
|
|
3542
|
-
isVerticalAxis: () => this.mode === "bottom" || this.mode === "top",
|
|
3543
|
-
isDestroyed: () => this.destroyed,
|
|
3544
|
-
isDragging: () => this.gesture?.isDragging ?? false,
|
|
3545
|
-
recomputeSnaps: () => this.recomputeSnaps(),
|
|
3546
|
-
resolveActiveSnap: () => this.snaps.findById(this.activeId),
|
|
3547
|
-
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
3548
|
-
getSize: () => this.size,
|
|
3549
|
-
setMaxAxisSize: (size) => {
|
|
3550
|
-
this.snaps.setMaxAxisSize(size);
|
|
3551
|
-
},
|
|
3552
|
-
setSize: (size) => {
|
|
3553
|
-
this.size = size;
|
|
3554
|
-
},
|
|
3555
|
-
applySize: (size) => this.applySize(size),
|
|
3556
|
-
cancelInFlight: () => {
|
|
3557
|
-
this.animation.cancel();
|
|
3558
|
-
},
|
|
3559
|
-
newCycle: () => {
|
|
3560
|
-
this.newCycle();
|
|
3561
|
-
},
|
|
3562
|
-
isAnimating: () => this.animation.isAnimating,
|
|
3563
|
-
resyncAfterCancel: () => this.resyncAfterResize()
|
|
3564
|
-
}));
|
|
3565
3321
|
}
|
|
3566
3322
|
this.teardowns.add(installSliderKeyboard({
|
|
3567
3323
|
handle: this.handle,
|
|
@@ -3638,13 +3394,13 @@ var BottomSheetEngine = class {
|
|
|
3638
3394
|
}
|
|
3639
3395
|
}
|
|
3640
3396
|
}
|
|
3641
|
-
applySize(size) {
|
|
3397
|
+
applySize(size, skipTransform = false) {
|
|
3642
3398
|
const cap = this.snaps.getMaxAxisSize();
|
|
3643
3399
|
const clamped = cap > 0 && size > cap && !this.gesture?.isDragging && !this.allowOvershoot ? cap : size;
|
|
3644
3400
|
this.size = clamped;
|
|
3645
3401
|
const offset = cap - clamped;
|
|
3646
3402
|
const style = this.element.style;
|
|
3647
|
-
style.transform = this.transformTemplate(offset);
|
|
3403
|
+
if (!skipTransform) style.transform = this.transformTemplate(offset);
|
|
3648
3404
|
if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
|
|
3649
3405
|
style.setProperty("--bs-size", `${clamped}px`);
|
|
3650
3406
|
if (this.scrimParent) {
|
|
@@ -3722,6 +3478,514 @@ var BottomSheetEngine = class {
|
|
|
3722
3478
|
}
|
|
3723
3479
|
};
|
|
3724
3480
|
|
|
3481
|
+
// src/core/features/history-coordinator.ts
|
|
3482
|
+
var entries = [];
|
|
3483
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
3484
|
+
var suppress = 0;
|
|
3485
|
+
var internalDepth = 0;
|
|
3486
|
+
var pendingRebrands = [];
|
|
3487
|
+
var listenerInstalled = false;
|
|
3488
|
+
var patchInstalled = false;
|
|
3489
|
+
var origPushState = null;
|
|
3490
|
+
var origReplaceState = null;
|
|
3491
|
+
var patchedPushState = null;
|
|
3492
|
+
var patchedReplaceState = null;
|
|
3493
|
+
var hasWindow = () => typeof window !== "undefined";
|
|
3494
|
+
var hasHistory = () => typeof history !== "undefined";
|
|
3495
|
+
var brandMarker = (surface) => ({
|
|
3496
|
+
...surface.markerState(),
|
|
3497
|
+
__bs: true
|
|
3498
|
+
});
|
|
3499
|
+
var runInternal = (fn) => {
|
|
3500
|
+
internalDepth += 1;
|
|
3501
|
+
try {
|
|
3502
|
+
fn();
|
|
3503
|
+
} finally {
|
|
3504
|
+
internalDepth -= 1;
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3507
|
+
var notifyRouteChange = () => {
|
|
3508
|
+
const snapshot = Array.from(subscribers);
|
|
3509
|
+
for (const fn of snapshot) fn();
|
|
3510
|
+
};
|
|
3511
|
+
var ensureListener = () => {
|
|
3512
|
+
if (listenerInstalled || !hasWindow()) return;
|
|
3513
|
+
window.addEventListener("popstate", onPopState);
|
|
3514
|
+
listenerInstalled = true;
|
|
3515
|
+
};
|
|
3516
|
+
var maybeTeardownListener = () => {
|
|
3517
|
+
if (!listenerInstalled) return;
|
|
3518
|
+
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
3519
|
+
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
3520
|
+
listenerInstalled = false;
|
|
3521
|
+
};
|
|
3522
|
+
var installPatch = () => {
|
|
3523
|
+
if (patchInstalled || !hasHistory()) return;
|
|
3524
|
+
origPushState = history.pushState;
|
|
3525
|
+
origReplaceState = history.replaceState;
|
|
3526
|
+
patchedPushState = function(...args) {
|
|
3527
|
+
origPushState.apply(this, args);
|
|
3528
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
3529
|
+
};
|
|
3530
|
+
patchedReplaceState = function(...args) {
|
|
3531
|
+
origReplaceState.apply(this, args);
|
|
3532
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
3533
|
+
};
|
|
3534
|
+
history.pushState = patchedPushState;
|
|
3535
|
+
history.replaceState = patchedReplaceState;
|
|
3536
|
+
patchInstalled = true;
|
|
3537
|
+
};
|
|
3538
|
+
var removePatch = () => {
|
|
3539
|
+
if (!patchInstalled) return;
|
|
3540
|
+
if (history.pushState === patchedPushState && origPushState) {
|
|
3541
|
+
history.pushState = origPushState;
|
|
3542
|
+
}
|
|
3543
|
+
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
3544
|
+
history.replaceState = origReplaceState;
|
|
3545
|
+
}
|
|
3546
|
+
origPushState = null;
|
|
3547
|
+
origReplaceState = null;
|
|
3548
|
+
patchedPushState = null;
|
|
3549
|
+
patchedReplaceState = null;
|
|
3550
|
+
patchInstalled = false;
|
|
3551
|
+
};
|
|
3552
|
+
function onPopState() {
|
|
3553
|
+
if (suppress > 0) {
|
|
3554
|
+
suppress -= 1;
|
|
3555
|
+
const rebrand = pendingRebrands.shift();
|
|
3556
|
+
if (rebrand) rebrand();
|
|
3557
|
+
maybeTeardownListener();
|
|
3558
|
+
return;
|
|
3559
|
+
}
|
|
3560
|
+
if (entries.length === 0) {
|
|
3561
|
+
notifyRouteChange();
|
|
3562
|
+
maybeTeardownListener();
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
let target = null;
|
|
3566
|
+
let targetIdx = -1;
|
|
3567
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
3568
|
+
const entry = entries[i];
|
|
3569
|
+
if (!entry.surface.isOpen()) continue;
|
|
3570
|
+
if (!target) {
|
|
3571
|
+
target = entry;
|
|
3572
|
+
targetIdx = i;
|
|
3573
|
+
}
|
|
3574
|
+
if (entry.surface.isTop()) {
|
|
3575
|
+
target = entry;
|
|
3576
|
+
targetIdx = i;
|
|
3577
|
+
break;
|
|
3578
|
+
}
|
|
3579
|
+
}
|
|
3580
|
+
if (!target) {
|
|
3581
|
+
const removed = entries.pop();
|
|
3582
|
+
if (removed) removed.live = false;
|
|
3583
|
+
maybeTeardownListener();
|
|
3584
|
+
return;
|
|
3585
|
+
}
|
|
3586
|
+
target.live = false;
|
|
3587
|
+
entries.splice(targetIdx, 1);
|
|
3588
|
+
const settled = target;
|
|
3589
|
+
void Promise.resolve(settled.surface.close()).then(() => {
|
|
3590
|
+
if (settled.surface.isOpen()) restore(settled);
|
|
3591
|
+
});
|
|
3592
|
+
maybeTeardownListener();
|
|
3593
|
+
}
|
|
3594
|
+
function restore(entry) {
|
|
3595
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
3596
|
+
entry.live = true;
|
|
3597
|
+
runInternal(() => {
|
|
3598
|
+
try {
|
|
3599
|
+
history.pushState(brandMarker(entry.surface), "", entry.surface.url);
|
|
3600
|
+
} catch {
|
|
3601
|
+
entry.live = false;
|
|
3602
|
+
}
|
|
3603
|
+
});
|
|
3604
|
+
if (entry.live) {
|
|
3605
|
+
entries.push(entry);
|
|
3606
|
+
ensureListener();
|
|
3607
|
+
}
|
|
3608
|
+
}
|
|
3609
|
+
function pushBackMarker(surface) {
|
|
3610
|
+
const entry = { surface, priorUrl: void 0, live: false };
|
|
3611
|
+
if (!hasWindow() || !hasHistory()) {
|
|
3612
|
+
return entry;
|
|
3613
|
+
}
|
|
3614
|
+
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
3615
|
+
runInternal(() => {
|
|
3616
|
+
try {
|
|
3617
|
+
history.pushState(brandMarker(surface), "", surface.url);
|
|
3618
|
+
entry.live = true;
|
|
3619
|
+
} catch {
|
|
3620
|
+
entry.live = false;
|
|
3621
|
+
}
|
|
3622
|
+
});
|
|
3623
|
+
if (entry.live) {
|
|
3624
|
+
entries.push(entry);
|
|
3625
|
+
ensureListener();
|
|
3626
|
+
}
|
|
3627
|
+
return entry;
|
|
3628
|
+
}
|
|
3629
|
+
function popBackMarker(handle) {
|
|
3630
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
3631
|
+
const entry = handle;
|
|
3632
|
+
const idx = entries.indexOf(entry);
|
|
3633
|
+
if (idx === -1 || !entry.live) return;
|
|
3634
|
+
const last = entries.length - 1;
|
|
3635
|
+
entry.live = false;
|
|
3636
|
+
entries.splice(idx, 1);
|
|
3637
|
+
let rebrand = null;
|
|
3638
|
+
if (idx !== last) {
|
|
3639
|
+
const rebrandSurface = entries[entries.length - 1].surface;
|
|
3640
|
+
const rebrandUrl = entry.priorUrl;
|
|
3641
|
+
rebrand = () => {
|
|
3642
|
+
runInternal(() => {
|
|
3643
|
+
history.replaceState(
|
|
3644
|
+
brandMarker(rebrandSurface),
|
|
3645
|
+
"",
|
|
3646
|
+
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
3647
|
+
);
|
|
3648
|
+
});
|
|
3649
|
+
};
|
|
3650
|
+
}
|
|
3651
|
+
pendingRebrands.push(rebrand);
|
|
3652
|
+
suppress += 1;
|
|
3653
|
+
runInternal(() => {
|
|
3654
|
+
try {
|
|
3655
|
+
history.back();
|
|
3656
|
+
} catch {
|
|
3657
|
+
suppress = Math.max(0, suppress - 1);
|
|
3658
|
+
pendingRebrands.pop();
|
|
3659
|
+
}
|
|
3660
|
+
});
|
|
3661
|
+
maybeTeardownListener();
|
|
3662
|
+
}
|
|
3663
|
+
function subscribeRouteChange(fn) {
|
|
3664
|
+
if (!hasWindow() || !hasHistory()) return () => {
|
|
3665
|
+
};
|
|
3666
|
+
subscribers.add(fn);
|
|
3667
|
+
if (subscribers.size === 1) installPatch();
|
|
3668
|
+
ensureListener();
|
|
3669
|
+
return () => {
|
|
3670
|
+
if (!subscribers.has(fn)) return;
|
|
3671
|
+
subscribers.delete(fn);
|
|
3672
|
+
if (subscribers.size === 0) removePatch();
|
|
3673
|
+
maybeTeardownListener();
|
|
3674
|
+
};
|
|
3675
|
+
}
|
|
3676
|
+
|
|
3677
|
+
// src/core/features/route.ts
|
|
3678
|
+
function installRoute(deps) {
|
|
3679
|
+
if (typeof window === "undefined") {
|
|
3680
|
+
return () => {
|
|
3681
|
+
};
|
|
3682
|
+
}
|
|
3683
|
+
if (!deps.routedTo && !deps.closeOnBack) {
|
|
3684
|
+
return () => {
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
let handle = null;
|
|
3688
|
+
const onOpen = () => {
|
|
3689
|
+
if (handle) return;
|
|
3690
|
+
handle = pushBackMarker({
|
|
3691
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
3692
|
+
isTop: deps.isTopSheet,
|
|
3693
|
+
close: deps.close,
|
|
3694
|
+
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
3695
|
+
url: deps.routedTo
|
|
3696
|
+
});
|
|
3697
|
+
};
|
|
3698
|
+
const onClose = () => {
|
|
3699
|
+
if (!handle) return;
|
|
3700
|
+
popBackMarker(handle);
|
|
3701
|
+
handle = null;
|
|
3702
|
+
};
|
|
3703
|
+
const unsubscribeOpen = deps.on("open", onOpen);
|
|
3704
|
+
const unsubscribeClose = deps.on("close", onClose);
|
|
3705
|
+
if (deps.getSize() > 0) onOpen();
|
|
3706
|
+
return () => {
|
|
3707
|
+
unsubscribeOpen();
|
|
3708
|
+
unsubscribeClose();
|
|
3709
|
+
if (handle) {
|
|
3710
|
+
popBackMarker(handle);
|
|
3711
|
+
handle = null;
|
|
3712
|
+
}
|
|
3713
|
+
};
|
|
3714
|
+
}
|
|
3715
|
+
function installRouteChange(deps) {
|
|
3716
|
+
return subscribeRouteChange(() => {
|
|
3717
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
3718
|
+
void deps.close();
|
|
3719
|
+
});
|
|
3720
|
+
}
|
|
3721
|
+
|
|
3722
|
+
// src/core/features/persist.ts
|
|
3723
|
+
function installPersist(engine, key) {
|
|
3724
|
+
const unsubscribe = engine.on("snap", ({ id }) => {
|
|
3725
|
+
if (typeof window === "undefined") return;
|
|
3726
|
+
if (typeof localStorage === "undefined") return;
|
|
3727
|
+
try {
|
|
3728
|
+
localStorage.setItem(key, id);
|
|
3729
|
+
} catch {
|
|
3730
|
+
}
|
|
3731
|
+
});
|
|
3732
|
+
return unsubscribe;
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
// src/core/features/auto-collapse.ts
|
|
3736
|
+
function installAutoCollapse(deps) {
|
|
3737
|
+
const { ms } = deps;
|
|
3738
|
+
if (ms === void 0 || ms <= 0) {
|
|
3739
|
+
return () => {
|
|
3740
|
+
};
|
|
3741
|
+
}
|
|
3742
|
+
let timer = null;
|
|
3743
|
+
const clearTimer = () => {
|
|
3744
|
+
if (timer !== null) {
|
|
3745
|
+
clearTimeout(timer);
|
|
3746
|
+
timer = null;
|
|
3747
|
+
}
|
|
3748
|
+
};
|
|
3749
|
+
const fire = () => {
|
|
3750
|
+
if (deps.isDestroyed()) return;
|
|
3751
|
+
if (deps.isDragging()) return;
|
|
3752
|
+
const active = deps.resolveSnap(deps.getActiveId());
|
|
3753
|
+
if (!active || active.size === 0) return;
|
|
3754
|
+
let target = null;
|
|
3755
|
+
for (const id of deps.getAllowedIds()) {
|
|
3756
|
+
const snap = deps.resolveSnap(id);
|
|
3757
|
+
if (!snap || snap.size <= 0) continue;
|
|
3758
|
+
if (!target || snap.size < target.size) target = snap;
|
|
3759
|
+
}
|
|
3760
|
+
if (!target) return;
|
|
3761
|
+
if (target.id === active.id || target.size >= active.size) return;
|
|
3762
|
+
deps.snapTo(target.id);
|
|
3763
|
+
};
|
|
3764
|
+
const reset = () => {
|
|
3765
|
+
clearTimer();
|
|
3766
|
+
if (deps.isDestroyed()) return;
|
|
3767
|
+
timer = setTimeout(() => {
|
|
3768
|
+
timer = null;
|
|
3769
|
+
fire();
|
|
3770
|
+
}, ms);
|
|
3771
|
+
};
|
|
3772
|
+
const unsubscribe = deps.on("snap", () => reset());
|
|
3773
|
+
if ((deps.resolveSnap(deps.getActiveId())?.size ?? 0) > 0) reset();
|
|
3774
|
+
return () => {
|
|
3775
|
+
clearTimer();
|
|
3776
|
+
unsubscribe();
|
|
3777
|
+
};
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3780
|
+
// src/core/features/content-swipe.ts
|
|
3781
|
+
var CONTENT_PULL_THRESHOLD = 60;
|
|
3782
|
+
function installContentSwipe(deps) {
|
|
3783
|
+
const { container } = deps;
|
|
3784
|
+
let startY = 0;
|
|
3785
|
+
let startScrollTop = 0;
|
|
3786
|
+
let moved = false;
|
|
3787
|
+
const onTouchStart = (e) => {
|
|
3788
|
+
const t = e.touches[0];
|
|
3789
|
+
if (!t) return;
|
|
3790
|
+
startY = t.clientY;
|
|
3791
|
+
startScrollTop = container.scrollTop;
|
|
3792
|
+
moved = false;
|
|
3793
|
+
};
|
|
3794
|
+
const onTouchMove = (e) => {
|
|
3795
|
+
const t = e.touches[0];
|
|
3796
|
+
if (!t) return;
|
|
3797
|
+
if (Math.abs(t.clientY - startY) > CONTENT_PULL_THRESHOLD) moved = true;
|
|
3798
|
+
};
|
|
3799
|
+
const onTouchEnd = (e) => {
|
|
3800
|
+
if (!moved) return;
|
|
3801
|
+
if (deps.isDragging() || deps.isAnimating()) return;
|
|
3802
|
+
if (container.scrollTop !== startScrollTop) return;
|
|
3803
|
+
const t = e.changedTouches[0];
|
|
3804
|
+
if (!t) return;
|
|
3805
|
+
const deltaY = t.clientY - startY;
|
|
3806
|
+
const atTop = container.scrollTop <= 0;
|
|
3807
|
+
const allowed = deps.getAllowedIds();
|
|
3808
|
+
const idx = allowed.indexOf(deps.getActiveId());
|
|
3809
|
+
if (idx === -1) return;
|
|
3810
|
+
if (atTop && deltaY > CONTENT_PULL_THRESHOLD && idx > 0) {
|
|
3811
|
+
deps.snapTo(allowed[idx - 1]);
|
|
3812
|
+
} else if (deltaY < -CONTENT_PULL_THRESHOLD && idx < allowed.length - 1) {
|
|
3813
|
+
deps.snapTo(allowed[idx + 1]);
|
|
3814
|
+
}
|
|
3815
|
+
};
|
|
3816
|
+
container.addEventListener("touchstart", onTouchStart, { passive: true });
|
|
3817
|
+
container.addEventListener("touchmove", onTouchMove, { passive: true });
|
|
3818
|
+
container.addEventListener("touchend", onTouchEnd, { passive: true });
|
|
3819
|
+
return () => {
|
|
3820
|
+
container.removeEventListener("touchstart", onTouchStart);
|
|
3821
|
+
container.removeEventListener("touchmove", onTouchMove);
|
|
3822
|
+
container.removeEventListener("touchend", onTouchEnd);
|
|
3823
|
+
};
|
|
3824
|
+
}
|
|
3825
|
+
|
|
3826
|
+
// src/core/features/visual-viewport.ts
|
|
3827
|
+
var SAFETY_PAD = 8;
|
|
3828
|
+
function installVisualViewport(deps) {
|
|
3829
|
+
if (typeof window === "undefined" || !window.visualViewport) {
|
|
3830
|
+
return () => {
|
|
3831
|
+
};
|
|
3832
|
+
}
|
|
3833
|
+
const vv = window.visualViewport;
|
|
3834
|
+
let rafId = null;
|
|
3835
|
+
const onResize = () => {
|
|
3836
|
+
if (rafId !== null) return;
|
|
3837
|
+
rafId = requestAnimationFrame(() => {
|
|
3838
|
+
rafId = null;
|
|
3839
|
+
if (deps.isDestroyed()) return;
|
|
3840
|
+
deps.recomputeSnaps();
|
|
3841
|
+
const isVertical = deps.isVerticalAxis();
|
|
3842
|
+
const visible = isVertical ? vv.height : vv.width;
|
|
3843
|
+
const windowSize = isVertical ? window.innerHeight : window.innerWidth;
|
|
3844
|
+
const clamp = Math.max(0, Math.min(windowSize, visible) - SAFETY_PAD);
|
|
3845
|
+
if (clamp < deps.getMaxAxisSize()) {
|
|
3846
|
+
deps.setMaxAxisSize(clamp);
|
|
3847
|
+
}
|
|
3848
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
3849
|
+
deps.cancelInFlight();
|
|
3850
|
+
deps.newCycle();
|
|
3851
|
+
const max = deps.getMaxAxisSize();
|
|
3852
|
+
deps.setSize(Math.min(deps.getSize(), max));
|
|
3853
|
+
const current = deps.resolveActiveSnap();
|
|
3854
|
+
if (current && !deps.isDragging()) {
|
|
3855
|
+
deps.applySize(Math.min(current.size, max));
|
|
3856
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
3857
|
+
} else {
|
|
3858
|
+
deps.applySize(deps.getSize());
|
|
3859
|
+
}
|
|
3860
|
+
});
|
|
3861
|
+
};
|
|
3862
|
+
vv.addEventListener("resize", onResize);
|
|
3863
|
+
return () => {
|
|
3864
|
+
vv.removeEventListener("resize", onResize);
|
|
3865
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
|
|
3869
|
+
// src/core/features/engine-features.ts
|
|
3870
|
+
function routeFeature() {
|
|
3871
|
+
return {
|
|
3872
|
+
name: "route",
|
|
3873
|
+
install: (ctx) => {
|
|
3874
|
+
const teardowns = new TeardownStack();
|
|
3875
|
+
if (ctx.options.closeOnRouteChange) {
|
|
3876
|
+
teardowns.add(
|
|
3877
|
+
installRouteChange({
|
|
3878
|
+
isDestroyed: ctx.isDestroyed,
|
|
3879
|
+
getSize: ctx.getSize,
|
|
3880
|
+
close: () => ctx.close()
|
|
3881
|
+
})
|
|
3882
|
+
);
|
|
3883
|
+
}
|
|
3884
|
+
teardowns.add(
|
|
3885
|
+
installRoute({
|
|
3886
|
+
routedTo: ctx.options.routedTo,
|
|
3887
|
+
closeOnBack: ctx.options.closeOnBack,
|
|
3888
|
+
isTopSheet: ctx.isTopSheet,
|
|
3889
|
+
getSize: ctx.getSize,
|
|
3890
|
+
isDestroyed: ctx.isDestroyed,
|
|
3891
|
+
close: () => ctx.close("back"),
|
|
3892
|
+
on: ctx.on,
|
|
3893
|
+
sheetId: ctx.sheetId
|
|
3894
|
+
})
|
|
3895
|
+
);
|
|
3896
|
+
return () => teardowns.drain();
|
|
3897
|
+
}
|
|
3898
|
+
};
|
|
3899
|
+
}
|
|
3900
|
+
function persistFeature() {
|
|
3901
|
+
return {
|
|
3902
|
+
name: "persist",
|
|
3903
|
+
install: (ctx) => {
|
|
3904
|
+
const key = ctx.options.persistKey;
|
|
3905
|
+
if (!key) return;
|
|
3906
|
+
return installPersist({ on: ctx.on }, key);
|
|
3907
|
+
}
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
function autoCollapseFeature() {
|
|
3911
|
+
return {
|
|
3912
|
+
name: "auto-collapse",
|
|
3913
|
+
install: (ctx) => installAutoCollapse({
|
|
3914
|
+
ms: ctx.options.autoCollapseAfter,
|
|
3915
|
+
isDestroyed: ctx.isDestroyed,
|
|
3916
|
+
isDragging: ctx.isDragging,
|
|
3917
|
+
getAllowedIds: ctx.getAllowedIds,
|
|
3918
|
+
getActiveId: ctx.getActiveId,
|
|
3919
|
+
resolveSnap: ctx.resolveSnap,
|
|
3920
|
+
snapTo: ctx.snapTo,
|
|
3921
|
+
on: ctx.on
|
|
3922
|
+
})
|
|
3923
|
+
};
|
|
3924
|
+
}
|
|
3925
|
+
function contentSwipeFeature() {
|
|
3926
|
+
return {
|
|
3927
|
+
name: "content-swipe",
|
|
3928
|
+
stage: "attach",
|
|
3929
|
+
install: (ctx) => {
|
|
3930
|
+
if (!ctx.scrollContainer) return;
|
|
3931
|
+
return installContentSwipe({
|
|
3932
|
+
container: ctx.scrollContainer,
|
|
3933
|
+
isDragging: ctx.isDragging,
|
|
3934
|
+
isAnimating: ctx.isAnimating,
|
|
3935
|
+
getAllowedIds: ctx.allowedIdsBySize,
|
|
3936
|
+
getActiveId: ctx.getActiveId,
|
|
3937
|
+
snapTo: ctx.snapTo
|
|
3938
|
+
});
|
|
3939
|
+
}
|
|
3940
|
+
};
|
|
3941
|
+
}
|
|
3942
|
+
function visualViewportFeature() {
|
|
3943
|
+
return {
|
|
3944
|
+
name: "visual-viewport",
|
|
3945
|
+
install: (ctx) => {
|
|
3946
|
+
if (typeof window === "undefined") return;
|
|
3947
|
+
return installVisualViewport({
|
|
3948
|
+
element: ctx.element,
|
|
3949
|
+
isVerticalAxis: ctx.isVerticalAxis,
|
|
3950
|
+
isDestroyed: ctx.isDestroyed,
|
|
3951
|
+
isDragging: ctx.isDragging,
|
|
3952
|
+
recomputeSnaps: ctx.recomputeSnaps,
|
|
3953
|
+
resolveActiveSnap: ctx.resolveActiveSnap,
|
|
3954
|
+
getMaxAxisSize: ctx.getMaxAxisSize,
|
|
3955
|
+
getSize: ctx.getSize,
|
|
3956
|
+
setMaxAxisSize: ctx.setMaxAxisSize,
|
|
3957
|
+
setSize: ctx.setSize,
|
|
3958
|
+
applySize: ctx.applySize,
|
|
3959
|
+
cancelInFlight: ctx.cancelInFlight,
|
|
3960
|
+
newCycle: ctx.newCycle,
|
|
3961
|
+
isAnimating: ctx.isAnimating,
|
|
3962
|
+
resyncAfterCancel: ctx.resyncAfterResize
|
|
3963
|
+
});
|
|
3964
|
+
}
|
|
3965
|
+
};
|
|
3966
|
+
}
|
|
3967
|
+
|
|
3968
|
+
// src/core/default-features.ts
|
|
3969
|
+
function defaultEngineFeatures() {
|
|
3970
|
+
return [
|
|
3971
|
+
contentSwipeFeature(),
|
|
3972
|
+
visualViewportFeature(),
|
|
3973
|
+
persistFeature(),
|
|
3974
|
+
autoCollapseFeature(),
|
|
3975
|
+
routeFeature()
|
|
3976
|
+
];
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
// src/core/BottomSheetEngine.ts
|
|
3980
|
+
var BottomSheetEngine = class extends BottomSheetCore {
|
|
3981
|
+
constructor(opts) {
|
|
3982
|
+
super({
|
|
3983
|
+
...opts,
|
|
3984
|
+
features: [...defaultEngineFeatures(), ...opts.features ?? []]
|
|
3985
|
+
});
|
|
3986
|
+
}
|
|
3987
|
+
};
|
|
3988
|
+
|
|
3725
3989
|
// src/core/lifecycle/sheetManager.ts
|
|
3726
3990
|
var createSheetManager = (initial = {}) => {
|
|
3727
3991
|
const registry = /* @__PURE__ */ new Map();
|
|
@@ -4472,6 +4736,7 @@ var OverlayEngine = class {
|
|
|
4472
4736
|
};
|
|
4473
4737
|
var createOverlay = (opts) => new OverlayEngine(opts);
|
|
4474
4738
|
|
|
4739
|
+
exports.BottomSheetCore = BottomSheetCore;
|
|
4475
4740
|
exports.BottomSheetEngine = BottomSheetEngine;
|
|
4476
4741
|
exports.DEFAULT_SPRING = DEFAULT_SPRING;
|
|
4477
4742
|
exports.OVERLAY_PRESETS = OVERLAY_PRESETS;
|
|
@@ -4481,8 +4746,11 @@ exports.SCRIM_PRESETS = SCRIM_PRESETS;
|
|
|
4481
4746
|
exports.allowedRange = allowedRange;
|
|
4482
4747
|
exports.applyOverlayPosition = applyOverlayPosition;
|
|
4483
4748
|
exports.attachGestures = attachGestures;
|
|
4749
|
+
exports.autoCollapseFeature = autoCollapseFeature;
|
|
4750
|
+
exports.contentSwipeFeature = contentSwipeFeature;
|
|
4484
4751
|
exports.createOverlay = createOverlay;
|
|
4485
4752
|
exports.createSheetManager = createSheetManager;
|
|
4753
|
+
exports.defaultEngineFeatures = defaultEngineFeatures;
|
|
4486
4754
|
exports.easeOutBack = easeOutBack;
|
|
4487
4755
|
exports.easeOutCubic = easeOutCubic;
|
|
4488
4756
|
exports.findById = findById;
|
|
@@ -4490,13 +4758,16 @@ exports.findNearest = findNearest;
|
|
|
4490
4758
|
exports.installFocusTrap = installFocusTrap;
|
|
4491
4759
|
exports.installGestures = installGestures;
|
|
4492
4760
|
exports.lockBodyScroll = lockBodyScroll;
|
|
4761
|
+
exports.persistFeature = persistFeature;
|
|
4493
4762
|
exports.prefersReducedMotion = prefersReducedMotion;
|
|
4494
4763
|
exports.resolveSheetAnchoredStyle = resolveSheetAnchoredStyle;
|
|
4495
4764
|
exports.resolveSnap = resolveSnap;
|
|
4496
4765
|
exports.resolveSnapList = resolveSnapList;
|
|
4766
|
+
exports.routeFeature = routeFeature;
|
|
4497
4767
|
exports.runAnchorTransition = runAnchorTransition;
|
|
4498
4768
|
exports.runSpring = runSpring;
|
|
4499
4769
|
exports.sheetStack = sheetStack;
|
|
4500
4770
|
exports.tween = tween;
|
|
4771
|
+
exports.visualViewportFeature = visualViewportFeature;
|
|
4501
4772
|
//# sourceMappingURL=index.cjs.map
|
|
4502
4773
|
//# sourceMappingURL=index.cjs.map
|