@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.cjs
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) {
|
|
@@ -400,7 +427,9 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
400
427
|
try {
|
|
401
428
|
if (linked.state.size === 0) continue;
|
|
402
429
|
const ids = linked.getAllowedIds();
|
|
403
|
-
const
|
|
430
|
+
const resolved = linked.getResolvedSnaps();
|
|
431
|
+
const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
|
|
432
|
+
const target = ids.find((id) => sizeOf(id) > 0);
|
|
404
433
|
if (target && target !== linked.state.activeId) {
|
|
405
434
|
void linked.snapTo(target);
|
|
406
435
|
}
|
|
@@ -412,46 +441,198 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
412
441
|
}
|
|
413
442
|
}
|
|
414
443
|
|
|
415
|
-
// src/core/features/
|
|
416
|
-
var
|
|
417
|
-
var
|
|
444
|
+
// src/core/features/history-coordinator.ts
|
|
445
|
+
var entries = [];
|
|
446
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
418
447
|
var suppress = 0;
|
|
419
|
-
var
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
448
|
+
var internalDepth = 0;
|
|
449
|
+
var pendingRebrand = null;
|
|
450
|
+
var listenerInstalled = false;
|
|
451
|
+
var patchInstalled = false;
|
|
452
|
+
var origPushState = null;
|
|
453
|
+
var origReplaceState = null;
|
|
454
|
+
var patchedPushState = null;
|
|
455
|
+
var patchedReplaceState = null;
|
|
456
|
+
var hasWindow = () => typeof window !== "undefined";
|
|
457
|
+
var hasHistory = () => typeof history !== "undefined";
|
|
458
|
+
var runInternal = (fn) => {
|
|
459
|
+
internalDepth += 1;
|
|
460
|
+
try {
|
|
461
|
+
fn();
|
|
462
|
+
} finally {
|
|
463
|
+
internalDepth -= 1;
|
|
464
|
+
}
|
|
465
|
+
};
|
|
466
|
+
var notifyRouteChange = () => {
|
|
467
|
+
const snapshot = Array.from(subscribers);
|
|
468
|
+
for (const fn of snapshot) fn();
|
|
469
|
+
};
|
|
470
|
+
var ensureListener = () => {
|
|
471
|
+
if (listenerInstalled || !hasWindow()) return;
|
|
472
|
+
window.addEventListener("popstate", onPopState);
|
|
473
|
+
listenerInstalled = true;
|
|
474
|
+
};
|
|
475
|
+
var maybeTeardownListener = () => {
|
|
476
|
+
if (!listenerInstalled) return;
|
|
477
|
+
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
478
|
+
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
479
|
+
listenerInstalled = false;
|
|
480
|
+
};
|
|
481
|
+
var installPatch = () => {
|
|
482
|
+
if (patchInstalled || !hasHistory()) return;
|
|
483
|
+
origPushState = history.pushState;
|
|
484
|
+
origReplaceState = history.replaceState;
|
|
485
|
+
patchedPushState = function(...args) {
|
|
486
|
+
origPushState.apply(this, args);
|
|
487
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
488
|
+
};
|
|
489
|
+
patchedReplaceState = function(...args) {
|
|
490
|
+
origReplaceState.apply(this, args);
|
|
491
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
492
|
+
};
|
|
493
|
+
history.pushState = patchedPushState;
|
|
494
|
+
history.replaceState = patchedReplaceState;
|
|
495
|
+
patchInstalled = true;
|
|
496
|
+
};
|
|
497
|
+
var removePatch = () => {
|
|
498
|
+
if (!patchInstalled) return;
|
|
499
|
+
if (history.pushState === patchedPushState && origPushState) {
|
|
500
|
+
history.pushState = origPushState;
|
|
501
|
+
}
|
|
502
|
+
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
503
|
+
history.replaceState = origReplaceState;
|
|
504
|
+
}
|
|
505
|
+
origPushState = null;
|
|
506
|
+
origReplaceState = null;
|
|
507
|
+
patchedPushState = null;
|
|
508
|
+
patchedReplaceState = null;
|
|
509
|
+
patchInstalled = false;
|
|
510
|
+
};
|
|
511
|
+
function onPopState() {
|
|
512
|
+
if (suppress > 0) {
|
|
513
|
+
suppress -= 1;
|
|
514
|
+
const rebrand = pendingRebrand;
|
|
515
|
+
pendingRebrand = null;
|
|
516
|
+
if (rebrand) rebrand();
|
|
517
|
+
maybeTeardownListener();
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
if (entries.length === 0) {
|
|
521
|
+
notifyRouteChange();
|
|
522
|
+
maybeTeardownListener();
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
let target = null;
|
|
526
|
+
let targetIdx = -1;
|
|
527
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
528
|
+
const entry = entries[i];
|
|
529
|
+
if (!entry.surface.isOpen()) continue;
|
|
530
|
+
if (!target) {
|
|
531
|
+
target = entry;
|
|
532
|
+
targetIdx = i;
|
|
426
533
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
if (!target) target = c;
|
|
432
|
-
if (c.isTop()) {
|
|
433
|
-
target = c;
|
|
434
|
-
break;
|
|
435
|
-
}
|
|
534
|
+
if (entry.surface.isTop()) {
|
|
535
|
+
target = entry;
|
|
536
|
+
targetIdx = i;
|
|
537
|
+
break;
|
|
436
538
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
const
|
|
440
|
-
if (
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
539
|
+
}
|
|
540
|
+
if (!target) {
|
|
541
|
+
const removed = entries.pop();
|
|
542
|
+
if (removed) removed.live = false;
|
|
543
|
+
maybeTeardownListener();
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
target.live = false;
|
|
547
|
+
entries.splice(targetIdx, 1);
|
|
548
|
+
const settled = target;
|
|
549
|
+
void Promise.resolve(settled.surface.close()).then(() => {
|
|
550
|
+
if (settled.surface.isOpen()) restore(settled);
|
|
445
551
|
});
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
552
|
+
maybeTeardownListener();
|
|
553
|
+
}
|
|
554
|
+
function restore(entry) {
|
|
555
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
556
|
+
entry.live = true;
|
|
557
|
+
runInternal(() => {
|
|
558
|
+
try {
|
|
559
|
+
history.pushState(entry.surface.markerState(), "", entry.surface.url);
|
|
560
|
+
} catch {
|
|
561
|
+
entry.live = false;
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
if (entry.live) {
|
|
565
|
+
entries.push(entry);
|
|
566
|
+
ensureListener();
|
|
453
567
|
}
|
|
454
|
-
}
|
|
568
|
+
}
|
|
569
|
+
function pushBackMarker(surface) {
|
|
570
|
+
const entry = { surface, priorUrl: void 0, live: false };
|
|
571
|
+
if (!hasWindow() || !hasHistory()) {
|
|
572
|
+
return entry;
|
|
573
|
+
}
|
|
574
|
+
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
575
|
+
runInternal(() => {
|
|
576
|
+
try {
|
|
577
|
+
history.pushState(surface.markerState(), "", surface.url);
|
|
578
|
+
entry.live = true;
|
|
579
|
+
} catch {
|
|
580
|
+
entry.live = false;
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
if (entry.live) {
|
|
584
|
+
entries.push(entry);
|
|
585
|
+
ensureListener();
|
|
586
|
+
}
|
|
587
|
+
return entry;
|
|
588
|
+
}
|
|
589
|
+
function popBackMarker(handle) {
|
|
590
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
591
|
+
const entry = handle;
|
|
592
|
+
const idx = entries.indexOf(entry);
|
|
593
|
+
if (idx === -1 || !entry.live) return;
|
|
594
|
+
const last = entries.length - 1;
|
|
595
|
+
entry.live = false;
|
|
596
|
+
entries.splice(idx, 1);
|
|
597
|
+
if (idx !== last) {
|
|
598
|
+
const rebrandSurface = entries[entries.length - 1].surface;
|
|
599
|
+
const rebrandUrl = entry.priorUrl;
|
|
600
|
+
pendingRebrand = () => {
|
|
601
|
+
runInternal(() => {
|
|
602
|
+
history.replaceState(
|
|
603
|
+
rebrandSurface.markerState(),
|
|
604
|
+
"",
|
|
605
|
+
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
606
|
+
);
|
|
607
|
+
});
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
suppress += 1;
|
|
611
|
+
runInternal(() => {
|
|
612
|
+
try {
|
|
613
|
+
history.back();
|
|
614
|
+
} catch {
|
|
615
|
+
suppress = Math.max(0, suppress - 1);
|
|
616
|
+
pendingRebrand = null;
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
maybeTeardownListener();
|
|
620
|
+
}
|
|
621
|
+
function subscribeRouteChange(fn) {
|
|
622
|
+
if (!hasWindow() || !hasHistory()) return () => {
|
|
623
|
+
};
|
|
624
|
+
subscribers.add(fn);
|
|
625
|
+
if (subscribers.size === 1) installPatch();
|
|
626
|
+
ensureListener();
|
|
627
|
+
return () => {
|
|
628
|
+
if (!subscribers.has(fn)) return;
|
|
629
|
+
subscribers.delete(fn);
|
|
630
|
+
if (subscribers.size === 0) removePatch();
|
|
631
|
+
maybeTeardownListener();
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// src/core/features/route.ts
|
|
455
636
|
function installRoute(deps) {
|
|
456
637
|
if (typeof window === "undefined") {
|
|
457
638
|
return () => {
|
|
@@ -461,92 +642,39 @@ function installRoute(deps) {
|
|
|
461
642
|
return () => {
|
|
462
643
|
};
|
|
463
644
|
}
|
|
464
|
-
let
|
|
465
|
-
let closer = null;
|
|
466
|
-
const teardownEntry = () => {
|
|
467
|
-
if (closer) {
|
|
468
|
-
const idx = closers.indexOf(closer);
|
|
469
|
-
if (idx !== -1) closers.splice(idx, 1);
|
|
470
|
-
}
|
|
471
|
-
const wasConsumed = closer?.consumed ?? false;
|
|
472
|
-
closer = null;
|
|
473
|
-
if (pushed && !wasConsumed) {
|
|
474
|
-
pushed = false;
|
|
475
|
-
programmaticBack();
|
|
476
|
-
} else {
|
|
477
|
-
pushed = false;
|
|
478
|
-
}
|
|
479
|
-
};
|
|
480
|
-
const pushEntry = () => {
|
|
481
|
-
try {
|
|
482
|
-
if (deps.routedTo !== void 0) {
|
|
483
|
-
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
484
|
-
} else {
|
|
485
|
-
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
486
|
-
}
|
|
487
|
-
pushed = true;
|
|
488
|
-
} catch {
|
|
489
|
-
pushed = false;
|
|
490
|
-
}
|
|
491
|
-
};
|
|
645
|
+
let handle = null;
|
|
492
646
|
const onOpen = () => {
|
|
493
|
-
if (
|
|
494
|
-
|
|
647
|
+
if (handle) return;
|
|
648
|
+
handle = pushBackMarker({
|
|
495
649
|
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
496
|
-
isTop:
|
|
497
|
-
close:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
closer = self;
|
|
507
|
-
ensureHandler();
|
|
508
|
-
closers.push(self);
|
|
509
|
-
pushEntry();
|
|
650
|
+
isTop: deps.isTopSheet,
|
|
651
|
+
close: deps.close,
|
|
652
|
+
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
653
|
+
url: deps.routedTo
|
|
654
|
+
});
|
|
655
|
+
};
|
|
656
|
+
const onClose = () => {
|
|
657
|
+
if (!handle) return;
|
|
658
|
+
popBackMarker(handle);
|
|
659
|
+
handle = null;
|
|
510
660
|
};
|
|
511
661
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
512
|
-
const unsubscribeClose = deps.on("close",
|
|
662
|
+
const unsubscribeClose = deps.on("close", onClose);
|
|
513
663
|
if (deps.getSize() > 0) onOpen();
|
|
514
664
|
return () => {
|
|
515
665
|
unsubscribeOpen();
|
|
516
666
|
unsubscribeClose();
|
|
517
|
-
|
|
667
|
+
if (handle) {
|
|
668
|
+
popBackMarker(handle);
|
|
669
|
+
handle = null;
|
|
670
|
+
}
|
|
518
671
|
};
|
|
519
672
|
}
|
|
520
673
|
function installRouteChange(deps) {
|
|
521
|
-
|
|
522
|
-
return () => {
|
|
523
|
-
};
|
|
524
|
-
}
|
|
525
|
-
const onChange = () => {
|
|
674
|
+
return subscribeRouteChange(() => {
|
|
526
675
|
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
527
676
|
void deps.close();
|
|
528
|
-
};
|
|
529
|
-
const wrap = (key) => {
|
|
530
|
-
const original = history[key];
|
|
531
|
-
const patched = function(...args) {
|
|
532
|
-
original.apply(this, args);
|
|
533
|
-
onChange();
|
|
534
|
-
};
|
|
535
|
-
history[key] = patched;
|
|
536
|
-
return () => {
|
|
537
|
-
if (history[key] === patched) {
|
|
538
|
-
history[key] = original;
|
|
539
|
-
}
|
|
540
|
-
};
|
|
541
|
-
};
|
|
542
|
-
window.addEventListener("popstate", onChange);
|
|
543
|
-
const restorePush = wrap("pushState");
|
|
544
|
-
const restoreReplace = wrap("replaceState");
|
|
545
|
-
return () => {
|
|
546
|
-
window.removeEventListener("popstate", onChange);
|
|
547
|
-
restorePush();
|
|
548
|
-
restoreReplace();
|
|
549
|
-
};
|
|
677
|
+
});
|
|
550
678
|
}
|
|
551
679
|
|
|
552
680
|
// src/core/features/content-swipe.ts
|
|
@@ -617,11 +745,15 @@ function installVisualViewport(deps) {
|
|
|
617
745
|
if (clamp < deps.getMaxAxisSize()) {
|
|
618
746
|
deps.setMaxAxisSize(clamp);
|
|
619
747
|
}
|
|
748
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
749
|
+
deps.cancelInFlight();
|
|
750
|
+
deps.newCycle();
|
|
620
751
|
const max = deps.getMaxAxisSize();
|
|
621
752
|
deps.setSize(Math.min(deps.getSize(), max));
|
|
622
753
|
const current = deps.resolveActiveSnap();
|
|
623
754
|
if (current && !deps.isDragging()) {
|
|
624
755
|
deps.applySize(Math.min(current.size, max));
|
|
756
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
625
757
|
} else {
|
|
626
758
|
deps.applySize(deps.getSize());
|
|
627
759
|
}
|
|
@@ -762,6 +894,54 @@ function installFitObserver(deps) {
|
|
|
762
894
|
};
|
|
763
895
|
}
|
|
764
896
|
|
|
897
|
+
// src/core/features/max-height-controller.ts
|
|
898
|
+
function createMaxHeightController(deps) {
|
|
899
|
+
let maxHeightCap;
|
|
900
|
+
let maxHeightRaw;
|
|
901
|
+
const resolveCap = () => {
|
|
902
|
+
const raw = maxHeightRaw;
|
|
903
|
+
if (raw === void 0) {
|
|
904
|
+
maxHeightCap = void 0;
|
|
905
|
+
return;
|
|
906
|
+
}
|
|
907
|
+
if (typeof raw === "number") {
|
|
908
|
+
maxHeightCap = raw;
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
if (typeof window === "undefined") return;
|
|
912
|
+
const measured = resolveSnap(raw, deps.mode);
|
|
913
|
+
maxHeightCap = measured > 0 ? measured : void 0;
|
|
914
|
+
};
|
|
915
|
+
const clampTo = () => {
|
|
916
|
+
if (maxHeightCap === void 0) return;
|
|
917
|
+
if (deps.getMaxAxisSize() > maxHeightCap) {
|
|
918
|
+
deps.setMaxAxisSize(maxHeightCap);
|
|
919
|
+
}
|
|
920
|
+
};
|
|
921
|
+
return {
|
|
922
|
+
setRadius(r) {
|
|
923
|
+
deps.element.style.setProperty(
|
|
924
|
+
"--bs-radius",
|
|
925
|
+
typeof r === "number" ? `${r}px` : r
|
|
926
|
+
);
|
|
927
|
+
},
|
|
928
|
+
setMaxHeight(h) {
|
|
929
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
930
|
+
const axis = layoutAxis(deps.mode);
|
|
931
|
+
deps.element.style.setProperty(
|
|
932
|
+
axis === "height" ? "max-height" : "max-width",
|
|
933
|
+
value
|
|
934
|
+
);
|
|
935
|
+
maxHeightRaw = h;
|
|
936
|
+
resolveCap();
|
|
937
|
+
deps.recompute();
|
|
938
|
+
},
|
|
939
|
+
resolveCap,
|
|
940
|
+
clampTo,
|
|
941
|
+
getCap: () => maxHeightCap
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
|
|
765
945
|
// src/core/features/fit-measurement.ts
|
|
766
946
|
var measureSheetNatural = (element, content, vertical) => {
|
|
767
947
|
if (!content) {
|
|
@@ -893,13 +1073,6 @@ var WriteSentinel = class {
|
|
|
893
1073
|
}
|
|
894
1074
|
};
|
|
895
1075
|
|
|
896
|
-
// src/core/primitives/devWarn.ts
|
|
897
|
-
function devWarn(...args) {
|
|
898
|
-
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
899
|
-
console.warn(...args);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
|
|
903
1076
|
// src/core/primitives/overlay-position.ts
|
|
904
1077
|
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
905
1078
|
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
@@ -2354,7 +2527,7 @@ var matchesRange = (def, progress) => {
|
|
|
2354
2527
|
};
|
|
2355
2528
|
function installScrimStages(deps, opts) {
|
|
2356
2529
|
const doc = deps.host.ownerDocument;
|
|
2357
|
-
const
|
|
2530
|
+
const entries2 = opts.stages.map((def) => {
|
|
2358
2531
|
const wrapper = doc.createElement("div");
|
|
2359
2532
|
wrapper.className = "bs-scrim-stage";
|
|
2360
2533
|
const ws = wrapper.style;
|
|
@@ -2375,9 +2548,9 @@ function installScrimStages(deps, opts) {
|
|
|
2375
2548
|
const resolveActive = () => {
|
|
2376
2549
|
const state = deps.getState();
|
|
2377
2550
|
if (state.size === 0) {
|
|
2378
|
-
return
|
|
2551
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2379
2552
|
}
|
|
2380
|
-
return
|
|
2553
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2381
2554
|
};
|
|
2382
2555
|
const hide = (entry, animate) => {
|
|
2383
2556
|
entry.inFlight?.cancel();
|
|
@@ -2426,13 +2599,13 @@ function installScrimStages(deps, opts) {
|
|
|
2426
2599
|
deps.on("open", () => update(true)),
|
|
2427
2600
|
deps.on("close", () => update(true))
|
|
2428
2601
|
];
|
|
2429
|
-
if (
|
|
2602
|
+
if (entries2.some((e) => e.def.forRange)) {
|
|
2430
2603
|
offs.push(deps.on("progress", () => update(true)));
|
|
2431
2604
|
}
|
|
2432
2605
|
update(false);
|
|
2433
2606
|
return () => {
|
|
2434
2607
|
offs.forEach((off) => off());
|
|
2435
|
-
for (const entry of
|
|
2608
|
+
for (const entry of entries2) {
|
|
2436
2609
|
entry.inFlight?.cancel();
|
|
2437
2610
|
entry.inFlight = null;
|
|
2438
2611
|
if (entry.wrapper.parentNode) {
|
|
@@ -2545,8 +2718,7 @@ var BottomSheetEngine = class {
|
|
|
2545
2718
|
__publicField(this, "disableCloseFlag");
|
|
2546
2719
|
__publicField(this, "disableDragFlag");
|
|
2547
2720
|
__publicField(this, "closeOnRouteChange");
|
|
2548
|
-
__publicField(this, "
|
|
2549
|
-
__publicField(this, "maxHeightRaw");
|
|
2721
|
+
__publicField(this, "maxHeight");
|
|
2550
2722
|
__publicField(this, "snapPointsRaw");
|
|
2551
2723
|
__publicField(this, "snaps");
|
|
2552
2724
|
__publicField(this, "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
|
}
|
|
@@ -3675,8 +3812,23 @@ var BottomSheet = (props) => {
|
|
|
3675
3812
|
props.onSnap?.(payload.id);
|
|
3676
3813
|
});
|
|
3677
3814
|
engine.on("before-snap", (payload) => props.onBeforeSnap?.(payload));
|
|
3678
|
-
engine.on("
|
|
3679
|
-
engine.on("
|
|
3815
|
+
engine.on("before-close", (payload) => props.onBeforeClose?.(payload));
|
|
3816
|
+
engine.on("open", (payload) => props.onOpen?.(payload.id));
|
|
3817
|
+
engine.on("close", () => props.onClose?.());
|
|
3818
|
+
engine.on("opened", (payload) => props.onOpened?.(payload.id));
|
|
3819
|
+
engine.on("closed", () => props.onClosed?.());
|
|
3820
|
+
engine.on("dragstart", (payload) => {
|
|
3821
|
+
sync();
|
|
3822
|
+
props.onDragStart?.(payload);
|
|
3823
|
+
});
|
|
3824
|
+
engine.on("dragend", (payload) => {
|
|
3825
|
+
sync();
|
|
3826
|
+
props.onDragEnd?.(payload);
|
|
3827
|
+
});
|
|
3828
|
+
if (props.onDrag) engine.on("drag", (payload) => props.onDrag?.(payload));
|
|
3829
|
+
if (props.onProgress) {
|
|
3830
|
+
engine.on("progress", (payload) => props.onProgress?.(payload));
|
|
3831
|
+
}
|
|
3680
3832
|
if (props.backdrop !== false && props.closeOnBackdrop !== false && backdropEl) {
|
|
3681
3833
|
const onBackdropClick = () => {
|
|
3682
3834
|
if (engine?.canDismiss()) void engine.close("backdrop");
|