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