@surdeddd/bottom-sheet 0.8.2 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BottomSheetEngine-7BDK2OWX.d.cts → BottomSheetEngine-BcyruNP1.d.cts} +12 -6
- package/dist/{BottomSheetEngine-BFTb0-4Z.d.ts → BottomSheetEngine-CBRcBwV-.d.ts} +12 -6
- package/dist/element.cjs +530 -349
- 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 +530 -349
- package/dist/index.cjs +438 -294
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +438 -294
- 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 +160 -96
- package/dist/overlay.d.cts +2 -0
- package/dist/overlay.d.ts +2 -0
- package/dist/overlay.js +160 -96
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +387 -211
- package/dist/qwik.d.cts +4 -3
- package/dist/qwik.d.ts +4 -3
- package/dist/qwik.js +387 -211
- package/dist/react.cjs +472 -296
- package/dist/react.d.cts +3 -2
- package/dist/react.d.ts +3 -2
- package/dist/react.js +472 -296
- package/dist/solid.cjs +417 -215
- package/dist/solid.d.cts +21 -7
- package/dist/solid.d.ts +21 -7
- package/dist/solid.js +417 -215
- package/dist/solid.source.jsx +412 -209
- package/dist/svelte-core.cjs +328 -209
- package/dist/svelte-core.js +328 -209
- package/dist/svelte-src/BottomSheet.svelte +56 -0
- package/dist/svelte.cjs +365 -210
- package/dist/svelte.d.cts +4 -0
- package/dist/svelte.d.ts +4 -0
- package/dist/svelte.js +365 -210
- package/dist/vue.cjs +358 -211
- package/dist/vue.d.cts +6 -0
- package/dist/vue.d.ts +6 -0
- package/dist/vue.js +358 -211
- package/package.json +6 -6
package/dist/solid.js
CHANGED
|
@@ -265,18 +265,25 @@ var SnapResolver = class {
|
|
|
265
265
|
__publicField(this, "resolved", []);
|
|
266
266
|
__publicField(this, "maxAxisSize", 0);
|
|
267
267
|
__publicField(this, "rangeCache", null);
|
|
268
|
+
__publicField(this, "notified", false);
|
|
268
269
|
this.raw = raw;
|
|
269
270
|
this.allowedIds = allowed ?? raw.map((p) => p.id);
|
|
270
271
|
this.recompute();
|
|
271
272
|
}
|
|
272
273
|
recompute() {
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
const measure = this.measureFit;
|
|
275
|
+
let measured;
|
|
276
|
+
const measureOnce = measure ? () => measured ?? (measured = measure()) : void 0;
|
|
277
|
+
this.resolved = resolveSnapList(this.raw, this.mode, measureOnce);
|
|
278
|
+
const nextMax = this.resolved.reduce(
|
|
275
279
|
(m, s) => s.size > m ? s.size : m,
|
|
276
280
|
0
|
|
277
281
|
);
|
|
278
282
|
this.rangeCache = null;
|
|
279
|
-
this.
|
|
283
|
+
const changed = nextMax !== this.maxAxisSize || !this.notified;
|
|
284
|
+
this.maxAxisSize = nextMax;
|
|
285
|
+
this.notified = true;
|
|
286
|
+
if (changed) this.onMaxAxisSizeChange?.(this.maxAxisSize);
|
|
280
287
|
}
|
|
281
288
|
setRaw(raw) {
|
|
282
289
|
this.raw = raw;
|
|
@@ -429,7 +436,10 @@ var ensureHandler = () => {
|
|
|
429
436
|
target.consumed = true;
|
|
430
437
|
const idx = closers.indexOf(target);
|
|
431
438
|
if (idx !== -1) closers.splice(idx, 1);
|
|
432
|
-
target
|
|
439
|
+
const settled = target;
|
|
440
|
+
void Promise.resolve(settled.close()).then(() => {
|
|
441
|
+
if (settled.isOpen()) settled.restore();
|
|
442
|
+
});
|
|
433
443
|
});
|
|
434
444
|
};
|
|
435
445
|
var programmaticBack = () => {
|
|
@@ -465,16 +475,7 @@ function installRoute(deps) {
|
|
|
465
475
|
pushed = false;
|
|
466
476
|
}
|
|
467
477
|
};
|
|
468
|
-
const
|
|
469
|
-
if (closer) return;
|
|
470
|
-
closer = {
|
|
471
|
-
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
472
|
-
isTop: () => deps.isTopSheet(),
|
|
473
|
-
close: () => void deps.close(),
|
|
474
|
-
consumed: false
|
|
475
|
-
};
|
|
476
|
-
ensureHandler();
|
|
477
|
-
closers.push(closer);
|
|
478
|
+
const pushEntry = () => {
|
|
478
479
|
try {
|
|
479
480
|
if (deps.routedTo !== void 0) {
|
|
480
481
|
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
@@ -486,6 +487,25 @@ function installRoute(deps) {
|
|
|
486
487
|
pushed = false;
|
|
487
488
|
}
|
|
488
489
|
};
|
|
490
|
+
const onOpen = () => {
|
|
491
|
+
if (closer) return;
|
|
492
|
+
const self = {
|
|
493
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
494
|
+
isTop: () => deps.isTopSheet(),
|
|
495
|
+
close: () => deps.close(),
|
|
496
|
+
restore: () => {
|
|
497
|
+
if (deps.isDestroyed() || closer !== self) return;
|
|
498
|
+
self.consumed = false;
|
|
499
|
+
if (!closers.includes(self)) closers.push(self);
|
|
500
|
+
pushEntry();
|
|
501
|
+
},
|
|
502
|
+
consumed: false
|
|
503
|
+
};
|
|
504
|
+
closer = self;
|
|
505
|
+
ensureHandler();
|
|
506
|
+
closers.push(self);
|
|
507
|
+
pushEntry();
|
|
508
|
+
};
|
|
489
509
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
490
510
|
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
491
511
|
if (deps.getSize() > 0) onOpen();
|
|
@@ -532,11 +552,13 @@ var CONTENT_PULL_THRESHOLD = 60;
|
|
|
532
552
|
function installContentSwipe(deps) {
|
|
533
553
|
const { container } = deps;
|
|
534
554
|
let startY = 0;
|
|
555
|
+
let startScrollTop = 0;
|
|
535
556
|
let moved = false;
|
|
536
557
|
const onTouchStart = (e) => {
|
|
537
558
|
const t = e.touches[0];
|
|
538
559
|
if (!t) return;
|
|
539
560
|
startY = t.clientY;
|
|
561
|
+
startScrollTop = container.scrollTop;
|
|
540
562
|
moved = false;
|
|
541
563
|
};
|
|
542
564
|
const onTouchMove = (e) => {
|
|
@@ -547,6 +569,7 @@ function installContentSwipe(deps) {
|
|
|
547
569
|
const onTouchEnd = (e) => {
|
|
548
570
|
if (!moved) return;
|
|
549
571
|
if (deps.isDragging() || deps.isAnimating()) return;
|
|
572
|
+
if (container.scrollTop !== startScrollTop) return;
|
|
550
573
|
const t = e.changedTouches[0];
|
|
551
574
|
if (!t) return;
|
|
552
575
|
const deltaY = t.clientY - startY;
|
|
@@ -658,6 +681,131 @@ function installResizeObserver(deps) {
|
|
|
658
681
|
};
|
|
659
682
|
}
|
|
660
683
|
|
|
684
|
+
// src/core/features/fit-observer.ts
|
|
685
|
+
var contentTargets = (scroller) => {
|
|
686
|
+
if (!scroller) return [];
|
|
687
|
+
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
688
|
+
const out = [];
|
|
689
|
+
for (const child of Array.from(scroller.children)) {
|
|
690
|
+
if (hasSlot && child instanceof HTMLSlotElement) {
|
|
691
|
+
for (const el of child.assignedElements()) out.push(el);
|
|
692
|
+
} else {
|
|
693
|
+
out.push(child);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return out;
|
|
697
|
+
};
|
|
698
|
+
function installFitObserver(deps) {
|
|
699
|
+
if (typeof ResizeObserver === "undefined") return () => {
|
|
700
|
+
};
|
|
701
|
+
if (!deps.hasFitSnap()) return () => {
|
|
702
|
+
};
|
|
703
|
+
let raf = 0;
|
|
704
|
+
const schedule = () => {
|
|
705
|
+
if (raf) return;
|
|
706
|
+
raf = requestAnimationFrame(() => {
|
|
707
|
+
raf = 0;
|
|
708
|
+
if (deps.isDestroyed() || deps.isDragging()) return;
|
|
709
|
+
deps.recompute();
|
|
710
|
+
});
|
|
711
|
+
};
|
|
712
|
+
const ro = new ResizeObserver(schedule);
|
|
713
|
+
ro.observe(deps.handle);
|
|
714
|
+
const scroller = deps.scrollContainer;
|
|
715
|
+
const observed = /* @__PURE__ */ new Set();
|
|
716
|
+
const slots = /* @__PURE__ */ new Set();
|
|
717
|
+
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
718
|
+
const onSlotChange = () => resync();
|
|
719
|
+
const trackSlots = () => {
|
|
720
|
+
if (!scroller || !hasSlot) return;
|
|
721
|
+
for (const child of Array.from(scroller.children)) {
|
|
722
|
+
if (child instanceof HTMLSlotElement && !slots.has(child)) {
|
|
723
|
+
child.addEventListener("slotchange", onSlotChange);
|
|
724
|
+
slots.add(child);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const resync = () => {
|
|
729
|
+
trackSlots();
|
|
730
|
+
const targets = contentTargets(scroller);
|
|
731
|
+
for (const el of observed) {
|
|
732
|
+
if (!targets.includes(el)) {
|
|
733
|
+
ro.unobserve(el);
|
|
734
|
+
observed.delete(el);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
for (const el of targets) {
|
|
738
|
+
if (!observed.has(el)) {
|
|
739
|
+
ro.observe(el);
|
|
740
|
+
observed.add(el);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
schedule();
|
|
744
|
+
};
|
|
745
|
+
let mo;
|
|
746
|
+
if (scroller) {
|
|
747
|
+
resync();
|
|
748
|
+
if (typeof MutationObserver !== "undefined") {
|
|
749
|
+
mo = new MutationObserver(resync);
|
|
750
|
+
mo.observe(scroller, { childList: true });
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
return () => {
|
|
754
|
+
ro.disconnect();
|
|
755
|
+
mo?.disconnect();
|
|
756
|
+
for (const slot of slots) {
|
|
757
|
+
slot.removeEventListener("slotchange", onSlotChange);
|
|
758
|
+
}
|
|
759
|
+
if (raf) cancelAnimationFrame(raf);
|
|
760
|
+
};
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
// src/core/features/fit-measurement.ts
|
|
764
|
+
var measureSheetNatural = (element, content, vertical) => {
|
|
765
|
+
if (!content) {
|
|
766
|
+
return vertical ? element.offsetHeight : element.offsetWidth;
|
|
767
|
+
}
|
|
768
|
+
const axis = vertical ? "height" : "width";
|
|
769
|
+
const sheetStyle = element.style;
|
|
770
|
+
const cs = content.style;
|
|
771
|
+
const prevSheet = sheetStyle[axis];
|
|
772
|
+
const prevFlex = cs.flex;
|
|
773
|
+
const prevContent = vertical ? cs.height : cs.width;
|
|
774
|
+
sheetStyle[axis] = "auto";
|
|
775
|
+
cs.flex = "none";
|
|
776
|
+
if (vertical) cs.height = "auto";
|
|
777
|
+
else cs.width = "auto";
|
|
778
|
+
const poked = vertical ? element.offsetHeight : element.offsetWidth;
|
|
779
|
+
const contentBox = vertical ? content.clientHeight : content.clientWidth;
|
|
780
|
+
const contentScroll = vertical ? content.scrollHeight : content.scrollWidth;
|
|
781
|
+
const natural = Math.max(poked, poked - contentBox + contentScroll);
|
|
782
|
+
sheetStyle[axis] = prevSheet;
|
|
783
|
+
cs.flex = prevFlex;
|
|
784
|
+
if (vertical) cs.height = prevContent;
|
|
785
|
+
else cs.width = prevContent;
|
|
786
|
+
return natural;
|
|
787
|
+
};
|
|
788
|
+
var containingExtent = (element, vertical) => {
|
|
789
|
+
const op = element.offsetParent;
|
|
790
|
+
if (op && op !== document.body && op !== document.documentElement) {
|
|
791
|
+
return vertical ? op.clientHeight : op.clientWidth;
|
|
792
|
+
}
|
|
793
|
+
return vertical ? window.innerHeight : window.innerWidth;
|
|
794
|
+
};
|
|
795
|
+
var measureFitSize = (deps) => {
|
|
796
|
+
const vertical = layoutAxis(deps.mode) === "height";
|
|
797
|
+
const natural = measureSheetNatural(
|
|
798
|
+
deps.element,
|
|
799
|
+
deps.scrollContainer,
|
|
800
|
+
vertical
|
|
801
|
+
);
|
|
802
|
+
const cap = deps.getMaxHeightCap();
|
|
803
|
+
const capped = cap !== void 0 ? Math.min(natural, cap) : natural;
|
|
804
|
+
if (typeof window === "undefined") return capped;
|
|
805
|
+
const viewport = containingExtent(deps.element, vertical);
|
|
806
|
+
return viewport > 0 ? Math.min(capped, viewport) : capped;
|
|
807
|
+
};
|
|
808
|
+
|
|
661
809
|
// src/core/features/slider-keyboard.ts
|
|
662
810
|
function installSliderKeyboard(deps) {
|
|
663
811
|
const isVerticalAxis = deps.mode === "bottom" || deps.mode === "top";
|
|
@@ -1144,6 +1292,9 @@ var ScrimController = class {
|
|
|
1144
1292
|
const s = this.screenComponent.style;
|
|
1145
1293
|
s.opacity = "";
|
|
1146
1294
|
s.display = "";
|
|
1295
|
+
s.position = "";
|
|
1296
|
+
s.inset = "";
|
|
1297
|
+
s.pointerEvents = "";
|
|
1147
1298
|
}
|
|
1148
1299
|
if (this.backdrop) {
|
|
1149
1300
|
this.backdrop.style.opacity = "";
|
|
@@ -1392,7 +1543,12 @@ var AnimationRunner = class {
|
|
|
1392
1543
|
this.currentSpring?.cancel();
|
|
1393
1544
|
}
|
|
1394
1545
|
async animateTo(target, velocityPxPerMs) {
|
|
1395
|
-
if (target === this.getSize())
|
|
1546
|
+
if (target === this.getSize()) {
|
|
1547
|
+
if (!this.isAnimating && !this.isDragging()) {
|
|
1548
|
+
this.element.style.willChange = "";
|
|
1549
|
+
}
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1396
1552
|
this.currentTween?.cancel();
|
|
1397
1553
|
this.currentSpring?.cancel();
|
|
1398
1554
|
this.getRootEl()?.setAttribute("data-animating", "true");
|
|
@@ -1400,7 +1556,7 @@ var AnimationRunner = class {
|
|
|
1400
1556
|
if (this.reducedMotion) {
|
|
1401
1557
|
this.applySizeFn(target);
|
|
1402
1558
|
this.getRootEl()?.removeAttribute("data-animating");
|
|
1403
|
-
if (!this.isDragging()) this.element.style.willChange = "
|
|
1559
|
+
if (!this.isDragging()) this.element.style.willChange = "";
|
|
1404
1560
|
return;
|
|
1405
1561
|
}
|
|
1406
1562
|
if (this.animationKind === "spring") {
|
|
@@ -1428,7 +1584,7 @@ var AnimationRunner = class {
|
|
|
1428
1584
|
}
|
|
1429
1585
|
if (!this.isAnimating) {
|
|
1430
1586
|
this.getRootEl()?.removeAttribute("data-animating");
|
|
1431
|
-
if (!this.isDragging()) this.element.style.willChange = "
|
|
1587
|
+
if (!this.isDragging()) this.element.style.willChange = "";
|
|
1432
1588
|
}
|
|
1433
1589
|
}
|
|
1434
1590
|
destroy() {
|
|
@@ -1459,9 +1615,35 @@ var isVisible = (el) => {
|
|
|
1459
1615
|
}
|
|
1460
1616
|
return el.offsetParent !== null;
|
|
1461
1617
|
};
|
|
1462
|
-
var
|
|
1618
|
+
var collectFocusables = (root) => {
|
|
1619
|
+
const out = Array.from(root.querySelectorAll(FOCUSABLE));
|
|
1620
|
+
if (typeof HTMLSlotElement !== "undefined") {
|
|
1621
|
+
for (const slot of Array.from(root.querySelectorAll("slot"))) {
|
|
1622
|
+
for (const assigned of slot.assignedElements()) {
|
|
1623
|
+
if (assigned.matches(FOCUSABLE)) out.push(assigned);
|
|
1624
|
+
out.push(...collectFocusables(assigned));
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
return out;
|
|
1629
|
+
};
|
|
1630
|
+
var focusables = (root) => collectFocusables(root).filter(
|
|
1463
1631
|
(el) => !el.hasAttribute("inert") && isVisible(el) && !el.matches("[aria-hidden='true']")
|
|
1464
1632
|
);
|
|
1633
|
+
var containsComposed = (container, node) => {
|
|
1634
|
+
let n = node;
|
|
1635
|
+
while (n) {
|
|
1636
|
+
if (n === container) return true;
|
|
1637
|
+
const slot = n.assignedSlot;
|
|
1638
|
+
if (slot) {
|
|
1639
|
+
n = slot;
|
|
1640
|
+
continue;
|
|
1641
|
+
}
|
|
1642
|
+
const parent = n.parentNode;
|
|
1643
|
+
n = parent instanceof ShadowRoot ? parent.host : parent;
|
|
1644
|
+
}
|
|
1645
|
+
return false;
|
|
1646
|
+
};
|
|
1465
1647
|
var trapStack = [];
|
|
1466
1648
|
var installFocusTrap = (container, options = {}) => {
|
|
1467
1649
|
if (typeof document === "undefined") return () => {
|
|
@@ -1471,7 +1653,13 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1471
1653
|
const isActive = () => trapStack[trapStack.length - 1] === token;
|
|
1472
1654
|
const previouslyFocused = document.activeElement;
|
|
1473
1655
|
const focusInitial = () => {
|
|
1474
|
-
const
|
|
1656
|
+
const spec = options.initialFocus;
|
|
1657
|
+
if (spec === false) {
|
|
1658
|
+
if (!container.hasAttribute("tabindex")) container.tabIndex = -1;
|
|
1659
|
+
container.focus({ preventScroll: true });
|
|
1660
|
+
return;
|
|
1661
|
+
}
|
|
1662
|
+
const initial = typeof spec === "string" ? container.querySelector(spec) : spec ?? focusables(container)[0] ?? container;
|
|
1475
1663
|
initial?.focus({ preventScroll: true });
|
|
1476
1664
|
};
|
|
1477
1665
|
focusInitial();
|
|
@@ -1501,7 +1689,7 @@ var installFocusTrap = (container, options = {}) => {
|
|
|
1501
1689
|
const handleFocusIn = (e) => {
|
|
1502
1690
|
if (!isActive()) return;
|
|
1503
1691
|
const target = e.target;
|
|
1504
|
-
if (target && !container
|
|
1692
|
+
if (target && !containsComposed(container, target)) {
|
|
1505
1693
|
const list = focusables(container);
|
|
1506
1694
|
list[0]?.focus({ preventScroll: true });
|
|
1507
1695
|
}
|
|
@@ -1538,8 +1726,14 @@ var lockBodyScroll = () => {
|
|
|
1538
1726
|
position: body.style.position,
|
|
1539
1727
|
top: body.style.top,
|
|
1540
1728
|
width: body.style.width,
|
|
1729
|
+
paddingRight: body.style.paddingRight,
|
|
1541
1730
|
scrollY: window.scrollY
|
|
1542
1731
|
};
|
|
1732
|
+
const scrollbarGap = window.innerWidth - document.documentElement.clientWidth;
|
|
1733
|
+
if (scrollbarGap > 0) {
|
|
1734
|
+
const current = parseFloat(getComputedStyle(body).paddingRight) || 0;
|
|
1735
|
+
body.style.paddingRight = `${current + scrollbarGap}px`;
|
|
1736
|
+
}
|
|
1543
1737
|
body.style.overflow = "hidden";
|
|
1544
1738
|
body.style.position = "fixed";
|
|
1545
1739
|
body.style.top = `-${savedStyles.scrollY}px`;
|
|
@@ -1557,6 +1751,7 @@ var lockBodyScroll = () => {
|
|
|
1557
1751
|
body.style.position = savedStyles.position;
|
|
1558
1752
|
body.style.top = savedStyles.top;
|
|
1559
1753
|
body.style.width = savedStyles.width;
|
|
1754
|
+
body.style.paddingRight = savedStyles.paddingRight;
|
|
1560
1755
|
window.scrollTo(0, savedStyles.scrollY);
|
|
1561
1756
|
savedStyles = null;
|
|
1562
1757
|
}
|
|
@@ -1769,12 +1964,14 @@ var installGestures = (handle, mode, callbacks) => {
|
|
|
1769
1964
|
handle.addEventListener("pointermove", onPointerMove);
|
|
1770
1965
|
handle.addEventListener("pointerup", finishGesture);
|
|
1771
1966
|
handle.addEventListener("pointercancel", onPointerCancel);
|
|
1967
|
+
const prevTouchAction = handle.style.touchAction;
|
|
1772
1968
|
handle.style.touchAction = isAxisVertical(mode) ? "pan-x" : "pan-y";
|
|
1773
1969
|
return () => {
|
|
1774
1970
|
handle.removeEventListener("pointerdown", onPointerDown);
|
|
1775
1971
|
handle.removeEventListener("pointermove", onPointerMove);
|
|
1776
1972
|
handle.removeEventListener("pointerup", finishGesture);
|
|
1777
1973
|
handle.removeEventListener("pointercancel", onPointerCancel);
|
|
1974
|
+
handle.style.touchAction = prevTouchAction;
|
|
1778
1975
|
if (activePointerId !== null && handle.hasPointerCapture(activePointerId)) {
|
|
1779
1976
|
handle.releasePointerCapture(activePointerId);
|
|
1780
1977
|
}
|
|
@@ -1901,7 +2098,7 @@ var GestureController = class {
|
|
|
1901
2098
|
this.isDragging_ = false;
|
|
1902
2099
|
this.keyboardDismissed = false;
|
|
1903
2100
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
1904
|
-
this.deps.element.style.willChange = "
|
|
2101
|
+
this.deps.element.style.willChange = "";
|
|
1905
2102
|
}
|
|
1906
2103
|
};
|
|
1907
2104
|
|
|
@@ -2300,8 +2497,7 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2300
2497
|
};
|
|
2301
2498
|
}
|
|
2302
2499
|
|
|
2303
|
-
// src/core/
|
|
2304
|
-
var HAPTIC_DURATION_MS = 8;
|
|
2500
|
+
// src/core/primitives/teardown-stack.ts
|
|
2305
2501
|
var TeardownStack = class {
|
|
2306
2502
|
constructor() {
|
|
2307
2503
|
__publicField(this, "fns", []);
|
|
@@ -2321,6 +2517,9 @@ var TeardownStack = class {
|
|
|
2321
2517
|
}
|
|
2322
2518
|
}
|
|
2323
2519
|
};
|
|
2520
|
+
|
|
2521
|
+
// src/core/BottomSheetEngine.ts
|
|
2522
|
+
var HAPTIC_DURATION_MS = 8;
|
|
2324
2523
|
var BottomSheetEngine = class {
|
|
2325
2524
|
constructor(opts) {
|
|
2326
2525
|
__publicField(this, "id", nextInstanceId("bs"));
|
|
@@ -2345,6 +2544,7 @@ var BottomSheetEngine = class {
|
|
|
2345
2544
|
__publicField(this, "disableDragFlag");
|
|
2346
2545
|
__publicField(this, "closeOnRouteChange");
|
|
2347
2546
|
__publicField(this, "maxHeightCap");
|
|
2547
|
+
__publicField(this, "maxHeightRaw");
|
|
2348
2548
|
__publicField(this, "snapPointsRaw");
|
|
2349
2549
|
__publicField(this, "snaps");
|
|
2350
2550
|
__publicField(this, "activeId");
|
|
@@ -2380,6 +2580,7 @@ var BottomSheetEngine = class {
|
|
|
2380
2580
|
__publicField(this, "detachScrimStages", null);
|
|
2381
2581
|
__publicField(this, "stackEffectEnabled", false);
|
|
2382
2582
|
__publicField(this, "stackEffectPrimed", false);
|
|
2583
|
+
__publicField(this, "fitDeps");
|
|
2383
2584
|
__publicField(this, "transformTemplate");
|
|
2384
2585
|
const resolved = resolveEngineOptions(opts, {
|
|
2385
2586
|
shouldApplyInertSiblings: () => {
|
|
@@ -2452,12 +2653,19 @@ var BottomSheetEngine = class {
|
|
|
2452
2653
|
}
|
|
2453
2654
|
this.activeId = resolved.initialId;
|
|
2454
2655
|
auditVhUsage(this.snapPointsRaw);
|
|
2656
|
+
this.auditDuplicateSnapIds(this.snapPointsRaw);
|
|
2455
2657
|
this.rootEl = this.element.closest(".bs-root");
|
|
2658
|
+
this.fitDeps = {
|
|
2659
|
+
element: this.element,
|
|
2660
|
+
scrollContainer: this.scrollContainer,
|
|
2661
|
+
mode: this.mode,
|
|
2662
|
+
getMaxHeightCap: () => this.maxHeightCap
|
|
2663
|
+
};
|
|
2456
2664
|
this.snaps = new SnapResolver(
|
|
2457
2665
|
this.snapPointsRaw,
|
|
2458
2666
|
resolved.initialAllowed,
|
|
2459
2667
|
this.mode,
|
|
2460
|
-
() => this.
|
|
2668
|
+
() => measureFitSize(this.fitDeps),
|
|
2461
2669
|
(maxAxisSize) => {
|
|
2462
2670
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2463
2671
|
}
|
|
@@ -2491,7 +2699,18 @@ var BottomSheetEngine = class {
|
|
|
2491
2699
|
io.observe(this.element);
|
|
2492
2700
|
this.teardowns.add(() => io.disconnect());
|
|
2493
2701
|
}
|
|
2494
|
-
this.
|
|
2702
|
+
this.teardowns.add(
|
|
2703
|
+
installFitObserver({
|
|
2704
|
+
handle: this.handle,
|
|
2705
|
+
scrollContainer: this.scrollContainer,
|
|
2706
|
+
hasFitSnap: () => this.snapPointsRaw.some(
|
|
2707
|
+
(p) => p.size === "fit" || p.size === "content"
|
|
2708
|
+
),
|
|
2709
|
+
isDestroyed: () => this.destroyed,
|
|
2710
|
+
isDragging: () => this.gesture?.isDragging ?? false,
|
|
2711
|
+
recompute: () => this.recompute()
|
|
2712
|
+
})
|
|
2713
|
+
);
|
|
2495
2714
|
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2496
2715
|
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2497
2716
|
this.applyAutoAriaLabelledBy();
|
|
@@ -2642,27 +2861,33 @@ var BottomSheetEngine = class {
|
|
|
2642
2861
|
} else {
|
|
2643
2862
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2644
2863
|
}
|
|
2645
|
-
this.opening = false;
|
|
2646
2864
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2647
2865
|
if (signal.aborted) return;
|
|
2648
|
-
this.
|
|
2866
|
+
this.opening = false;
|
|
2867
|
+
this.completeSnap(id, target.size, previousSize, wasClosed, false);
|
|
2868
|
+
}
|
|
2869
|
+
completeSnap(id, targetSize, previousSize, wasClosed, withHaptic) {
|
|
2870
|
+
this.scrollCache.restore(id, previousSize, targetSize);
|
|
2649
2871
|
this.updateAriaSlider();
|
|
2650
2872
|
this.emit("snap", {
|
|
2651
2873
|
id,
|
|
2652
2874
|
size: this.size,
|
|
2653
2875
|
progress: this.computeProgress(this.size)
|
|
2654
2876
|
});
|
|
2655
|
-
if (
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
}
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2877
|
+
if (withHaptic) this.haptic();
|
|
2878
|
+
if (wasClosed && targetSize > 0) this.emitOpenSequence(id);
|
|
2879
|
+
if (targetSize === 0) this.emitCloseSequence();
|
|
2880
|
+
}
|
|
2881
|
+
emitOpenSequence(id) {
|
|
2882
|
+
this.emit("open", { id });
|
|
2883
|
+
this.handleOpen();
|
|
2884
|
+
notifyLinkedSheets(this.linkedSheets, this);
|
|
2885
|
+
this.emit("opened", { id });
|
|
2886
|
+
}
|
|
2887
|
+
emitCloseSequence() {
|
|
2888
|
+
this.emit("close", void 0);
|
|
2889
|
+
this.handleClose();
|
|
2890
|
+
this.emit("closed", void 0);
|
|
2666
2891
|
}
|
|
2667
2892
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
2668
2893
|
if (this.destroyed) return;
|
|
@@ -2683,19 +2908,31 @@ var BottomSheetEngine = class {
|
|
|
2683
2908
|
}
|
|
2684
2909
|
open(id) {
|
|
2685
2910
|
if (this.destroyed) return Promise.resolve();
|
|
2686
|
-
const target = id ?? this.snaps.getAllowedIds().find((a) => a
|
|
2911
|
+
const target = id ?? this.snaps.getAllowedIds().find((a) => (this.snaps.findById(a)?.size ?? 0) > 0) ?? this.activeId;
|
|
2687
2912
|
return this.snapTo(target);
|
|
2688
2913
|
}
|
|
2689
2914
|
close(reason = "programmatic") {
|
|
2690
2915
|
if (this.destroyed) return Promise.resolve();
|
|
2691
2916
|
if (this.disableCloseFlag) return Promise.resolve();
|
|
2692
2917
|
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2693
|
-
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2918
|
+
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds().find((a) => this.snaps.findById(a)?.size === 0) ?? this.snaps.getAllowedIds()[0];
|
|
2694
2919
|
return this.snapTo(closedId ?? this.activeId);
|
|
2695
2920
|
}
|
|
2696
2921
|
canDismiss() {
|
|
2697
2922
|
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2698
2923
|
}
|
|
2924
|
+
setPersistent(value) {
|
|
2925
|
+
if (this.destroyed) return;
|
|
2926
|
+
this.persistent = value;
|
|
2927
|
+
}
|
|
2928
|
+
setDisableClose(value) {
|
|
2929
|
+
if (this.destroyed) return;
|
|
2930
|
+
this.disableCloseFlag = value;
|
|
2931
|
+
}
|
|
2932
|
+
setDisableDrag(value) {
|
|
2933
|
+
if (this.destroyed) return;
|
|
2934
|
+
this.disableDragFlag = value;
|
|
2935
|
+
}
|
|
2699
2936
|
isTop() {
|
|
2700
2937
|
return this.isTopSheet;
|
|
2701
2938
|
}
|
|
@@ -2732,18 +2969,23 @@ var BottomSheetEngine = class {
|
|
|
2732
2969
|
axis === "height" ? "max-height" : "max-width",
|
|
2733
2970
|
value
|
|
2734
2971
|
);
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2745
|
-
this.recompute();
|
|
2972
|
+
this.maxHeightRaw = h;
|
|
2973
|
+
this.resolveMaxHeightCap();
|
|
2974
|
+
this.recompute();
|
|
2975
|
+
}
|
|
2976
|
+
resolveMaxHeightCap() {
|
|
2977
|
+
const raw = this.maxHeightRaw;
|
|
2978
|
+
if (raw === void 0) {
|
|
2979
|
+
this.maxHeightCap = void 0;
|
|
2980
|
+
return;
|
|
2746
2981
|
}
|
|
2982
|
+
if (typeof raw === "number") {
|
|
2983
|
+
this.maxHeightCap = raw;
|
|
2984
|
+
return;
|
|
2985
|
+
}
|
|
2986
|
+
if (typeof window === "undefined") return;
|
|
2987
|
+
const measured = resolveSnap(raw, this.mode);
|
|
2988
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2747
2989
|
}
|
|
2748
2990
|
clampToMaxHeight() {
|
|
2749
2991
|
if (this.maxHeightCap === void 0) return;
|
|
@@ -2874,6 +3116,7 @@ var BottomSheetEngine = class {
|
|
|
2874
3116
|
this.newCycle();
|
|
2875
3117
|
this.snapPointsRaw = points;
|
|
2876
3118
|
auditVhUsage(points);
|
|
3119
|
+
this.auditDuplicateSnapIds(points);
|
|
2877
3120
|
this.snaps.setRaw(points);
|
|
2878
3121
|
if (allowed) this.snaps.setAllowedIds(allowed);
|
|
2879
3122
|
this.scrollCache.clear();
|
|
@@ -2886,6 +3129,7 @@ var BottomSheetEngine = class {
|
|
|
2886
3129
|
}
|
|
2887
3130
|
recompute() {
|
|
2888
3131
|
if (this.destroyed) return;
|
|
3132
|
+
this.resolveMaxHeightCap();
|
|
2889
3133
|
this.snaps.recompute();
|
|
2890
3134
|
this.clampToMaxHeight();
|
|
2891
3135
|
this.scrim.invalidateOpacityCache();
|
|
@@ -2897,129 +3141,6 @@ var BottomSheetEngine = class {
|
|
|
2897
3141
|
this.updateAriaSlider();
|
|
2898
3142
|
}
|
|
2899
3143
|
}
|
|
2900
|
-
contentTargets() {
|
|
2901
|
-
const scroller = this.scrollContainer;
|
|
2902
|
-
if (!scroller) return [];
|
|
2903
|
-
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
2904
|
-
const out = [];
|
|
2905
|
-
for (const child of Array.from(scroller.children)) {
|
|
2906
|
-
if (hasSlot && child instanceof HTMLSlotElement) {
|
|
2907
|
-
for (const el of child.assignedElements()) out.push(el);
|
|
2908
|
-
} else {
|
|
2909
|
-
out.push(child);
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
return out;
|
|
2913
|
-
}
|
|
2914
|
-
measureSheetNatural(vertical) {
|
|
2915
|
-
const el = this.element;
|
|
2916
|
-
const content = this.scrollContainer;
|
|
2917
|
-
if (!content) {
|
|
2918
|
-
return vertical ? el.offsetHeight : el.offsetWidth;
|
|
2919
|
-
}
|
|
2920
|
-
const axis = vertical ? "height" : "width";
|
|
2921
|
-
const sheetStyle = el.style;
|
|
2922
|
-
const cs = content.style;
|
|
2923
|
-
const prevSheet = sheetStyle[axis];
|
|
2924
|
-
const prevFlex = cs.flex;
|
|
2925
|
-
const prevContent = vertical ? cs.height : cs.width;
|
|
2926
|
-
sheetStyle[axis] = "auto";
|
|
2927
|
-
cs.flex = "none";
|
|
2928
|
-
if (vertical) cs.height = "auto";
|
|
2929
|
-
else cs.width = "auto";
|
|
2930
|
-
const poked = vertical ? el.offsetHeight : el.offsetWidth;
|
|
2931
|
-
const contentBox = vertical ? content.clientHeight : content.clientWidth;
|
|
2932
|
-
const contentScroll = vertical ? content.scrollHeight : content.scrollWidth;
|
|
2933
|
-
const natural = Math.max(poked, poked - contentBox + contentScroll);
|
|
2934
|
-
sheetStyle[axis] = prevSheet;
|
|
2935
|
-
cs.flex = prevFlex;
|
|
2936
|
-
if (vertical) cs.height = prevContent;
|
|
2937
|
-
else cs.width = prevContent;
|
|
2938
|
-
return natural;
|
|
2939
|
-
}
|
|
2940
|
-
measureFitSize() {
|
|
2941
|
-
const vertical = layoutAxis(this.mode) === "height";
|
|
2942
|
-
const natural = this.measureSheetNatural(vertical);
|
|
2943
|
-
const capped = this.maxHeightCap !== void 0 ? Math.min(natural, this.maxHeightCap) : natural;
|
|
2944
|
-
if (typeof window === "undefined") return capped;
|
|
2945
|
-
const viewport = this.containingExtent(vertical);
|
|
2946
|
-
return viewport > 0 ? Math.min(capped, viewport) : capped;
|
|
2947
|
-
}
|
|
2948
|
-
// The fit cap is the sheet's containing block, not always the window: a
|
|
2949
|
-
// position:fixed sheet nested under a transform/filter/will-change ancestor
|
|
2950
|
-
// is clipped to that ancestor, so capping by window.innerHeight oversizes the
|
|
2951
|
-
// sheet and the content/footer get clipped. offsetParent resolves to that
|
|
2952
|
-
// ancestor when present, and is null (→ viewport) for a plain fixed sheet.
|
|
2953
|
-
containingExtent(vertical) {
|
|
2954
|
-
const op = this.element.offsetParent;
|
|
2955
|
-
if (op && op !== document.body && op !== document.documentElement) {
|
|
2956
|
-
return vertical ? op.clientHeight : op.clientWidth;
|
|
2957
|
-
}
|
|
2958
|
-
return vertical ? window.innerHeight : window.innerWidth;
|
|
2959
|
-
}
|
|
2960
|
-
installFitObserver() {
|
|
2961
|
-
if (typeof ResizeObserver === "undefined") return;
|
|
2962
|
-
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2963
|
-
return;
|
|
2964
|
-
let raf = 0;
|
|
2965
|
-
const schedule = () => {
|
|
2966
|
-
if (raf) return;
|
|
2967
|
-
raf = requestAnimationFrame(() => {
|
|
2968
|
-
raf = 0;
|
|
2969
|
-
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2970
|
-
this.recompute();
|
|
2971
|
-
});
|
|
2972
|
-
};
|
|
2973
|
-
const ro = new ResizeObserver(schedule);
|
|
2974
|
-
ro.observe(this.handle);
|
|
2975
|
-
const scroller = this.scrollContainer;
|
|
2976
|
-
const observed = /* @__PURE__ */ new Set();
|
|
2977
|
-
const slots = /* @__PURE__ */ new Set();
|
|
2978
|
-
const hasSlot = typeof HTMLSlotElement !== "undefined";
|
|
2979
|
-
const onSlotChange = () => resync();
|
|
2980
|
-
const trackSlots = () => {
|
|
2981
|
-
if (!scroller || !hasSlot) return;
|
|
2982
|
-
for (const child of Array.from(scroller.children)) {
|
|
2983
|
-
if (child instanceof HTMLSlotElement && !slots.has(child)) {
|
|
2984
|
-
child.addEventListener("slotchange", onSlotChange);
|
|
2985
|
-
slots.add(child);
|
|
2986
|
-
}
|
|
2987
|
-
}
|
|
2988
|
-
};
|
|
2989
|
-
const resync = () => {
|
|
2990
|
-
trackSlots();
|
|
2991
|
-
const targets = this.contentTargets();
|
|
2992
|
-
for (const el of observed) {
|
|
2993
|
-
if (!targets.includes(el)) {
|
|
2994
|
-
ro.unobserve(el);
|
|
2995
|
-
observed.delete(el);
|
|
2996
|
-
}
|
|
2997
|
-
}
|
|
2998
|
-
for (const el of targets) {
|
|
2999
|
-
if (!observed.has(el)) {
|
|
3000
|
-
ro.observe(el);
|
|
3001
|
-
observed.add(el);
|
|
3002
|
-
}
|
|
3003
|
-
}
|
|
3004
|
-
schedule();
|
|
3005
|
-
};
|
|
3006
|
-
let mo;
|
|
3007
|
-
if (scroller) {
|
|
3008
|
-
resync();
|
|
3009
|
-
if (typeof MutationObserver !== "undefined") {
|
|
3010
|
-
mo = new MutationObserver(resync);
|
|
3011
|
-
mo.observe(scroller, { childList: true });
|
|
3012
|
-
}
|
|
3013
|
-
}
|
|
3014
|
-
this.teardowns.add(() => {
|
|
3015
|
-
ro.disconnect();
|
|
3016
|
-
mo?.disconnect();
|
|
3017
|
-
for (const slot of slots) {
|
|
3018
|
-
slot.removeEventListener("slotchange", onSlotChange);
|
|
3019
|
-
}
|
|
3020
|
-
if (raf) cancelAnimationFrame(raf);
|
|
3021
|
-
});
|
|
3022
|
-
}
|
|
3023
3144
|
destroy() {
|
|
3024
3145
|
this.destroyed = true;
|
|
3025
3146
|
this.opening = false;
|
|
@@ -3037,9 +3158,10 @@ var BottomSheetEngine = class {
|
|
|
3037
3158
|
this.backdrop.style.opacity = "";
|
|
3038
3159
|
this.backdrop.style.pointerEvents = "";
|
|
3039
3160
|
}
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3161
|
+
for (const host of [this.anchorHost, this.scrimParent, this.rootEl]) {
|
|
3162
|
+
if (!host) continue;
|
|
3163
|
+
host.style.removeProperty("--bs-size");
|
|
3164
|
+
host.style.removeProperty("--bs-progress");
|
|
3043
3165
|
}
|
|
3044
3166
|
if (this.screenComponent) {
|
|
3045
3167
|
this.screenComponent.style.opacity = "";
|
|
@@ -3053,6 +3175,7 @@ var BottomSheetEngine = class {
|
|
|
3053
3175
|
}
|
|
3054
3176
|
newCycle() {
|
|
3055
3177
|
this.allowOvershoot = false;
|
|
3178
|
+
this.opening = false;
|
|
3056
3179
|
this.currentAbort.abort();
|
|
3057
3180
|
this.currentAbort = new AbortController();
|
|
3058
3181
|
return this.currentAbort.signal;
|
|
@@ -3108,8 +3231,14 @@ var BottomSheetEngine = class {
|
|
|
3108
3231
|
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3109
3232
|
}
|
|
3110
3233
|
recomputeSnaps() {
|
|
3234
|
+
this.resolveMaxHeightCap();
|
|
3235
|
+
this.snaps.setRaw(this.snapPointsRaw);
|
|
3236
|
+
this.clampToMaxHeight();
|
|
3237
|
+
this.scrim.invalidateOpacityCache();
|
|
3238
|
+
}
|
|
3239
|
+
auditDuplicateSnapIds(points) {
|
|
3111
3240
|
const seen = /* @__PURE__ */ new Set();
|
|
3112
|
-
for (const p of
|
|
3241
|
+
for (const p of points) {
|
|
3113
3242
|
if (seen.has(p.id)) {
|
|
3114
3243
|
console.warn(
|
|
3115
3244
|
`[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
|
|
@@ -3117,9 +3246,6 @@ var BottomSheetEngine = class {
|
|
|
3117
3246
|
}
|
|
3118
3247
|
seen.add(p.id);
|
|
3119
3248
|
}
|
|
3120
|
-
this.snaps.setRaw(this.snapPointsRaw);
|
|
3121
|
-
this.clampToMaxHeight();
|
|
3122
|
-
this.scrim.invalidateOpacityCache();
|
|
3123
3249
|
}
|
|
3124
3250
|
getAllowedRange() {
|
|
3125
3251
|
return this.snaps.getAllowedRange();
|
|
@@ -3307,9 +3433,15 @@ var BottomSheetEngine = class {
|
|
|
3307
3433
|
flickVelocity: this.flickVelocity,
|
|
3308
3434
|
dragThreshold: this.dragThreshold
|
|
3309
3435
|
});
|
|
3310
|
-
if (!target)
|
|
3436
|
+
if (!target) {
|
|
3437
|
+
this.clearWillChangeIfIdle();
|
|
3438
|
+
return;
|
|
3439
|
+
}
|
|
3311
3440
|
const previousId = this.activeId;
|
|
3312
|
-
if (target.id === previousId && target.size === this.size)
|
|
3441
|
+
if (target.id === previousId && target.size === this.size) {
|
|
3442
|
+
this.clearWillChangeIfIdle();
|
|
3443
|
+
return;
|
|
3444
|
+
}
|
|
3313
3445
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
3314
3446
|
const restore = this.snaps.findById(previousId);
|
|
3315
3447
|
if (restore) {
|
|
@@ -3332,27 +3464,19 @@ var BottomSheetEngine = class {
|
|
|
3332
3464
|
if (signal.aborted) return;
|
|
3333
3465
|
this.allowOvershoot = false;
|
|
3334
3466
|
this.opening = false;
|
|
3335
|
-
this.
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
this.haptic();
|
|
3343
|
-
if (previousSnapSize === 0 && target.size > 0) {
|
|
3344
|
-
this.emit("open", { id: target.id });
|
|
3345
|
-
this.handleOpen();
|
|
3346
|
-
notifyLinkedSheets(this.linkedSheets, this);
|
|
3347
|
-
this.emit("opened", { id: target.id });
|
|
3348
|
-
}
|
|
3349
|
-
if (target.size === 0) {
|
|
3350
|
-
this.emit("close", void 0);
|
|
3351
|
-
this.handleClose();
|
|
3352
|
-
this.emit("closed", void 0);
|
|
3353
|
-
}
|
|
3467
|
+
this.completeSnap(
|
|
3468
|
+
target.id,
|
|
3469
|
+
target.size,
|
|
3470
|
+
previousSize,
|
|
3471
|
+
previousSnapSize === 0,
|
|
3472
|
+
true
|
|
3473
|
+
);
|
|
3354
3474
|
});
|
|
3355
3475
|
}
|
|
3476
|
+
clearWillChangeIfIdle() {
|
|
3477
|
+
if (this.animation.isAnimating || this.gesture?.isDragging) return;
|
|
3478
|
+
this.element.style.willChange = "";
|
|
3479
|
+
}
|
|
3356
3480
|
haptic() {
|
|
3357
3481
|
if (typeof navigator !== "undefined" && "vibrate" in navigator) {
|
|
3358
3482
|
try {
|
|
@@ -3433,14 +3557,9 @@ var BottomSheetEngine = class {
|
|
|
3433
3557
|
progress: this.computeProgress(this.size)
|
|
3434
3558
|
});
|
|
3435
3559
|
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3436
|
-
this.
|
|
3437
|
-
this.handleOpen();
|
|
3438
|
-
notifyLinkedSheets(this.linkedSheets, this);
|
|
3439
|
-
this.emit("opened", { id: target.id });
|
|
3560
|
+
this.emitOpenSequence(target.id);
|
|
3440
3561
|
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3441
|
-
this.
|
|
3442
|
-
this.handleClose();
|
|
3443
|
-
this.emit("closed", void 0);
|
|
3562
|
+
this.emitCloseSequence();
|
|
3444
3563
|
}
|
|
3445
3564
|
}
|
|
3446
3565
|
handleClose() {
|
|
@@ -3450,11 +3569,45 @@ var BottomSheetEngine = class {
|
|
|
3450
3569
|
}
|
|
3451
3570
|
};
|
|
3452
3571
|
|
|
3572
|
+
// src/core/features/teleport.ts
|
|
3573
|
+
var resolveTeleportTarget = (target) => {
|
|
3574
|
+
if (!target) return null;
|
|
3575
|
+
if (typeof target !== "string") return target;
|
|
3576
|
+
if (typeof document === "undefined") return null;
|
|
3577
|
+
if (target === "body") return document.body;
|
|
3578
|
+
return document.querySelector(target);
|
|
3579
|
+
};
|
|
3580
|
+
var teleportElements = (els, target) => {
|
|
3581
|
+
const records = [];
|
|
3582
|
+
for (const el of els) {
|
|
3583
|
+
if (!el || el.parentNode === target) continue;
|
|
3584
|
+
records.push({ el, parent: el.parentNode, next: el.nextSibling });
|
|
3585
|
+
target.appendChild(el);
|
|
3586
|
+
}
|
|
3587
|
+
return () => {
|
|
3588
|
+
for (let i = records.length - 1; i >= 0; i--) {
|
|
3589
|
+
const { el, parent, next } = records[i];
|
|
3590
|
+
if (parent && parent.isConnected) {
|
|
3591
|
+
const before = next && next.parentNode === parent ? next : null;
|
|
3592
|
+
try {
|
|
3593
|
+
parent.insertBefore(el, before);
|
|
3594
|
+
} catch {
|
|
3595
|
+
el.parentNode?.removeChild(el);
|
|
3596
|
+
}
|
|
3597
|
+
} else {
|
|
3598
|
+
el.parentNode?.removeChild(el);
|
|
3599
|
+
}
|
|
3600
|
+
}
|
|
3601
|
+
};
|
|
3602
|
+
};
|
|
3603
|
+
|
|
3453
3604
|
// src/solid/index.tsx
|
|
3454
3605
|
var _tmpl$ = /* @__PURE__ */ template(`<div class=bs-header>`);
|
|
3455
3606
|
var _tmpl$2 = /* @__PURE__ */ template(`<div class=bs-footer>`);
|
|
3456
|
-
var _tmpl$3 = /* @__PURE__ */ template(`<div class=bs-
|
|
3457
|
-
var _tmpl$4 = /* @__PURE__ */ template(`<div class=bs-
|
|
3607
|
+
var _tmpl$3 = /* @__PURE__ */ template(`<div class=bs-button-slot data-side=left>`);
|
|
3608
|
+
var _tmpl$4 = /* @__PURE__ */ template(`<div class=bs-button-slot data-side=right>`);
|
|
3609
|
+
var _tmpl$5 = /* @__PURE__ */ template(`<div class=bs-root><div class=bs-screen></div><section class=bs-sheet role=dialog><div class=bs-handle role=slider tabindex=0 aria-label="Resize sheet"></div><div class=bs-content tabindex=0 role=region aria-label="Sheet content"></div><span class=bs-sr-only role=status aria-live=polite>`);
|
|
3610
|
+
var _tmpl$6 = /* @__PURE__ */ template(`<div class=bs-backdrop>`);
|
|
3458
3611
|
var BottomSheet = (props) => {
|
|
3459
3612
|
let sheetEl;
|
|
3460
3613
|
let handleEl;
|
|
@@ -3470,6 +3623,7 @@ var BottomSheet = (props) => {
|
|
|
3470
3623
|
progress: 0
|
|
3471
3624
|
});
|
|
3472
3625
|
let engine = null;
|
|
3626
|
+
let restoreTeleport = null;
|
|
3473
3627
|
onMount(() => {
|
|
3474
3628
|
if (!sheetEl) return;
|
|
3475
3629
|
const engineOpts = {
|
|
@@ -3496,10 +3650,15 @@ var BottomSheet = (props) => {
|
|
|
3496
3650
|
disableClose: props.disableClose,
|
|
3497
3651
|
disableDrag: props.disableDrag,
|
|
3498
3652
|
closeOnRouteChange: props.closeOnRouteChange,
|
|
3653
|
+
stackEffect: props.stackEffect,
|
|
3499
3654
|
returnFocusTo: props.returnFocusTo
|
|
3500
3655
|
};
|
|
3501
3656
|
engine = new BottomSheetEngine(engineOpts);
|
|
3502
3657
|
props.engineRef?.(engine);
|
|
3658
|
+
const teleportTarget = props.teleport === false ? null : resolveTeleportTarget(props.teleportTo);
|
|
3659
|
+
if (teleportTarget) {
|
|
3660
|
+
restoreTeleport = teleportElements([backdropEl, scrimEl, sheetEl], teleportTarget);
|
|
3661
|
+
}
|
|
3503
3662
|
const sync = () => {
|
|
3504
3663
|
if (!engine) return;
|
|
3505
3664
|
const s = engine.state;
|
|
@@ -3513,6 +3672,7 @@ var BottomSheet = (props) => {
|
|
|
3513
3672
|
sync();
|
|
3514
3673
|
props.onSnap?.(payload.id);
|
|
3515
3674
|
});
|
|
3675
|
+
engine.on("before-snap", (payload) => props.onBeforeSnap?.(payload));
|
|
3516
3676
|
engine.on("dragstart", sync);
|
|
3517
3677
|
engine.on("dragend", sync);
|
|
3518
3678
|
if (props.backdrop !== false && props.closeOnBackdrop !== false && backdropEl) {
|
|
@@ -3526,6 +3686,8 @@ var BottomSheet = (props) => {
|
|
|
3526
3686
|
}
|
|
3527
3687
|
});
|
|
3528
3688
|
onCleanup(() => {
|
|
3689
|
+
restoreTeleport?.();
|
|
3690
|
+
restoreTeleport = null;
|
|
3529
3691
|
engine?.destroy();
|
|
3530
3692
|
engine = null;
|
|
3531
3693
|
props.engineRef?.(null);
|
|
@@ -3542,17 +3704,35 @@ var BottomSheet = (props) => {
|
|
|
3542
3704
|
}, {
|
|
3543
3705
|
defer: true
|
|
3544
3706
|
}));
|
|
3707
|
+
createEffect(on(() => props.persistent, (value, prev) => {
|
|
3708
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
3709
|
+
engine.setPersistent(value);
|
|
3710
|
+
}, {
|
|
3711
|
+
defer: true
|
|
3712
|
+
}));
|
|
3713
|
+
createEffect(on(() => props.disableClose, (value, prev) => {
|
|
3714
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
3715
|
+
engine.setDisableClose(value);
|
|
3716
|
+
}, {
|
|
3717
|
+
defer: true
|
|
3718
|
+
}));
|
|
3719
|
+
createEffect(on(() => props.disableDrag, (value, prev) => {
|
|
3720
|
+
if (!engine || prev === void 0 || value === void 0) return;
|
|
3721
|
+
engine.setDisableDrag(value);
|
|
3722
|
+
}, {
|
|
3723
|
+
defer: true
|
|
3724
|
+
}));
|
|
3545
3725
|
const showBackdrop = createMemo(() => props.backdrop !== false);
|
|
3546
3726
|
const mode = createMemo(() => props.mode ?? "bottom");
|
|
3547
3727
|
const ariaLabel = createMemo(() => props.ariaLabel ?? "Bottom sheet");
|
|
3548
3728
|
return (() => {
|
|
3549
|
-
var _el$ = _tmpl$
|
|
3729
|
+
var _el$ = _tmpl$5(), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$6 = _el$4.nextSibling, _el$8 = _el$6.nextSibling;
|
|
3550
3730
|
insert(_el$, (() => {
|
|
3551
3731
|
var _c$ = memo(() => !!showBackdrop());
|
|
3552
3732
|
return () => _c$() ? (() => {
|
|
3553
|
-
var _el$
|
|
3554
|
-
use((el) => backdropEl = el, _el$
|
|
3555
|
-
return _el$
|
|
3733
|
+
var _el$1 = _tmpl$6();
|
|
3734
|
+
use((el) => backdropEl = el, _el$1);
|
|
3735
|
+
return _el$1;
|
|
3556
3736
|
})() : null;
|
|
3557
3737
|
})(), _el$2);
|
|
3558
3738
|
use((el) => scrimEl = el, _el$2);
|
|
@@ -3582,6 +3762,28 @@ var BottomSheet = (props) => {
|
|
|
3582
3762
|
}
|
|
3583
3763
|
}), _el$8);
|
|
3584
3764
|
insert(_el$8, () => state().activeId);
|
|
3765
|
+
insert(_el$, createComponent(Show, {
|
|
3766
|
+
get when() {
|
|
3767
|
+
return props.leftButton;
|
|
3768
|
+
},
|
|
3769
|
+
get children() {
|
|
3770
|
+
var _el$9 = _tmpl$3();
|
|
3771
|
+
insert(_el$9, () => props.leftButton);
|
|
3772
|
+
effect(() => setAttribute(_el$9, "data-mode", mode()));
|
|
3773
|
+
return _el$9;
|
|
3774
|
+
}
|
|
3775
|
+
}), null);
|
|
3776
|
+
insert(_el$, createComponent(Show, {
|
|
3777
|
+
get when() {
|
|
3778
|
+
return props.rightButton;
|
|
3779
|
+
},
|
|
3780
|
+
get children() {
|
|
3781
|
+
var _el$0 = _tmpl$4();
|
|
3782
|
+
insert(_el$0, () => props.rightButton);
|
|
3783
|
+
effect(() => setAttribute(_el$0, "data-mode", mode()));
|
|
3784
|
+
return _el$0;
|
|
3785
|
+
}
|
|
3786
|
+
}), null);
|
|
3585
3787
|
effect((_p$) => {
|
|
3586
3788
|
var _v$ = mode(), _v$2 = state().activeId, _v$3 = props.focusTrap ? "true" : void 0, _v$4 = ariaLabel();
|
|
3587
3789
|
_v$ !== _p$.e && setAttribute(_el$3, "data-mode", _p$.e = _v$);
|