@surdeddd/bottom-sheet 0.3.0 → 0.4.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/dist/{BottomSheetEngine-CAymrH-P.d.cts → BottomSheetEngine-BJrH7qY3.d.cts} +39 -3
- package/dist/{BottomSheetEngine-DcqcuudN.d.ts → BottomSheetEngine-L05jGZvU.d.ts} +39 -3
- package/dist/element.cjs +480 -89
- package/dist/element.d.cts +23 -4
- package/dist/element.d.ts +23 -4
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +480 -89
- package/dist/index.cjs +341 -80
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +341 -80
- 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 +13 -2
- package/dist/overlay.js +13 -2
- package/dist/preact.d.cts +1 -1
- package/dist/preact.d.ts +1 -1
- package/dist/qwik.cjs +352 -81
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +352 -81
- package/dist/react.cjs +427 -87
- package/dist/react.d.cts +29 -4
- package/dist/react.d.ts +29 -4
- package/dist/react.js +427 -87
- package/dist/solid.cjs +341 -80
- package/dist/solid.d.cts +38 -2
- package/dist/solid.d.ts +38 -2
- package/dist/solid.js +341 -80
- package/dist/solid.source.jsx +341 -80
- package/dist/styles.css +57 -56
- package/dist/svelte-core.cjs +346 -80
- package/dist/svelte-core.js +346 -80
- package/dist/svelte-src/BottomSheet.svelte +103 -5
- package/dist/svelte.cjs +421 -88
- package/dist/svelte.d.cts +21 -0
- package/dist/svelte.d.ts +21 -0
- package/dist/svelte.js +421 -88
- package/dist/vue.cjs +584 -91
- package/dist/vue.d.cts +51 -2
- package/dist/vue.d.ts +51 -2
- package/dist/vue.js +585 -92
- package/package.json +6 -6
package/dist/svelte-core.js
CHANGED
|
@@ -37,6 +37,15 @@ var SheetStack = class {
|
|
|
37
37
|
size() {
|
|
38
38
|
return this.entries.length;
|
|
39
39
|
}
|
|
40
|
+
depthOf(id) {
|
|
41
|
+
const open = [];
|
|
42
|
+
for (const entry of this.entries) {
|
|
43
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
44
|
+
}
|
|
45
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
46
|
+
if (idx === -1) return 0;
|
|
47
|
+
return open.length - 1 - idx;
|
|
48
|
+
}
|
|
40
49
|
clear() {
|
|
41
50
|
this.entries = [];
|
|
42
51
|
}
|
|
@@ -155,7 +164,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
155
164
|
var resolveSnap = (point, mode, measureFit) => {
|
|
156
165
|
if (typeof point === "number") return Math.max(0, point);
|
|
157
166
|
if (point === "full") return viewportSize(mode);
|
|
158
|
-
if (point === "fit"
|
|
167
|
+
if (point === "fit" || point === "content") {
|
|
168
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
169
|
+
}
|
|
159
170
|
const pctMatch = point.match(PERCENT);
|
|
160
171
|
if (pctMatch) {
|
|
161
172
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -392,6 +403,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
392
403
|
}
|
|
393
404
|
|
|
394
405
|
// src/core/features/route.ts
|
|
406
|
+
var closers = [];
|
|
407
|
+
var handlerInstalled = false;
|
|
408
|
+
var suppress = 0;
|
|
409
|
+
var ensureHandler = () => {
|
|
410
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
411
|
+
handlerInstalled = true;
|
|
412
|
+
window.addEventListener("popstate", () => {
|
|
413
|
+
if (suppress > 0) {
|
|
414
|
+
suppress -= 1;
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
let target = null;
|
|
418
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
419
|
+
const c = closers[i];
|
|
420
|
+
if (!c.isOpen()) continue;
|
|
421
|
+
if (!target) target = c;
|
|
422
|
+
if (c.isTop()) {
|
|
423
|
+
target = c;
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (!target) return;
|
|
428
|
+
target.consumed = true;
|
|
429
|
+
const idx = closers.indexOf(target);
|
|
430
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
431
|
+
target.close();
|
|
432
|
+
});
|
|
433
|
+
};
|
|
434
|
+
var programmaticBack = () => {
|
|
435
|
+
suppress += 1;
|
|
436
|
+
try {
|
|
437
|
+
history.back();
|
|
438
|
+
} catch {
|
|
439
|
+
suppress = Math.max(0, suppress - 1);
|
|
440
|
+
}
|
|
441
|
+
};
|
|
395
442
|
function installRoute(deps) {
|
|
396
443
|
if (typeof window === "undefined") {
|
|
397
444
|
return () => {
|
|
@@ -401,82 +448,81 @@ function installRoute(deps) {
|
|
|
401
448
|
return () => {
|
|
402
449
|
};
|
|
403
450
|
}
|
|
404
|
-
let
|
|
405
|
-
let
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
451
|
+
let pushed = false;
|
|
452
|
+
let closer = null;
|
|
453
|
+
const teardownEntry = () => {
|
|
454
|
+
if (closer) {
|
|
455
|
+
const idx = closers.indexOf(closer);
|
|
456
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
457
|
+
}
|
|
458
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
459
|
+
closer = null;
|
|
460
|
+
if (pushed && !wasConsumed) {
|
|
461
|
+
pushed = false;
|
|
462
|
+
programmaticBack();
|
|
463
|
+
} else {
|
|
464
|
+
pushed = false;
|
|
414
465
|
}
|
|
415
466
|
};
|
|
416
467
|
const onOpen = () => {
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
window.addEventListener("popstate", onPop);
|
|
433
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
434
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
435
|
-
try {
|
|
468
|
+
if (closer) return;
|
|
469
|
+
closer = {
|
|
470
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
471
|
+
isTop: () => deps.isTopSheet(),
|
|
472
|
+
close: () => void deps.close(),
|
|
473
|
+
consumed: false
|
|
474
|
+
};
|
|
475
|
+
ensureHandler();
|
|
476
|
+
closers.push(closer);
|
|
477
|
+
try {
|
|
478
|
+
if (deps.routedTo !== void 0) {
|
|
479
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
480
|
+
} else {
|
|
436
481
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
437
|
-
closeOnBackPushed = true;
|
|
438
|
-
} catch {
|
|
439
482
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
const state = history.state;
|
|
444
|
-
if (state?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
445
|
-
void deps.close();
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
window.addEventListener("popstate", onPop);
|
|
449
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
const onClose = () => {
|
|
453
|
-
detachPopstate?.();
|
|
454
|
-
detachPopstate = null;
|
|
455
|
-
if (routePushed) {
|
|
456
|
-
routePushed = false;
|
|
457
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
458
|
-
}
|
|
459
|
-
if (closeOnBackPushed) {
|
|
460
|
-
closeOnBackPushed = false;
|
|
461
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
483
|
+
pushed = true;
|
|
484
|
+
} catch {
|
|
485
|
+
pushed = false;
|
|
462
486
|
}
|
|
463
487
|
};
|
|
464
488
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
465
|
-
const unsubscribeClose = deps.on("close",
|
|
489
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
466
490
|
if (deps.getSize() > 0) onOpen();
|
|
467
491
|
return () => {
|
|
468
492
|
unsubscribeOpen();
|
|
469
493
|
unsubscribeClose();
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
494
|
+
teardownEntry();
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
function installRouteChange(deps) {
|
|
498
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
499
|
+
return () => {
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
const onChange = () => {
|
|
503
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
504
|
+
void deps.close();
|
|
505
|
+
};
|
|
506
|
+
const wrap = (key) => {
|
|
507
|
+
const original = history[key];
|
|
508
|
+
const patched = function(...args) {
|
|
509
|
+
original.apply(this, args);
|
|
510
|
+
onChange();
|
|
511
|
+
};
|
|
512
|
+
history[key] = patched;
|
|
513
|
+
return () => {
|
|
514
|
+
if (history[key] === patched) {
|
|
515
|
+
history[key] = original;
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
};
|
|
519
|
+
window.addEventListener("popstate", onChange);
|
|
520
|
+
const restorePush = wrap("pushState");
|
|
521
|
+
const restoreReplace = wrap("replaceState");
|
|
522
|
+
return () => {
|
|
523
|
+
window.removeEventListener("popstate", onChange);
|
|
524
|
+
restorePush();
|
|
525
|
+
restoreReplace();
|
|
480
526
|
};
|
|
481
527
|
}
|
|
482
528
|
|
|
@@ -784,6 +830,7 @@ function applyOverlayPosition(ws, mode, position, inset) {
|
|
|
784
830
|
|
|
785
831
|
// src/core/controllers/scrim-controller.ts
|
|
786
832
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
833
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
787
834
|
var ScrimController = class {
|
|
788
835
|
constructor(deps, opts) {
|
|
789
836
|
__publicField(this, "screenComponent");
|
|
@@ -822,9 +869,11 @@ var ScrimController = class {
|
|
|
822
869
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
823
870
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
824
871
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
872
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
873
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
825
874
|
if (this.screenComponent) {
|
|
826
875
|
this.applyScrimStyles({
|
|
827
|
-
color:
|
|
876
|
+
color: effectiveColor,
|
|
828
877
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
829
878
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
830
879
|
});
|
|
@@ -1598,7 +1647,7 @@ var LifecycleController = class {
|
|
|
1598
1647
|
this.releaseScrollLock = null;
|
|
1599
1648
|
this.inertSiblings.remove();
|
|
1600
1649
|
if (this.returnFocus) {
|
|
1601
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1650
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1602
1651
|
target?.focus?.();
|
|
1603
1652
|
}
|
|
1604
1653
|
}
|
|
@@ -1765,6 +1814,7 @@ var GestureController = class {
|
|
|
1765
1814
|
__publicField(this, "dragStartSize", 0);
|
|
1766
1815
|
__publicField(this, "currentPointerKind", "touch");
|
|
1767
1816
|
__publicField(this, "keyboardDismissed", false);
|
|
1817
|
+
__publicField(this, "dragSuppressed", false);
|
|
1768
1818
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1769
1819
|
this.deps = deps;
|
|
1770
1820
|
}
|
|
@@ -1775,6 +1825,11 @@ var GestureController = class {
|
|
|
1775
1825
|
if (this.detach) return this.detach;
|
|
1776
1826
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1777
1827
|
onStart: (_coord, kind) => {
|
|
1828
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1829
|
+
this.dragSuppressed = true;
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
this.dragSuppressed = false;
|
|
1778
1833
|
this.deps.cancelAnimation();
|
|
1779
1834
|
this.isDragging_ = true;
|
|
1780
1835
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1785,6 +1840,7 @@ var GestureController = class {
|
|
|
1785
1840
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1786
1841
|
},
|
|
1787
1842
|
onMove: (delta) => {
|
|
1843
|
+
if (this.dragSuppressed) return;
|
|
1788
1844
|
const ctx = this.deps.getDragContext();
|
|
1789
1845
|
const { min, max } = ctx.range;
|
|
1790
1846
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1808,6 +1864,10 @@ var GestureController = class {
|
|
|
1808
1864
|
}
|
|
1809
1865
|
},
|
|
1810
1866
|
onEnd: (delta, velocity, kind) => {
|
|
1867
|
+
if (this.dragSuppressed) {
|
|
1868
|
+
this.dragSuppressed = false;
|
|
1869
|
+
return;
|
|
1870
|
+
}
|
|
1811
1871
|
this.isDragging_ = false;
|
|
1812
1872
|
this.keyboardDismissed = false;
|
|
1813
1873
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1818,6 +1878,10 @@ var GestureController = class {
|
|
|
1818
1878
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1819
1879
|
},
|
|
1820
1880
|
onCancel: () => {
|
|
1881
|
+
if (this.dragSuppressed) {
|
|
1882
|
+
this.dragSuppressed = false;
|
|
1883
|
+
return;
|
|
1884
|
+
}
|
|
1821
1885
|
this.isDragging_ = false;
|
|
1822
1886
|
this.keyboardDismissed = false;
|
|
1823
1887
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -2197,6 +2261,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2197
2261
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2198
2262
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2199
2263
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2264
|
+
persistent: opts.persistent ?? false,
|
|
2265
|
+
disableClose: opts.disableClose ?? false,
|
|
2266
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2267
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2268
|
+
radius: opts.radius,
|
|
2269
|
+
maxHeight: opts.maxHeight,
|
|
2200
2270
|
initialAllowed,
|
|
2201
2271
|
initialId,
|
|
2202
2272
|
scrim: {
|
|
@@ -2223,7 +2293,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2223
2293
|
closeOnEscape: opts.closeOnEscape,
|
|
2224
2294
|
lockBodyScroll: opts.lockBodyScroll,
|
|
2225
2295
|
inertSiblings: opts.inertSiblings,
|
|
2226
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2296
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2297
|
+
returnFocus: opts.returnFocusTo
|
|
2227
2298
|
}
|
|
2228
2299
|
};
|
|
2229
2300
|
}
|
|
@@ -2268,6 +2339,11 @@ var BottomSheetEngine = class {
|
|
|
2268
2339
|
__publicField(this, "lifecycle");
|
|
2269
2340
|
__publicField(this, "closeOnBack");
|
|
2270
2341
|
__publicField(this, "routedTo");
|
|
2342
|
+
__publicField(this, "persistent");
|
|
2343
|
+
__publicField(this, "disableCloseFlag");
|
|
2344
|
+
__publicField(this, "disableDragFlag");
|
|
2345
|
+
__publicField(this, "closeOnRouteChange");
|
|
2346
|
+
__publicField(this, "maxHeightCap");
|
|
2271
2347
|
__publicField(this, "snapPointsRaw");
|
|
2272
2348
|
__publicField(this, "snaps");
|
|
2273
2349
|
__publicField(this, "activeId");
|
|
@@ -2280,6 +2356,7 @@ var BottomSheetEngine = class {
|
|
|
2280
2356
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
2281
2357
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
2282
2358
|
__publicField(this, "isTopSheet", true);
|
|
2359
|
+
__publicField(this, "opening", false);
|
|
2283
2360
|
__publicField(this, "progressPayload", {
|
|
2284
2361
|
value: 0,
|
|
2285
2362
|
size: 0
|
|
@@ -2336,7 +2413,8 @@ var BottomSheetEngine = class {
|
|
|
2336
2413
|
void this.snapTo(id);
|
|
2337
2414
|
},
|
|
2338
2415
|
close: () => {
|
|
2339
|
-
|
|
2416
|
+
if (!this.canDismiss()) return;
|
|
2417
|
+
void this.close("backdrop");
|
|
2340
2418
|
}
|
|
2341
2419
|
},
|
|
2342
2420
|
resolved.scrim
|
|
@@ -2360,6 +2438,10 @@ var BottomSheetEngine = class {
|
|
|
2360
2438
|
);
|
|
2361
2439
|
this.closeOnBack = resolved.closeOnBack;
|
|
2362
2440
|
this.routedTo = opts.routedTo;
|
|
2441
|
+
this.persistent = resolved.persistent;
|
|
2442
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2443
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2444
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2363
2445
|
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2364
2446
|
this.snapPointsRaw = opts.snapPoints;
|
|
2365
2447
|
this.persistKey = opts.persistKey;
|
|
@@ -2373,7 +2455,7 @@ var BottomSheetEngine = class {
|
|
|
2373
2455
|
this.snapPointsRaw,
|
|
2374
2456
|
resolved.initialAllowed,
|
|
2375
2457
|
this.mode,
|
|
2376
|
-
() =>
|
|
2458
|
+
() => this.measureFitSize(),
|
|
2377
2459
|
(maxAxisSize) => {
|
|
2378
2460
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2379
2461
|
}
|
|
@@ -2407,6 +2489,19 @@ var BottomSheetEngine = class {
|
|
|
2407
2489
|
io.observe(this.element);
|
|
2408
2490
|
this.teardowns.add(() => io.disconnect());
|
|
2409
2491
|
}
|
|
2492
|
+
this.installFitObserver();
|
|
2493
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2494
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2495
|
+
this.applyAutoAriaLabelledBy();
|
|
2496
|
+
if (this.closeOnRouteChange) {
|
|
2497
|
+
this.teardowns.add(
|
|
2498
|
+
installRouteChange({
|
|
2499
|
+
isDestroyed: () => this.destroyed,
|
|
2500
|
+
getSize: () => this.size,
|
|
2501
|
+
close: () => this.close()
|
|
2502
|
+
})
|
|
2503
|
+
);
|
|
2504
|
+
}
|
|
2410
2505
|
if (this.persistKey) {
|
|
2411
2506
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2412
2507
|
}
|
|
@@ -2431,7 +2526,7 @@ var BottomSheetEngine = class {
|
|
|
2431
2526
|
isTopSheet: () => this.isTopSheet,
|
|
2432
2527
|
getSize: () => this.size,
|
|
2433
2528
|
isDestroyed: () => this.destroyed,
|
|
2434
|
-
close: () => this.close(),
|
|
2529
|
+
close: () => this.close("back"),
|
|
2435
2530
|
on: (event, fn) => this.on(event, fn),
|
|
2436
2531
|
sheetId: this.id
|
|
2437
2532
|
})
|
|
@@ -2525,6 +2620,10 @@ var BottomSheetEngine = class {
|
|
|
2525
2620
|
const previousSize = this.size;
|
|
2526
2621
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2527
2622
|
this.activeId = id;
|
|
2623
|
+
if (wasClosed && target.size > 0) {
|
|
2624
|
+
this.opening = true;
|
|
2625
|
+
sheetStack.promote(this.id);
|
|
2626
|
+
}
|
|
2528
2627
|
if (this.animation.viewTransitionsAvailable) {
|
|
2529
2628
|
this.currentViewTransition?.skipTransition?.();
|
|
2530
2629
|
const vt = document.startViewTransition(() => {
|
|
@@ -2539,19 +2638,26 @@ var BottomSheetEngine = class {
|
|
|
2539
2638
|
} else {
|
|
2540
2639
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2541
2640
|
}
|
|
2641
|
+
this.opening = false;
|
|
2542
2642
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2543
2643
|
if (signal.aborted) return;
|
|
2544
2644
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2545
2645
|
this.updateAriaSlider();
|
|
2546
|
-
this.emit("snap", {
|
|
2646
|
+
this.emit("snap", {
|
|
2647
|
+
id,
|
|
2648
|
+
size: target.size,
|
|
2649
|
+
progress: this.computeProgress(target.size)
|
|
2650
|
+
});
|
|
2547
2651
|
if (wasClosed && target.size > 0) {
|
|
2548
2652
|
this.emit("open", { id });
|
|
2549
2653
|
this.handleOpen();
|
|
2550
2654
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2655
|
+
this.emit("opened", { id });
|
|
2551
2656
|
}
|
|
2552
2657
|
if (target.size === 0) {
|
|
2553
2658
|
this.emit("close", void 0);
|
|
2554
2659
|
this.handleClose();
|
|
2660
|
+
this.emit("closed", void 0);
|
|
2555
2661
|
}
|
|
2556
2662
|
}
|
|
2557
2663
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2576,11 +2682,74 @@ var BottomSheetEngine = class {
|
|
|
2576
2682
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2577
2683
|
return this.snapTo(target);
|
|
2578
2684
|
}
|
|
2579
|
-
close() {
|
|
2685
|
+
close(reason = "programmatic") {
|
|
2580
2686
|
if (this.destroyed) return Promise.resolve();
|
|
2687
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2688
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2581
2689
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2582
2690
|
return this.snapTo(closedId ?? this.activeId);
|
|
2583
2691
|
}
|
|
2692
|
+
canDismiss() {
|
|
2693
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2694
|
+
}
|
|
2695
|
+
isTop() {
|
|
2696
|
+
return this.isTopSheet;
|
|
2697
|
+
}
|
|
2698
|
+
depth() {
|
|
2699
|
+
return sheetStack.depthOf(this.id);
|
|
2700
|
+
}
|
|
2701
|
+
expand() {
|
|
2702
|
+
if (this.destroyed) return Promise.resolve();
|
|
2703
|
+
const ids = this.allowedIdsBySize();
|
|
2704
|
+
const target = ids[ids.length - 1];
|
|
2705
|
+
if (!target) return Promise.resolve();
|
|
2706
|
+
return this.snapTo(target);
|
|
2707
|
+
}
|
|
2708
|
+
collapse() {
|
|
2709
|
+
if (this.destroyed) return Promise.resolve();
|
|
2710
|
+
const ids = this.allowedIdsBySize();
|
|
2711
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2712
|
+
const target = nonZero ?? ids[0];
|
|
2713
|
+
if (!target) return Promise.resolve();
|
|
2714
|
+
return this.snapTo(target);
|
|
2715
|
+
}
|
|
2716
|
+
setRadius(r) {
|
|
2717
|
+
if (this.destroyed) return;
|
|
2718
|
+
this.element.style.setProperty(
|
|
2719
|
+
"--bs-radius",
|
|
2720
|
+
typeof r === "number" ? `${r}px` : r
|
|
2721
|
+
);
|
|
2722
|
+
}
|
|
2723
|
+
setMaxHeight(h) {
|
|
2724
|
+
if (this.destroyed) return;
|
|
2725
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2726
|
+
const axis = layoutAxis(this.mode);
|
|
2727
|
+
this.element.style.setProperty(
|
|
2728
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2729
|
+
value
|
|
2730
|
+
);
|
|
2731
|
+
if (typeof h === "number") {
|
|
2732
|
+
this.maxHeightCap = h;
|
|
2733
|
+
this.clampToMaxHeight();
|
|
2734
|
+
} else if (typeof window !== "undefined") {
|
|
2735
|
+
const probe2 = document.createElement("div");
|
|
2736
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2737
|
+
document.body.appendChild(probe2);
|
|
2738
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2739
|
+
probe2.remove();
|
|
2740
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2741
|
+
this.clampToMaxHeight();
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
clampToMaxHeight() {
|
|
2745
|
+
if (this.maxHeightCap === void 0) return;
|
|
2746
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2747
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2748
|
+
}
|
|
2749
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2750
|
+
this.applySize(this.maxHeightCap);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2584
2753
|
setAllowed(ids, snap) {
|
|
2585
2754
|
if (this.destroyed) return;
|
|
2586
2755
|
this.snaps.setAllowedIds(ids);
|
|
@@ -2714,8 +2883,53 @@ var BottomSheetEngine = class {
|
|
|
2714
2883
|
}
|
|
2715
2884
|
this.updateAriaSlider();
|
|
2716
2885
|
}
|
|
2886
|
+
recompute() {
|
|
2887
|
+
if (this.destroyed) return;
|
|
2888
|
+
this.snaps.recompute();
|
|
2889
|
+
this.scrim.invalidateOpacityCache();
|
|
2890
|
+
if (this.gesture?.isDragging) return;
|
|
2891
|
+
const current = this.snaps.findById(this.activeId);
|
|
2892
|
+
if (current) {
|
|
2893
|
+
this.size = current.size;
|
|
2894
|
+
this.applySize(this.size);
|
|
2895
|
+
this.updateAriaSlider();
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
measureFitSize() {
|
|
2899
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2900
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2901
|
+
const content = this.scrollContainer;
|
|
2902
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2903
|
+
if (typeof window === "undefined") return natural;
|
|
2904
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2905
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2906
|
+
}
|
|
2907
|
+
installFitObserver() {
|
|
2908
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2909
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2910
|
+
return;
|
|
2911
|
+
const targets = [this.handle];
|
|
2912
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2913
|
+
targets.push(this.scrollContainer);
|
|
2914
|
+
}
|
|
2915
|
+
let raf = 0;
|
|
2916
|
+
const ro = new ResizeObserver(() => {
|
|
2917
|
+
if (raf) return;
|
|
2918
|
+
raf = requestAnimationFrame(() => {
|
|
2919
|
+
raf = 0;
|
|
2920
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2921
|
+
this.recompute();
|
|
2922
|
+
});
|
|
2923
|
+
});
|
|
2924
|
+
for (const t of targets) ro.observe(t);
|
|
2925
|
+
this.teardowns.add(() => {
|
|
2926
|
+
ro.disconnect();
|
|
2927
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2928
|
+
});
|
|
2929
|
+
}
|
|
2717
2930
|
destroy() {
|
|
2718
2931
|
this.destroyed = true;
|
|
2932
|
+
this.opening = false;
|
|
2719
2933
|
this.currentAbort.abort();
|
|
2720
2934
|
this.currentViewTransition?.skipTransition?.();
|
|
2721
2935
|
this.currentViewTransition = null;
|
|
@@ -2765,6 +2979,36 @@ var BottomSheetEngine = class {
|
|
|
2765
2979
|
frozen = true;
|
|
2766
2980
|
return cancelled;
|
|
2767
2981
|
}
|
|
2982
|
+
emitBeforeClose(reason) {
|
|
2983
|
+
let cancelled = false;
|
|
2984
|
+
let frozen = false;
|
|
2985
|
+
this.emit("before-close", {
|
|
2986
|
+
reason,
|
|
2987
|
+
cancel: () => {
|
|
2988
|
+
if (frozen) {
|
|
2989
|
+
console.warn(
|
|
2990
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
2991
|
+
);
|
|
2992
|
+
return;
|
|
2993
|
+
}
|
|
2994
|
+
cancelled = true;
|
|
2995
|
+
}
|
|
2996
|
+
});
|
|
2997
|
+
frozen = true;
|
|
2998
|
+
return cancelled;
|
|
2999
|
+
}
|
|
3000
|
+
applyAutoAriaLabelledBy() {
|
|
3001
|
+
if (typeof document === "undefined") return;
|
|
3002
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3003
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3004
|
+
const scope = this.handle ?? this.element;
|
|
3005
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3006
|
+
if (!titled) return;
|
|
3007
|
+
if (!titled.id) {
|
|
3008
|
+
titled.id = nextInstanceId("bs-title");
|
|
3009
|
+
}
|
|
3010
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3011
|
+
}
|
|
2768
3012
|
recomputeSnaps() {
|
|
2769
3013
|
const seen = /* @__PURE__ */ new Set();
|
|
2770
3014
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2800,11 +3044,8 @@ var BottomSheetEngine = class {
|
|
|
2800
3044
|
},
|
|
2801
3045
|
setIsTop: (isTop) => {
|
|
2802
3046
|
this.isTopSheet = isTop;
|
|
2803
|
-
if (this.backdrop) {
|
|
2804
|
-
this.backdrop.style.display = isTop ? "" : "none";
|
|
2805
|
-
}
|
|
2806
3047
|
},
|
|
2807
|
-
isOpen: () => this.size > 0,
|
|
3048
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
2808
3049
|
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2809
3050
|
}));
|
|
2810
3051
|
}
|
|
@@ -2836,6 +3077,7 @@ var BottomSheetEngine = class {
|
|
|
2836
3077
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2837
3078
|
return buf;
|
|
2838
3079
|
},
|
|
3080
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2839
3081
|
cancelAnimation: () => this.animation.cancel(),
|
|
2840
3082
|
applySize: (size) => this.applySize(size),
|
|
2841
3083
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2915,8 +3157,9 @@ var BottomSheetEngine = class {
|
|
|
2915
3157
|
if (this.lifecycle.closeOnEscape) {
|
|
2916
3158
|
const onKey = (e) => {
|
|
2917
3159
|
if (this.destroyed || e.defaultPrevented) return;
|
|
3160
|
+
if (!this.canDismiss()) return;
|
|
2918
3161
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2919
|
-
void this.close();
|
|
3162
|
+
void this.close("escape");
|
|
2920
3163
|
}
|
|
2921
3164
|
};
|
|
2922
3165
|
document.addEventListener("keydown", onKey);
|
|
@@ -2979,20 +3222,31 @@ var BottomSheetEngine = class {
|
|
|
2979
3222
|
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2980
3223
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2981
3224
|
this.activeId = target.id;
|
|
3225
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3226
|
+
this.opening = true;
|
|
3227
|
+
sheetStack.promote(this.id);
|
|
3228
|
+
}
|
|
2982
3229
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3230
|
+
this.opening = false;
|
|
2983
3231
|
if (signal.aborted) return;
|
|
2984
3232
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2985
3233
|
this.updateAriaSlider();
|
|
2986
|
-
this.emit("snap", {
|
|
3234
|
+
this.emit("snap", {
|
|
3235
|
+
id: target.id,
|
|
3236
|
+
size: target.size,
|
|
3237
|
+
progress: this.computeProgress(target.size)
|
|
3238
|
+
});
|
|
2987
3239
|
this.haptic();
|
|
2988
3240
|
if (previousSnapSize === 0 && target.size > 0) {
|
|
2989
3241
|
this.emit("open", { id: target.id });
|
|
2990
3242
|
this.handleOpen();
|
|
2991
3243
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3244
|
+
this.emit("opened", { id: target.id });
|
|
2992
3245
|
}
|
|
2993
3246
|
if (target.size === 0) {
|
|
2994
3247
|
this.emit("close", void 0);
|
|
2995
3248
|
this.handleClose();
|
|
3249
|
+
this.emit("closed", void 0);
|
|
2996
3250
|
}
|
|
2997
3251
|
});
|
|
2998
3252
|
}
|
|
@@ -3061,17 +3315,24 @@ var BottomSheetEngine = class {
|
|
|
3061
3315
|
const target = this.snaps.findById(this.activeId);
|
|
3062
3316
|
if (!target) return;
|
|
3063
3317
|
this.updateAriaSlider();
|
|
3064
|
-
this.emit("snap", {
|
|
3318
|
+
this.emit("snap", {
|
|
3319
|
+
id: target.id,
|
|
3320
|
+
size: target.size,
|
|
3321
|
+
progress: this.computeProgress(target.size)
|
|
3322
|
+
});
|
|
3065
3323
|
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3066
3324
|
this.emit("open", { id: target.id });
|
|
3067
3325
|
this.handleOpen();
|
|
3068
3326
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3327
|
+
this.emit("opened", { id: target.id });
|
|
3069
3328
|
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3070
3329
|
this.emit("close", void 0);
|
|
3071
3330
|
this.handleClose();
|
|
3331
|
+
this.emit("closed", void 0);
|
|
3072
3332
|
}
|
|
3073
3333
|
}
|
|
3074
3334
|
handleClose() {
|
|
3335
|
+
this.opening = false;
|
|
3075
3336
|
this.lifecycle.release();
|
|
3076
3337
|
sheetStack.update();
|
|
3077
3338
|
}
|
|
@@ -3125,6 +3386,10 @@ function createBottomSheet(opts) {
|
|
|
3125
3386
|
snapTo: (id) => engine?.snapTo(id) ?? Promise.resolve(),
|
|
3126
3387
|
open: (id) => engine?.open(id) ?? Promise.resolve(),
|
|
3127
3388
|
close: () => engine?.close() ?? Promise.resolve(),
|
|
3389
|
+
expand: () => engine?.expand() ?? Promise.resolve(),
|
|
3390
|
+
collapse: () => engine?.collapse() ?? Promise.resolve(),
|
|
3391
|
+
isTop: () => engine?.isTop() ?? false,
|
|
3392
|
+
depth: () => engine?.depth() ?? 0,
|
|
3128
3393
|
setAllowed: (ids, snap) => engine?.setAllowed(ids, snap),
|
|
3129
3394
|
setSnapPoints: (points, allowed) => engine?.setSnapPoints(points, allowed),
|
|
3130
3395
|
setScrim: (scrimOpts) => engine?.setScrim(scrimOpts),
|
|
@@ -3134,6 +3399,7 @@ function createBottomSheet(opts) {
|
|
|
3134
3399
|
}),
|
|
3135
3400
|
setScrimStages: (stagesOpts) => engine?.setScrimStages(stagesOpts) ?? (() => {
|
|
3136
3401
|
}),
|
|
3402
|
+
recompute: () => engine?.recompute(),
|
|
3137
3403
|
destroy: () => {
|
|
3138
3404
|
engine?.destroy();
|
|
3139
3405
|
engine = null;
|