@surdeddd/bottom-sheet 0.8.1 → 0.9.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/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 +365 -217
- package/dist/vue.d.cts +6 -0
- package/dist/vue.d.ts +6 -0
- package/dist/vue.js +365 -217
- package/package.json +6 -6
package/dist/qwik.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
|
-
|
|
2745
|
-
|
|
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;
|
|
2981
|
+
}
|
|
2982
|
+
if (typeof raw === "number") {
|
|
2983
|
+
this.maxHeightCap = raw;
|
|
2984
|
+
return;
|
|
2746
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() {
|
|
@@ -3457,6 +3576,8 @@ var BottomSheet = component$((props) => {
|
|
|
3457
3576
|
const scrimRef = useSignal();
|
|
3458
3577
|
const headerRef = useSignal();
|
|
3459
3578
|
const footerRef = useSignal();
|
|
3579
|
+
const leftBtnRef = useSignal();
|
|
3580
|
+
const rightBtnRef = useSignal();
|
|
3460
3581
|
const initialActive = props.initial ?? props.snapPoints[0]?.id ?? "default";
|
|
3461
3582
|
const state = useStore({
|
|
3462
3583
|
size: 0,
|
|
@@ -3495,6 +3616,7 @@ var BottomSheet = component$((props) => {
|
|
|
3495
3616
|
disableClose: props.disableClose,
|
|
3496
3617
|
disableDrag: props.disableDrag,
|
|
3497
3618
|
closeOnRouteChange: props.closeOnRouteChange,
|
|
3619
|
+
stackEffect: props.stackEffect,
|
|
3498
3620
|
returnFocusTo: props.returnFocusTo,
|
|
3499
3621
|
radius: props.radius,
|
|
3500
3622
|
maxHeight: props.maxHeight
|
|
@@ -3530,9 +3652,33 @@ var BottomSheet = component$((props) => {
|
|
|
3530
3652
|
if (empty) el.setAttribute("hidden", "");
|
|
3531
3653
|
else el.removeAttribute("hidden");
|
|
3532
3654
|
};
|
|
3533
|
-
|
|
3534
|
-
|
|
3655
|
+
const collapseBoth = () => {
|
|
3656
|
+
collapseEmpty(headerRef.value);
|
|
3657
|
+
collapseEmpty(footerRef.value);
|
|
3658
|
+
collapseEmpty(leftBtnRef.value);
|
|
3659
|
+
collapseEmpty(rightBtnRef.value);
|
|
3660
|
+
};
|
|
3661
|
+
collapseBoth();
|
|
3662
|
+
let slotObserver;
|
|
3663
|
+
if (typeof MutationObserver !== "undefined") {
|
|
3664
|
+
slotObserver = new MutationObserver(collapseBoth);
|
|
3665
|
+
for (const el of [
|
|
3666
|
+
headerRef.value,
|
|
3667
|
+
footerRef.value,
|
|
3668
|
+
leftBtnRef.value,
|
|
3669
|
+
rightBtnRef.value
|
|
3670
|
+
]) {
|
|
3671
|
+
if (el) {
|
|
3672
|
+
slotObserver.observe(el, {
|
|
3673
|
+
childList: true,
|
|
3674
|
+
subtree: true,
|
|
3675
|
+
characterData: true
|
|
3676
|
+
});
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
}
|
|
3535
3680
|
cleanup(() => {
|
|
3681
|
+
slotObserver?.disconnect();
|
|
3536
3682
|
if (onBackdropClick && backdropRef.value) {
|
|
3537
3683
|
backdropRef.value.removeEventListener("click", onBackdropClick);
|
|
3538
3684
|
}
|
|
@@ -3558,6 +3704,16 @@ var BottomSheet = component$((props) => {
|
|
|
3558
3704
|
if (radius !== void 0) engine.setRadius(radius);
|
|
3559
3705
|
if (maxHeight !== void 0) engine.setMaxHeight(maxHeight);
|
|
3560
3706
|
});
|
|
3707
|
+
useTask$(({ track }) => {
|
|
3708
|
+
const persistent = track(() => props.persistent);
|
|
3709
|
+
const disableClose = track(() => props.disableClose);
|
|
3710
|
+
const disableDrag = track(() => props.disableDrag);
|
|
3711
|
+
const engine = engineStore.engine;
|
|
3712
|
+
if (!engine) return;
|
|
3713
|
+
if (persistent !== void 0) engine.setPersistent(persistent);
|
|
3714
|
+
if (disableClose !== void 0) engine.setDisableClose(disableClose);
|
|
3715
|
+
if (disableDrag !== void 0) engine.setDisableDrag(disableDrag);
|
|
3716
|
+
});
|
|
3561
3717
|
const showBackdrop = props.backdrop !== false;
|
|
3562
3718
|
const mode = props.mode ?? "bottom";
|
|
3563
3719
|
const ariaLabel = props.ariaLabel ?? "Bottom sheet";
|
|
@@ -3591,6 +3747,26 @@ var BottomSheet = component$((props) => {
|
|
|
3591
3747
|
/* @__PURE__ */ jsx("span", { class: "bs-sr-only", role: "status", "aria-live": "polite", children: state.activeId })
|
|
3592
3748
|
]
|
|
3593
3749
|
}
|
|
3750
|
+
),
|
|
3751
|
+
/* @__PURE__ */ jsx(
|
|
3752
|
+
"div",
|
|
3753
|
+
{
|
|
3754
|
+
class: "bs-button-slot",
|
|
3755
|
+
"data-side": "left",
|
|
3756
|
+
"data-mode": mode,
|
|
3757
|
+
ref: leftBtnRef,
|
|
3758
|
+
children: /* @__PURE__ */ jsx(Slot, { name: "leftButton" })
|
|
3759
|
+
}
|
|
3760
|
+
),
|
|
3761
|
+
/* @__PURE__ */ jsx(
|
|
3762
|
+
"div",
|
|
3763
|
+
{
|
|
3764
|
+
class: "bs-button-slot",
|
|
3765
|
+
"data-side": "right",
|
|
3766
|
+
"data-mode": mode,
|
|
3767
|
+
ref: rightBtnRef,
|
|
3768
|
+
children: /* @__PURE__ */ jsx(Slot, { name: "rightButton" })
|
|
3769
|
+
}
|
|
3594
3770
|
)
|
|
3595
3771
|
] });
|
|
3596
3772
|
});
|