@surdeddd/bottom-sheet 0.9.1 → 0.11.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.
Files changed (50) hide show
  1. package/README.md +126 -83
  2. package/dist/{BottomSheetEngine-CBRcBwV-.d.ts → BottomSheetEngine-DRjCU73e.d.ts} +6 -5
  3. package/dist/{BottomSheetEngine-BcyruNP1.d.cts → BottomSheetEngine-DzsIwD28.d.cts} +6 -5
  4. package/dist/element.cjs +388 -222
  5. package/dist/element.d.cts +1 -1
  6. package/dist/element.d.ts +1 -1
  7. package/dist/element.iife.global.js +2 -2
  8. package/dist/element.js +388 -222
  9. package/dist/index.cjs +389 -266
  10. package/dist/index.d.cts +2 -2
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +389 -266
  13. package/dist/integrations/formik.d.cts +1 -1
  14. package/dist/integrations/formik.d.ts +1 -1
  15. package/dist/integrations/react-hook-form.d.cts +1 -1
  16. package/dist/integrations/react-hook-form.d.ts +1 -1
  17. package/dist/overlay.cjs +191 -58
  18. package/dist/overlay.d.cts +4 -3
  19. package/dist/overlay.d.ts +4 -3
  20. package/dist/overlay.js +191 -58
  21. package/dist/preact.d.cts +2 -1
  22. package/dist/preact.d.ts +2 -1
  23. package/dist/qwik.cjs +396 -211
  24. package/dist/qwik.d.cts +11 -2
  25. package/dist/qwik.d.ts +11 -2
  26. package/dist/qwik.js +396 -211
  27. package/dist/react.cjs +500 -332
  28. package/dist/react.d.cts +26 -4
  29. package/dist/react.d.ts +26 -4
  30. package/dist/react.js +500 -332
  31. package/dist/solid.cjs +362 -210
  32. package/dist/solid.d.cts +14 -4
  33. package/dist/solid.d.ts +14 -4
  34. package/dist/solid.js +362 -210
  35. package/dist/solid.source.jsx +362 -210
  36. package/dist/styles.css +17 -1
  37. package/dist/svelte-core.cjs +345 -208
  38. package/dist/svelte-core.js +345 -208
  39. package/dist/svelte-src/BottomSheet.svelte +6 -0
  40. package/dist/svelte.cjs +359 -220
  41. package/dist/svelte.d.cts +2 -0
  42. package/dist/svelte.d.ts +2 -0
  43. package/dist/svelte.js +359 -220
  44. package/dist/teleport-7uYNiEAT.d.cts +3 -0
  45. package/dist/teleport-7uYNiEAT.d.ts +3 -0
  46. package/dist/vue.cjs +353 -209
  47. package/dist/vue.d.cts +3 -1
  48. package/dist/vue.d.ts +3 -1
  49. package/dist/vue.js +353 -209
  50. package/package.json +11 -9
package/dist/element.cjs CHANGED
@@ -215,15 +215,27 @@ var init_cssLength = __esm({
215
215
  }
216
216
  });
217
217
 
218
+ // src/core/primitives/devWarn.ts
219
+ function devWarn(...args) {
220
+ if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
221
+ console.warn(...args);
222
+ }
223
+ }
224
+ var init_devWarn = __esm({
225
+ "src/core/primitives/devWarn.ts"() {
226
+ }
227
+ });
228
+
218
229
  // src/core/primitives/snap-points.ts
219
230
  var resolveSnapList, VH_NOT_DVH, auditVhUsage, findNearest, allowedRange, findById, MOUSE_FLICK_VELOCITY, MOUSE_DRAG_THRESHOLD, DIRECTIONAL_INTENT_VELOCITY, findDragSettleTarget;
220
231
  var init_snap_points = __esm({
221
232
  "src/core/primitives/snap-points.ts"() {
222
233
  init_cssLength();
234
+ init_devWarn();
223
235
  resolveSnapList = (points, mode, measureFit) => points.map((p) => {
224
236
  const raw = resolveSnap(p.size, mode, measureFit);
225
237
  if (!Number.isFinite(raw) || raw < 0) {
226
- console.warn(
238
+ devWarn(
227
239
  `[BottomSheet] snap "${p.id}" resolved to invalid size (${String(p.size)} \u2192 ${raw}); clamped to 0.`
228
240
  );
229
241
  return { id: p.id, size: 0 };
@@ -235,7 +247,7 @@ var init_snap_points = __esm({
235
247
  for (const p of points) {
236
248
  if (typeof p.size !== "string") continue;
237
249
  if (!VH_NOT_DVH.test(p.size)) continue;
238
- console.warn(
250
+ devWarn(
239
251
  `[BottomSheet] snap "${p.id}" uses "vh" \u2014 prefer "dvh" on mobile (iOS Safari URL bar makes vh unstable). See https://web.dev/blog/viewport-units`
240
252
  );
241
253
  }
@@ -291,6 +303,31 @@ var init_snap_points = __esm({
291
303
  }
292
304
  });
293
305
 
306
+ // src/core/primitives/cancelable-emit.ts
307
+ function emitCancelable(emit, base, warnLabel) {
308
+ let cancelled = false;
309
+ let frozen = false;
310
+ emit({
311
+ ...base,
312
+ cancel: () => {
313
+ if (frozen) {
314
+ devWarn(
315
+ `[BottomSheet] ${warnLabel}.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener.`
316
+ );
317
+ return;
318
+ }
319
+ cancelled = true;
320
+ }
321
+ });
322
+ frozen = true;
323
+ return cancelled;
324
+ }
325
+ var init_cancelable_emit = __esm({
326
+ "src/core/primitives/cancelable-emit.ts"() {
327
+ init_devWarn();
328
+ }
329
+ });
330
+
294
331
  // src/core/primitives/snap-resolver.ts
295
332
  var SnapResolver;
296
333
  var init_snap_resolver = __esm({
@@ -449,7 +486,9 @@ function notifyLinkedSheets(sheets, self) {
449
486
  try {
450
487
  if (linked.state.size === 0) continue;
451
488
  const ids = linked.getAllowedIds();
452
- const target = ids.find((id) => id !== "closed");
489
+ const resolved = linked.getResolvedSnaps();
490
+ const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
491
+ const target = ids.find((id) => sizeOf(id) > 0);
453
492
  if (target && target !== linked.state.activeId) {
454
493
  void linked.snapTo(target);
455
494
  }
@@ -465,6 +504,202 @@ var init_linked_sheets = __esm({
465
504
  }
466
505
  });
467
506
 
507
+ // src/core/features/history-coordinator.ts
508
+ function onPopState() {
509
+ if (suppress > 0) {
510
+ suppress -= 1;
511
+ const rebrand = pendingRebrand;
512
+ pendingRebrand = null;
513
+ if (rebrand) rebrand();
514
+ maybeTeardownListener();
515
+ return;
516
+ }
517
+ if (entries.length === 0) {
518
+ notifyRouteChange();
519
+ maybeTeardownListener();
520
+ return;
521
+ }
522
+ let target = null;
523
+ let targetIdx = -1;
524
+ for (let i = entries.length - 1; i >= 0; i -= 1) {
525
+ const entry = entries[i];
526
+ if (!entry.surface.isOpen()) continue;
527
+ if (!target) {
528
+ target = entry;
529
+ targetIdx = i;
530
+ }
531
+ if (entry.surface.isTop()) {
532
+ target = entry;
533
+ targetIdx = i;
534
+ break;
535
+ }
536
+ }
537
+ if (!target) {
538
+ const removed = entries.pop();
539
+ if (removed) removed.live = false;
540
+ maybeTeardownListener();
541
+ return;
542
+ }
543
+ target.live = false;
544
+ entries.splice(targetIdx, 1);
545
+ const settled = target;
546
+ void Promise.resolve(settled.surface.close()).then(() => {
547
+ if (settled.surface.isOpen()) restore(settled);
548
+ });
549
+ maybeTeardownListener();
550
+ }
551
+ function restore(entry) {
552
+ if (!hasWindow() || !hasHistory()) return;
553
+ entry.live = true;
554
+ runInternal(() => {
555
+ try {
556
+ history.pushState(entry.surface.markerState(), "", entry.surface.url);
557
+ } catch {
558
+ entry.live = false;
559
+ }
560
+ });
561
+ if (entry.live) {
562
+ entries.push(entry);
563
+ ensureListener();
564
+ }
565
+ }
566
+ function pushBackMarker(surface) {
567
+ const entry = { surface, priorUrl: void 0, live: false };
568
+ if (!hasWindow() || !hasHistory()) {
569
+ return entry;
570
+ }
571
+ entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
572
+ runInternal(() => {
573
+ try {
574
+ history.pushState(surface.markerState(), "", surface.url);
575
+ entry.live = true;
576
+ } catch {
577
+ entry.live = false;
578
+ }
579
+ });
580
+ if (entry.live) {
581
+ entries.push(entry);
582
+ ensureListener();
583
+ }
584
+ return entry;
585
+ }
586
+ function popBackMarker(handle) {
587
+ if (!hasWindow() || !hasHistory()) return;
588
+ const entry = handle;
589
+ const idx = entries.indexOf(entry);
590
+ if (idx === -1 || !entry.live) return;
591
+ const last = entries.length - 1;
592
+ entry.live = false;
593
+ entries.splice(idx, 1);
594
+ if (idx !== last) {
595
+ const rebrandSurface = entries[entries.length - 1].surface;
596
+ const rebrandUrl = entry.priorUrl;
597
+ pendingRebrand = () => {
598
+ runInternal(() => {
599
+ history.replaceState(
600
+ rebrandSurface.markerState(),
601
+ "",
602
+ rebrandUrl !== void 0 ? rebrandUrl : location.href
603
+ );
604
+ });
605
+ };
606
+ }
607
+ suppress += 1;
608
+ runInternal(() => {
609
+ try {
610
+ history.back();
611
+ } catch {
612
+ suppress = Math.max(0, suppress - 1);
613
+ pendingRebrand = null;
614
+ }
615
+ });
616
+ maybeTeardownListener();
617
+ }
618
+ function subscribeRouteChange(fn) {
619
+ if (!hasWindow() || !hasHistory()) return () => {
620
+ };
621
+ subscribers.add(fn);
622
+ if (subscribers.size === 1) installPatch();
623
+ ensureListener();
624
+ return () => {
625
+ if (!subscribers.has(fn)) return;
626
+ subscribers.delete(fn);
627
+ if (subscribers.size === 0) removePatch();
628
+ maybeTeardownListener();
629
+ };
630
+ }
631
+ var entries, subscribers, suppress, internalDepth, pendingRebrand, listenerInstalled, patchInstalled, origPushState, origReplaceState, patchedPushState, patchedReplaceState, hasWindow, hasHistory, runInternal, notifyRouteChange, ensureListener, maybeTeardownListener, installPatch, removePatch;
632
+ var init_history_coordinator = __esm({
633
+ "src/core/features/history-coordinator.ts"() {
634
+ entries = [];
635
+ subscribers = /* @__PURE__ */ new Set();
636
+ suppress = 0;
637
+ internalDepth = 0;
638
+ pendingRebrand = null;
639
+ listenerInstalled = false;
640
+ patchInstalled = false;
641
+ origPushState = null;
642
+ origReplaceState = null;
643
+ patchedPushState = null;
644
+ patchedReplaceState = null;
645
+ hasWindow = () => typeof window !== "undefined";
646
+ hasHistory = () => typeof history !== "undefined";
647
+ runInternal = (fn) => {
648
+ internalDepth += 1;
649
+ try {
650
+ fn();
651
+ } finally {
652
+ internalDepth -= 1;
653
+ }
654
+ };
655
+ notifyRouteChange = () => {
656
+ const snapshot = Array.from(subscribers);
657
+ for (const fn of snapshot) fn();
658
+ };
659
+ ensureListener = () => {
660
+ if (listenerInstalled || !hasWindow()) return;
661
+ window.addEventListener("popstate", onPopState);
662
+ listenerInstalled = true;
663
+ };
664
+ maybeTeardownListener = () => {
665
+ if (!listenerInstalled) return;
666
+ if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
667
+ if (hasWindow()) window.removeEventListener("popstate", onPopState);
668
+ listenerInstalled = false;
669
+ };
670
+ installPatch = () => {
671
+ if (patchInstalled || !hasHistory()) return;
672
+ origPushState = history.pushState;
673
+ origReplaceState = history.replaceState;
674
+ patchedPushState = function(...args) {
675
+ origPushState.apply(this, args);
676
+ if (internalDepth === 0) notifyRouteChange();
677
+ };
678
+ patchedReplaceState = function(...args) {
679
+ origReplaceState.apply(this, args);
680
+ if (internalDepth === 0) notifyRouteChange();
681
+ };
682
+ history.pushState = patchedPushState;
683
+ history.replaceState = patchedReplaceState;
684
+ patchInstalled = true;
685
+ };
686
+ removePatch = () => {
687
+ if (!patchInstalled) return;
688
+ if (history.pushState === patchedPushState && origPushState) {
689
+ history.pushState = origPushState;
690
+ }
691
+ if (history.replaceState === patchedReplaceState && origReplaceState) {
692
+ history.replaceState = origReplaceState;
693
+ }
694
+ origPushState = null;
695
+ origReplaceState = null;
696
+ patchedPushState = null;
697
+ patchedReplaceState = null;
698
+ patchInstalled = false;
699
+ };
700
+ }
701
+ });
702
+
468
703
  // src/core/features/route.ts
469
704
  function installRoute(deps) {
470
705
  if (typeof window === "undefined") {
@@ -475,135 +710,43 @@ function installRoute(deps) {
475
710
  return () => {
476
711
  };
477
712
  }
478
- let pushed = false;
479
- let closer = null;
480
- const teardownEntry = () => {
481
- if (closer) {
482
- const idx = closers.indexOf(closer);
483
- if (idx !== -1) closers.splice(idx, 1);
484
- }
485
- const wasConsumed = closer?.consumed ?? false;
486
- closer = null;
487
- if (pushed && !wasConsumed) {
488
- pushed = false;
489
- programmaticBack();
490
- } else {
491
- pushed = false;
492
- }
493
- };
494
- const pushEntry = () => {
495
- try {
496
- if (deps.routedTo !== void 0) {
497
- history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
498
- } else {
499
- history.pushState({ __bsSheet: deps.sheetId }, "");
500
- }
501
- pushed = true;
502
- } catch {
503
- pushed = false;
504
- }
505
- };
713
+ let handle = null;
506
714
  const onOpen = () => {
507
- if (closer) return;
508
- const self = {
715
+ if (handle) return;
716
+ handle = pushBackMarker({
509
717
  isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
510
- isTop: () => deps.isTopSheet(),
511
- close: () => deps.close(),
512
- restore: () => {
513
- if (deps.isDestroyed() || closer !== self) return;
514
- self.consumed = false;
515
- if (!closers.includes(self)) closers.push(self);
516
- pushEntry();
517
- },
518
- consumed: false
519
- };
520
- closer = self;
521
- ensureHandler();
522
- closers.push(self);
523
- pushEntry();
718
+ isTop: deps.isTopSheet,
719
+ close: deps.close,
720
+ markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
721
+ url: deps.routedTo
722
+ });
723
+ };
724
+ const onClose = () => {
725
+ if (!handle) return;
726
+ popBackMarker(handle);
727
+ handle = null;
524
728
  };
525
729
  const unsubscribeOpen = deps.on("open", onOpen);
526
- const unsubscribeClose = deps.on("close", teardownEntry);
730
+ const unsubscribeClose = deps.on("close", onClose);
527
731
  if (deps.getSize() > 0) onOpen();
528
732
  return () => {
529
733
  unsubscribeOpen();
530
734
  unsubscribeClose();
531
- teardownEntry();
735
+ if (handle) {
736
+ popBackMarker(handle);
737
+ handle = null;
738
+ }
532
739
  };
533
740
  }
534
741
  function installRouteChange(deps) {
535
- if (typeof window === "undefined" || typeof history === "undefined") {
536
- return () => {
537
- };
538
- }
539
- const onChange = () => {
742
+ return subscribeRouteChange(() => {
540
743
  if (deps.isDestroyed() || deps.getSize() <= 0) return;
541
744
  void deps.close();
542
- };
543
- const wrap = (key) => {
544
- const original = history[key];
545
- const patched = function(...args) {
546
- original.apply(this, args);
547
- onChange();
548
- };
549
- history[key] = patched;
550
- return () => {
551
- if (history[key] === patched) {
552
- history[key] = original;
553
- }
554
- };
555
- };
556
- window.addEventListener("popstate", onChange);
557
- const restorePush = wrap("pushState");
558
- const restoreReplace = wrap("replaceState");
559
- return () => {
560
- window.removeEventListener("popstate", onChange);
561
- restorePush();
562
- restoreReplace();
563
- };
745
+ });
564
746
  }
565
- var closers, handlerInstalled, suppress, ensureHandler, programmaticBack;
566
747
  var init_route = __esm({
567
748
  "src/core/features/route.ts"() {
568
- closers = [];
569
- handlerInstalled = false;
570
- suppress = 0;
571
- ensureHandler = () => {
572
- if (handlerInstalled || typeof window === "undefined") return;
573
- handlerInstalled = true;
574
- window.addEventListener("popstate", () => {
575
- if (suppress > 0) {
576
- suppress -= 1;
577
- return;
578
- }
579
- let target = null;
580
- for (let i = closers.length - 1; i >= 0; i -= 1) {
581
- const c = closers[i];
582
- if (!c.isOpen()) continue;
583
- if (!target) target = c;
584
- if (c.isTop()) {
585
- target = c;
586
- break;
587
- }
588
- }
589
- if (!target) return;
590
- target.consumed = true;
591
- const idx = closers.indexOf(target);
592
- if (idx !== -1) closers.splice(idx, 1);
593
- const settled = target;
594
- void Promise.resolve(settled.close()).then(() => {
595
- if (settled.isOpen()) settled.restore();
596
- });
597
- });
598
- };
599
- programmaticBack = () => {
600
- suppress += 1;
601
- try {
602
- history.back();
603
- } catch {
604
- suppress = Math.max(0, suppress - 1);
605
- }
606
- };
749
+ init_history_coordinator();
607
750
  }
608
751
  });
609
752
 
@@ -679,11 +822,15 @@ function installVisualViewport(deps) {
679
822
  if (clamp < deps.getMaxAxisSize()) {
680
823
  deps.setMaxAxisSize(clamp);
681
824
  }
825
+ const wasAnimating = deps.isAnimating?.() ?? false;
826
+ deps.cancelInFlight();
827
+ deps.newCycle();
682
828
  const max = deps.getMaxAxisSize();
683
829
  deps.setSize(Math.min(deps.getSize(), max));
684
830
  const current = deps.resolveActiveSnap();
685
831
  if (current && !deps.isDragging()) {
686
832
  deps.applySize(Math.min(current.size, max));
833
+ if (wasAnimating) deps.resyncAfterCancel?.();
687
834
  } else {
688
835
  deps.applySize(deps.getSize());
689
836
  }
@@ -839,6 +986,60 @@ var init_fit_observer = __esm({
839
986
  }
840
987
  });
841
988
 
989
+ // src/core/features/max-height-controller.ts
990
+ function createMaxHeightController(deps) {
991
+ let maxHeightCap;
992
+ let maxHeightRaw;
993
+ const resolveCap = () => {
994
+ const raw = maxHeightRaw;
995
+ if (raw === void 0) {
996
+ maxHeightCap = void 0;
997
+ return;
998
+ }
999
+ if (typeof raw === "number") {
1000
+ maxHeightCap = raw;
1001
+ return;
1002
+ }
1003
+ if (typeof window === "undefined") return;
1004
+ const measured = resolveSnap(raw, deps.mode);
1005
+ maxHeightCap = measured > 0 ? measured : void 0;
1006
+ };
1007
+ const clampTo = () => {
1008
+ if (maxHeightCap === void 0) return;
1009
+ if (deps.getMaxAxisSize() > maxHeightCap) {
1010
+ deps.setMaxAxisSize(maxHeightCap);
1011
+ }
1012
+ };
1013
+ return {
1014
+ setRadius(r) {
1015
+ deps.element.style.setProperty(
1016
+ "--bs-radius",
1017
+ typeof r === "number" ? `${r}px` : r
1018
+ );
1019
+ },
1020
+ setMaxHeight(h) {
1021
+ const value = typeof h === "number" ? `${h}px` : h;
1022
+ const axis = layoutAxis(deps.mode);
1023
+ deps.element.style.setProperty(
1024
+ axis === "height" ? "max-height" : "max-width",
1025
+ value
1026
+ );
1027
+ maxHeightRaw = h;
1028
+ resolveCap();
1029
+ deps.recompute();
1030
+ },
1031
+ resolveCap,
1032
+ clampTo,
1033
+ getCap: () => maxHeightCap
1034
+ };
1035
+ }
1036
+ var init_max_height_controller = __esm({
1037
+ "src/core/features/max-height-controller.ts"() {
1038
+ init_snap_points();
1039
+ init_transform();
1040
+ }
1041
+ });
1042
+
842
1043
  // src/core/features/fit-measurement.ts
843
1044
  var measureSheetNatural, containingExtent, measureFitSize;
844
1045
  var init_fit_measurement = __esm({
@@ -995,17 +1196,6 @@ var init_opacity_dedup = __esm({
995
1196
  }
996
1197
  });
997
1198
 
998
- // src/core/primitives/devWarn.ts
999
- function devWarn(...args) {
1000
- if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
1001
- console.warn(...args);
1002
- }
1003
- }
1004
- var init_devWarn = __esm({
1005
- "src/core/primitives/devWarn.ts"() {
1006
- }
1007
- });
1008
-
1009
1199
  // src/core/primitives/overlay-position.ts
1010
1200
  function resolveSheetAnchoredStyle(mode, position, inset) {
1011
1201
  const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
@@ -2554,7 +2744,7 @@ var init_sheet_anchors = __esm({
2554
2744
  // src/core/features/scrim-stages.ts
2555
2745
  function installScrimStages(deps, opts) {
2556
2746
  const doc = deps.host.ownerDocument;
2557
- const entries = opts.stages.map((def) => {
2747
+ const entries2 = opts.stages.map((def) => {
2558
2748
  const wrapper = doc.createElement("div");
2559
2749
  wrapper.className = "bs-scrim-stage";
2560
2750
  const ws = wrapper.style;
@@ -2575,9 +2765,9 @@ function installScrimStages(deps, opts) {
2575
2765
  const resolveActive = () => {
2576
2766
  const state = deps.getState();
2577
2767
  if (state.size === 0) {
2578
- return entries.find((e) => matchesId(e.def, state.activeId)) ?? null;
2768
+ return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
2579
2769
  }
2580
- return entries.find((e) => matchesId(e.def, state.activeId)) ?? entries.find((e) => matchesRange(e.def, state.progress)) ?? null;
2770
+ return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
2581
2771
  };
2582
2772
  const hide = (entry, animate) => {
2583
2773
  entry.inFlight?.cancel();
@@ -2626,13 +2816,13 @@ function installScrimStages(deps, opts) {
2626
2816
  deps.on("open", () => update(true)),
2627
2817
  deps.on("close", () => update(true))
2628
2818
  ];
2629
- if (entries.some((e) => e.def.forRange)) {
2819
+ if (entries2.some((e) => e.def.forRange)) {
2630
2820
  offs.push(deps.on("progress", () => update(true)));
2631
2821
  }
2632
2822
  update(false);
2633
2823
  return () => {
2634
2824
  offs.forEach((off) => off());
2635
- for (const entry of entries) {
2825
+ for (const entry of entries2) {
2636
2826
  entry.inFlight?.cancel();
2637
2827
  entry.inFlight = null;
2638
2828
  if (entry.wrapper.parentNode) {
@@ -2756,6 +2946,8 @@ var init_BottomSheetEngine = __esm({
2756
2946
  init_instance_id();
2757
2947
  init_event_bus();
2758
2948
  init_snap_points();
2949
+ init_cancelable_emit();
2950
+ init_devWarn();
2759
2951
  init_snap_resolver();
2760
2952
  init_persist();
2761
2953
  init_auto_collapse();
@@ -2765,6 +2957,7 @@ var init_BottomSheetEngine = __esm({
2765
2957
  init_visual_viewport();
2766
2958
  init_resize_observer();
2767
2959
  init_fit_observer();
2960
+ init_max_height_controller();
2768
2961
  init_fit_measurement();
2769
2962
  init_slider_keyboard();
2770
2963
  init_scrim_controller();
@@ -2803,8 +2996,7 @@ var init_BottomSheetEngine = __esm({
2803
2996
  __publicField(this, "disableCloseFlag");
2804
2997
  __publicField(this, "disableDragFlag");
2805
2998
  __publicField(this, "closeOnRouteChange");
2806
- __publicField(this, "maxHeightCap");
2807
- __publicField(this, "maxHeightRaw");
2999
+ __publicField(this, "maxHeight");
2808
3000
  __publicField(this, "snapPointsRaw");
2809
3001
  __publicField(this, "snaps");
2810
3002
  __publicField(this, "activeId");
@@ -2915,11 +3107,20 @@ var init_BottomSheetEngine = __esm({
2915
3107
  auditVhUsage(this.snapPointsRaw);
2916
3108
  this.auditDuplicateSnapIds(this.snapPointsRaw);
2917
3109
  this.rootEl = this.element.closest(".bs-root");
3110
+ this.maxHeight = createMaxHeightController({
3111
+ element: this.element,
3112
+ mode: this.mode,
3113
+ getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
3114
+ setMaxAxisSize: (size) => {
3115
+ this.snaps.setMaxAxisSize(size);
3116
+ },
3117
+ recompute: () => this.recompute()
3118
+ });
2918
3119
  this.fitDeps = {
2919
3120
  element: this.element,
2920
3121
  scrollContainer: this.scrollContainer,
2921
3122
  mode: this.mode,
2922
- getMaxHeightCap: () => this.maxHeightCap
3123
+ getMaxHeightCap: () => this.maxHeight.getCap()
2923
3124
  };
2924
3125
  this.snaps = new SnapResolver(
2925
3126
  this.snapPointsRaw,
@@ -2941,8 +3142,8 @@ var init_BottomSheetEngine = __esm({
2941
3142
  this.attach();
2942
3143
  this.registerInStack();
2943
3144
  if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
2944
- const io = new IntersectionObserver((entries) => {
2945
- for (const entry of entries) {
3145
+ const io = new IntersectionObserver((entries2) => {
3146
+ for (const entry of entries2) {
2946
3147
  if (!entry.isIntersecting) continue;
2947
3148
  if (this.destroyed) return;
2948
3149
  this.snaps.recompute();
@@ -3030,7 +3231,7 @@ var init_BottomSheetEngine = __esm({
3030
3231
  }
3031
3232
  use(plugin) {
3032
3233
  if (this.destroyed) {
3033
- console.warn(
3234
+ devWarn(
3034
3235
  `[BottomSheet] use("${plugin.name}") called on destroyed engine \u2014 ignored.`
3035
3236
  );
3036
3237
  return this;
@@ -3072,6 +3273,9 @@ var init_BottomSheetEngine = __esm({
3072
3273
  getAllowedIds() {
3073
3274
  return this.snaps.getAllowedIds().slice();
3074
3275
  }
3276
+ getResolvedSnaps() {
3277
+ return this.snaps.getResolvedSnaps();
3278
+ }
3075
3279
  async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
3076
3280
  if (this.destroyed) return;
3077
3281
  const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
@@ -3080,11 +3284,11 @@ var init_BottomSheetEngine = __esm({
3080
3284
  if (externalSignal?.aborted) return;
3081
3285
  const target = this.snaps.findById(id);
3082
3286
  if (!target) {
3083
- console.warn(`[BottomSheet] unknown snap id: ${id}`);
3287
+ devWarn(`[BottomSheet] unknown snap id: ${id}`);
3084
3288
  return;
3085
3289
  }
3086
3290
  if (!this.snaps.getAllowedIds().includes(id)) {
3087
- console.warn(`[BottomSheet] snap "${id}" is not in allowed list`);
3291
+ devWarn(`[BottomSheet] snap "${id}" is not in allowed list`);
3088
3292
  return;
3089
3293
  }
3090
3294
  if (!_skipBeforeSnap && this.emitBeforeSnap(target, this.activeId)) {
@@ -3216,42 +3420,11 @@ var init_BottomSheetEngine = __esm({
3216
3420
  }
3217
3421
  setRadius(r) {
3218
3422
  if (this.destroyed) return;
3219
- this.element.style.setProperty(
3220
- "--bs-radius",
3221
- typeof r === "number" ? `${r}px` : r
3222
- );
3423
+ this.maxHeight.setRadius(r);
3223
3424
  }
3224
3425
  setMaxHeight(h) {
3225
3426
  if (this.destroyed) return;
3226
- const value = typeof h === "number" ? `${h}px` : h;
3227
- const axis = layoutAxis(this.mode);
3228
- this.element.style.setProperty(
3229
- axis === "height" ? "max-height" : "max-width",
3230
- value
3231
- );
3232
- this.maxHeightRaw = h;
3233
- this.resolveMaxHeightCap();
3234
- this.recompute();
3235
- }
3236
- resolveMaxHeightCap() {
3237
- const raw = this.maxHeightRaw;
3238
- if (raw === void 0) {
3239
- this.maxHeightCap = void 0;
3240
- return;
3241
- }
3242
- if (typeof raw === "number") {
3243
- this.maxHeightCap = raw;
3244
- return;
3245
- }
3246
- if (typeof window === "undefined") return;
3247
- const measured = resolveSnap(raw, this.mode);
3248
- this.maxHeightCap = measured > 0 ? measured : void 0;
3249
- }
3250
- clampToMaxHeight() {
3251
- if (this.maxHeightCap === void 0) return;
3252
- if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
3253
- this.snaps.setMaxAxisSize(this.maxHeightCap);
3254
- }
3427
+ this.maxHeight.setMaxHeight(h);
3255
3428
  }
3256
3429
  setAllowed(ids, snap) {
3257
3430
  if (this.destroyed) return;
@@ -3339,7 +3512,7 @@ var init_BottomSheetEngine = __esm({
3339
3512
  };
3340
3513
  const host = this.screenComponent?.parentElement;
3341
3514
  if (!host) {
3342
- console.warn(
3515
+ devWarn(
3343
3516
  "[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
3344
3517
  );
3345
3518
  return () => {
@@ -3389,9 +3562,9 @@ var init_BottomSheetEngine = __esm({
3389
3562
  }
3390
3563
  recompute() {
3391
3564
  if (this.destroyed) return;
3392
- this.resolveMaxHeightCap();
3565
+ this.maxHeight.resolveCap();
3393
3566
  this.snaps.recompute();
3394
- this.clampToMaxHeight();
3567
+ this.maxHeight.clampTo();
3395
3568
  this.scrim.invalidateOpacityCache();
3396
3569
  if (this.gesture?.isDragging) return;
3397
3570
  const current = this.snaps.findById(this.activeId);
@@ -3441,42 +3614,18 @@ var init_BottomSheetEngine = __esm({
3441
3614
  return this.currentAbort.signal;
3442
3615
  }
3443
3616
  emitBeforeSnap(target, previousId) {
3444
- let cancelled = false;
3445
- let frozen = false;
3446
- this.emit("before-snap", {
3447
- id: target.id,
3448
- size: target.size,
3449
- previousId,
3450
- cancel: () => {
3451
- if (frozen) {
3452
- console.warn(
3453
- "[BottomSheet] before-snap.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
3454
- );
3455
- return;
3456
- }
3457
- cancelled = true;
3458
- }
3459
- });
3460
- frozen = true;
3461
- return cancelled;
3617
+ return emitCancelable(
3618
+ (payload) => this.emit("before-snap", payload),
3619
+ { id: target.id, size: target.size, previousId },
3620
+ "before-snap"
3621
+ );
3462
3622
  }
3463
3623
  emitBeforeClose(reason) {
3464
- let cancelled = false;
3465
- let frozen = false;
3466
- this.emit("before-close", {
3467
- reason,
3468
- cancel: () => {
3469
- if (frozen) {
3470
- console.warn(
3471
- "[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
3472
- );
3473
- return;
3474
- }
3475
- cancelled = true;
3476
- }
3477
- });
3478
- frozen = true;
3479
- return cancelled;
3624
+ return emitCancelable(
3625
+ (payload) => this.emit("before-close", payload),
3626
+ { reason },
3627
+ "before-close"
3628
+ );
3480
3629
  }
3481
3630
  applyAutoAriaLabelledBy() {
3482
3631
  if (typeof document === "undefined") return;
@@ -3491,16 +3640,16 @@ var init_BottomSheetEngine = __esm({
3491
3640
  this.element.setAttribute("aria-labelledby", titled.id);
3492
3641
  }
3493
3642
  recomputeSnaps() {
3494
- this.resolveMaxHeightCap();
3643
+ this.maxHeight.resolveCap();
3495
3644
  this.snaps.setRaw(this.snapPointsRaw);
3496
- this.clampToMaxHeight();
3645
+ this.maxHeight.clampTo();
3497
3646
  this.scrim.invalidateOpacityCache();
3498
3647
  }
3499
3648
  auditDuplicateSnapIds(points) {
3500
3649
  const seen = /* @__PURE__ */ new Set();
3501
3650
  for (const p of points) {
3502
3651
  if (seen.has(p.id)) {
3503
- console.warn(
3652
+ devWarn(
3504
3653
  `[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
3505
3654
  );
3506
3655
  }
@@ -3667,7 +3816,15 @@ var init_BottomSheetEngine = __esm({
3667
3816
  setSize: (size) => {
3668
3817
  this.size = size;
3669
3818
  },
3670
- applySize: (size) => this.applySize(size)
3819
+ applySize: (size) => this.applySize(size),
3820
+ cancelInFlight: () => {
3821
+ this.animation.cancel();
3822
+ },
3823
+ newCycle: () => {
3824
+ this.newCycle();
3825
+ },
3826
+ isAnimating: () => this.animation.isAnimating,
3827
+ resyncAfterCancel: () => this.resyncAfterResize()
3671
3828
  }));
3672
3829
  }
3673
3830
  this.teardowns.add(installSliderKeyboard({
@@ -3703,9 +3860,9 @@ var init_BottomSheetEngine = __esm({
3703
3860
  return;
3704
3861
  }
3705
3862
  if (this.emitBeforeSnap(target, previousId)) {
3706
- const restore = this.snaps.findById(previousId);
3707
- if (restore) {
3708
- void this.animation.animateTo(restore.size, 0);
3863
+ const restore2 = this.snaps.findById(previousId);
3864
+ if (restore2) {
3865
+ void this.animation.animateTo(restore2.size, 0);
3709
3866
  }
3710
3867
  return;
3711
3868
  }
@@ -3835,7 +3992,7 @@ var init_BottomSheetEngine = __esm({
3835
3992
  var baseStyles;
3836
3993
  var init_baseStyles = __esm({
3837
3994
  "src/web-component/baseStyles.ts"() {
3838
- baseStyles = `:where(.bs-root){--bs-surface-d:#ffffff;--bs-surface-border-d:rgba(225,227,237,1);--bs-radius-d:20px;--bs-handle-color-d:rgba(26,22,20,0.3);--bs-handle-width:40px;--bs-handle-height:5px;--bs-z-backdrop:90;--bs-z-sheet:100;--bs-header-min-height:80px;--bs-backdrop-color-d:rgba(0,0,0,0.5);--bs-scrim-color-d:transparent;--bs-scrim-blur:0px;--bs-z-scrim:calc(var(--bs-z-sheet) - 1);--bs-size:0px;--bs-progress:0}.bs-backdrop{position:fixed;inset:0;background:var(--bs-backdrop-color,var(--bs-backdrop-color-d));opacity:0;pointer-events:none;z-index:var(--bs-z-backdrop);transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-backdrop,.bs-root[data-animating="true"] .bs-backdrop{transition:none}.bs-sheet{position:fixed;background:var(--bs-surface,var(--bs-surface-d));box-shadow:var(--bs-shadow,var(--bs-shadow-auto,none));z-index:var(--bs-z-sheet);pointer-events:auto;overflow:hidden;display:flex;flex-direction:column;-webkit-tap-highlight-color:transparent;user-select:none;overscroll-behavior:contain}.bs-sheet[data-mode="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));padding-bottom:env(safe-area-inset-bottom);--bs-shadow-auto:0 calc(var(--bs-progress,0) * -2px - 3px) calc(var(--bs-progress,0) * 18px + 12px) rgba(0,0,0,calc(var(--bs-progress,0) * 0.15 + 0.12))}.bs-sheet[data-mode="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom:1px solid var(--bs-surface-border,var(--bs-surface-border-d));flex-direction:column-reverse;--bs-shadow-auto:0 3px 12px rgba(0,0,0,0.12);padding-top:env(safe-area-inset-top)}.bs-sheet[data-mode="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:3px 0 12px rgba(0,0,0,0.12)}.bs-sheet[data-mode="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:-3px 0 12px rgba(0,0,0,0.12)}.bs-sheet[data-mode="left"] .bs-content{padding-right:36px}.bs-sheet[data-mode="right"] .bs-content{padding-left:36px}.bs-handle{flex-shrink:0;min-height:44px;display:flex;flex-direction:column;justify-content:center;padding:var(--bs-handle-padding,8px 16px 4px);cursor:grab;touch-action:none;user-select:none;background:var(--bs-surface,var(--bs-surface-d));-webkit-tap-highlight-color:transparent;outline:none;position:relative}.bs-handle:active{cursor:grabbing}.bs-handle:focus-visible{outline:2px solid currentColor;outline-offset:-2px;border-radius:var(--bs-radius,var(--bs-radius-d))}.bs-handle::before{content:"";display:block;width:var(--bs-handle-width);height:var(--bs-handle-height);background:var(--bs-handle-color,var(--bs-handle-color-d));border-radius:calc(var(--bs-handle-height) / 2);margin:0 auto 8px;transition:width 0.15s ease,background 0.15s ease,transform 0.15s ease;pointer-events:none}.bs-sheet[data-mode="left"] .bs-handle,.bs-sheet[data-mode="right"] .bs-handle{position:absolute;top:0;bottom:0;width:28px;min-width:0;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0;background:var(--bs-surface,var(--bs-surface-d));z-index:1;overflow:hidden}.bs-sheet[data-mode="left"] .bs-handle>*,.bs-sheet[data-mode="right"] .bs-handle>*{display:none}.bs-sheet[data-mode="left"] .bs-handle{right:0;border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="right"] .bs-handle{left:0;border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="left"] .bs-handle::before,.bs-sheet[data-mode="right"] .bs-handle::before{width:var(--bs-handle-height);height:var(--bs-handle-width);margin:0}.bs-sheet:hover .bs-handle::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 15%)}.bs-handle:active::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 35%);transform:scaleX(1.15)}.bs-handle.bs-handle--ticks::after{content:"";display:block;position:absolute;left:50%;bottom:6px;transform:translateX(-50%);width:calc(var(--bs-handle-width) * 2);height:3px;background-image:radial-gradient( circle,var(--bs-handle-color,var(--bs-handle-color-d)) 0 1.5px,transparent 1.6px );background-size:8px 3px;background-repeat:repeat-x;background-position:center;opacity:0;transition:opacity 0.18s ease-out;pointer-events:none}.bs-root[data-dragging="true"] .bs-handle.bs-handle--ticks::after{opacity:0.4}.bs-sheet[data-mode="top"] .bs-handle.bs-handle--ticks::after{bottom:auto;top:6px}.bs-sheet[data-mode="left"] .bs-handle.bs-handle--ticks::after,.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{left:50%;top:50%;bottom:auto;transform:translate(-50%,-50%);width:3px;height:calc(var(--bs-handle-width) * 2);background-size:3px 8px;background-repeat:repeat-y;margin-left:calc(var(--bs-handle-height) + 6px)}.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{margin-left:calc(-1 * (var(--bs-handle-height) + 6px))}.bs-header{flex:0 0 auto;padding:var(--bs-header-padding,0 16px 8px);background:var(--bs-surface,var(--bs-surface-d))}.bs-content{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;user-select:text;padding:var(--bs-content-padding,0 16px 16px)}.bs-footer{flex:0 0 auto;padding:var(--bs-footer-padding,12px 16px calc(12px + env(safe-area-inset-bottom)));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));background:var(--bs-surface,var(--bs-surface-d))}.bs-sheet[data-mode="bottom"]:has(.bs-footer:not([hidden]):has(*)){padding-bottom:0}.bs-header:not(:has(*)),.bs-footer:not(:has(*)),.bs-header[hidden],.bs-footer[hidden]{display:none}.bs-screen{position:absolute;inset:0;pointer-events:none;z-index:var(--bs-z-scrim);background:var(--bs-scrim-color,var(--bs-scrim-color-d));transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-screen,.bs-root[data-animating="true"] .bs-screen{transition:none}.bs-scrim-overlay{z-index:calc(var(--bs-z-sheet) + 1);pointer-events:none}.bs-button-slot{position:fixed;z-index:calc(var(--bs-z-sheet) + 1);pointer-events:auto}.bs-button-slot[data-side="left"]{left:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-side="right"]{right:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="top"]{bottom:auto;top:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="left"]{left:calc(var(--bs-size,0px) + 12px);right:auto;bottom:auto;top:16px}.bs-button-slot[data-mode="right"]{right:calc(var(--bs-size,0px) + 12px);left:auto;bottom:auto;top:16px}@media (prefers-reduced-motion:reduce){.bs-backdrop,.bs-handle::before,.bs-button-slot[data-side="left"],.bs-button-slot[data-side="right"]{transition:none !important}}@media (prefers-color-scheme:dark){:where(.bs-root){--bs-surface-d:#1a1a1d;--bs-surface-border-d:rgba(255,255,255,0.08);--bs-handle-color-d:rgba(255,255,255,0.45);--bs-shadow-auto:0 -3px 16px rgba(0,0,0,0.5)}}.bs-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:where(.ovl-root){--ovl-surface:var(--bs-surface,var(--bs-surface-d,#ffffff));--ovl-surface-border:var(--bs-surface-border,var(--bs-surface-border-d,rgba(0,0,0,0.08)));--ovl-shadow:0 -8px 40px rgba(0,0,0,0.35);--ovl-radius:var(--bs-radius,var(--bs-radius-d,20px));--ovl-backdrop-color:rgba(0,0,0,0.5);--ovl-z-backdrop:200;--ovl-z-panel:201}.ovl-backdrop{position:fixed;inset:0;background:var(--ovl-backdrop-color);opacity:0;pointer-events:none;z-index:var(--ovl-z-backdrop)}.ovl-panel{position:fixed;background:var(--ovl-surface);box-shadow:var(--ovl-shadow);z-index:var(--ovl-z-panel);-webkit-tap-highlight-color:transparent;outline:none;transition:transform 0.32s cubic-bezier(0.29,1.24,0.84,0.99),opacity 0.32s ease-out}.ovl-panel[data-state="open"]{transform:translate3d(0,0,0);opacity:1}@starting-style{.ovl-panel[data-edge="bottom"][data-state="open"]{transform:translate3d(0,100%,0);opacity:0}.ovl-panel[data-edge="top"][data-state="open"]{transform:translate3d(0,-100%,0);opacity:0}.ovl-panel[data-edge="left"][data-state="open"]{transform:translate3d(-100%,0,0);opacity:0}.ovl-panel[data-edge="right"][data-state="open"]{transform:translate3d(100%,0,0);opacity:0}}.ovl-panel[data-edge="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--ovl-radius);border-top-right-radius:var(--ovl-radius);border-top:1px solid var(--ovl-surface-border);padding-bottom:env(safe-area-inset-bottom)}.ovl-panel[data-edge="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-bottom:1px solid var(--ovl-surface-border);padding-top:env(safe-area-inset-top)}.ovl-panel[data-edge="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-right:1px solid var(--ovl-surface-border)}.ovl-panel[data-edge="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--ovl-radius);border-bottom-left-radius:var(--ovl-radius);border-left:1px solid var(--ovl-surface-border)}@media (prefers-reduced-motion:reduce){.ovl-panel,.ovl-backdrop{transition:none !important}}`;
3995
+ baseStyles = `:where(.bs-root){--bs-surface-d:#ffffff;--bs-surface-border-d:rgba(225,227,237,1);--bs-radius-d:20px;--bs-handle-color-d:rgba(26,22,20,0.3);--bs-handle-width:40px;--bs-handle-height:5px;--bs-z-backdrop:90;--bs-z-sheet:100;--bs-backdrop-color-d:rgba(0,0,0,0.5);--bs-scrim-color-d:transparent;--bs-scrim-blur:0px;--bs-z-scrim:calc(var(--bs-z-sheet) - 1);--bs-size:0px;--bs-progress:0}.bs-backdrop{position:fixed;inset:0;background:var(--bs-backdrop-color,var(--bs-backdrop-color-d));opacity:0;pointer-events:none;z-index:var(--bs-z-backdrop);transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-backdrop,.bs-root[data-animating="true"] .bs-backdrop{transition:none}.bs-sheet{position:fixed;background:var(--bs-surface,var(--bs-surface-d));box-shadow:var(--bs-shadow,var(--bs-shadow-auto,none));z-index:var(--bs-z-sheet);pointer-events:auto;overflow:hidden;display:flex;flex-direction:column;-webkit-tap-highlight-color:transparent;user-select:none;overscroll-behavior:contain}.bs-sheet[data-mode="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));padding-bottom:env(safe-area-inset-bottom);--bs-shadow-auto:0 calc(var(--bs-progress,0) * -2px - 3px) calc(var(--bs-progress,0) * 18px + 12px) rgba(0,0,0,calc(var(--bs-progress,0) * 0.15 + 0.12))}.bs-sheet[data-mode="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom:1px solid var(--bs-surface-border,var(--bs-surface-border-d));flex-direction:column-reverse;--bs-shadow-auto:0 3px 12px rgba(0,0,0,0.12);padding-top:env(safe-area-inset-top)}.bs-sheet[data-mode="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-right-radius:var(--bs-radius,var(--bs-radius-d));border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:3px 0 12px rgba(0,0,0,0.12)}.bs-sheet[data-mode="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--bs-radius,var(--bs-radius-d));border-bottom-left-radius:var(--bs-radius,var(--bs-radius-d));border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d));--bs-shadow-auto:-3px 0 12px rgba(0,0,0,0.12)}.bs-sheet[data-mode="left"] .bs-content{padding-right:36px}.bs-sheet[data-mode="right"] .bs-content{padding-left:36px}.bs-handle{flex-shrink:0;min-height:44px;display:flex;flex-direction:column;justify-content:center;padding:var(--bs-handle-padding,8px 16px 4px);cursor:grab;touch-action:none;user-select:none;background:var(--bs-surface,var(--bs-surface-d));-webkit-tap-highlight-color:transparent;outline:none;position:relative}.bs-handle:active{cursor:grabbing}.bs-handle:focus-visible{outline:2px solid currentColor;outline-offset:-2px;border-radius:var(--bs-radius,var(--bs-radius-d))}.bs-handle::before{content:"";display:block;width:var(--bs-handle-width);height:var(--bs-handle-height);background:var(--bs-handle-color,var(--bs-handle-color-d));border-radius:calc(var(--bs-handle-height) / 2);margin:0 auto 8px;transition:width 0.15s ease,background 0.15s ease,transform 0.15s ease;pointer-events:none}.bs-sheet[data-mode="left"] .bs-handle,.bs-sheet[data-mode="right"] .bs-handle{position:absolute;top:0;bottom:0;width:28px;min-width:0;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0;background:var(--bs-surface,var(--bs-surface-d));z-index:1;overflow:hidden}.bs-sheet[data-mode="left"] .bs-handle>*,.bs-sheet[data-mode="right"] .bs-handle>*{display:none}.bs-sheet[data-mode="left"] .bs-handle{right:0;border-left:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="right"] .bs-handle{left:0;border-right:1px solid var(--bs-surface-border,var(--bs-surface-border-d))}.bs-sheet[data-mode="left"] .bs-handle::before,.bs-sheet[data-mode="right"] .bs-handle::before{width:var(--bs-handle-height);height:var(--bs-handle-width);margin:0}.bs-sheet:hover .bs-handle::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 15%)}.bs-handle:active::before{background:color-mix(in oklab,var(--bs-handle-color,var(--bs-handle-color-d)),#000 35%);transform:scaleX(1.15)}.bs-handle.bs-handle--ticks::after{content:"";display:block;position:absolute;left:50%;bottom:6px;transform:translateX(-50%);width:calc(var(--bs-handle-width) * 2);height:3px;background-image:radial-gradient( circle,var(--bs-handle-color,var(--bs-handle-color-d)) 0 1.5px,transparent 1.6px );background-size:8px 3px;background-repeat:repeat-x;background-position:center;opacity:0;transition:opacity 0.18s ease-out;pointer-events:none}.bs-root[data-dragging="true"] .bs-handle.bs-handle--ticks::after{opacity:0.4}.bs-sheet[data-mode="top"] .bs-handle.bs-handle--ticks::after{bottom:auto;top:6px}.bs-sheet[data-mode="left"] .bs-handle.bs-handle--ticks::after,.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{left:50%;top:50%;bottom:auto;transform:translate(-50%,-50%);width:3px;height:calc(var(--bs-handle-width) * 2);background-size:3px 8px;background-repeat:repeat-y;margin-left:calc(var(--bs-handle-height) + 6px)}.bs-sheet[data-mode="right"] .bs-handle.bs-handle--ticks::after{margin-left:calc(-1 * (var(--bs-handle-height) + 6px))}.bs-header{flex:0 0 auto;min-height:var(--bs-header-min-height,0px);padding:var(--bs-header-padding,0 16px 8px);background:var(--bs-surface,var(--bs-surface-d))}.bs-content{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;user-select:text;padding:var(--bs-content-padding,0 16px 16px)}.bs-footer{flex:0 0 auto;padding:var(--bs-footer-padding,12px 16px calc(12px + env(safe-area-inset-bottom)));border-top:1px solid var(--bs-surface-border,var(--bs-surface-border-d));background:var(--bs-surface,var(--bs-surface-d))}.bs-sheet[data-mode="bottom"]:has(.bs-footer:not([hidden]):has(*)){padding-bottom:0}.bs-header:not(:has(*)),.bs-footer:not(:has(*)),.bs-header[hidden],.bs-footer[hidden]{display:none}.bs-screen{position:absolute;inset:0;pointer-events:none;z-index:var(--bs-z-scrim);background:var(--bs-scrim-color,var(--bs-scrim-color-d));backdrop-filter:blur(var(--bs-scrim-blur,0px));-webkit-backdrop-filter:blur(var(--bs-scrim-blur,0px));transition:opacity 0.24s cubic-bezier(0.22,1,0.36,1);will-change:opacity}.bs-root[data-dragging="true"] .bs-screen,.bs-root[data-animating="true"] .bs-screen{transition:none}.bs-scrim-overlay{z-index:calc(var(--bs-z-sheet) + 1);pointer-events:none}.bs-button-slot{position:fixed;z-index:calc(var(--bs-z-sheet) + 1);pointer-events:auto}.bs-button-slot[data-side="left"]{left:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-side="right"]{right:16px;bottom:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="top"]{bottom:auto;top:calc(var(--bs-size,0px) + 12px)}.bs-button-slot[data-mode="left"]{left:calc(var(--bs-size,0px) + 12px);right:auto;bottom:auto;top:16px}.bs-button-slot[data-mode="right"]{right:calc(var(--bs-size,0px) + 12px);left:auto;bottom:auto;top:16px}@media (prefers-reduced-motion:reduce){.bs-backdrop,.bs-handle::before,.bs-button-slot[data-side="left"],.bs-button-slot[data-side="right"]{transition:none !important}}@media (prefers-color-scheme:dark){:where(.bs-root){--bs-surface-d:#1a1a1d;--bs-surface-border-d:rgba(255,255,255,0.08);--bs-handle-color-d:rgba(255,255,255,0.45);--bs-shadow-auto:0 -3px 16px rgba(0,0,0,0.5)}}@media (forced-colors:active){.bs-sheet{border:1px solid CanvasText}.bs-handle::before{background:CanvasText;forced-color-adjust:none}.bs-backdrop,.bs-screen{forced-color-adjust:none}}.bs-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}:where(.ovl-root){--ovl-surface:var(--bs-surface,var(--bs-surface-d,#ffffff));--ovl-surface-border:var(--bs-surface-border,var(--bs-surface-border-d,rgba(0,0,0,0.08)));--ovl-shadow:0 -8px 40px rgba(0,0,0,0.35);--ovl-radius:var(--bs-radius,var(--bs-radius-d,20px));--ovl-backdrop-color:rgba(0,0,0,0.5);--ovl-z-backdrop:200;--ovl-z-panel:201}.ovl-backdrop{position:fixed;inset:0;background:var(--ovl-backdrop-color);opacity:0;pointer-events:none;z-index:var(--ovl-z-backdrop)}.ovl-panel{position:fixed;background:var(--ovl-surface);box-shadow:var(--ovl-shadow);z-index:var(--ovl-z-panel);-webkit-tap-highlight-color:transparent;outline:none;transition:transform 0.32s cubic-bezier(0.29,1.24,0.84,0.99),opacity 0.32s ease-out}.ovl-panel[data-state="open"]{transform:translate3d(0,0,0);opacity:1}@starting-style{.ovl-panel[data-edge="bottom"][data-state="open"]{transform:translate3d(0,100%,0);opacity:0}.ovl-panel[data-edge="top"][data-state="open"]{transform:translate3d(0,-100%,0);opacity:0}.ovl-panel[data-edge="left"][data-state="open"]{transform:translate3d(-100%,0,0);opacity:0}.ovl-panel[data-edge="right"][data-state="open"]{transform:translate3d(100%,0,0);opacity:0}}.ovl-panel[data-edge="bottom"]{left:0;right:0;bottom:0;width:100%;border-top-left-radius:var(--ovl-radius);border-top-right-radius:var(--ovl-radius);border-top:1px solid var(--ovl-surface-border);padding-bottom:env(safe-area-inset-bottom)}.ovl-panel[data-edge="top"]{left:0;right:0;top:0;width:100%;border-bottom-left-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-bottom:1px solid var(--ovl-surface-border);padding-top:env(safe-area-inset-top)}.ovl-panel[data-edge="left"]{top:0;bottom:0;left:0;height:100%;border-top-right-radius:var(--ovl-radius);border-bottom-right-radius:var(--ovl-radius);border-right:1px solid var(--ovl-surface-border)}.ovl-panel[data-edge="right"]{top:0;bottom:0;right:0;height:100%;border-top-left-radius:var(--ovl-radius);border-bottom-left-radius:var(--ovl-radius);border-left:1px solid var(--ovl-surface-border)}@media (prefers-reduced-motion:reduce){.ovl-panel,.ovl-backdrop{transition:none !important}}`;
3839
3996
  }
3840
3997
  });
3841
3998
 
@@ -4278,10 +4435,15 @@ var init_BottomSheetElement = __esm({
4278
4435
  "progress",
4279
4436
  (payload) => this.dispatchEvent(new CustomEvent("progress", { detail: payload }))
4280
4437
  ),
4281
- this.engine.on(
4282
- "before-close",
4283
- (payload) => this.dispatchEvent(new CustomEvent("before-close", { detail: payload }))
4284
- ),
4438
+ this.engine.on("before-close", (payload) => {
4439
+ const accepted = this.dispatchEvent(
4440
+ new CustomEvent("before-close", {
4441
+ detail: payload,
4442
+ cancelable: true
4443
+ })
4444
+ );
4445
+ if (!accepted) payload.cancel();
4446
+ }),
4285
4447
  this.engine.on(
4286
4448
  "opened",
4287
4449
  (payload) => this.dispatchEvent(new CustomEvent("opened", { detail: payload }))
@@ -4297,6 +4459,10 @@ var init_BottomSheetElement = __esm({
4297
4459
  this.engine.on(
4298
4460
  "dragend",
4299
4461
  (payload) => this.dispatchEvent(new CustomEvent("drag-end", { detail: payload }))
4462
+ ),
4463
+ this.engine.on(
4464
+ "drag",
4465
+ (payload) => this.dispatchEvent(new CustomEvent("drag", { detail: payload }))
4300
4466
  )
4301
4467
  ];
4302
4468
  }