@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.
- package/README.md +126 -83
- package/dist/{BottomSheetEngine-CBRcBwV-.d.ts → BottomSheetEngine-DRjCU73e.d.ts} +6 -5
- package/dist/{BottomSheetEngine-BcyruNP1.d.cts → BottomSheetEngine-DzsIwD28.d.cts} +6 -5
- package/dist/element.cjs +388 -222
- package/dist/element.d.cts +1 -1
- package/dist/element.d.ts +1 -1
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +388 -222
- package/dist/index.cjs +389 -266
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +389 -266
- package/dist/integrations/formik.d.cts +1 -1
- package/dist/integrations/formik.d.ts +1 -1
- package/dist/integrations/react-hook-form.d.cts +1 -1
- package/dist/integrations/react-hook-form.d.ts +1 -1
- package/dist/overlay.cjs +191 -58
- package/dist/overlay.d.cts +4 -3
- package/dist/overlay.d.ts +4 -3
- package/dist/overlay.js +191 -58
- package/dist/preact.d.cts +2 -1
- package/dist/preact.d.ts +2 -1
- package/dist/qwik.cjs +396 -211
- package/dist/qwik.d.cts +11 -2
- package/dist/qwik.d.ts +11 -2
- package/dist/qwik.js +396 -211
- package/dist/react.cjs +500 -332
- package/dist/react.d.cts +26 -4
- package/dist/react.d.ts +26 -4
- package/dist/react.js +500 -332
- package/dist/solid.cjs +362 -210
- package/dist/solid.d.cts +14 -4
- package/dist/solid.d.ts +14 -4
- package/dist/solid.js +362 -210
- package/dist/solid.source.jsx +362 -210
- package/dist/styles.css +17 -1
- package/dist/svelte-core.cjs +345 -208
- package/dist/svelte-core.js +345 -208
- package/dist/svelte-src/BottomSheet.svelte +6 -0
- package/dist/svelte.cjs +359 -220
- package/dist/svelte.d.cts +2 -0
- package/dist/svelte.d.ts +2 -0
- package/dist/svelte.js +359 -220
- package/dist/teleport-7uYNiEAT.d.cts +3 -0
- package/dist/teleport-7uYNiEAT.d.ts +3 -0
- package/dist/vue.cjs +353 -209
- package/dist/vue.d.cts +3 -1
- package/dist/vue.d.ts +3 -1
- package/dist/vue.js +353 -209
- package/package.json +11 -9
package/dist/solid.source.jsx
CHANGED
|
@@ -186,11 +186,18 @@ var resolveSnap = (point, mode, measureFit) => {
|
|
|
186
186
|
return Math.max(0, el.getBoundingClientRect().width);
|
|
187
187
|
};
|
|
188
188
|
|
|
189
|
+
// src/core/primitives/devWarn.ts
|
|
190
|
+
function devWarn(...args) {
|
|
191
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
192
|
+
console.warn(...args);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
189
196
|
// src/core/primitives/snap-points.ts
|
|
190
197
|
var resolveSnapList = (points, mode, measureFit) => points.map((p) => {
|
|
191
198
|
const raw = resolveSnap(p.size, mode, measureFit);
|
|
192
199
|
if (!Number.isFinite(raw) || raw < 0) {
|
|
193
|
-
|
|
200
|
+
devWarn(
|
|
194
201
|
`[BottomSheet] snap "${p.id}" resolved to invalid size (${String(p.size)} \u2192 ${raw}); clamped to 0.`
|
|
195
202
|
);
|
|
196
203
|
return { id: p.id, size: 0 };
|
|
@@ -202,7 +209,7 @@ var auditVhUsage = (points) => {
|
|
|
202
209
|
for (const p of points) {
|
|
203
210
|
if (typeof p.size !== "string") continue;
|
|
204
211
|
if (!VH_NOT_DVH.test(p.size)) continue;
|
|
205
|
-
|
|
212
|
+
devWarn(
|
|
206
213
|
`[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`
|
|
207
214
|
);
|
|
208
215
|
}
|
|
@@ -256,6 +263,26 @@ var findDragSettleTarget = (input) => {
|
|
|
256
263
|
);
|
|
257
264
|
};
|
|
258
265
|
|
|
266
|
+
// src/core/primitives/cancelable-emit.ts
|
|
267
|
+
function emitCancelable(emit, base, warnLabel) {
|
|
268
|
+
let cancelled = false;
|
|
269
|
+
let frozen = false;
|
|
270
|
+
emit({
|
|
271
|
+
...base,
|
|
272
|
+
cancel: () => {
|
|
273
|
+
if (frozen) {
|
|
274
|
+
devWarn(
|
|
275
|
+
`[BottomSheet] ${warnLabel}.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener.`
|
|
276
|
+
);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
cancelled = true;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
frozen = true;
|
|
283
|
+
return cancelled;
|
|
284
|
+
}
|
|
285
|
+
|
|
259
286
|
// src/core/primitives/snap-resolver.ts
|
|
260
287
|
var SnapResolver = class {
|
|
261
288
|
constructor(raw, allowed, mode, measureFit, onMaxAxisSizeChange) {
|
|
@@ -403,7 +430,9 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
403
430
|
try {
|
|
404
431
|
if (linked.state.size === 0) continue;
|
|
405
432
|
const ids = linked.getAllowedIds();
|
|
406
|
-
const
|
|
433
|
+
const resolved = linked.getResolvedSnaps();
|
|
434
|
+
const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
|
|
435
|
+
const target = ids.find((id) => sizeOf(id) > 0);
|
|
407
436
|
if (target && target !== linked.state.activeId) {
|
|
408
437
|
void linked.snapTo(target);
|
|
409
438
|
}
|
|
@@ -415,46 +444,198 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
415
444
|
}
|
|
416
445
|
}
|
|
417
446
|
|
|
418
|
-
// src/core/features/
|
|
419
|
-
var
|
|
420
|
-
var
|
|
447
|
+
// src/core/features/history-coordinator.ts
|
|
448
|
+
var entries = [];
|
|
449
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
421
450
|
var suppress = 0;
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
451
|
+
var internalDepth = 0;
|
|
452
|
+
var pendingRebrand = null;
|
|
453
|
+
var listenerInstalled = false;
|
|
454
|
+
var patchInstalled = false;
|
|
455
|
+
var origPushState = null;
|
|
456
|
+
var origReplaceState = null;
|
|
457
|
+
var patchedPushState = null;
|
|
458
|
+
var patchedReplaceState = null;
|
|
459
|
+
var hasWindow = () => typeof window !== "undefined";
|
|
460
|
+
var hasHistory = () => typeof history !== "undefined";
|
|
461
|
+
var runInternal = (fn) => {
|
|
462
|
+
internalDepth += 1;
|
|
463
|
+
try {
|
|
464
|
+
fn();
|
|
465
|
+
} finally {
|
|
466
|
+
internalDepth -= 1;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
var notifyRouteChange = () => {
|
|
470
|
+
const snapshot = Array.from(subscribers);
|
|
471
|
+
for (const fn of snapshot) fn();
|
|
472
|
+
};
|
|
473
|
+
var ensureListener = () => {
|
|
474
|
+
if (listenerInstalled || !hasWindow()) return;
|
|
475
|
+
window.addEventListener("popstate", onPopState);
|
|
476
|
+
listenerInstalled = true;
|
|
477
|
+
};
|
|
478
|
+
var maybeTeardownListener = () => {
|
|
479
|
+
if (!listenerInstalled) return;
|
|
480
|
+
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
481
|
+
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
482
|
+
listenerInstalled = false;
|
|
483
|
+
};
|
|
484
|
+
var installPatch = () => {
|
|
485
|
+
if (patchInstalled || !hasHistory()) return;
|
|
486
|
+
origPushState = history.pushState;
|
|
487
|
+
origReplaceState = history.replaceState;
|
|
488
|
+
patchedPushState = function(...args) {
|
|
489
|
+
origPushState.apply(this, args);
|
|
490
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
491
|
+
};
|
|
492
|
+
patchedReplaceState = function(...args) {
|
|
493
|
+
origReplaceState.apply(this, args);
|
|
494
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
495
|
+
};
|
|
496
|
+
history.pushState = patchedPushState;
|
|
497
|
+
history.replaceState = patchedReplaceState;
|
|
498
|
+
patchInstalled = true;
|
|
499
|
+
};
|
|
500
|
+
var removePatch = () => {
|
|
501
|
+
if (!patchInstalled) return;
|
|
502
|
+
if (history.pushState === patchedPushState && origPushState) {
|
|
503
|
+
history.pushState = origPushState;
|
|
504
|
+
}
|
|
505
|
+
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
506
|
+
history.replaceState = origReplaceState;
|
|
507
|
+
}
|
|
508
|
+
origPushState = null;
|
|
509
|
+
origReplaceState = null;
|
|
510
|
+
patchedPushState = null;
|
|
511
|
+
patchedReplaceState = null;
|
|
512
|
+
patchInstalled = false;
|
|
513
|
+
};
|
|
514
|
+
function onPopState() {
|
|
515
|
+
if (suppress > 0) {
|
|
516
|
+
suppress -= 1;
|
|
517
|
+
const rebrand = pendingRebrand;
|
|
518
|
+
pendingRebrand = null;
|
|
519
|
+
if (rebrand) rebrand();
|
|
520
|
+
maybeTeardownListener();
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
if (entries.length === 0) {
|
|
524
|
+
notifyRouteChange();
|
|
525
|
+
maybeTeardownListener();
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
let target = null;
|
|
529
|
+
let targetIdx = -1;
|
|
530
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
531
|
+
const entry = entries[i];
|
|
532
|
+
if (!entry.surface.isOpen()) continue;
|
|
533
|
+
if (!target) {
|
|
534
|
+
target = entry;
|
|
535
|
+
targetIdx = i;
|
|
429
536
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if (!target) target = c;
|
|
435
|
-
if (c.isTop()) {
|
|
436
|
-
target = c;
|
|
437
|
-
break;
|
|
438
|
-
}
|
|
537
|
+
if (entry.surface.isTop()) {
|
|
538
|
+
target = entry;
|
|
539
|
+
targetIdx = i;
|
|
540
|
+
break;
|
|
439
541
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
const
|
|
443
|
-
if (
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
542
|
+
}
|
|
543
|
+
if (!target) {
|
|
544
|
+
const removed = entries.pop();
|
|
545
|
+
if (removed) removed.live = false;
|
|
546
|
+
maybeTeardownListener();
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
target.live = false;
|
|
550
|
+
entries.splice(targetIdx, 1);
|
|
551
|
+
const settled = target;
|
|
552
|
+
void Promise.resolve(settled.surface.close()).then(() => {
|
|
553
|
+
if (settled.surface.isOpen()) restore(settled);
|
|
448
554
|
});
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
555
|
+
maybeTeardownListener();
|
|
556
|
+
}
|
|
557
|
+
function restore(entry) {
|
|
558
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
559
|
+
entry.live = true;
|
|
560
|
+
runInternal(() => {
|
|
561
|
+
try {
|
|
562
|
+
history.pushState(entry.surface.markerState(), "", entry.surface.url);
|
|
563
|
+
} catch {
|
|
564
|
+
entry.live = false;
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
if (entry.live) {
|
|
568
|
+
entries.push(entry);
|
|
569
|
+
ensureListener();
|
|
456
570
|
}
|
|
457
|
-
}
|
|
571
|
+
}
|
|
572
|
+
function pushBackMarker(surface) {
|
|
573
|
+
const entry = { surface, priorUrl: void 0, live: false };
|
|
574
|
+
if (!hasWindow() || !hasHistory()) {
|
|
575
|
+
return entry;
|
|
576
|
+
}
|
|
577
|
+
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
578
|
+
runInternal(() => {
|
|
579
|
+
try {
|
|
580
|
+
history.pushState(surface.markerState(), "", surface.url);
|
|
581
|
+
entry.live = true;
|
|
582
|
+
} catch {
|
|
583
|
+
entry.live = false;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
if (entry.live) {
|
|
587
|
+
entries.push(entry);
|
|
588
|
+
ensureListener();
|
|
589
|
+
}
|
|
590
|
+
return entry;
|
|
591
|
+
}
|
|
592
|
+
function popBackMarker(handle) {
|
|
593
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
594
|
+
const entry = handle;
|
|
595
|
+
const idx = entries.indexOf(entry);
|
|
596
|
+
if (idx === -1 || !entry.live) return;
|
|
597
|
+
const last = entries.length - 1;
|
|
598
|
+
entry.live = false;
|
|
599
|
+
entries.splice(idx, 1);
|
|
600
|
+
if (idx !== last) {
|
|
601
|
+
const rebrandSurface = entries[entries.length - 1].surface;
|
|
602
|
+
const rebrandUrl = entry.priorUrl;
|
|
603
|
+
pendingRebrand = () => {
|
|
604
|
+
runInternal(() => {
|
|
605
|
+
history.replaceState(
|
|
606
|
+
rebrandSurface.markerState(),
|
|
607
|
+
"",
|
|
608
|
+
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
609
|
+
);
|
|
610
|
+
});
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
suppress += 1;
|
|
614
|
+
runInternal(() => {
|
|
615
|
+
try {
|
|
616
|
+
history.back();
|
|
617
|
+
} catch {
|
|
618
|
+
suppress = Math.max(0, suppress - 1);
|
|
619
|
+
pendingRebrand = null;
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
maybeTeardownListener();
|
|
623
|
+
}
|
|
624
|
+
function subscribeRouteChange(fn) {
|
|
625
|
+
if (!hasWindow() || !hasHistory()) return () => {
|
|
626
|
+
};
|
|
627
|
+
subscribers.add(fn);
|
|
628
|
+
if (subscribers.size === 1) installPatch();
|
|
629
|
+
ensureListener();
|
|
630
|
+
return () => {
|
|
631
|
+
if (!subscribers.has(fn)) return;
|
|
632
|
+
subscribers.delete(fn);
|
|
633
|
+
if (subscribers.size === 0) removePatch();
|
|
634
|
+
maybeTeardownListener();
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// src/core/features/route.ts
|
|
458
639
|
function installRoute(deps) {
|
|
459
640
|
if (typeof window === "undefined") {
|
|
460
641
|
return () => {
|
|
@@ -464,92 +645,39 @@ function installRoute(deps) {
|
|
|
464
645
|
return () => {
|
|
465
646
|
};
|
|
466
647
|
}
|
|
467
|
-
let
|
|
468
|
-
let closer = null;
|
|
469
|
-
const teardownEntry = () => {
|
|
470
|
-
if (closer) {
|
|
471
|
-
const idx = closers.indexOf(closer);
|
|
472
|
-
if (idx !== -1) closers.splice(idx, 1);
|
|
473
|
-
}
|
|
474
|
-
const wasConsumed = closer?.consumed ?? false;
|
|
475
|
-
closer = null;
|
|
476
|
-
if (pushed && !wasConsumed) {
|
|
477
|
-
pushed = false;
|
|
478
|
-
programmaticBack();
|
|
479
|
-
} else {
|
|
480
|
-
pushed = false;
|
|
481
|
-
}
|
|
482
|
-
};
|
|
483
|
-
const pushEntry = () => {
|
|
484
|
-
try {
|
|
485
|
-
if (deps.routedTo !== void 0) {
|
|
486
|
-
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
487
|
-
} else {
|
|
488
|
-
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
489
|
-
}
|
|
490
|
-
pushed = true;
|
|
491
|
-
} catch {
|
|
492
|
-
pushed = false;
|
|
493
|
-
}
|
|
494
|
-
};
|
|
648
|
+
let handle = null;
|
|
495
649
|
const onOpen = () => {
|
|
496
|
-
if (
|
|
497
|
-
|
|
650
|
+
if (handle) return;
|
|
651
|
+
handle = pushBackMarker({
|
|
498
652
|
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
499
|
-
isTop:
|
|
500
|
-
close:
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
closer = self;
|
|
510
|
-
ensureHandler();
|
|
511
|
-
closers.push(self);
|
|
512
|
-
pushEntry();
|
|
653
|
+
isTop: deps.isTopSheet,
|
|
654
|
+
close: deps.close,
|
|
655
|
+
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
656
|
+
url: deps.routedTo
|
|
657
|
+
});
|
|
658
|
+
};
|
|
659
|
+
const onClose = () => {
|
|
660
|
+
if (!handle) return;
|
|
661
|
+
popBackMarker(handle);
|
|
662
|
+
handle = null;
|
|
513
663
|
};
|
|
514
664
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
515
|
-
const unsubscribeClose = deps.on("close",
|
|
665
|
+
const unsubscribeClose = deps.on("close", onClose);
|
|
516
666
|
if (deps.getSize() > 0) onOpen();
|
|
517
667
|
return () => {
|
|
518
668
|
unsubscribeOpen();
|
|
519
669
|
unsubscribeClose();
|
|
520
|
-
|
|
670
|
+
if (handle) {
|
|
671
|
+
popBackMarker(handle);
|
|
672
|
+
handle = null;
|
|
673
|
+
}
|
|
521
674
|
};
|
|
522
675
|
}
|
|
523
676
|
function installRouteChange(deps) {
|
|
524
|
-
|
|
525
|
-
return () => {
|
|
526
|
-
};
|
|
527
|
-
}
|
|
528
|
-
const onChange = () => {
|
|
677
|
+
return subscribeRouteChange(() => {
|
|
529
678
|
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
530
679
|
void deps.close();
|
|
531
|
-
};
|
|
532
|
-
const wrap = (key) => {
|
|
533
|
-
const original = history[key];
|
|
534
|
-
const patched = function(...args) {
|
|
535
|
-
original.apply(this, args);
|
|
536
|
-
onChange();
|
|
537
|
-
};
|
|
538
|
-
history[key] = patched;
|
|
539
|
-
return () => {
|
|
540
|
-
if (history[key] === patched) {
|
|
541
|
-
history[key] = original;
|
|
542
|
-
}
|
|
543
|
-
};
|
|
544
|
-
};
|
|
545
|
-
window.addEventListener("popstate", onChange);
|
|
546
|
-
const restorePush = wrap("pushState");
|
|
547
|
-
const restoreReplace = wrap("replaceState");
|
|
548
|
-
return () => {
|
|
549
|
-
window.removeEventListener("popstate", onChange);
|
|
550
|
-
restorePush();
|
|
551
|
-
restoreReplace();
|
|
552
|
-
};
|
|
680
|
+
});
|
|
553
681
|
}
|
|
554
682
|
|
|
555
683
|
// src/core/features/content-swipe.ts
|
|
@@ -620,11 +748,15 @@ function installVisualViewport(deps) {
|
|
|
620
748
|
if (clamp < deps.getMaxAxisSize()) {
|
|
621
749
|
deps.setMaxAxisSize(clamp);
|
|
622
750
|
}
|
|
751
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
752
|
+
deps.cancelInFlight();
|
|
753
|
+
deps.newCycle();
|
|
623
754
|
const max = deps.getMaxAxisSize();
|
|
624
755
|
deps.setSize(Math.min(deps.getSize(), max));
|
|
625
756
|
const current = deps.resolveActiveSnap();
|
|
626
757
|
if (current && !deps.isDragging()) {
|
|
627
758
|
deps.applySize(Math.min(current.size, max));
|
|
759
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
628
760
|
} else {
|
|
629
761
|
deps.applySize(deps.getSize());
|
|
630
762
|
}
|
|
@@ -765,6 +897,54 @@ function installFitObserver(deps) {
|
|
|
765
897
|
};
|
|
766
898
|
}
|
|
767
899
|
|
|
900
|
+
// src/core/features/max-height-controller.ts
|
|
901
|
+
function createMaxHeightController(deps) {
|
|
902
|
+
let maxHeightCap;
|
|
903
|
+
let maxHeightRaw;
|
|
904
|
+
const resolveCap = () => {
|
|
905
|
+
const raw = maxHeightRaw;
|
|
906
|
+
if (raw === void 0) {
|
|
907
|
+
maxHeightCap = void 0;
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
if (typeof raw === "number") {
|
|
911
|
+
maxHeightCap = raw;
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (typeof window === "undefined") return;
|
|
915
|
+
const measured = resolveSnap(raw, deps.mode);
|
|
916
|
+
maxHeightCap = measured > 0 ? measured : void 0;
|
|
917
|
+
};
|
|
918
|
+
const clampTo = () => {
|
|
919
|
+
if (maxHeightCap === void 0) return;
|
|
920
|
+
if (deps.getMaxAxisSize() > maxHeightCap) {
|
|
921
|
+
deps.setMaxAxisSize(maxHeightCap);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
return {
|
|
925
|
+
setRadius(r) {
|
|
926
|
+
deps.element.style.setProperty(
|
|
927
|
+
"--bs-radius",
|
|
928
|
+
typeof r === "number" ? `${r}px` : r
|
|
929
|
+
);
|
|
930
|
+
},
|
|
931
|
+
setMaxHeight(h) {
|
|
932
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
933
|
+
const axis = layoutAxis(deps.mode);
|
|
934
|
+
deps.element.style.setProperty(
|
|
935
|
+
axis === "height" ? "max-height" : "max-width",
|
|
936
|
+
value
|
|
937
|
+
);
|
|
938
|
+
maxHeightRaw = h;
|
|
939
|
+
resolveCap();
|
|
940
|
+
deps.recompute();
|
|
941
|
+
},
|
|
942
|
+
resolveCap,
|
|
943
|
+
clampTo,
|
|
944
|
+
getCap: () => maxHeightCap
|
|
945
|
+
};
|
|
946
|
+
}
|
|
947
|
+
|
|
768
948
|
// src/core/features/fit-measurement.ts
|
|
769
949
|
var measureSheetNatural = (element, content, vertical) => {
|
|
770
950
|
if (!content) {
|
|
@@ -894,13 +1074,6 @@ var WriteSentinel = class {
|
|
|
894
1074
|
}
|
|
895
1075
|
};
|
|
896
1076
|
|
|
897
|
-
// src/core/primitives/devWarn.ts
|
|
898
|
-
function devWarn(...args) {
|
|
899
|
-
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
900
|
-
console.warn(...args);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
|
|
904
1077
|
// src/core/primitives/overlay-position.ts
|
|
905
1078
|
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
906
1079
|
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
@@ -2356,7 +2529,7 @@ var matchesRange = (def, progress) => {
|
|
|
2356
2529
|
};
|
|
2357
2530
|
function installScrimStages(deps, opts) {
|
|
2358
2531
|
const doc = deps.host.ownerDocument;
|
|
2359
|
-
const
|
|
2532
|
+
const entries2 = opts.stages.map((def) => {
|
|
2360
2533
|
const wrapper = doc.createElement("div");
|
|
2361
2534
|
wrapper.className = "bs-scrim-stage";
|
|
2362
2535
|
const ws = wrapper.style;
|
|
@@ -2377,9 +2550,9 @@ function installScrimStages(deps, opts) {
|
|
|
2377
2550
|
const resolveActive = () => {
|
|
2378
2551
|
const state = deps.getState();
|
|
2379
2552
|
if (state.size === 0) {
|
|
2380
|
-
return
|
|
2553
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2381
2554
|
}
|
|
2382
|
-
return
|
|
2555
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2383
2556
|
};
|
|
2384
2557
|
const hide = (entry, animate) => {
|
|
2385
2558
|
entry.inFlight?.cancel();
|
|
@@ -2428,13 +2601,13 @@ function installScrimStages(deps, opts) {
|
|
|
2428
2601
|
deps.on("open", () => update(true)),
|
|
2429
2602
|
deps.on("close", () => update(true))
|
|
2430
2603
|
];
|
|
2431
|
-
if (
|
|
2604
|
+
if (entries2.some((e) => e.def.forRange)) {
|
|
2432
2605
|
offs.push(deps.on("progress", () => update(true)));
|
|
2433
2606
|
}
|
|
2434
2607
|
update(false);
|
|
2435
2608
|
return () => {
|
|
2436
2609
|
offs.forEach((off) => off());
|
|
2437
|
-
for (const entry of
|
|
2610
|
+
for (const entry of entries2) {
|
|
2438
2611
|
entry.inFlight?.cancel();
|
|
2439
2612
|
entry.inFlight = null;
|
|
2440
2613
|
if (entry.wrapper.parentNode) {
|
|
@@ -2544,8 +2717,7 @@ var BottomSheetEngine = class {
|
|
|
2544
2717
|
disableCloseFlag;
|
|
2545
2718
|
disableDragFlag;
|
|
2546
2719
|
closeOnRouteChange;
|
|
2547
|
-
|
|
2548
|
-
maxHeightRaw;
|
|
2720
|
+
maxHeight;
|
|
2549
2721
|
snapPointsRaw;
|
|
2550
2722
|
snaps;
|
|
2551
2723
|
activeId;
|
|
@@ -2657,11 +2829,20 @@ var BottomSheetEngine = class {
|
|
|
2657
2829
|
auditVhUsage(this.snapPointsRaw);
|
|
2658
2830
|
this.auditDuplicateSnapIds(this.snapPointsRaw);
|
|
2659
2831
|
this.rootEl = this.element.closest(".bs-root");
|
|
2832
|
+
this.maxHeight = createMaxHeightController({
|
|
2833
|
+
element: this.element,
|
|
2834
|
+
mode: this.mode,
|
|
2835
|
+
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
2836
|
+
setMaxAxisSize: (size) => {
|
|
2837
|
+
this.snaps.setMaxAxisSize(size);
|
|
2838
|
+
},
|
|
2839
|
+
recompute: () => this.recompute()
|
|
2840
|
+
});
|
|
2660
2841
|
this.fitDeps = {
|
|
2661
2842
|
element: this.element,
|
|
2662
2843
|
scrollContainer: this.scrollContainer,
|
|
2663
2844
|
mode: this.mode,
|
|
2664
|
-
getMaxHeightCap: () => this.
|
|
2845
|
+
getMaxHeightCap: () => this.maxHeight.getCap()
|
|
2665
2846
|
};
|
|
2666
2847
|
this.snaps = new SnapResolver(
|
|
2667
2848
|
this.snapPointsRaw,
|
|
@@ -2683,8 +2864,8 @@ var BottomSheetEngine = class {
|
|
|
2683
2864
|
this.attach();
|
|
2684
2865
|
this.registerInStack();
|
|
2685
2866
|
if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
|
|
2686
|
-
const io = new IntersectionObserver((
|
|
2687
|
-
for (const entry of
|
|
2867
|
+
const io = new IntersectionObserver((entries2) => {
|
|
2868
|
+
for (const entry of entries2) {
|
|
2688
2869
|
if (!entry.isIntersecting) continue;
|
|
2689
2870
|
if (this.destroyed) return;
|
|
2690
2871
|
this.snaps.recompute();
|
|
@@ -2772,7 +2953,7 @@ var BottomSheetEngine = class {
|
|
|
2772
2953
|
}
|
|
2773
2954
|
use(plugin) {
|
|
2774
2955
|
if (this.destroyed) {
|
|
2775
|
-
|
|
2956
|
+
devWarn(
|
|
2776
2957
|
`[BottomSheet] use("${plugin.name}") called on destroyed engine \u2014 ignored.`
|
|
2777
2958
|
);
|
|
2778
2959
|
return this;
|
|
@@ -2814,6 +2995,9 @@ var BottomSheetEngine = class {
|
|
|
2814
2995
|
getAllowedIds() {
|
|
2815
2996
|
return this.snaps.getAllowedIds().slice();
|
|
2816
2997
|
}
|
|
2998
|
+
getResolvedSnaps() {
|
|
2999
|
+
return this.snaps.getResolvedSnaps();
|
|
3000
|
+
}
|
|
2817
3001
|
async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
|
|
2818
3002
|
if (this.destroyed) return;
|
|
2819
3003
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2822,11 +3006,11 @@ var BottomSheetEngine = class {
|
|
|
2822
3006
|
if (externalSignal?.aborted) return;
|
|
2823
3007
|
const target = this.snaps.findById(id);
|
|
2824
3008
|
if (!target) {
|
|
2825
|
-
|
|
3009
|
+
devWarn(`[BottomSheet] unknown snap id: ${id}`);
|
|
2826
3010
|
return;
|
|
2827
3011
|
}
|
|
2828
3012
|
if (!this.snaps.getAllowedIds().includes(id)) {
|
|
2829
|
-
|
|
3013
|
+
devWarn(`[BottomSheet] snap "${id}" is not in allowed list`);
|
|
2830
3014
|
return;
|
|
2831
3015
|
}
|
|
2832
3016
|
if (!_skipBeforeSnap && this.emitBeforeSnap(target, this.activeId)) {
|
|
@@ -2958,42 +3142,11 @@ var BottomSheetEngine = class {
|
|
|
2958
3142
|
}
|
|
2959
3143
|
setRadius(r) {
|
|
2960
3144
|
if (this.destroyed) return;
|
|
2961
|
-
this.
|
|
2962
|
-
"--bs-radius",
|
|
2963
|
-
typeof r === "number" ? `${r}px` : r
|
|
2964
|
-
);
|
|
3145
|
+
this.maxHeight.setRadius(r);
|
|
2965
3146
|
}
|
|
2966
3147
|
setMaxHeight(h) {
|
|
2967
3148
|
if (this.destroyed) return;
|
|
2968
|
-
|
|
2969
|
-
const axis = layoutAxis(this.mode);
|
|
2970
|
-
this.element.style.setProperty(
|
|
2971
|
-
axis === "height" ? "max-height" : "max-width",
|
|
2972
|
-
value
|
|
2973
|
-
);
|
|
2974
|
-
this.maxHeightRaw = h;
|
|
2975
|
-
this.resolveMaxHeightCap();
|
|
2976
|
-
this.recompute();
|
|
2977
|
-
}
|
|
2978
|
-
resolveMaxHeightCap() {
|
|
2979
|
-
const raw = this.maxHeightRaw;
|
|
2980
|
-
if (raw === void 0) {
|
|
2981
|
-
this.maxHeightCap = void 0;
|
|
2982
|
-
return;
|
|
2983
|
-
}
|
|
2984
|
-
if (typeof raw === "number") {
|
|
2985
|
-
this.maxHeightCap = raw;
|
|
2986
|
-
return;
|
|
2987
|
-
}
|
|
2988
|
-
if (typeof window === "undefined") return;
|
|
2989
|
-
const measured = resolveSnap(raw, this.mode);
|
|
2990
|
-
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2991
|
-
}
|
|
2992
|
-
clampToMaxHeight() {
|
|
2993
|
-
if (this.maxHeightCap === void 0) return;
|
|
2994
|
-
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2995
|
-
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2996
|
-
}
|
|
3149
|
+
this.maxHeight.setMaxHeight(h);
|
|
2997
3150
|
}
|
|
2998
3151
|
setAllowed(ids, snap) {
|
|
2999
3152
|
if (this.destroyed) return;
|
|
@@ -3081,7 +3234,7 @@ var BottomSheetEngine = class {
|
|
|
3081
3234
|
};
|
|
3082
3235
|
const host = this.screenComponent?.parentElement;
|
|
3083
3236
|
if (!host) {
|
|
3084
|
-
|
|
3237
|
+
devWarn(
|
|
3085
3238
|
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
3086
3239
|
);
|
|
3087
3240
|
return () => {
|
|
@@ -3131,9 +3284,9 @@ var BottomSheetEngine = class {
|
|
|
3131
3284
|
}
|
|
3132
3285
|
recompute() {
|
|
3133
3286
|
if (this.destroyed) return;
|
|
3134
|
-
this.
|
|
3287
|
+
this.maxHeight.resolveCap();
|
|
3135
3288
|
this.snaps.recompute();
|
|
3136
|
-
this.
|
|
3289
|
+
this.maxHeight.clampTo();
|
|
3137
3290
|
this.scrim.invalidateOpacityCache();
|
|
3138
3291
|
if (this.gesture?.isDragging) return;
|
|
3139
3292
|
const current = this.snaps.findById(this.activeId);
|
|
@@ -3183,42 +3336,18 @@ var BottomSheetEngine = class {
|
|
|
3183
3336
|
return this.currentAbort.signal;
|
|
3184
3337
|
}
|
|
3185
3338
|
emitBeforeSnap(target, previousId) {
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
previousId,
|
|
3192
|
-
cancel: () => {
|
|
3193
|
-
if (frozen) {
|
|
3194
|
-
console.warn(
|
|
3195
|
-
"[BottomSheet] before-snap.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3196
|
-
);
|
|
3197
|
-
return;
|
|
3198
|
-
}
|
|
3199
|
-
cancelled = true;
|
|
3200
|
-
}
|
|
3201
|
-
});
|
|
3202
|
-
frozen = true;
|
|
3203
|
-
return cancelled;
|
|
3339
|
+
return emitCancelable(
|
|
3340
|
+
(payload) => this.emit("before-snap", payload),
|
|
3341
|
+
{ id: target.id, size: target.size, previousId },
|
|
3342
|
+
"before-snap"
|
|
3343
|
+
);
|
|
3204
3344
|
}
|
|
3205
3345
|
emitBeforeClose(reason) {
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
if (frozen) {
|
|
3212
|
-
console.warn(
|
|
3213
|
-
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3214
|
-
);
|
|
3215
|
-
return;
|
|
3216
|
-
}
|
|
3217
|
-
cancelled = true;
|
|
3218
|
-
}
|
|
3219
|
-
});
|
|
3220
|
-
frozen = true;
|
|
3221
|
-
return cancelled;
|
|
3346
|
+
return emitCancelable(
|
|
3347
|
+
(payload) => this.emit("before-close", payload),
|
|
3348
|
+
{ reason },
|
|
3349
|
+
"before-close"
|
|
3350
|
+
);
|
|
3222
3351
|
}
|
|
3223
3352
|
applyAutoAriaLabelledBy() {
|
|
3224
3353
|
if (typeof document === "undefined") return;
|
|
@@ -3233,16 +3362,16 @@ var BottomSheetEngine = class {
|
|
|
3233
3362
|
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3234
3363
|
}
|
|
3235
3364
|
recomputeSnaps() {
|
|
3236
|
-
this.
|
|
3365
|
+
this.maxHeight.resolveCap();
|
|
3237
3366
|
this.snaps.setRaw(this.snapPointsRaw);
|
|
3238
|
-
this.
|
|
3367
|
+
this.maxHeight.clampTo();
|
|
3239
3368
|
this.scrim.invalidateOpacityCache();
|
|
3240
3369
|
}
|
|
3241
3370
|
auditDuplicateSnapIds(points) {
|
|
3242
3371
|
const seen = /* @__PURE__ */ new Set();
|
|
3243
3372
|
for (const p of points) {
|
|
3244
3373
|
if (seen.has(p.id)) {
|
|
3245
|
-
|
|
3374
|
+
devWarn(
|
|
3246
3375
|
`[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
|
|
3247
3376
|
);
|
|
3248
3377
|
}
|
|
@@ -3409,7 +3538,15 @@ var BottomSheetEngine = class {
|
|
|
3409
3538
|
setSize: (size) => {
|
|
3410
3539
|
this.size = size;
|
|
3411
3540
|
},
|
|
3412
|
-
applySize: (size) => this.applySize(size)
|
|
3541
|
+
applySize: (size) => this.applySize(size),
|
|
3542
|
+
cancelInFlight: () => {
|
|
3543
|
+
this.animation.cancel();
|
|
3544
|
+
},
|
|
3545
|
+
newCycle: () => {
|
|
3546
|
+
this.newCycle();
|
|
3547
|
+
},
|
|
3548
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3549
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
3413
3550
|
}));
|
|
3414
3551
|
}
|
|
3415
3552
|
this.teardowns.add(installSliderKeyboard({
|
|
@@ -3445,9 +3582,9 @@ var BottomSheetEngine = class {
|
|
|
3445
3582
|
return;
|
|
3446
3583
|
}
|
|
3447
3584
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
3448
|
-
const
|
|
3449
|
-
if (
|
|
3450
|
-
void this.animation.animateTo(
|
|
3585
|
+
const restore2 = this.snaps.findById(previousId);
|
|
3586
|
+
if (restore2) {
|
|
3587
|
+
void this.animation.animateTo(restore2.size, 0);
|
|
3451
3588
|
}
|
|
3452
3589
|
return;
|
|
3453
3590
|
}
|
|
@@ -3670,8 +3807,23 @@ var BottomSheet = (props) => {
|
|
|
3670
3807
|
props.onSnap?.(payload.id);
|
|
3671
3808
|
});
|
|
3672
3809
|
engine.on("before-snap", (payload) => props.onBeforeSnap?.(payload));
|
|
3673
|
-
engine.on("
|
|
3674
|
-
engine.on("
|
|
3810
|
+
engine.on("before-close", (payload) => props.onBeforeClose?.(payload));
|
|
3811
|
+
engine.on("open", (payload) => props.onOpen?.(payload.id));
|
|
3812
|
+
engine.on("close", () => props.onClose?.());
|
|
3813
|
+
engine.on("opened", (payload) => props.onOpened?.(payload.id));
|
|
3814
|
+
engine.on("closed", () => props.onClosed?.());
|
|
3815
|
+
engine.on("dragstart", (payload) => {
|
|
3816
|
+
sync();
|
|
3817
|
+
props.onDragStart?.(payload);
|
|
3818
|
+
});
|
|
3819
|
+
engine.on("dragend", (payload) => {
|
|
3820
|
+
sync();
|
|
3821
|
+
props.onDragEnd?.(payload);
|
|
3822
|
+
});
|
|
3823
|
+
if (props.onDrag) engine.on("drag", (payload) => props.onDrag?.(payload));
|
|
3824
|
+
if (props.onProgress) {
|
|
3825
|
+
engine.on("progress", (payload) => props.onProgress?.(payload));
|
|
3826
|
+
}
|
|
3675
3827
|
if (props.backdrop !== false && props.closeOnBackdrop !== false && backdropEl) {
|
|
3676
3828
|
const onBackdropClick = () => {
|
|
3677
3829
|
if (engine?.canDismiss()) void engine.close("backdrop");
|