@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/react.cjs
CHANGED
|
@@ -193,11 +193,18 @@ var resolveSnap = (point, mode, measureFit) => {
|
|
|
193
193
|
return Math.max(0, el.getBoundingClientRect().width);
|
|
194
194
|
};
|
|
195
195
|
|
|
196
|
+
// src/core/primitives/devWarn.ts
|
|
197
|
+
function devWarn(...args) {
|
|
198
|
+
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
199
|
+
console.warn(...args);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
196
203
|
// src/core/primitives/snap-points.ts
|
|
197
204
|
var resolveSnapList = (points, mode, measureFit) => points.map((p) => {
|
|
198
205
|
const raw = resolveSnap(p.size, mode, measureFit);
|
|
199
206
|
if (!Number.isFinite(raw) || raw < 0) {
|
|
200
|
-
|
|
207
|
+
devWarn(
|
|
201
208
|
`[BottomSheet] snap "${p.id}" resolved to invalid size (${String(p.size)} \u2192 ${raw}); clamped to 0.`
|
|
202
209
|
);
|
|
203
210
|
return { id: p.id, size: 0 };
|
|
@@ -209,7 +216,7 @@ var auditVhUsage = (points) => {
|
|
|
209
216
|
for (const p of points) {
|
|
210
217
|
if (typeof p.size !== "string") continue;
|
|
211
218
|
if (!VH_NOT_DVH.test(p.size)) continue;
|
|
212
|
-
|
|
219
|
+
devWarn(
|
|
213
220
|
`[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`
|
|
214
221
|
);
|
|
215
222
|
}
|
|
@@ -263,6 +270,26 @@ var findDragSettleTarget = (input) => {
|
|
|
263
270
|
);
|
|
264
271
|
};
|
|
265
272
|
|
|
273
|
+
// src/core/primitives/cancelable-emit.ts
|
|
274
|
+
function emitCancelable(emit, base, warnLabel) {
|
|
275
|
+
let cancelled = false;
|
|
276
|
+
let frozen = false;
|
|
277
|
+
emit({
|
|
278
|
+
...base,
|
|
279
|
+
cancel: () => {
|
|
280
|
+
if (frozen) {
|
|
281
|
+
devWarn(
|
|
282
|
+
`[BottomSheet] ${warnLabel}.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener.`
|
|
283
|
+
);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
cancelled = true;
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
frozen = true;
|
|
290
|
+
return cancelled;
|
|
291
|
+
}
|
|
292
|
+
|
|
266
293
|
// src/core/primitives/snap-resolver.ts
|
|
267
294
|
var SnapResolver = class {
|
|
268
295
|
constructor(raw, allowed, mode, measureFit, onMaxAxisSizeChange) {
|
|
@@ -407,7 +434,9 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
407
434
|
try {
|
|
408
435
|
if (linked.state.size === 0) continue;
|
|
409
436
|
const ids = linked.getAllowedIds();
|
|
410
|
-
const
|
|
437
|
+
const resolved = linked.getResolvedSnaps();
|
|
438
|
+
const sizeOf = (id) => resolved.find((s) => s.id === id)?.size ?? 0;
|
|
439
|
+
const target = ids.find((id) => sizeOf(id) > 0);
|
|
411
440
|
if (target && target !== linked.state.activeId) {
|
|
412
441
|
void linked.snapTo(target);
|
|
413
442
|
}
|
|
@@ -419,46 +448,198 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
419
448
|
}
|
|
420
449
|
}
|
|
421
450
|
|
|
422
|
-
// src/core/features/
|
|
423
|
-
var
|
|
424
|
-
var
|
|
451
|
+
// src/core/features/history-coordinator.ts
|
|
452
|
+
var entries = [];
|
|
453
|
+
var subscribers = /* @__PURE__ */ new Set();
|
|
425
454
|
var suppress = 0;
|
|
426
|
-
var
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
455
|
+
var internalDepth = 0;
|
|
456
|
+
var pendingRebrand = null;
|
|
457
|
+
var listenerInstalled = false;
|
|
458
|
+
var patchInstalled = false;
|
|
459
|
+
var origPushState = null;
|
|
460
|
+
var origReplaceState = null;
|
|
461
|
+
var patchedPushState = null;
|
|
462
|
+
var patchedReplaceState = null;
|
|
463
|
+
var hasWindow = () => typeof window !== "undefined";
|
|
464
|
+
var hasHistory = () => typeof history !== "undefined";
|
|
465
|
+
var runInternal = (fn) => {
|
|
466
|
+
internalDepth += 1;
|
|
467
|
+
try {
|
|
468
|
+
fn();
|
|
469
|
+
} finally {
|
|
470
|
+
internalDepth -= 1;
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
var notifyRouteChange = () => {
|
|
474
|
+
const snapshot = Array.from(subscribers);
|
|
475
|
+
for (const fn of snapshot) fn();
|
|
476
|
+
};
|
|
477
|
+
var ensureListener = () => {
|
|
478
|
+
if (listenerInstalled || !hasWindow()) return;
|
|
479
|
+
window.addEventListener("popstate", onPopState);
|
|
480
|
+
listenerInstalled = true;
|
|
481
|
+
};
|
|
482
|
+
var maybeTeardownListener = () => {
|
|
483
|
+
if (!listenerInstalled) return;
|
|
484
|
+
if (entries.length > 0 || subscribers.size > 0 || suppress > 0) return;
|
|
485
|
+
if (hasWindow()) window.removeEventListener("popstate", onPopState);
|
|
486
|
+
listenerInstalled = false;
|
|
487
|
+
};
|
|
488
|
+
var installPatch = () => {
|
|
489
|
+
if (patchInstalled || !hasHistory()) return;
|
|
490
|
+
origPushState = history.pushState;
|
|
491
|
+
origReplaceState = history.replaceState;
|
|
492
|
+
patchedPushState = function(...args) {
|
|
493
|
+
origPushState.apply(this, args);
|
|
494
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
495
|
+
};
|
|
496
|
+
patchedReplaceState = function(...args) {
|
|
497
|
+
origReplaceState.apply(this, args);
|
|
498
|
+
if (internalDepth === 0) notifyRouteChange();
|
|
499
|
+
};
|
|
500
|
+
history.pushState = patchedPushState;
|
|
501
|
+
history.replaceState = patchedReplaceState;
|
|
502
|
+
patchInstalled = true;
|
|
503
|
+
};
|
|
504
|
+
var removePatch = () => {
|
|
505
|
+
if (!patchInstalled) return;
|
|
506
|
+
if (history.pushState === patchedPushState && origPushState) {
|
|
507
|
+
history.pushState = origPushState;
|
|
508
|
+
}
|
|
509
|
+
if (history.replaceState === patchedReplaceState && origReplaceState) {
|
|
510
|
+
history.replaceState = origReplaceState;
|
|
511
|
+
}
|
|
512
|
+
origPushState = null;
|
|
513
|
+
origReplaceState = null;
|
|
514
|
+
patchedPushState = null;
|
|
515
|
+
patchedReplaceState = null;
|
|
516
|
+
patchInstalled = false;
|
|
517
|
+
};
|
|
518
|
+
function onPopState() {
|
|
519
|
+
if (suppress > 0) {
|
|
520
|
+
suppress -= 1;
|
|
521
|
+
const rebrand = pendingRebrand;
|
|
522
|
+
pendingRebrand = null;
|
|
523
|
+
if (rebrand) rebrand();
|
|
524
|
+
maybeTeardownListener();
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
if (entries.length === 0) {
|
|
528
|
+
notifyRouteChange();
|
|
529
|
+
maybeTeardownListener();
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
let target = null;
|
|
533
|
+
let targetIdx = -1;
|
|
534
|
+
for (let i = entries.length - 1; i >= 0; i -= 1) {
|
|
535
|
+
const entry = entries[i];
|
|
536
|
+
if (!entry.surface.isOpen()) continue;
|
|
537
|
+
if (!target) {
|
|
538
|
+
target = entry;
|
|
539
|
+
targetIdx = i;
|
|
433
540
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if (!target) target = c;
|
|
439
|
-
if (c.isTop()) {
|
|
440
|
-
target = c;
|
|
441
|
-
break;
|
|
442
|
-
}
|
|
541
|
+
if (entry.surface.isTop()) {
|
|
542
|
+
target = entry;
|
|
543
|
+
targetIdx = i;
|
|
544
|
+
break;
|
|
443
545
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
const
|
|
447
|
-
if (
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
546
|
+
}
|
|
547
|
+
if (!target) {
|
|
548
|
+
const removed = entries.pop();
|
|
549
|
+
if (removed) removed.live = false;
|
|
550
|
+
maybeTeardownListener();
|
|
551
|
+
return;
|
|
552
|
+
}
|
|
553
|
+
target.live = false;
|
|
554
|
+
entries.splice(targetIdx, 1);
|
|
555
|
+
const settled = target;
|
|
556
|
+
void Promise.resolve(settled.surface.close()).then(() => {
|
|
557
|
+
if (settled.surface.isOpen()) restore(settled);
|
|
452
558
|
});
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
559
|
+
maybeTeardownListener();
|
|
560
|
+
}
|
|
561
|
+
function restore(entry) {
|
|
562
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
563
|
+
entry.live = true;
|
|
564
|
+
runInternal(() => {
|
|
565
|
+
try {
|
|
566
|
+
history.pushState(entry.surface.markerState(), "", entry.surface.url);
|
|
567
|
+
} catch {
|
|
568
|
+
entry.live = false;
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
if (entry.live) {
|
|
572
|
+
entries.push(entry);
|
|
573
|
+
ensureListener();
|
|
460
574
|
}
|
|
461
|
-
}
|
|
575
|
+
}
|
|
576
|
+
function pushBackMarker(surface) {
|
|
577
|
+
const entry = { surface, priorUrl: void 0, live: false };
|
|
578
|
+
if (!hasWindow() || !hasHistory()) {
|
|
579
|
+
return entry;
|
|
580
|
+
}
|
|
581
|
+
entry.priorUrl = surface.url !== void 0 ? location.href : void 0;
|
|
582
|
+
runInternal(() => {
|
|
583
|
+
try {
|
|
584
|
+
history.pushState(surface.markerState(), "", surface.url);
|
|
585
|
+
entry.live = true;
|
|
586
|
+
} catch {
|
|
587
|
+
entry.live = false;
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
if (entry.live) {
|
|
591
|
+
entries.push(entry);
|
|
592
|
+
ensureListener();
|
|
593
|
+
}
|
|
594
|
+
return entry;
|
|
595
|
+
}
|
|
596
|
+
function popBackMarker(handle) {
|
|
597
|
+
if (!hasWindow() || !hasHistory()) return;
|
|
598
|
+
const entry = handle;
|
|
599
|
+
const idx = entries.indexOf(entry);
|
|
600
|
+
if (idx === -1 || !entry.live) return;
|
|
601
|
+
const last = entries.length - 1;
|
|
602
|
+
entry.live = false;
|
|
603
|
+
entries.splice(idx, 1);
|
|
604
|
+
if (idx !== last) {
|
|
605
|
+
const rebrandSurface = entries[entries.length - 1].surface;
|
|
606
|
+
const rebrandUrl = entry.priorUrl;
|
|
607
|
+
pendingRebrand = () => {
|
|
608
|
+
runInternal(() => {
|
|
609
|
+
history.replaceState(
|
|
610
|
+
rebrandSurface.markerState(),
|
|
611
|
+
"",
|
|
612
|
+
rebrandUrl !== void 0 ? rebrandUrl : location.href
|
|
613
|
+
);
|
|
614
|
+
});
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
suppress += 1;
|
|
618
|
+
runInternal(() => {
|
|
619
|
+
try {
|
|
620
|
+
history.back();
|
|
621
|
+
} catch {
|
|
622
|
+
suppress = Math.max(0, suppress - 1);
|
|
623
|
+
pendingRebrand = null;
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
maybeTeardownListener();
|
|
627
|
+
}
|
|
628
|
+
function subscribeRouteChange(fn) {
|
|
629
|
+
if (!hasWindow() || !hasHistory()) return () => {
|
|
630
|
+
};
|
|
631
|
+
subscribers.add(fn);
|
|
632
|
+
if (subscribers.size === 1) installPatch();
|
|
633
|
+
ensureListener();
|
|
634
|
+
return () => {
|
|
635
|
+
if (!subscribers.has(fn)) return;
|
|
636
|
+
subscribers.delete(fn);
|
|
637
|
+
if (subscribers.size === 0) removePatch();
|
|
638
|
+
maybeTeardownListener();
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// src/core/features/route.ts
|
|
462
643
|
function installRoute(deps) {
|
|
463
644
|
if (typeof window === "undefined") {
|
|
464
645
|
return () => {
|
|
@@ -468,92 +649,39 @@ function installRoute(deps) {
|
|
|
468
649
|
return () => {
|
|
469
650
|
};
|
|
470
651
|
}
|
|
471
|
-
let
|
|
472
|
-
let closer = null;
|
|
473
|
-
const teardownEntry = () => {
|
|
474
|
-
if (closer) {
|
|
475
|
-
const idx = closers.indexOf(closer);
|
|
476
|
-
if (idx !== -1) closers.splice(idx, 1);
|
|
477
|
-
}
|
|
478
|
-
const wasConsumed = closer?.consumed ?? false;
|
|
479
|
-
closer = null;
|
|
480
|
-
if (pushed && !wasConsumed) {
|
|
481
|
-
pushed = false;
|
|
482
|
-
programmaticBack();
|
|
483
|
-
} else {
|
|
484
|
-
pushed = false;
|
|
485
|
-
}
|
|
486
|
-
};
|
|
487
|
-
const pushEntry = () => {
|
|
488
|
-
try {
|
|
489
|
-
if (deps.routedTo !== void 0) {
|
|
490
|
-
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
491
|
-
} else {
|
|
492
|
-
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
493
|
-
}
|
|
494
|
-
pushed = true;
|
|
495
|
-
} catch {
|
|
496
|
-
pushed = false;
|
|
497
|
-
}
|
|
498
|
-
};
|
|
652
|
+
let handle = null;
|
|
499
653
|
const onOpen = () => {
|
|
500
|
-
if (
|
|
501
|
-
|
|
654
|
+
if (handle) return;
|
|
655
|
+
handle = pushBackMarker({
|
|
502
656
|
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
503
|
-
isTop:
|
|
504
|
-
close:
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
closer = self;
|
|
514
|
-
ensureHandler();
|
|
515
|
-
closers.push(self);
|
|
516
|
-
pushEntry();
|
|
657
|
+
isTop: deps.isTopSheet,
|
|
658
|
+
close: deps.close,
|
|
659
|
+
markerState: () => deps.routedTo !== void 0 ? { __bsRouted: deps.sheetId } : { __bsSheet: deps.sheetId },
|
|
660
|
+
url: deps.routedTo
|
|
661
|
+
});
|
|
662
|
+
};
|
|
663
|
+
const onClose = () => {
|
|
664
|
+
if (!handle) return;
|
|
665
|
+
popBackMarker(handle);
|
|
666
|
+
handle = null;
|
|
517
667
|
};
|
|
518
668
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
519
|
-
const unsubscribeClose = deps.on("close",
|
|
669
|
+
const unsubscribeClose = deps.on("close", onClose);
|
|
520
670
|
if (deps.getSize() > 0) onOpen();
|
|
521
671
|
return () => {
|
|
522
672
|
unsubscribeOpen();
|
|
523
673
|
unsubscribeClose();
|
|
524
|
-
|
|
674
|
+
if (handle) {
|
|
675
|
+
popBackMarker(handle);
|
|
676
|
+
handle = null;
|
|
677
|
+
}
|
|
525
678
|
};
|
|
526
679
|
}
|
|
527
680
|
function installRouteChange(deps) {
|
|
528
|
-
|
|
529
|
-
return () => {
|
|
530
|
-
};
|
|
531
|
-
}
|
|
532
|
-
const onChange = () => {
|
|
681
|
+
return subscribeRouteChange(() => {
|
|
533
682
|
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
534
683
|
void deps.close();
|
|
535
|
-
};
|
|
536
|
-
const wrap = (key) => {
|
|
537
|
-
const original = history[key];
|
|
538
|
-
const patched = function(...args) {
|
|
539
|
-
original.apply(this, args);
|
|
540
|
-
onChange();
|
|
541
|
-
};
|
|
542
|
-
history[key] = patched;
|
|
543
|
-
return () => {
|
|
544
|
-
if (history[key] === patched) {
|
|
545
|
-
history[key] = original;
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
|
-
};
|
|
549
|
-
window.addEventListener("popstate", onChange);
|
|
550
|
-
const restorePush = wrap("pushState");
|
|
551
|
-
const restoreReplace = wrap("replaceState");
|
|
552
|
-
return () => {
|
|
553
|
-
window.removeEventListener("popstate", onChange);
|
|
554
|
-
restorePush();
|
|
555
|
-
restoreReplace();
|
|
556
|
-
};
|
|
684
|
+
});
|
|
557
685
|
}
|
|
558
686
|
|
|
559
687
|
// src/core/features/content-swipe.ts
|
|
@@ -624,11 +752,15 @@ function installVisualViewport(deps) {
|
|
|
624
752
|
if (clamp < deps.getMaxAxisSize()) {
|
|
625
753
|
deps.setMaxAxisSize(clamp);
|
|
626
754
|
}
|
|
755
|
+
const wasAnimating = deps.isAnimating?.() ?? false;
|
|
756
|
+
deps.cancelInFlight();
|
|
757
|
+
deps.newCycle();
|
|
627
758
|
const max = deps.getMaxAxisSize();
|
|
628
759
|
deps.setSize(Math.min(deps.getSize(), max));
|
|
629
760
|
const current = deps.resolveActiveSnap();
|
|
630
761
|
if (current && !deps.isDragging()) {
|
|
631
762
|
deps.applySize(Math.min(current.size, max));
|
|
763
|
+
if (wasAnimating) deps.resyncAfterCancel?.();
|
|
632
764
|
} else {
|
|
633
765
|
deps.applySize(deps.getSize());
|
|
634
766
|
}
|
|
@@ -769,6 +901,54 @@ function installFitObserver(deps) {
|
|
|
769
901
|
};
|
|
770
902
|
}
|
|
771
903
|
|
|
904
|
+
// src/core/features/max-height-controller.ts
|
|
905
|
+
function createMaxHeightController(deps) {
|
|
906
|
+
let maxHeightCap;
|
|
907
|
+
let maxHeightRaw;
|
|
908
|
+
const resolveCap = () => {
|
|
909
|
+
const raw = maxHeightRaw;
|
|
910
|
+
if (raw === void 0) {
|
|
911
|
+
maxHeightCap = void 0;
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (typeof raw === "number") {
|
|
915
|
+
maxHeightCap = raw;
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
if (typeof window === "undefined") return;
|
|
919
|
+
const measured = resolveSnap(raw, deps.mode);
|
|
920
|
+
maxHeightCap = measured > 0 ? measured : void 0;
|
|
921
|
+
};
|
|
922
|
+
const clampTo = () => {
|
|
923
|
+
if (maxHeightCap === void 0) return;
|
|
924
|
+
if (deps.getMaxAxisSize() > maxHeightCap) {
|
|
925
|
+
deps.setMaxAxisSize(maxHeightCap);
|
|
926
|
+
}
|
|
927
|
+
};
|
|
928
|
+
return {
|
|
929
|
+
setRadius(r) {
|
|
930
|
+
deps.element.style.setProperty(
|
|
931
|
+
"--bs-radius",
|
|
932
|
+
typeof r === "number" ? `${r}px` : r
|
|
933
|
+
);
|
|
934
|
+
},
|
|
935
|
+
setMaxHeight(h) {
|
|
936
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
937
|
+
const axis = layoutAxis(deps.mode);
|
|
938
|
+
deps.element.style.setProperty(
|
|
939
|
+
axis === "height" ? "max-height" : "max-width",
|
|
940
|
+
value
|
|
941
|
+
);
|
|
942
|
+
maxHeightRaw = h;
|
|
943
|
+
resolveCap();
|
|
944
|
+
deps.recompute();
|
|
945
|
+
},
|
|
946
|
+
resolveCap,
|
|
947
|
+
clampTo,
|
|
948
|
+
getCap: () => maxHeightCap
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
|
|
772
952
|
// src/core/features/fit-measurement.ts
|
|
773
953
|
var measureSheetNatural = (element, content, vertical) => {
|
|
774
954
|
if (!content) {
|
|
@@ -900,13 +1080,6 @@ var WriteSentinel = class {
|
|
|
900
1080
|
}
|
|
901
1081
|
};
|
|
902
1082
|
|
|
903
|
-
// src/core/primitives/devWarn.ts
|
|
904
|
-
function devWarn(...args) {
|
|
905
|
-
if (typeof process !== "undefined" && process.env && process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
|
|
906
|
-
console.warn(...args);
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
|
|
910
1083
|
// src/core/primitives/overlay-position.ts
|
|
911
1084
|
function resolveSheetAnchoredStyle(mode, position, inset) {
|
|
912
1085
|
const sizeOffset = `calc(var(--bs-size, 0px) + ${inset})`;
|
|
@@ -2361,7 +2534,7 @@ var matchesRange = (def, progress) => {
|
|
|
2361
2534
|
};
|
|
2362
2535
|
function installScrimStages(deps, opts) {
|
|
2363
2536
|
const doc = deps.host.ownerDocument;
|
|
2364
|
-
const
|
|
2537
|
+
const entries2 = opts.stages.map((def) => {
|
|
2365
2538
|
const wrapper = doc.createElement("div");
|
|
2366
2539
|
wrapper.className = "bs-scrim-stage";
|
|
2367
2540
|
const ws = wrapper.style;
|
|
@@ -2382,9 +2555,9 @@ function installScrimStages(deps, opts) {
|
|
|
2382
2555
|
const resolveActive = () => {
|
|
2383
2556
|
const state = deps.getState();
|
|
2384
2557
|
if (state.size === 0) {
|
|
2385
|
-
return
|
|
2558
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? null;
|
|
2386
2559
|
}
|
|
2387
|
-
return
|
|
2560
|
+
return entries2.find((e) => matchesId(e.def, state.activeId)) ?? entries2.find((e) => matchesRange(e.def, state.progress)) ?? null;
|
|
2388
2561
|
};
|
|
2389
2562
|
const hide = (entry, animate) => {
|
|
2390
2563
|
entry.inFlight?.cancel();
|
|
@@ -2433,13 +2606,13 @@ function installScrimStages(deps, opts) {
|
|
|
2433
2606
|
deps.on("open", () => update(true)),
|
|
2434
2607
|
deps.on("close", () => update(true))
|
|
2435
2608
|
];
|
|
2436
|
-
if (
|
|
2609
|
+
if (entries2.some((e) => e.def.forRange)) {
|
|
2437
2610
|
offs.push(deps.on("progress", () => update(true)));
|
|
2438
2611
|
}
|
|
2439
2612
|
update(false);
|
|
2440
2613
|
return () => {
|
|
2441
2614
|
offs.forEach((off) => off());
|
|
2442
|
-
for (const entry of
|
|
2615
|
+
for (const entry of entries2) {
|
|
2443
2616
|
entry.inFlight?.cancel();
|
|
2444
2617
|
entry.inFlight = null;
|
|
2445
2618
|
if (entry.wrapper.parentNode) {
|
|
@@ -2552,8 +2725,7 @@ var BottomSheetEngine = class {
|
|
|
2552
2725
|
__publicField(this, "disableCloseFlag");
|
|
2553
2726
|
__publicField(this, "disableDragFlag");
|
|
2554
2727
|
__publicField(this, "closeOnRouteChange");
|
|
2555
|
-
__publicField(this, "
|
|
2556
|
-
__publicField(this, "maxHeightRaw");
|
|
2728
|
+
__publicField(this, "maxHeight");
|
|
2557
2729
|
__publicField(this, "snapPointsRaw");
|
|
2558
2730
|
__publicField(this, "snaps");
|
|
2559
2731
|
__publicField(this, "activeId");
|
|
@@ -2664,11 +2836,20 @@ var BottomSheetEngine = class {
|
|
|
2664
2836
|
auditVhUsage(this.snapPointsRaw);
|
|
2665
2837
|
this.auditDuplicateSnapIds(this.snapPointsRaw);
|
|
2666
2838
|
this.rootEl = this.element.closest(".bs-root");
|
|
2839
|
+
this.maxHeight = createMaxHeightController({
|
|
2840
|
+
element: this.element,
|
|
2841
|
+
mode: this.mode,
|
|
2842
|
+
getMaxAxisSize: () => this.snaps.getMaxAxisSize(),
|
|
2843
|
+
setMaxAxisSize: (size) => {
|
|
2844
|
+
this.snaps.setMaxAxisSize(size);
|
|
2845
|
+
},
|
|
2846
|
+
recompute: () => this.recompute()
|
|
2847
|
+
});
|
|
2667
2848
|
this.fitDeps = {
|
|
2668
2849
|
element: this.element,
|
|
2669
2850
|
scrollContainer: this.scrollContainer,
|
|
2670
2851
|
mode: this.mode,
|
|
2671
|
-
getMaxHeightCap: () => this.
|
|
2852
|
+
getMaxHeightCap: () => this.maxHeight.getCap()
|
|
2672
2853
|
};
|
|
2673
2854
|
this.snaps = new SnapResolver(
|
|
2674
2855
|
this.snapPointsRaw,
|
|
@@ -2690,8 +2871,8 @@ var BottomSheetEngine = class {
|
|
|
2690
2871
|
this.attach();
|
|
2691
2872
|
this.registerInStack();
|
|
2692
2873
|
if (this.snaps.getMaxAxisSize() === 0 && typeof IntersectionObserver !== "undefined" && typeof document !== "undefined") {
|
|
2693
|
-
const io = new IntersectionObserver((
|
|
2694
|
-
for (const entry of
|
|
2874
|
+
const io = new IntersectionObserver((entries2) => {
|
|
2875
|
+
for (const entry of entries2) {
|
|
2695
2876
|
if (!entry.isIntersecting) continue;
|
|
2696
2877
|
if (this.destroyed) return;
|
|
2697
2878
|
this.snaps.recompute();
|
|
@@ -2779,7 +2960,7 @@ var BottomSheetEngine = class {
|
|
|
2779
2960
|
}
|
|
2780
2961
|
use(plugin) {
|
|
2781
2962
|
if (this.destroyed) {
|
|
2782
|
-
|
|
2963
|
+
devWarn(
|
|
2783
2964
|
`[BottomSheet] use("${plugin.name}") called on destroyed engine \u2014 ignored.`
|
|
2784
2965
|
);
|
|
2785
2966
|
return this;
|
|
@@ -2821,6 +3002,9 @@ var BottomSheetEngine = class {
|
|
|
2821
3002
|
getAllowedIds() {
|
|
2822
3003
|
return this.snaps.getAllowedIds().slice();
|
|
2823
3004
|
}
|
|
3005
|
+
getResolvedSnaps() {
|
|
3006
|
+
return this.snaps.getResolvedSnaps();
|
|
3007
|
+
}
|
|
2824
3008
|
async snapTo(id, velocityOrOpts = 0, _skipBeforeSnap = false) {
|
|
2825
3009
|
if (this.destroyed) return;
|
|
2826
3010
|
const opts = typeof velocityOrOpts === "object" ? velocityOrOpts : { velocity: velocityOrOpts };
|
|
@@ -2829,11 +3013,11 @@ var BottomSheetEngine = class {
|
|
|
2829
3013
|
if (externalSignal?.aborted) return;
|
|
2830
3014
|
const target = this.snaps.findById(id);
|
|
2831
3015
|
if (!target) {
|
|
2832
|
-
|
|
3016
|
+
devWarn(`[BottomSheet] unknown snap id: ${id}`);
|
|
2833
3017
|
return;
|
|
2834
3018
|
}
|
|
2835
3019
|
if (!this.snaps.getAllowedIds().includes(id)) {
|
|
2836
|
-
|
|
3020
|
+
devWarn(`[BottomSheet] snap "${id}" is not in allowed list`);
|
|
2837
3021
|
return;
|
|
2838
3022
|
}
|
|
2839
3023
|
if (!_skipBeforeSnap && this.emitBeforeSnap(target, this.activeId)) {
|
|
@@ -2965,42 +3149,11 @@ var BottomSheetEngine = class {
|
|
|
2965
3149
|
}
|
|
2966
3150
|
setRadius(r) {
|
|
2967
3151
|
if (this.destroyed) return;
|
|
2968
|
-
this.
|
|
2969
|
-
"--bs-radius",
|
|
2970
|
-
typeof r === "number" ? `${r}px` : r
|
|
2971
|
-
);
|
|
3152
|
+
this.maxHeight.setRadius(r);
|
|
2972
3153
|
}
|
|
2973
3154
|
setMaxHeight(h) {
|
|
2974
3155
|
if (this.destroyed) return;
|
|
2975
|
-
|
|
2976
|
-
const axis = layoutAxis(this.mode);
|
|
2977
|
-
this.element.style.setProperty(
|
|
2978
|
-
axis === "height" ? "max-height" : "max-width",
|
|
2979
|
-
value
|
|
2980
|
-
);
|
|
2981
|
-
this.maxHeightRaw = h;
|
|
2982
|
-
this.resolveMaxHeightCap();
|
|
2983
|
-
this.recompute();
|
|
2984
|
-
}
|
|
2985
|
-
resolveMaxHeightCap() {
|
|
2986
|
-
const raw = this.maxHeightRaw;
|
|
2987
|
-
if (raw === void 0) {
|
|
2988
|
-
this.maxHeightCap = void 0;
|
|
2989
|
-
return;
|
|
2990
|
-
}
|
|
2991
|
-
if (typeof raw === "number") {
|
|
2992
|
-
this.maxHeightCap = raw;
|
|
2993
|
-
return;
|
|
2994
|
-
}
|
|
2995
|
-
if (typeof window === "undefined") return;
|
|
2996
|
-
const measured = resolveSnap(raw, this.mode);
|
|
2997
|
-
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2998
|
-
}
|
|
2999
|
-
clampToMaxHeight() {
|
|
3000
|
-
if (this.maxHeightCap === void 0) return;
|
|
3001
|
-
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
3002
|
-
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
3003
|
-
}
|
|
3156
|
+
this.maxHeight.setMaxHeight(h);
|
|
3004
3157
|
}
|
|
3005
3158
|
setAllowed(ids, snap) {
|
|
3006
3159
|
if (this.destroyed) return;
|
|
@@ -3088,7 +3241,7 @@ var BottomSheetEngine = class {
|
|
|
3088
3241
|
};
|
|
3089
3242
|
const host = this.screenComponent?.parentElement;
|
|
3090
3243
|
if (!host) {
|
|
3091
|
-
|
|
3244
|
+
devWarn(
|
|
3092
3245
|
"[BottomSheet] setScrimStages: no scrim element mounted \u2014 pass `scrim` to the engine first."
|
|
3093
3246
|
);
|
|
3094
3247
|
return () => {
|
|
@@ -3138,9 +3291,9 @@ var BottomSheetEngine = class {
|
|
|
3138
3291
|
}
|
|
3139
3292
|
recompute() {
|
|
3140
3293
|
if (this.destroyed) return;
|
|
3141
|
-
this.
|
|
3294
|
+
this.maxHeight.resolveCap();
|
|
3142
3295
|
this.snaps.recompute();
|
|
3143
|
-
this.
|
|
3296
|
+
this.maxHeight.clampTo();
|
|
3144
3297
|
this.scrim.invalidateOpacityCache();
|
|
3145
3298
|
if (this.gesture?.isDragging) return;
|
|
3146
3299
|
const current = this.snaps.findById(this.activeId);
|
|
@@ -3190,42 +3343,18 @@ var BottomSheetEngine = class {
|
|
|
3190
3343
|
return this.currentAbort.signal;
|
|
3191
3344
|
}
|
|
3192
3345
|
emitBeforeSnap(target, previousId) {
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
previousId,
|
|
3199
|
-
cancel: () => {
|
|
3200
|
-
if (frozen) {
|
|
3201
|
-
console.warn(
|
|
3202
|
-
"[BottomSheet] before-snap.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3203
|
-
);
|
|
3204
|
-
return;
|
|
3205
|
-
}
|
|
3206
|
-
cancelled = true;
|
|
3207
|
-
}
|
|
3208
|
-
});
|
|
3209
|
-
frozen = true;
|
|
3210
|
-
return cancelled;
|
|
3346
|
+
return emitCancelable(
|
|
3347
|
+
(payload) => this.emit("before-snap", payload),
|
|
3348
|
+
{ id: target.id, size: target.size, previousId },
|
|
3349
|
+
"before-snap"
|
|
3350
|
+
);
|
|
3211
3351
|
}
|
|
3212
3352
|
emitBeforeClose(reason) {
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
if (frozen) {
|
|
3219
|
-
console.warn(
|
|
3220
|
-
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
3221
|
-
);
|
|
3222
|
-
return;
|
|
3223
|
-
}
|
|
3224
|
-
cancelled = true;
|
|
3225
|
-
}
|
|
3226
|
-
});
|
|
3227
|
-
frozen = true;
|
|
3228
|
-
return cancelled;
|
|
3353
|
+
return emitCancelable(
|
|
3354
|
+
(payload) => this.emit("before-close", payload),
|
|
3355
|
+
{ reason },
|
|
3356
|
+
"before-close"
|
|
3357
|
+
);
|
|
3229
3358
|
}
|
|
3230
3359
|
applyAutoAriaLabelledBy() {
|
|
3231
3360
|
if (typeof document === "undefined") return;
|
|
@@ -3240,16 +3369,16 @@ var BottomSheetEngine = class {
|
|
|
3240
3369
|
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3241
3370
|
}
|
|
3242
3371
|
recomputeSnaps() {
|
|
3243
|
-
this.
|
|
3372
|
+
this.maxHeight.resolveCap();
|
|
3244
3373
|
this.snaps.setRaw(this.snapPointsRaw);
|
|
3245
|
-
this.
|
|
3374
|
+
this.maxHeight.clampTo();
|
|
3246
3375
|
this.scrim.invalidateOpacityCache();
|
|
3247
3376
|
}
|
|
3248
3377
|
auditDuplicateSnapIds(points) {
|
|
3249
3378
|
const seen = /* @__PURE__ */ new Set();
|
|
3250
3379
|
for (const p of points) {
|
|
3251
3380
|
if (seen.has(p.id)) {
|
|
3252
|
-
|
|
3381
|
+
devWarn(
|
|
3253
3382
|
`[BottomSheet] duplicate snap id "${p.id}" \u2014 only the first occurrence is reachable.`
|
|
3254
3383
|
);
|
|
3255
3384
|
}
|
|
@@ -3416,7 +3545,15 @@ var BottomSheetEngine = class {
|
|
|
3416
3545
|
setSize: (size) => {
|
|
3417
3546
|
this.size = size;
|
|
3418
3547
|
},
|
|
3419
|
-
applySize: (size) => this.applySize(size)
|
|
3548
|
+
applySize: (size) => this.applySize(size),
|
|
3549
|
+
cancelInFlight: () => {
|
|
3550
|
+
this.animation.cancel();
|
|
3551
|
+
},
|
|
3552
|
+
newCycle: () => {
|
|
3553
|
+
this.newCycle();
|
|
3554
|
+
},
|
|
3555
|
+
isAnimating: () => this.animation.isAnimating,
|
|
3556
|
+
resyncAfterCancel: () => this.resyncAfterResize()
|
|
3420
3557
|
}));
|
|
3421
3558
|
}
|
|
3422
3559
|
this.teardowns.add(installSliderKeyboard({
|
|
@@ -3452,9 +3589,9 @@ var BottomSheetEngine = class {
|
|
|
3452
3589
|
return;
|
|
3453
3590
|
}
|
|
3454
3591
|
if (this.emitBeforeSnap(target, previousId)) {
|
|
3455
|
-
const
|
|
3456
|
-
if (
|
|
3457
|
-
void this.animation.animateTo(
|
|
3592
|
+
const restore2 = this.snaps.findById(previousId);
|
|
3593
|
+
if (restore2) {
|
|
3594
|
+
void this.animation.animateTo(restore2.size, 0);
|
|
3458
3595
|
}
|
|
3459
3596
|
return;
|
|
3460
3597
|
}
|
|
@@ -3577,6 +3714,72 @@ var BottomSheetEngine = class {
|
|
|
3577
3714
|
sheetStack.update();
|
|
3578
3715
|
}
|
|
3579
3716
|
};
|
|
3717
|
+
function useEnginePropSync(engineRef, opts) {
|
|
3718
|
+
const optsRef = react.useRef(opts);
|
|
3719
|
+
optsRef.current = opts;
|
|
3720
|
+
const allowedKey = (opts.allowed ?? opts.snapPoints.map((p) => p.id)).join(
|
|
3721
|
+
"\0"
|
|
3722
|
+
);
|
|
3723
|
+
const defKey = opts.snapPoints.map((p) => `${p.id}${String(p.size)}`).join("\0");
|
|
3724
|
+
const defApplied = react.useRef(false);
|
|
3725
|
+
react.useEffect(() => {
|
|
3726
|
+
if (!defApplied.current) {
|
|
3727
|
+
defApplied.current = true;
|
|
3728
|
+
return;
|
|
3729
|
+
}
|
|
3730
|
+
const engine = engineRef.current;
|
|
3731
|
+
if (!engine) return;
|
|
3732
|
+
const current = optsRef.current;
|
|
3733
|
+
engine.setSnapPoints(
|
|
3734
|
+
current.snapPoints,
|
|
3735
|
+
current.allowed ? Array.from(current.allowed) : void 0
|
|
3736
|
+
);
|
|
3737
|
+
}, [defKey]);
|
|
3738
|
+
react.useEffect(() => {
|
|
3739
|
+
if (!engineRef.current) return;
|
|
3740
|
+
const ids = opts.allowed ? Array.from(opts.allowed) : opts.snapPoints.map((p) => p.id);
|
|
3741
|
+
engineRef.current.setAllowed(ids);
|
|
3742
|
+
}, [allowedKey]);
|
|
3743
|
+
react.useEffect(() => {
|
|
3744
|
+
if (!engineRef.current) return;
|
|
3745
|
+
if (opts.backdropColor !== void 0) {
|
|
3746
|
+
engineRef.current.setScrimColor(opts.backdropColor);
|
|
3747
|
+
}
|
|
3748
|
+
}, [opts.backdropColor]);
|
|
3749
|
+
react.useEffect(() => {
|
|
3750
|
+
if (!engineRef.current) return;
|
|
3751
|
+
if (opts.backdropOpacity !== void 0) {
|
|
3752
|
+
engineRef.current.setBackdropRange([0, opts.backdropOpacity]);
|
|
3753
|
+
}
|
|
3754
|
+
}, [opts.backdropOpacity]);
|
|
3755
|
+
react.useEffect(() => {
|
|
3756
|
+
if (!engineRef.current) return;
|
|
3757
|
+
if (opts.radius !== void 0) {
|
|
3758
|
+
engineRef.current.setRadius(opts.radius);
|
|
3759
|
+
}
|
|
3760
|
+
}, [opts.radius]);
|
|
3761
|
+
react.useEffect(() => {
|
|
3762
|
+
if (!engineRef.current) return;
|
|
3763
|
+
if (opts.maxHeight !== void 0) {
|
|
3764
|
+
engineRef.current.setMaxHeight(opts.maxHeight);
|
|
3765
|
+
}
|
|
3766
|
+
}, [opts.maxHeight]);
|
|
3767
|
+
react.useEffect(() => {
|
|
3768
|
+
if (opts.persistent !== void 0) {
|
|
3769
|
+
engineRef.current?.setPersistent(opts.persistent);
|
|
3770
|
+
}
|
|
3771
|
+
}, [opts.persistent]);
|
|
3772
|
+
react.useEffect(() => {
|
|
3773
|
+
if (opts.disableClose !== void 0) {
|
|
3774
|
+
engineRef.current?.setDisableClose(opts.disableClose);
|
|
3775
|
+
}
|
|
3776
|
+
}, [opts.disableClose]);
|
|
3777
|
+
react.useEffect(() => {
|
|
3778
|
+
if (opts.disableDrag !== void 0) {
|
|
3779
|
+
engineRef.current?.setDisableDrag(opts.disableDrag);
|
|
3780
|
+
}
|
|
3781
|
+
}, [opts.disableDrag]);
|
|
3782
|
+
}
|
|
3580
3783
|
|
|
3581
3784
|
// src/core/features/teleport.ts
|
|
3582
3785
|
var resolveTeleportTarget = (target) => {
|
|
@@ -3671,6 +3874,12 @@ function useBottomSheet(opts) {
|
|
|
3671
3874
|
engine.on("before-close", (payload) => {
|
|
3672
3875
|
optsRef.current.onBeforeClose?.(payload);
|
|
3673
3876
|
}),
|
|
3877
|
+
engine.on("open", (payload) => {
|
|
3878
|
+
optsRef.current.onOpen?.(payload.id);
|
|
3879
|
+
}),
|
|
3880
|
+
engine.on("close", () => {
|
|
3881
|
+
optsRef.current.onClose?.();
|
|
3882
|
+
}),
|
|
3674
3883
|
engine.on("opened", (payload) => {
|
|
3675
3884
|
optsRef.current.onOpened?.(payload.id);
|
|
3676
3885
|
}),
|
|
@@ -3686,6 +3895,20 @@ function useBottomSheet(opts) {
|
|
|
3686
3895
|
optsRef.current.onDragEnd?.(payload);
|
|
3687
3896
|
})
|
|
3688
3897
|
];
|
|
3898
|
+
if (optsRef.current.onDrag) {
|
|
3899
|
+
offs.push(
|
|
3900
|
+
engine.on("drag", (payload) => {
|
|
3901
|
+
optsRef.current.onDrag?.(payload);
|
|
3902
|
+
})
|
|
3903
|
+
);
|
|
3904
|
+
}
|
|
3905
|
+
if (optsRef.current.onProgress) {
|
|
3906
|
+
offs.push(
|
|
3907
|
+
engine.on("progress", (payload) => {
|
|
3908
|
+
optsRef.current.onProgress?.(payload);
|
|
3909
|
+
})
|
|
3910
|
+
);
|
|
3911
|
+
}
|
|
3689
3912
|
return () => {
|
|
3690
3913
|
offs.forEach((off) => off());
|
|
3691
3914
|
restoreTeleport?.();
|
|
@@ -3695,68 +3918,17 @@ function useBottomSheet(opts) {
|
|
|
3695
3918
|
setMounted((n) => n + 1);
|
|
3696
3919
|
};
|
|
3697
3920
|
}, []);
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
if (!engine) return;
|
|
3710
|
-
const current = optsRef.current;
|
|
3711
|
-
engine.setSnapPoints(
|
|
3712
|
-
current.snapPoints,
|
|
3713
|
-
current.allowed ? Array.from(current.allowed) : void 0
|
|
3714
|
-
);
|
|
3715
|
-
}, [defKey]);
|
|
3716
|
-
react.useEffect(() => {
|
|
3717
|
-
if (!engineRef.current) return;
|
|
3718
|
-
const ids = opts.allowed ? Array.from(opts.allowed) : opts.snapPoints.map((p) => p.id);
|
|
3719
|
-
engineRef.current.setAllowed(ids);
|
|
3720
|
-
}, [allowedKey]);
|
|
3721
|
-
react.useEffect(() => {
|
|
3722
|
-
if (!engineRef.current) return;
|
|
3723
|
-
if (opts.backdropColor !== void 0) {
|
|
3724
|
-
engineRef.current.setScrimColor(opts.backdropColor);
|
|
3725
|
-
}
|
|
3726
|
-
}, [opts.backdropColor]);
|
|
3727
|
-
react.useEffect(() => {
|
|
3728
|
-
if (!engineRef.current) return;
|
|
3729
|
-
if (opts.backdropOpacity !== void 0) {
|
|
3730
|
-
engineRef.current.setBackdropRange([0, opts.backdropOpacity]);
|
|
3731
|
-
}
|
|
3732
|
-
}, [opts.backdropOpacity]);
|
|
3733
|
-
react.useEffect(() => {
|
|
3734
|
-
if (!engineRef.current) return;
|
|
3735
|
-
if (opts.radius !== void 0) {
|
|
3736
|
-
engineRef.current.setRadius(opts.radius);
|
|
3737
|
-
}
|
|
3738
|
-
}, [opts.radius]);
|
|
3739
|
-
react.useEffect(() => {
|
|
3740
|
-
if (!engineRef.current) return;
|
|
3741
|
-
if (opts.maxHeight !== void 0) {
|
|
3742
|
-
engineRef.current.setMaxHeight(opts.maxHeight);
|
|
3743
|
-
}
|
|
3744
|
-
}, [opts.maxHeight]);
|
|
3745
|
-
react.useEffect(() => {
|
|
3746
|
-
if (opts.persistent !== void 0) {
|
|
3747
|
-
engineRef.current?.setPersistent(opts.persistent);
|
|
3748
|
-
}
|
|
3749
|
-
}, [opts.persistent]);
|
|
3750
|
-
react.useEffect(() => {
|
|
3751
|
-
if (opts.disableClose !== void 0) {
|
|
3752
|
-
engineRef.current?.setDisableClose(opts.disableClose);
|
|
3753
|
-
}
|
|
3754
|
-
}, [opts.disableClose]);
|
|
3755
|
-
react.useEffect(() => {
|
|
3756
|
-
if (opts.disableDrag !== void 0) {
|
|
3757
|
-
engineRef.current?.setDisableDrag(opts.disableDrag);
|
|
3758
|
-
}
|
|
3759
|
-
}, [opts.disableDrag]);
|
|
3921
|
+
useEnginePropSync(engineRef, {
|
|
3922
|
+
snapPoints: opts.snapPoints,
|
|
3923
|
+
allowed: opts.allowed,
|
|
3924
|
+
backdropColor: opts.backdropColor,
|
|
3925
|
+
backdropOpacity: opts.backdropOpacity,
|
|
3926
|
+
radius: opts.radius,
|
|
3927
|
+
maxHeight: opts.maxHeight,
|
|
3928
|
+
persistent: opts.persistent,
|
|
3929
|
+
disableClose: opts.disableClose,
|
|
3930
|
+
disableDrag: opts.disableDrag
|
|
3931
|
+
});
|
|
3760
3932
|
const subscribe = react.useCallback((fn) => {
|
|
3761
3933
|
subscribersRef.current.add(fn);
|
|
3762
3934
|
return () => subscribersRef.current.delete(fn);
|
|
@@ -3865,10 +4037,14 @@ var BottomSheet = react.forwardRef(
|
|
|
3865
4037
|
scrimStages,
|
|
3866
4038
|
onChange,
|
|
3867
4039
|
onBeforeClose,
|
|
4040
|
+
onOpen,
|
|
4041
|
+
onClose,
|
|
3868
4042
|
onOpened,
|
|
3869
4043
|
onClosed,
|
|
3870
4044
|
onDragStart,
|
|
3871
4045
|
onDragEnd,
|
|
4046
|
+
onDrag,
|
|
4047
|
+
onProgress,
|
|
3872
4048
|
ariaLabel = "Bottom sheet",
|
|
3873
4049
|
ariaLabelledBy,
|
|
3874
4050
|
noSSR = false,
|
|
@@ -3894,10 +4070,14 @@ var BottomSheet = react.forwardRef(
|
|
|
3894
4070
|
} = useBottomSheet({
|
|
3895
4071
|
...engineOpts,
|
|
3896
4072
|
onBeforeClose,
|
|
4073
|
+
onOpen,
|
|
4074
|
+
onClose,
|
|
3897
4075
|
onOpened,
|
|
3898
4076
|
onClosed,
|
|
3899
4077
|
onDragStart,
|
|
3900
|
-
onDragEnd
|
|
4078
|
+
onDragEnd,
|
|
4079
|
+
onDrag,
|
|
4080
|
+
onProgress
|
|
3901
4081
|
});
|
|
3902
4082
|
const ariaModal = engineOpts.focusTrap === true;
|
|
3903
4083
|
const lastAnnouncedRef = react.useRef("");
|
|
@@ -4181,7 +4361,7 @@ function installOverlaySwipe(deps) {
|
|
|
4181
4361
|
};
|
|
4182
4362
|
}
|
|
4183
4363
|
|
|
4184
|
-
// src/core/overlay.ts
|
|
4364
|
+
// src/core/overlay-options.ts
|
|
4185
4365
|
var OVERLAY_PRESETS = Object.freeze({
|
|
4186
4366
|
sheet: Object.freeze({
|
|
4187
4367
|
enterAnimation: "slide",
|
|
@@ -4212,6 +4392,8 @@ var OVERLAY_PRESETS = Object.freeze({
|
|
|
4212
4392
|
swipeToClose: false
|
|
4213
4393
|
})
|
|
4214
4394
|
});
|
|
4395
|
+
|
|
4396
|
+
// src/core/overlay.ts
|
|
4215
4397
|
var OverlayEngine = class {
|
|
4216
4398
|
constructor(opts) {
|
|
4217
4399
|
__publicField(this, "id", nextInstanceId("ovl"));
|
|
@@ -4246,7 +4428,7 @@ var OverlayEngine = class {
|
|
|
4246
4428
|
__publicField(this, "detachSwipe", null);
|
|
4247
4429
|
__publicField(this, "respectReducedMotionEnabled");
|
|
4248
4430
|
__publicField(this, "isTop", true);
|
|
4249
|
-
__publicField(this, "
|
|
4431
|
+
__publicField(this, "backMarker", null);
|
|
4250
4432
|
__publicField(this, "movedToTarget", false);
|
|
4251
4433
|
__publicField(this, "onOpenCb");
|
|
4252
4434
|
__publicField(this, "onCloseCb");
|
|
@@ -4258,7 +4440,6 @@ var OverlayEngine = class {
|
|
|
4258
4440
|
__publicField(this, "bus", createEventBus());
|
|
4259
4441
|
__publicField(this, "detachEscape", null);
|
|
4260
4442
|
__publicField(this, "detachBackdrop", null);
|
|
4261
|
-
__publicField(this, "detachHardwareBack", null);
|
|
4262
4443
|
__publicField(this, "releaseStackEntry", null);
|
|
4263
4444
|
__publicField(this, "lifecycle");
|
|
4264
4445
|
this.element = opts.element;
|
|
@@ -4288,7 +4469,7 @@ var OverlayEngine = class {
|
|
|
4288
4469
|
this.onOpenCb = opts.onOpen;
|
|
4289
4470
|
this.onCloseCb = opts.onClose;
|
|
4290
4471
|
if (this.peekRaw !== void 0 && this.edge !== "bottom") {
|
|
4291
|
-
|
|
4472
|
+
devWarn(
|
|
4292
4473
|
"[OverlayEngine] `peek` is only supported on edge: 'bottom' \u2014 ignoring."
|
|
4293
4474
|
);
|
|
4294
4475
|
this.peekRaw = void 0;
|
|
@@ -4355,10 +4536,9 @@ var OverlayEngine = class {
|
|
|
4355
4536
|
this.element.style.opacity = "1";
|
|
4356
4537
|
if (this.backdrop) {
|
|
4357
4538
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
4358
|
-
this.
|
|
4539
|
+
this.syncBackdropPointerEvents();
|
|
4359
4540
|
if (this.backdropFilter) {
|
|
4360
|
-
this.
|
|
4361
|
-
this.backdrop.style.webkitBackdropFilter = this.backdropFilter;
|
|
4541
|
+
this.applyBackdropFilter(this.backdropFilter);
|
|
4362
4542
|
}
|
|
4363
4543
|
}
|
|
4364
4544
|
try {
|
|
@@ -4378,8 +4558,7 @@ var OverlayEngine = class {
|
|
|
4378
4558
|
this.backdrop.style.opacity = "0";
|
|
4379
4559
|
this.backdrop.style.pointerEvents = "none";
|
|
4380
4560
|
if (this.backdropFilter) {
|
|
4381
|
-
this.
|
|
4382
|
-
this.backdrop.style.webkitBackdropFilter = "";
|
|
4561
|
+
this.applyBackdropFilter(void 0);
|
|
4383
4562
|
}
|
|
4384
4563
|
}
|
|
4385
4564
|
this.element.setAttribute("data-state", "closed");
|
|
@@ -4414,7 +4593,10 @@ var OverlayEngine = class {
|
|
|
4414
4593
|
this.isOpen_ = false;
|
|
4415
4594
|
this.isAnimating_ = true;
|
|
4416
4595
|
sheetStack.update();
|
|
4417
|
-
this.
|
|
4596
|
+
if (reason !== "back" && this.backMarker) {
|
|
4597
|
+
popBackMarker(this.backMarker);
|
|
4598
|
+
}
|
|
4599
|
+
this.backMarker = null;
|
|
4418
4600
|
this.element.setAttribute("data-state", "exiting");
|
|
4419
4601
|
const dur = this.effectiveDuration();
|
|
4420
4602
|
const transitionStr = `transform ${dur}ms ${this.exitEasing}, opacity ${dur}ms ease-in`;
|
|
@@ -4437,8 +4619,7 @@ var OverlayEngine = class {
|
|
|
4437
4619
|
this.backdrop.style.opacity = "0";
|
|
4438
4620
|
this.backdrop.style.pointerEvents = "none";
|
|
4439
4621
|
if (this.backdropFilter) {
|
|
4440
|
-
this.
|
|
4441
|
-
this.backdrop.style.webkitBackdropFilter = "";
|
|
4622
|
+
this.applyBackdropFilter(void 0);
|
|
4442
4623
|
}
|
|
4443
4624
|
}
|
|
4444
4625
|
this.releaseInteractiveListeners();
|
|
@@ -4473,6 +4654,10 @@ var OverlayEngine = class {
|
|
|
4473
4654
|
this.bus.clear();
|
|
4474
4655
|
this.setWillChange(false);
|
|
4475
4656
|
this.releaseInteractiveListeners();
|
|
4657
|
+
if (this.backMarker) {
|
|
4658
|
+
popBackMarker(this.backMarker);
|
|
4659
|
+
this.backMarker = null;
|
|
4660
|
+
}
|
|
4476
4661
|
this.releaseStackEntry?.();
|
|
4477
4662
|
this.releaseStackEntry = null;
|
|
4478
4663
|
const hadOriginalParent = this.originalParent !== null;
|
|
@@ -4486,20 +4671,14 @@ var OverlayEngine = class {
|
|
|
4486
4671
|
this.backdropOpacity = opacity;
|
|
4487
4672
|
if (this.isOpen_ && this.backdrop) {
|
|
4488
4673
|
this.backdrop.style.opacity = String(opacity);
|
|
4674
|
+
this.syncBackdropPointerEvents();
|
|
4489
4675
|
}
|
|
4490
4676
|
}
|
|
4491
4677
|
setBackdropFilter(filter) {
|
|
4492
4678
|
if (this.destroyed) return;
|
|
4493
4679
|
this.backdropFilter = filter;
|
|
4494
4680
|
if (!this.isOpen_ || !this.backdrop) return;
|
|
4495
|
-
|
|
4496
|
-
if (filter) {
|
|
4497
|
-
this.backdrop.style.backdropFilter = filter;
|
|
4498
|
-
style.webkitBackdropFilter = filter;
|
|
4499
|
-
} else {
|
|
4500
|
-
this.backdrop.style.backdropFilter = "";
|
|
4501
|
-
style.webkitBackdropFilter = "";
|
|
4502
|
-
}
|
|
4681
|
+
this.applyBackdropFilter(filter);
|
|
4503
4682
|
}
|
|
4504
4683
|
setSwipeToClose(config) {
|
|
4505
4684
|
if (this.destroyed) return;
|
|
@@ -4568,16 +4747,10 @@ var OverlayEngine = class {
|
|
|
4568
4747
|
if (this.isOpen_ && this.backdrop) {
|
|
4569
4748
|
if (merged.backdropOpacity !== void 0) {
|
|
4570
4749
|
this.backdrop.style.opacity = String(this.backdropOpacity);
|
|
4750
|
+
this.syncBackdropPointerEvents();
|
|
4571
4751
|
}
|
|
4572
4752
|
if (merged.backdropFilter !== void 0) {
|
|
4573
|
-
|
|
4574
|
-
if (this.backdropFilter) {
|
|
4575
|
-
this.backdrop.style.backdropFilter = this.backdropFilter;
|
|
4576
|
-
style.webkitBackdropFilter = this.backdropFilter;
|
|
4577
|
-
} else {
|
|
4578
|
-
this.backdrop.style.backdropFilter = "";
|
|
4579
|
-
style.webkitBackdropFilter = "";
|
|
4580
|
-
}
|
|
4753
|
+
this.applyBackdropFilter(this.backdropFilter);
|
|
4581
4754
|
}
|
|
4582
4755
|
}
|
|
4583
4756
|
if (opts.duration !== void 0) this.duration = opts.duration;
|
|
@@ -4646,19 +4819,6 @@ var OverlayEngine = class {
|
|
|
4646
4819
|
effectiveDuration() {
|
|
4647
4820
|
return this.respectReducedMotionEnabled && prefersReducedMotion() ? 0 : this.duration;
|
|
4648
4821
|
}
|
|
4649
|
-
popBackMarker(reason) {
|
|
4650
|
-
if (!this.backPushed) return;
|
|
4651
|
-
this.backPushed = false;
|
|
4652
|
-
if (reason === "back") return;
|
|
4653
|
-
const state = history.state;
|
|
4654
|
-
if (state && state.__bsOverlay === this.id) {
|
|
4655
|
-
try {
|
|
4656
|
-
history.back();
|
|
4657
|
-
} catch {
|
|
4658
|
-
return;
|
|
4659
|
-
}
|
|
4660
|
-
}
|
|
4661
|
-
}
|
|
4662
4822
|
resolvePeekPx(raw) {
|
|
4663
4823
|
if (typeof raw === "number") return Math.max(0, raw);
|
|
4664
4824
|
try {
|
|
@@ -4712,6 +4872,21 @@ var OverlayEngine = class {
|
|
|
4712
4872
|
this.backdrop.style.pointerEvents = "none";
|
|
4713
4873
|
}
|
|
4714
4874
|
}
|
|
4875
|
+
syncBackdropPointerEvents() {
|
|
4876
|
+
if (!this.backdrop) return;
|
|
4877
|
+
this.backdrop.style.pointerEvents = this.backdropOpacity > 0 ? "auto" : "none";
|
|
4878
|
+
}
|
|
4879
|
+
applyBackdropFilter(filter) {
|
|
4880
|
+
if (!this.backdrop) return;
|
|
4881
|
+
const style = this.backdrop.style;
|
|
4882
|
+
if (filter) {
|
|
4883
|
+
this.backdrop.style.backdropFilter = filter;
|
|
4884
|
+
style.webkitBackdropFilter = filter;
|
|
4885
|
+
} else {
|
|
4886
|
+
this.backdrop.style.backdropFilter = "";
|
|
4887
|
+
style.webkitBackdropFilter = "";
|
|
4888
|
+
}
|
|
4889
|
+
}
|
|
4715
4890
|
setWillChange(on) {
|
|
4716
4891
|
this.element.style.willChange = on ? "transform, opacity" : "";
|
|
4717
4892
|
if (this.backdrop) {
|
|
@@ -4759,21 +4934,6 @@ var OverlayEngine = class {
|
|
|
4759
4934
|
this.backdrop.addEventListener("click", handler);
|
|
4760
4935
|
this.detachBackdrop = () => this.backdrop?.removeEventListener("click", handler);
|
|
4761
4936
|
}
|
|
4762
|
-
if (this.closeOnBackEnabled && typeof window !== "undefined" && !this.detachHardwareBack) {
|
|
4763
|
-
try {
|
|
4764
|
-
history.pushState({ __bsOverlay: this.id }, "");
|
|
4765
|
-
this.backPushed = true;
|
|
4766
|
-
} catch {
|
|
4767
|
-
}
|
|
4768
|
-
const onPop = () => {
|
|
4769
|
-
if (this.isOpen_ && this.isTop) {
|
|
4770
|
-
this.backPushed = false;
|
|
4771
|
-
void this.close("back");
|
|
4772
|
-
}
|
|
4773
|
-
};
|
|
4774
|
-
window.addEventListener("popstate", onPop);
|
|
4775
|
-
this.detachHardwareBack = () => window.removeEventListener("popstate", onPop);
|
|
4776
|
-
}
|
|
4777
4937
|
if (this.closeOnOutsidePointerEnabled && !this.detachOutsidePointer) {
|
|
4778
4938
|
const handler = (e) => {
|
|
4779
4939
|
if (!this.isOpen_) return;
|
|
@@ -4786,14 +4946,20 @@ var OverlayEngine = class {
|
|
|
4786
4946
|
document.addEventListener("pointerdown", handler, true);
|
|
4787
4947
|
this.detachOutsidePointer = () => document.removeEventListener("pointerdown", handler, true);
|
|
4788
4948
|
}
|
|
4949
|
+
if (this.closeOnBackEnabled && this.backMarker === null && typeof window !== "undefined") {
|
|
4950
|
+
this.backMarker = pushBackMarker({
|
|
4951
|
+
isOpen: () => this.isOpen_,
|
|
4952
|
+
isTop: () => this.isTop,
|
|
4953
|
+
close: () => this.close("back"),
|
|
4954
|
+
markerState: () => ({ __bsOverlay: this.id })
|
|
4955
|
+
});
|
|
4956
|
+
}
|
|
4789
4957
|
}
|
|
4790
4958
|
releaseInteractiveListeners() {
|
|
4791
4959
|
this.detachEscape?.();
|
|
4792
4960
|
this.detachEscape = null;
|
|
4793
4961
|
this.detachBackdrop?.();
|
|
4794
4962
|
this.detachBackdrop = null;
|
|
4795
|
-
this.detachHardwareBack?.();
|
|
4796
|
-
this.detachHardwareBack = null;
|
|
4797
4963
|
this.detachSwipe?.();
|
|
4798
4964
|
this.detachSwipe = null;
|
|
4799
4965
|
this.detachOutsidePointer?.();
|
|
@@ -4944,6 +5110,8 @@ var Overlay = react.forwardRef(function Overlay2(props, ref) {
|
|
|
4944
5110
|
)
|
|
4945
5111
|
] });
|
|
4946
5112
|
});
|
|
5113
|
+
|
|
5114
|
+
// src/react/config-validation.ts
|
|
4947
5115
|
var SUPPORTED_VERSION = 1;
|
|
4948
5116
|
var TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
|
|
4949
5117
|
"version",
|
|
@@ -4968,7 +5136,7 @@ var warnUnknownKeys = (obj, allowed, context) => {
|
|
|
4968
5136
|
if (!obj || typeof obj !== "object") return;
|
|
4969
5137
|
const unknown = Object.keys(obj).filter((k) => !allowed.has(k));
|
|
4970
5138
|
if (unknown.length === 0) return;
|
|
4971
|
-
|
|
5139
|
+
devWarn(
|
|
4972
5140
|
`[BottomSheetFromConfig] Unknown ${unknown.length === 1 ? "key" : "keys"} in ${context}: ${unknown.map((k) => `"${k}"`).join(", ")}. Allowed: ${[...allowed].join(", ")}. Likely a typo \u2014 values ignored.`
|
|
4973
5141
|
);
|
|
4974
5142
|
};
|
|
@@ -4978,7 +5146,7 @@ function validateConfig(config) {
|
|
|
4978
5146
|
validatedConfigs.add(config);
|
|
4979
5147
|
let ok = true;
|
|
4980
5148
|
if (config.version !== SUPPORTED_VERSION) {
|
|
4981
|
-
|
|
5149
|
+
devWarn(
|
|
4982
5150
|
`[BottomSheetFromConfig] Unsupported config version ${String(
|
|
4983
5151
|
config.version
|
|
4984
5152
|
)}; expected ${SUPPORTED_VERSION}. Falling back to defaults.`
|
|
@@ -4986,7 +5154,7 @@ function validateConfig(config) {
|
|
|
4986
5154
|
return false;
|
|
4987
5155
|
}
|
|
4988
5156
|
if (!Array.isArray(config.snapPoints) || config.snapPoints.length === 0) {
|
|
4989
|
-
|
|
5157
|
+
devWarn(
|
|
4990
5158
|
"[BottomSheetFromConfig] config.snapPoints is missing or empty; using a single full-height fallback snap."
|
|
4991
5159
|
);
|
|
4992
5160
|
ok = false;
|