@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.js CHANGED
@@ -213,15 +213,27 @@ var init_cssLength = __esm({
213
213
  }
214
214
  });
215
215
 
216
+ // src/core/primitives/devWarn.ts
217
+ function devWarn(...args) {
218
+ if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
219
+ console.warn(...args);
220
+ }
221
+ }
222
+ var init_devWarn = __esm({
223
+ "src/core/primitives/devWarn.ts"() {
224
+ }
225
+ });
226
+
216
227
  // src/core/primitives/snap-points.ts
217
228
  var resolveSnapList, VH_NOT_DVH, auditVhUsage, findNearest, allowedRange, findById, MOUSE_FLICK_VELOCITY, MOUSE_DRAG_THRESHOLD, DIRECTIONAL_INTENT_VELOCITY, findDragSettleTarget;
218
229
  var init_snap_points = __esm({
219
230
  "src/core/primitives/snap-points.ts"() {
220
231
  init_cssLength();
232
+ init_devWarn();
221
233
  resolveSnapList = (points, mode, measureFit) => points.map((p) => {
222
234
  const raw = resolveSnap(p.size, mode, measureFit);
223
235
  if (!Number.isFinite(raw) || raw < 0) {
224
- console.warn(
236
+ devWarn(
225
237
  `[BottomSheet] snap "${p.id}" resolved to invalid size (${String(p.size)} \u2192 ${raw}); clamped to 0.`
226
238
  );
227
239
  return { id: p.id, size: 0 };
@@ -233,7 +245,7 @@ var init_snap_points = __esm({
233
245
  for (const p of points) {
234
246
  if (typeof p.size !== "string") continue;
235
247
  if (!VH_NOT_DVH.test(p.size)) continue;
236
- console.warn(
248
+ devWarn(
237
249
  `[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`
238
250
  );
239
251
  }
@@ -289,6 +301,31 @@ var init_snap_points = __esm({
289
301
  }
290
302
  });
291
303
 
304
+ // src/core/primitives/cancelable-emit.ts
305
+ function emitCancelable(emit, base, warnLabel) {
306
+ let cancelled = false;
307
+ let frozen = false;
308
+ emit({
309
+ ...base,
310
+ cancel: () => {
311
+ if (frozen) {
312
+ devWarn(
313
+ `[BottomSheet] ${warnLabel}.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener.`
314
+ );
315
+ return;
316
+ }
317
+ cancelled = true;
318
+ }
319
+ });
320
+ frozen = true;
321
+ return cancelled;
322
+ }
323
+ var init_cancelable_emit = __esm({
324
+ "src/core/primitives/cancelable-emit.ts"() {
325
+ init_devWarn();
326
+ }
327
+ });
328
+
292
329
  // src/core/primitives/snap-resolver.ts
293
330
  var SnapResolver;
294
331
  var init_snap_resolver = __esm({
@@ -447,7 +484,9 @@ function notifyLinkedSheets(sheets, self) {
447
484
  try {
448
485
  if (linked.state.size === 0) continue;
449
486
  const ids = linked.getAllowedIds();
450
- const target = ids.find((id) => id !== "closed");
487
+ const resolved = linked.getResolvedSnaps();
488
+ const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
489
+ const target = ids.find((id) => sizeOf(id) > 0);
451
490
  if (target && target !== linked.state.activeId) {
452
491
  void linked.snapTo(target);
453
492
  }
@@ -463,6 +502,202 @@ var init_linked_sheets = __esm({
463
502
  }
464
503
  });
465
504
 
505
+ // src/core/features/history-coordinator.ts
506
+ function onPopState() {
507
+ if (suppress > 0) {
508
+ suppress -= 1;
509
+ const rebrand = pendingRebrand;
510
+ pendingRebrand = null;
511
+ if (rebrand) rebrand();
512
+ maybeTeardownListener();
513
+ return;
514
+ }
515
+ if (entries.length === 0) {
516
+ notifyRouteChange();
517
+ maybeTeardownListener();
518
+ return;
519
+ }
520
+ let target = null;
521
+ let targetIdx = -1;
522
+ for (let i = entries.length - 1; i >= 0; i -= 1) {
523
+ const entry = entries[i];
524
+ if (!entry.surface.isOpen()) continue;
525
+ if (!target) {
526
+ target = entry;
527
+ targetIdx = i;
528
+ }
529
+ if (entry.surface.isTop()) {
530
+ target = entry;
531
+ targetIdx = i;
532
+ break;
533
+ }
534
+ }
535
+ if (!target) {
536
+ const removed = entries.pop();
537
+ if (removed) removed.live = false;
538
+ maybeTeardownListener();
539
+ return;
540
+ }
541
+ target.live = false;
542
+ entries.splice(targetIdx, 1);
543
+ const settled = target;
544
+ void Promise.resolve(settled.surface.close()).then(() => {
545
+ if (settled.surface.isOpen()) restore(settled);
546
+ });
547
+ maybeTeardownListener();
548
+ }
549
+ function restore(entry) {
550
+ if (!hasWindow() || !hasHistory()) return;
551
+ entry.live = true;
552
+ runInternal(() => {
553
+ try {
554
+ history.pushState(entry.surface.markerState(), "", entry.surface.url);
555
+ } catch {
556
+ entry.live = false;
557
+ }
558
+ });
559
+ if (entry.live) {
560
+ entries.push(entry);
561
+ ensureListener();
562
+ }
563
+ }
564
+ function pushBackMarker(surface) {
565
+ const entry = { surface, priorUrl: void 0, live: false };
566
+ if (!hasWindow() || !hasHistory()) {
567
+ return entry;
568
+ }
569
+ entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
570
+ runInternal(() => {
571
+ try {
572
+ history.pushState(surface.markerState(), "", surface.url);
573
+ entry.live = true;
574
+ } catch {
575
+ entry.live = false;
576
+ }
577
+ });
578
+ if (entry.live) {
579
+ entries.push(entry);
580
+ ensureListener();
581
+ }
582
+ return entry;
583
+ }
584
+ function popBackMarker(handle) {
585
+ if (!hasWindow() || !hasHistory()) return;
586
+ const entry = handle;
587
+ const idx = entries.indexOf(entry);
588
+ if (idx === -1 || !entry.live) return;
589
+ const last = entries.length - 1;
590
+ entry.live = false;
591
+ entries.splice(idx, 1);
592
+ if (idx !== last) {
593
+ const rebrandSurface = entries[entries.length - 1].surface;
594
+ const rebrandUrl = entry.priorUrl;
595
+ pendingRebrand = () => {
596
+ runInternal(() => {
597
+ history.replaceState(
598
+ rebrandSurface.markerState(),
599
+ "",
600
+ rebrandUrl !== void 0 ? rebrandUrl : location.href
601
+ );
602
+ });
603
+ };
604
+ }
605
+ suppress += 1;
606
+ runInternal(() => {
607
+ try {
608
+ history.back();
609
+ } catch {
610
+ suppress = Math.max(0, suppress - 1);
611
+ pendingRebrand = null;
612
+ }
613
+ });
614
+ maybeTeardownListener();
615
+ }
616
+ function subscribeRouteChange(fn) {
617
+ if (!hasWindow() || !hasHistory()) return () => {
618
+ };
619
+ subscribers.add(fn);
620
+ if (subscribers.size === 1) installPatch();
621
+ ensureListener();
622
+ return () => {
623
+ if (!subscribers.has(fn)) return;
624
+ subscribers.delete(fn);
625
+ if (subscribers.size === 0) removePatch();
626
+ maybeTeardownListener();
627
+ };
628
+ }
629
+ var entries, subscribers, suppress, internalDepth, pendingRebrand, listenerInstalled, patchInstalled, origPushState, origReplaceState, patchedPushState, patchedReplaceState, hasWindow, hasHistory, runInternal, notifyRouteChange, ensureListener, maybeTeardownListener, installPatch, removePatch;
630
+ var init_history_coordinator = __esm({
631
+ "src/core/features/history-coordinator.ts"() {
632
+ entries = [];
633
+ subscribers = /* @__PURE__ */ new Set();
634
+ suppress = 0;
635
+ internalDepth = 0;
636
+ pendingRebrand = null;
637
+ listenerInstalled = false;
638
+ patchInstalled = false;
639
+ origPushState = null;
640
+ origReplaceState = null;
641
+ patchedPushState = null;
642
+ patchedReplaceState = null;
643
+ hasWindow = () => typeof window !== "undefined";
644
+ hasHistory = () => typeof history !== "undefined";
645
+ runInternal = (fn) => {
646
+ internalDepth += 1;
647
+ try {
648
+ fn();
649
+ } finally {
650
+ internalDepth -= 1;
651
+ }
652
+ };
653
+ notifyRouteChange = () => {
654
+ const snapshot = Array.from(subscribers);
655
+ for (const fn of snapshot) fn();
656
+ };
657
+ ensureListener = () => {
658
+ if (listenerInstalled || !hasWindow()) return;
659
+ window.addEventListener("popstate", onPopState);
660
+ listenerInstalled = true;
661
+ };
662
+ maybeTeardownListener = () => {
663
+ if (!listenerInstalled) return;
664
+ if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
665
+ if (hasWindow()) window.removeEventListener("popstate", onPopState);
666
+ listenerInstalled = false;
667
+ };
668
+ installPatch = () => {
669
+ if (patchInstalled || !hasHistory()) return;
670
+ origPushState = history.pushState;
671
+ origReplaceState = history.replaceState;
672
+ patchedPushState = function(...args) {
673
+ origPushState.apply(this, args);
674
+ if (internalDepth === 0) notifyRouteChange();
675
+ };
676
+ patchedReplaceState = function(...args) {
677
+ origReplaceState.apply(this, args);
678
+ if (internalDepth === 0) notifyRouteChange();
679
+ };
680
+ history.pushState = patchedPushState;
681
+ history.replaceState = patchedReplaceState;
682
+ patchInstalled = true;
683
+ };
684
+ removePatch = () => {
685
+ if (!patchInstalled) return;
686
+ if (history.pushState === patchedPushState && origPushState) {
687
+ history.pushState = origPushState;
688
+ }
689
+ if (history.replaceState === patchedReplaceState && origReplaceState) {
690
+ history.replaceState = origReplaceState;
691
+ }
692
+ origPushState = null;
693
+ origReplaceState = null;
694
+ patchedPushState = null;
695
+ patchedReplaceState = null;
696
+ patchInstalled = false;
697
+ };
698
+ }
699
+ });
700
+
466
701
  // src/core/features/route.ts
467
702
  function installRoute(deps) {
468
703
  if (typeof window === "undefined") {
@@ -473,135 +708,43 @@ function installRoute(deps) {
473
708
  return () => {
474
709
  };
475
710
  }
476
- let pushed = false;
477
- let closer = null;
478
- const teardownEntry = () => {
479
- if (closer) {
480
- const idx = closers.indexOf(closer);
481
- if (idx !== -1) closers.splice(idx, 1);
482
- }
483
- const wasConsumed = closer?.consumed ?? false;
484
- closer = null;
485
- if (pushed && !wasConsumed) {
486
- pushed = false;
487
- programmaticBack();
488
- } else {
489
- pushed = false;
490
- }
491
- };
492
- const pushEntry = () => {
493
- try {
494
- if (deps.routedTo !== void 0) {
495
- history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
496
- } else {
497
- history.pushState({ __bsSheet: deps.sheetId }, "");
498
- }
499
- pushed = true;
500
- } catch {
501
- pushed = false;
502
- }
503
- };
711
+ let handle = null;
504
712
  const onOpen = () => {
505
- if (closer) return;
506
- const self = {
713
+ if (handle) return;
714
+ handle = pushBackMarker({
507
715
  isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
508
- isTop: () => deps.isTopSheet(),
509
- close: () => deps.close(),
510
- restore: () => {
511
- if (deps.isDestroyed() || closer !== self) return;
512
- self.consumed = false;
513
- if (!closers.includes(self)) closers.push(self);
514
- pushEntry();
515
- },
516
- consumed: false
517
- };
518
- closer = self;
519
- ensureHandler();
520
- closers.push(self);
521
- pushEntry();
716
+ isTop: deps.isTopSheet,
717
+ close: deps.close,
718
+ markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
719
+ url: deps.routedTo
720
+ });
721
+ };
722
+ const onClose = () => {
723
+ if (!handle) return;
724
+ popBackMarker(handle);
725
+ handle = null;
522
726
  };
523
727
  const unsubscribeOpen = deps.on("open", onOpen);
524
- const unsubscribeClose = deps.on("close", teardownEntry);
728
+ const unsubscribeClose = deps.on("close", onClose);
525
729
  if (deps.getSize() > 0) onOpen();
526
730
  return () => {
527
731
  unsubscribeOpen();
528
732
  unsubscribeClose();
529
- teardownEntry();
733
+ if (handle) {
734
+ popBackMarker(handle);
735
+ handle = null;
736
+ }
530
737
  };
531
738
  }
532
739
  function installRouteChange(deps) {
533
- if (typeof window === "undefined" || typeof history === "undefined") {
534
- return () => {
535
- };
536
- }
537
- const onChange = () => {
740
+ return subscribeRouteChange(() => {
538
741
  if (deps.isDestroyed() || deps.getSize() <= 0) return;
539
742
  void deps.close();
540
- };
541
- const wrap = (key) => {
542
- const original = history[key];
543
- const patched = function(...args) {
544
- original.apply(this, args);
545
- onChange();
546
- };
547
- history[key] = patched;
548
- return () => {
549
- if (history[key] === patched) {
550
- history[key] = original;
551
- }
552
- };
553
- };
554
- window.addEventListener("popstate", onChange);
555
- const restorePush = wrap("pushState");
556
- const restoreReplace = wrap("replaceState");
557
- return () => {
558
- window.removeEventListener("popstate", onChange);
559
- restorePush();
560
- restoreReplace();
561
- };
743
+ });
562
744
  }
563
- var closers, handlerInstalled, suppress, ensureHandler, programmaticBack;
564
745
  var init_route = __esm({
565
746
  "src/core/features/route.ts"() {
566
- closers = [];
567
- handlerInstalled = false;
568
- suppress = 0;
569
- ensureHandler = () => {
570
- if (handlerInstalled || typeof window === "undefined") return;
571
- handlerInstalled = true;
572
- window.addEventListener("popstate", () => {
573
- if (suppress > 0) {
574
- suppress -= 1;
575
- return;
576
- }
577
- let target = null;
578
- for (let i = closers.length - 1; i >= 0; i -= 1) {
579
- const c = closers[i];
580
- if (!c.isOpen()) continue;
581
- if (!target) target = c;
582
- if (c.isTop()) {
583
- target = c;
584
- break;
585
- }
586
- }
587
- if (!target) return;
588
- target.consumed = true;
589
- const idx = closers.indexOf(target);
590
- if (idx !== -1) closers.splice(idx, 1);
591
- const settled = target;
592
- void Promise.resolve(settled.close()).then(() => {
593
- if (settled.isOpen()) settled.restore();
594
- });
595
- });
596
- };
597
- programmaticBack = () => {
598
- suppress += 1;
599
- try {
600
- history.back();
601
- } catch {
602
- suppress = Math.max(0, suppress - 1);
603
- }
604
- };
747
+ init_history_coordinator();
605
748
  }
606
749
  });
607
750
 
@@ -677,11 +820,15 @@ function installVisualViewport(deps) {
677
820
  if (clamp < deps.getMaxAxisSize()) {
678
821
  deps.setMaxAxisSize(clamp);
679
822
  }
823
+ const wasAnimating = deps.isAnimating?.() ?? false;
824
+ deps.cancelInFlight();
825
+ deps.newCycle();
680
826
  const max = deps.getMaxAxisSize();
681
827
  deps.setSize(Math.min(deps.getSize(), max));
682
828
  const current = deps.resolveActiveSnap();
683
829
  if (current && !deps.isDragging()) {
684
830
  deps.applySize(Math.min(current.size, max));
831
+ if (wasAnimating) deps.resyncAfterCancel?.();
685
832
  } else {
686
833
  deps.applySize(deps.getSize());
687
834
  }
@@ -837,6 +984,60 @@ var init_fit_observer = __esm({
837
984
  }
838
985
  });
839
986
 
987
+ // src/core/features/max-height-controller.ts
988
+ function createMaxHeightController(deps) {
989
+ let maxHeightCap;
990
+ let maxHeightRaw;
991
+ const resolveCap = () => {
992
+ const raw = maxHeightRaw;
993
+ if (raw === void 0) {
994
+ maxHeightCap = void 0;
995
+ return;
996
+ }
997
+ if (typeof raw === "number") {
998
+ maxHeightCap = raw;
999
+ return;
1000
+ }
1001
+ if (typeof window === "undefined") return;
1002
+ const measured = resolveSnap(raw, deps.mode);
1003
+ maxHeightCap = measured > 0 ? measured : void 0;
1004
+ };
1005
+ const clampTo = () => {
1006
+ if (maxHeightCap === void 0) return;
1007
+ if (deps.getMaxAxisSize() > maxHeightCap) {
1008
+ deps.setMaxAxisSize(maxHeightCap);
1009
+ }
1010
+ };
1011
+ return {
1012
+ setRadius(r) {
1013
+ deps.element.style.setProperty(
1014
+ "--bs-radius",
1015
+ typeof r === "number" ? `${r}px` : r
1016
+ );
1017
+ },
1018
+ setMaxHeight(h) {
1019
+ const value = typeof h === "number" ? `${h}px` : h;
1020
+ const axis = layoutAxis(deps.mode);
1021
+ deps.element.style.setProperty(
1022
+ axis === "height" ? "max-height" : "max-width",
1023
+ value
1024
+ );
1025
+ maxHeightRaw = h;
1026
+ resolveCap();
1027
+ deps.recompute();
1028
+ },
1029
+ resolveCap,
1030
+ clampTo,
1031
+ getCap: () => maxHeightCap
1032
+ };
1033
+ }
1034
+ var init_max_height_controller = __esm({
1035
+ "src/core/features/max-height-controller.ts"() {
1036
+ init_snap_points();
1037
+ init_transform();
1038
+ }
1039
+ });
1040
+
840
1041
  // src/core/features/fit-measurement.ts
841
1042
  var measureSheetNatural, containingExtent, measureFitSize;
842
1043
  var init_fit_measurement = __esm({
@@ -993,17 +1194,6 @@ var init_opacity_dedup = __esm({
993
1194
  }
994
1195
  });
995
1196
 
996
- // src/core/primitives/devWarn.ts
997
- function devWarn(...args) {
998
- if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
999
- console.warn(...args);
1000
- }
1001
- }
1002
- var init_devWarn = __esm({
1003
- "src/core/primitives/devWarn.ts"() {
1004
- }
1005
- });
1006
-
1007
1197
  // src/core/primitives/overlay-position.ts
1008
1198
  function resolveSheetAnchoredStyle(mode, position, inset) {
1009
1199
  const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
@@ -2552,7 +2742,7 @@ var init_sheet_anchors = __esm({
2552
2742
  // src/core/features/scrim-stages.ts
2553
2743
  function installScrimStages(deps, opts) {
2554
2744
  const doc = deps.host.ownerDocument;
2555
- const entries = opts.stages.map((def) => {
2745
+ const entries2 = opts.stages.map((def) => {
2556
2746
  const wrapper = doc.createElement("div");
2557
2747
  wrapper.className = "bs-scrim-stage";
2558
2748
  const ws = wrapper.style;
@@ -2573,9 +2763,9 @@ function installScrimStages(deps, opts) {
2573
2763
  const resolveActive = () => {
2574
2764
  const state = deps.getState();
2575
2765
  if (state.size === 0) {
2576
- return entries.find((e) => matchesId(e.def, state.activeId)) ?? null;
2766
+ return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
2577
2767
  }
2578
- return entries.find((e) => matchesId(e.def, state.activeId)) ?? entries.find((e) => matchesRange(e.def, state.progress)) ?? null;
2768
+ return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
2579
2769
  };
2580
2770
  const hide = (entry, animate) => {
2581
2771
  entry.inFlight?.cancel();
@@ -2624,13 +2814,13 @@ function installScrimStages(deps, opts) {
2624
2814
  deps.on("open", () => update(true)),
2625
2815
  deps.on("close", () => update(true))
2626
2816
  ];
2627
- if (entries.some((e) => e.def.forRange)) {
2817
+ if (entries2.some((e) => e.def.forRange)) {
2628
2818
  offs.push(deps.on("progress", () => update(true)));
2629
2819
  }
2630
2820
  update(false);
2631
2821
  return () => {
2632
2822
  offs.forEach((off) => off());
2633
- for (const entry of entries) {
2823
+ for (const entry of entries2) {
2634
2824
  entry.inFlight?.cancel();
2635
2825
  entry.inFlight = null;
2636
2826
  if (entry.wrapper.parentNode) {
@@ -2754,6 +2944,8 @@ var init_BottomSheetEngine = __esm({
2754
2944
  init_instance_id();
2755
2945
  init_event_bus();
2756
2946
  init_snap_points();
2947
+ init_cancelable_emit();
2948
+ init_devWarn();
2757
2949
  init_snap_resolver();
2758
2950
  init_persist();
2759
2951
  init_auto_collapse();
@@ -2763,6 +2955,7 @@ var init_BottomSheetEngine = __esm({
2763
2955
  init_visual_viewport();
2764
2956
  init_resize_observer();
2765
2957
  init_fit_observer();
2958
+ init_max_height_controller();
2766
2959
  init_fit_measurement();
2767
2960
  init_slider_keyboard();
2768
2961
  init_scrim_controller();
@@ -2801,8 +2994,7 @@ var init_BottomSheetEngine = __esm({
2801
2994
  __publicField(this, "disableCloseFlag");
2802
2995
  __publicField(this, "disableDragFlag");
2803
2996
  __publicField(this, "closeOnRouteChange");
2804
- __publicField(this, "maxHeightCap");
2805
- __publicField(this, "maxHeightRaw");
2997
+ __publicField(this, "maxHeight");
2806
2998
  __publicField(this, "snapPointsRaw");
2807
2999
  __publicField(this, "snaps");
2808
3000
  __publicField(this, "activeId");
@@ -2913,11 +3105,20 @@ var init_BottomSheetEngine = __esm({
2913
3105
  auditVhUsage(this.snapPointsRaw);
2914
3106
  this.auditDuplicateSnapIds(this.snapPointsRaw);
2915
3107
  this.rootEl = this.element.closest(".bs-root");
3108
+ this.maxHeight = createMaxHeightController({
3109
+ element: this.element,
3110
+ mode: this.mode,
3111
+ getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
3112
+ setMaxAxisSize: (size) => {
3113
+ this.snaps.setMaxAxisSize(size);
3114
+ },
3115
+ recompute: () => this.recompute()
3116
+ });
2916
3117
  this.fitDeps = {
2917
3118
  element: this.element,
2918
3119
  scrollContainer: this.scrollContainer,
2919
3120
  mode: this.mode,
2920
- getMaxHeightCap: () => this.maxHeightCap
3121
+ getMaxHeightCap: () => this.maxHeight.getCap()
2921
3122
  };
2922
3123
  this.snaps = new SnapResolver(
2923
3124
  this.snapPointsRaw,
@@ -2939,8 +3140,8 @@ var init_BottomSheetEngine = __esm({
2939
3140
  this.attach();
2940
3141
  this.registerInStack();
2941
3142
  if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
2942
- const io = new IntersectionObserver((entries) => {
2943
- for (const entry of entries) {
3143
+ const io = new IntersectionObserver((entries2) => {
3144
+ for (const entry of entries2) {
2944
3145
  if (!entry.isIntersecting) continue;
2945
3146
  if (this.destroyed) return;
2946
3147
  this.snaps.recompute();
@@ -3028,7 +3229,7 @@ var init_BottomSheetEngine = __esm({
3028
3229
  }
3029
3230
  use(plugin) {
3030
3231
  if (this.destroyed) {
3031
- console.warn(
3232
+ devWarn(
3032
3233
  `[BottomSheet] use("${plugin.name}") called on destroyed engine \u2014 ignored.`
3033
3234
  );
3034
3235
  return this;
@@ -3070,6 +3271,9 @@ var init_BottomSheetEngine = __esm({
3070
3271
  getAllowedIds() {
3071
3272
  return this.snaps.getAllowedIds().slice();
3072
3273
  }
3274
+ getResolvedSnaps() {
3275
+ return this.snaps.getResolvedSnaps();
3276
+ }
3073
3277
  async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
3074
3278
  if (this.destroyed) return;
3075
3279
  const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
@@ -3078,11 +3282,11 @@ var init_BottomSheetEngine = __esm({
3078
3282
  if (externalSignal?.aborted) return;
3079
3283
  const target = this.snaps.findById(id);
3080
3284
  if (!target) {
3081
- console.warn(`[BottomSheet] unknown snap id: ${id}`);
3285
+ devWarn(`[BottomSheet] unknown snap id: ${id}`);
3082
3286
  return;
3083
3287
  }
3084
3288
  if (!this.snaps.getAllowedIds().includes(id)) {
3085
- console.warn(`[BottomSheet] snap "${id}" is not in allowed list`);
3289
+ devWarn(`[BottomSheet] snap "${id}" is not in allowed list`);
3086
3290
  return;
3087
3291
  }
3088
3292
  if (!_skipBeforeSnap && this.emitBeforeSnap(target, this.activeId)) {
@@ -3214,42 +3418,11 @@ var init_BottomSheetEngine = __esm({
3214
3418
  }
3215
3419
  setRadius(r) {
3216
3420
  if (this.destroyed) return;
3217
- this.element.style.setProperty(
3218
- "--bs-radius",
3219
- typeof r === "number" ? `${r}px` : r
3220
- );
3421
+ this.maxHeight.setRadius(r);
3221
3422
  }
3222
3423
  setMaxHeight(h) {
3223
3424
  if (this.destroyed) return;
3224
- const value = typeof h === "number" ? `${h}px` : h;
3225
- const axis = layoutAxis(this.mode);
3226
- this.element.style.setProperty(
3227
- axis === "height" ? "max-height" : "max-width",
3228
- value
3229
- );
3230
- this.maxHeightRaw = h;
3231
- this.resolveMaxHeightCap();
3232
- this.recompute();
3233
- }
3234
- resolveMaxHeightCap() {
3235
- const raw = this.maxHeightRaw;
3236
- if (raw === void 0) {
3237
- this.maxHeightCap = void 0;
3238
- return;
3239
- }
3240
- if (typeof raw === "number") {
3241
- this.maxHeightCap = raw;
3242
- return;
3243
- }
3244
- if (typeof window === "undefined") return;
3245
- const measured = resolveSnap(raw, this.mode);
3246
- this.maxHeightCap = measured > 0 ? measured : void 0;
3247
- }
3248
- clampToMaxHeight() {
3249
- if (this.maxHeightCap === void 0) return;
3250
- if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
3251
- this.snaps.setMaxAxisSize(this.maxHeightCap);
3252
- }
3425
+ this.maxHeight.setMaxHeight(h);
3253
3426
  }
3254
3427
  setAllowed(ids, snap) {
3255
3428
  if (this.destroyed) return;
@@ -3337,7 +3510,7 @@ var init_BottomSheetEngine = __esm({
3337
3510
  };
3338
3511
  const host = this.screenComponent?.parentElement;
3339
3512
  if (!host) {
3340
- console.warn(
3513
+ devWarn(
3341
3514
  "[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
3342
3515
  );
3343
3516
  return () => {
@@ -3387,9 +3560,9 @@ var init_BottomSheetEngine = __esm({
3387
3560
  }
3388
3561
  recompute() {
3389
3562
  if (this.destroyed) return;
3390
- this.resolveMaxHeightCap();
3563
+ this.maxHeight.resolveCap();
3391
3564
  this.snaps.recompute();
3392
- this.clampToMaxHeight();
3565
+ this.maxHeight.clampTo();
3393
3566
  this.scrim.invalidateOpacityCache();
3394
3567
  if (this.gesture?.isDragging) return;
3395
3568
  const current = this.snaps.findById(this.activeId);
@@ -3439,42 +3612,18 @@ var init_BottomSheetEngine = __esm({
3439
3612
  return this.currentAbort.signal;
3440
3613
  }
3441
3614
  emitBeforeSnap(target, previousId) {
3442
- let cancelled = false;
3443
- let frozen = false;
3444
- this.emit("before-snap", {
3445
- id: target.id,
3446
- size: target.size,
3447
- previousId,
3448
- cancel: () => {
3449
- if (frozen) {
3450
- console.warn(
3451
- "[BottomSheet] before-snap.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
3452
- );
3453
- return;
3454
- }
3455
- cancelled = true;
3456
- }
3457
- });
3458
- frozen = true;
3459
- return cancelled;
3615
+ return emitCancelable(
3616
+ (payload) => this.emit("before-snap", payload),
3617
+ { id: target.id, size: target.size, previousId },
3618
+ "before-snap"
3619
+ );
3460
3620
  }
3461
3621
  emitBeforeClose(reason) {
3462
- let cancelled = false;
3463
- let frozen = false;
3464
- this.emit("before-close", {
3465
- reason,
3466
- cancel: () => {
3467
- if (frozen) {
3468
- console.warn(
3469
- "[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
3470
- );
3471
- return;
3472
- }
3473
- cancelled = true;
3474
- }
3475
- });
3476
- frozen = true;
3477
- return cancelled;
3622
+ return emitCancelable(
3623
+ (payload) => this.emit("before-close", payload),
3624
+ { reason },
3625
+ "before-close"
3626
+ );
3478
3627
  }
3479
3628
  applyAutoAriaLabelledBy() {
3480
3629
  if (typeof document === "undefined") return;
@@ -3489,16 +3638,16 @@ var init_BottomSheetEngine = __esm({
3489
3638
  this.element.setAttribute("aria-labelledby", titled.id);
3490
3639
  }
3491
3640
  recomputeSnaps() {
3492
- this.resolveMaxHeightCap();
3641
+ this.maxHeight.resolveCap();
3493
3642
  this.snaps.setRaw(this.snapPointsRaw);
3494
- this.clampToMaxHeight();
3643
+ this.maxHeight.clampTo();
3495
3644
  this.scrim.invalidateOpacityCache();
3496
3645
  }
3497
3646
  auditDuplicateSnapIds(points) {
3498
3647
  const seen = /* @__PURE__ */ new Set();
3499
3648
  for (const p of points) {
3500
3649
  if (seen.has(p.id)) {
3501
- console.warn(
3650
+ devWarn(
3502
3651
  `[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
3503
3652
  );
3504
3653
  }
@@ -3665,7 +3814,15 @@ var init_BottomSheetEngine = __esm({
3665
3814
  setSize: (size) => {
3666
3815
  this.size = size;
3667
3816
  },
3668
- applySize: (size) => this.applySize(size)
3817
+ applySize: (size) => this.applySize(size),
3818
+ cancelInFlight: () => {
3819
+ this.animation.cancel();
3820
+ },
3821
+ newCycle: () => {
3822
+ this.newCycle();
3823
+ },
3824
+ isAnimating: () => this.animation.isAnimating,
3825
+ resyncAfterCancel: () => this.resyncAfterResize()
3669
3826
  }));
3670
3827
  }
3671
3828
  this.teardowns.add(installSliderKeyboard({
@@ -3701,9 +3858,9 @@ var init_BottomSheetEngine = __esm({
3701
3858
  return;
3702
3859
  }
3703
3860
  if (this.emitBeforeSnap(target, previousId)) {
3704
- const restore = this.snaps.findById(previousId);
3705
- if (restore) {
3706
- void this.animation.animateTo(restore.size, 0);
3861
+ const restore2 = this.snaps.findById(previousId);
3862
+ if (restore2) {
3863
+ void this.animation.animateTo(restore2.size, 0);
3707
3864
  }
3708
3865
  return;
3709
3866
  }
@@ -3833,7 +3990,7 @@ var init_BottomSheetEngine = __esm({
3833
3990
  var baseStyles;
3834
3991
  var init_baseStyles = __esm({
3835
3992
  "src/web-component/baseStyles.ts"() {
3836
- 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}}`;
3993
+ 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}}`;
3837
3994
  }
3838
3995
  });
3839
3996
 
@@ -4276,10 +4433,15 @@ var init_BottomSheetElement = __esm({
4276
4433
  "progress",
4277
4434
  (payload) => this.dispatchEvent(new CustomEvent("progress", { detail: payload }))
4278
4435
  ),
4279
- this.engine.on(
4280
- "before-close",
4281
- (payload) => this.dispatchEvent(new CustomEvent("before-close", { detail: payload }))
4282
- ),
4436
+ this.engine.on("before-close", (payload) => {
4437
+ const accepted = this.dispatchEvent(
4438
+ new CustomEvent("before-close", {
4439
+ detail: payload,
4440
+ cancelable: true
4441
+ })
4442
+ );
4443
+ if (!accepted) payload.cancel();
4444
+ }),
4283
4445
  this.engine.on(
4284
4446
  "opened",
4285
4447
  (payload) => this.dispatchEvent(new CustomEvent("opened", { detail: payload }))
@@ -4295,6 +4457,10 @@ var init_BottomSheetElement = __esm({
4295
4457
  this.engine.on(
4296
4458
  "dragend",
4297
4459
  (payload) => this.dispatchEvent(new CustomEvent("drag-end", { detail: payload }))
4460
+ ),
4461
+ this.engine.on(
4462
+ "drag",
4463
+ (payload) => this.dispatchEvent(new CustomEvent("drag", { detail: payload }))
4298
4464
  )
4299
4465
  ];
4300
4466
  }