@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/index.js
CHANGED
|
@@ -35,6 +35,15 @@ var SheetStack = class {
|
|
|
35
35
|
size() {
|
|
36
36
|
return this.entries.length;
|
|
37
37
|
}
|
|
38
|
+
depthOf(id) {
|
|
39
|
+
const open = [];
|
|
40
|
+
for (const entry of this.entries) {
|
|
41
|
+
if (!entry.isOpen || entry.isOpen()) open.push(entry);
|
|
42
|
+
}
|
|
43
|
+
const idx = open.findIndex((e) => e.id === id);
|
|
44
|
+
if (idx === -1) return 0;
|
|
45
|
+
return open.length - 1 - idx;
|
|
46
|
+
}
|
|
38
47
|
clear() {
|
|
39
48
|
this.entries = [];
|
|
40
49
|
}
|
|
@@ -159,7 +168,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
159
168
|
var resolveSnap = (point, mode, measureFit) => {
|
|
160
169
|
if (typeof point === "number") return Math.max(0, point);
|
|
161
170
|
if (point === "full") return viewportSize(mode);
|
|
162
|
-
if (point === "fit"
|
|
171
|
+
if (point === "fit" || point === "content") {
|
|
172
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
173
|
+
}
|
|
163
174
|
const pctMatch = point.match(PERCENT);
|
|
164
175
|
if (pctMatch) {
|
|
165
176
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -396,6 +407,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
396
407
|
}
|
|
397
408
|
|
|
398
409
|
// src/core/features/route.ts
|
|
410
|
+
var closers = [];
|
|
411
|
+
var handlerInstalled = false;
|
|
412
|
+
var suppress = 0;
|
|
413
|
+
var ensureHandler = () => {
|
|
414
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
415
|
+
handlerInstalled = true;
|
|
416
|
+
window.addEventListener("popstate", () => {
|
|
417
|
+
if (suppress > 0) {
|
|
418
|
+
suppress -= 1;
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
let target = null;
|
|
422
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
423
|
+
const c = closers[i];
|
|
424
|
+
if (!c.isOpen()) continue;
|
|
425
|
+
if (!target) target = c;
|
|
426
|
+
if (c.isTop()) {
|
|
427
|
+
target = c;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (!target) return;
|
|
432
|
+
target.consumed = true;
|
|
433
|
+
const idx = closers.indexOf(target);
|
|
434
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
435
|
+
target.close();
|
|
436
|
+
});
|
|
437
|
+
};
|
|
438
|
+
var programmaticBack = () => {
|
|
439
|
+
suppress += 1;
|
|
440
|
+
try {
|
|
441
|
+
history.back();
|
|
442
|
+
} catch {
|
|
443
|
+
suppress = Math.max(0, suppress - 1);
|
|
444
|
+
}
|
|
445
|
+
};
|
|
399
446
|
function installRoute(deps) {
|
|
400
447
|
if (typeof window === "undefined") {
|
|
401
448
|
return () => {
|
|
@@ -405,82 +452,81 @@ function installRoute(deps) {
|
|
|
405
452
|
return () => {
|
|
406
453
|
};
|
|
407
454
|
}
|
|
408
|
-
let
|
|
409
|
-
let
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
455
|
+
let pushed = false;
|
|
456
|
+
let closer = null;
|
|
457
|
+
const teardownEntry = () => {
|
|
458
|
+
if (closer) {
|
|
459
|
+
const idx = closers.indexOf(closer);
|
|
460
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
461
|
+
}
|
|
462
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
463
|
+
closer = null;
|
|
464
|
+
if (pushed && !wasConsumed) {
|
|
465
|
+
pushed = false;
|
|
466
|
+
programmaticBack();
|
|
467
|
+
} else {
|
|
468
|
+
pushed = false;
|
|
418
469
|
}
|
|
419
470
|
};
|
|
420
471
|
const onOpen = () => {
|
|
421
|
-
if (
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
|
-
window.addEventListener("popstate", onPop);
|
|
437
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
438
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
439
|
-
try {
|
|
472
|
+
if (closer) return;
|
|
473
|
+
closer = {
|
|
474
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
475
|
+
isTop: () => deps.isTopSheet(),
|
|
476
|
+
close: () => void deps.close(),
|
|
477
|
+
consumed: false
|
|
478
|
+
};
|
|
479
|
+
ensureHandler();
|
|
480
|
+
closers.push(closer);
|
|
481
|
+
try {
|
|
482
|
+
if (deps.routedTo !== void 0) {
|
|
483
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
484
|
+
} else {
|
|
440
485
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
441
|
-
closeOnBackPushed = true;
|
|
442
|
-
} catch {
|
|
443
486
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const state = history.state;
|
|
448
|
-
if (state?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
449
|
-
void deps.close();
|
|
450
|
-
}
|
|
451
|
-
};
|
|
452
|
-
window.addEventListener("popstate", onPop);
|
|
453
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
const onClose = () => {
|
|
457
|
-
detachPopstate?.();
|
|
458
|
-
detachPopstate = null;
|
|
459
|
-
if (routePushed) {
|
|
460
|
-
routePushed = false;
|
|
461
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
462
|
-
}
|
|
463
|
-
if (closeOnBackPushed) {
|
|
464
|
-
closeOnBackPushed = false;
|
|
465
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
487
|
+
pushed = true;
|
|
488
|
+
} catch {
|
|
489
|
+
pushed = false;
|
|
466
490
|
}
|
|
467
491
|
};
|
|
468
492
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
469
|
-
const unsubscribeClose = deps.on("close",
|
|
493
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
470
494
|
if (deps.getSize() > 0) onOpen();
|
|
471
495
|
return () => {
|
|
472
496
|
unsubscribeOpen();
|
|
473
497
|
unsubscribeClose();
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
498
|
+
teardownEntry();
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function installRouteChange(deps) {
|
|
502
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
503
|
+
return () => {
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
const onChange = () => {
|
|
507
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
508
|
+
void deps.close();
|
|
509
|
+
};
|
|
510
|
+
const wrap = (key) => {
|
|
511
|
+
const original = history[key];
|
|
512
|
+
const patched = function(...args) {
|
|
513
|
+
original.apply(this, args);
|
|
514
|
+
onChange();
|
|
515
|
+
};
|
|
516
|
+
history[key] = patched;
|
|
517
|
+
return () => {
|
|
518
|
+
if (history[key] === patched) {
|
|
519
|
+
history[key] = original;
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
};
|
|
523
|
+
window.addEventListener("popstate", onChange);
|
|
524
|
+
const restorePush = wrap("pushState");
|
|
525
|
+
const restoreReplace = wrap("replaceState");
|
|
526
|
+
return () => {
|
|
527
|
+
window.removeEventListener("popstate", onChange);
|
|
528
|
+
restorePush();
|
|
529
|
+
restoreReplace();
|
|
484
530
|
};
|
|
485
531
|
}
|
|
486
532
|
|
|
@@ -788,6 +834,7 @@ function applyOverlayPosition(ws, mode, position, inset) {
|
|
|
788
834
|
|
|
789
835
|
// src/core/controllers/scrim-controller.ts
|
|
790
836
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
837
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
791
838
|
var ScrimController = class {
|
|
792
839
|
constructor(deps, opts) {
|
|
793
840
|
__publicField(this, "screenComponent");
|
|
@@ -826,9 +873,11 @@ var ScrimController = class {
|
|
|
826
873
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
827
874
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
828
875
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
876
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
877
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
829
878
|
if (this.screenComponent) {
|
|
830
879
|
this.applyScrimStyles({
|
|
831
|
-
color:
|
|
880
|
+
color: effectiveColor,
|
|
832
881
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
833
882
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
834
883
|
});
|
|
@@ -1602,7 +1651,7 @@ var LifecycleController = class {
|
|
|
1602
1651
|
this.releaseScrollLock = null;
|
|
1603
1652
|
this.inertSiblings.remove();
|
|
1604
1653
|
if (this.returnFocus) {
|
|
1605
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1654
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1606
1655
|
target?.focus?.();
|
|
1607
1656
|
}
|
|
1608
1657
|
}
|
|
@@ -1770,6 +1819,7 @@ var GestureController = class {
|
|
|
1770
1819
|
__publicField(this, "dragStartSize", 0);
|
|
1771
1820
|
__publicField(this, "currentPointerKind", "touch");
|
|
1772
1821
|
__publicField(this, "keyboardDismissed", false);
|
|
1822
|
+
__publicField(this, "dragSuppressed", false);
|
|
1773
1823
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1774
1824
|
this.deps = deps;
|
|
1775
1825
|
}
|
|
@@ -1780,6 +1830,11 @@ var GestureController = class {
|
|
|
1780
1830
|
if (this.detach) return this.detach;
|
|
1781
1831
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1782
1832
|
onStart: (_coord, kind) => {
|
|
1833
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1834
|
+
this.dragSuppressed = true;
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
this.dragSuppressed = false;
|
|
1783
1838
|
this.deps.cancelAnimation();
|
|
1784
1839
|
this.isDragging_ = true;
|
|
1785
1840
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1790,6 +1845,7 @@ var GestureController = class {
|
|
|
1790
1845
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1791
1846
|
},
|
|
1792
1847
|
onMove: (delta) => {
|
|
1848
|
+
if (this.dragSuppressed) return;
|
|
1793
1849
|
const ctx = this.deps.getDragContext();
|
|
1794
1850
|
const { min, max } = ctx.range;
|
|
1795
1851
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1813,6 +1869,10 @@ var GestureController = class {
|
|
|
1813
1869
|
}
|
|
1814
1870
|
},
|
|
1815
1871
|
onEnd: (delta, velocity, kind) => {
|
|
1872
|
+
if (this.dragSuppressed) {
|
|
1873
|
+
this.dragSuppressed = false;
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1816
1876
|
this.isDragging_ = false;
|
|
1817
1877
|
this.keyboardDismissed = false;
|
|
1818
1878
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1823,6 +1883,10 @@ var GestureController = class {
|
|
|
1823
1883
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1824
1884
|
},
|
|
1825
1885
|
onCancel: () => {
|
|
1886
|
+
if (this.dragSuppressed) {
|
|
1887
|
+
this.dragSuppressed = false;
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1826
1890
|
this.isDragging_ = false;
|
|
1827
1891
|
this.keyboardDismissed = false;
|
|
1828
1892
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -2202,6 +2266,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2202
2266
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2203
2267
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2204
2268
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2269
|
+
persistent: opts.persistent ?? false,
|
|
2270
|
+
disableClose: opts.disableClose ?? false,
|
|
2271
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2272
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2273
|
+
radius: opts.radius,
|
|
2274
|
+
maxHeight: opts.maxHeight,
|
|
2205
2275
|
initialAllowed,
|
|
2206
2276
|
initialId,
|
|
2207
2277
|
scrim: {
|
|
@@ -2228,7 +2298,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2228
2298
|
closeOnEscape: opts.closeOnEscape,
|
|
2229
2299
|
lockBodyScroll: opts.lockBodyScroll,
|
|
2230
2300
|
inertSiblings: opts.inertSiblings,
|
|
2231
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2301
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2302
|
+
returnFocus: opts.returnFocusTo
|
|
2232
2303
|
}
|
|
2233
2304
|
};
|
|
2234
2305
|
}
|
|
@@ -2273,6 +2344,11 @@ var BottomSheetEngine = class {
|
|
|
2273
2344
|
__publicField(this, "lifecycle");
|
|
2274
2345
|
__publicField(this, "closeOnBack");
|
|
2275
2346
|
__publicField(this, "routedTo");
|
|
2347
|
+
__publicField(this, "persistent");
|
|
2348
|
+
__publicField(this, "disableCloseFlag");
|
|
2349
|
+
__publicField(this, "disableDragFlag");
|
|
2350
|
+
__publicField(this, "closeOnRouteChange");
|
|
2351
|
+
__publicField(this, "maxHeightCap");
|
|
2276
2352
|
__publicField(this, "snapPointsRaw");
|
|
2277
2353
|
__publicField(this, "snaps");
|
|
2278
2354
|
__publicField(this, "activeId");
|
|
@@ -2285,6 +2361,7 @@ var BottomSheetEngine = class {
|
|
|
2285
2361
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
2286
2362
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
2287
2363
|
__publicField(this, "isTopSheet", true);
|
|
2364
|
+
__publicField(this, "opening", false);
|
|
2288
2365
|
__publicField(this, "progressPayload", {
|
|
2289
2366
|
value: 0,
|
|
2290
2367
|
size: 0
|
|
@@ -2341,7 +2418,8 @@ var BottomSheetEngine = class {
|
|
|
2341
2418
|
void this.snapTo(id);
|
|
2342
2419
|
},
|
|
2343
2420
|
close: () => {
|
|
2344
|
-
|
|
2421
|
+
if (!this.canDismiss()) return;
|
|
2422
|
+
void this.close("backdrop");
|
|
2345
2423
|
}
|
|
2346
2424
|
},
|
|
2347
2425
|
resolved.scrim
|
|
@@ -2365,6 +2443,10 @@ var BottomSheetEngine = class {
|
|
|
2365
2443
|
);
|
|
2366
2444
|
this.closeOnBack = resolved.closeOnBack;
|
|
2367
2445
|
this.routedTo = opts.routedTo;
|
|
2446
|
+
this.persistent = resolved.persistent;
|
|
2447
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2448
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2449
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2368
2450
|
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2369
2451
|
this.snapPointsRaw = opts.snapPoints;
|
|
2370
2452
|
this.persistKey = opts.persistKey;
|
|
@@ -2378,7 +2460,7 @@ var BottomSheetEngine = class {
|
|
|
2378
2460
|
this.snapPointsRaw,
|
|
2379
2461
|
resolved.initialAllowed,
|
|
2380
2462
|
this.mode,
|
|
2381
|
-
() =>
|
|
2463
|
+
() => this.measureFitSize(),
|
|
2382
2464
|
(maxAxisSize) => {
|
|
2383
2465
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2384
2466
|
}
|
|
@@ -2412,6 +2494,19 @@ var BottomSheetEngine = class {
|
|
|
2412
2494
|
io.observe(this.element);
|
|
2413
2495
|
this.teardowns.add(() => io.disconnect());
|
|
2414
2496
|
}
|
|
2497
|
+
this.installFitObserver();
|
|
2498
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2499
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2500
|
+
this.applyAutoAriaLabelledBy();
|
|
2501
|
+
if (this.closeOnRouteChange) {
|
|
2502
|
+
this.teardowns.add(
|
|
2503
|
+
installRouteChange({
|
|
2504
|
+
isDestroyed: () => this.destroyed,
|
|
2505
|
+
getSize: () => this.size,
|
|
2506
|
+
close: () => this.close()
|
|
2507
|
+
})
|
|
2508
|
+
);
|
|
2509
|
+
}
|
|
2415
2510
|
if (this.persistKey) {
|
|
2416
2511
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2417
2512
|
}
|
|
@@ -2436,7 +2531,7 @@ var BottomSheetEngine = class {
|
|
|
2436
2531
|
isTopSheet: () => this.isTopSheet,
|
|
2437
2532
|
getSize: () => this.size,
|
|
2438
2533
|
isDestroyed: () => this.destroyed,
|
|
2439
|
-
close: () => this.close(),
|
|
2534
|
+
close: () => this.close("back"),
|
|
2440
2535
|
on: (event, fn) => this.on(event, fn),
|
|
2441
2536
|
sheetId: this.id
|
|
2442
2537
|
})
|
|
@@ -2530,6 +2625,10 @@ var BottomSheetEngine = class {
|
|
|
2530
2625
|
const previousSize = this.size;
|
|
2531
2626
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2532
2627
|
this.activeId = id;
|
|
2628
|
+
if (wasClosed && target.size > 0) {
|
|
2629
|
+
this.opening = true;
|
|
2630
|
+
sheetStack.promote(this.id);
|
|
2631
|
+
}
|
|
2533
2632
|
if (this.animation.viewTransitionsAvailable) {
|
|
2534
2633
|
this.currentViewTransition?.skipTransition?.();
|
|
2535
2634
|
const vt = document.startViewTransition(() => {
|
|
@@ -2544,19 +2643,26 @@ var BottomSheetEngine = class {
|
|
|
2544
2643
|
} else {
|
|
2545
2644
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2546
2645
|
}
|
|
2646
|
+
this.opening = false;
|
|
2547
2647
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2548
2648
|
if (signal.aborted) return;
|
|
2549
2649
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2550
2650
|
this.updateAriaSlider();
|
|
2551
|
-
this.emit("snap", {
|
|
2651
|
+
this.emit("snap", {
|
|
2652
|
+
id,
|
|
2653
|
+
size: target.size,
|
|
2654
|
+
progress: this.computeProgress(target.size)
|
|
2655
|
+
});
|
|
2552
2656
|
if (wasClosed && target.size > 0) {
|
|
2553
2657
|
this.emit("open", { id });
|
|
2554
2658
|
this.handleOpen();
|
|
2555
2659
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2660
|
+
this.emit("opened", { id });
|
|
2556
2661
|
}
|
|
2557
2662
|
if (target.size === 0) {
|
|
2558
2663
|
this.emit("close", void 0);
|
|
2559
2664
|
this.handleClose();
|
|
2665
|
+
this.emit("closed", void 0);
|
|
2560
2666
|
}
|
|
2561
2667
|
}
|
|
2562
2668
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2581,11 +2687,74 @@ var BottomSheetEngine = class {
|
|
|
2581
2687
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2582
2688
|
return this.snapTo(target);
|
|
2583
2689
|
}
|
|
2584
|
-
close() {
|
|
2690
|
+
close(reason = "programmatic") {
|
|
2585
2691
|
if (this.destroyed) return Promise.resolve();
|
|
2692
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2693
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2586
2694
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2587
2695
|
return this.snapTo(closedId ?? this.activeId);
|
|
2588
2696
|
}
|
|
2697
|
+
canDismiss() {
|
|
2698
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2699
|
+
}
|
|
2700
|
+
isTop() {
|
|
2701
|
+
return this.isTopSheet;
|
|
2702
|
+
}
|
|
2703
|
+
depth() {
|
|
2704
|
+
return sheetStack.depthOf(this.id);
|
|
2705
|
+
}
|
|
2706
|
+
expand() {
|
|
2707
|
+
if (this.destroyed) return Promise.resolve();
|
|
2708
|
+
const ids = this.allowedIdsBySize();
|
|
2709
|
+
const target = ids[ids.length - 1];
|
|
2710
|
+
if (!target) return Promise.resolve();
|
|
2711
|
+
return this.snapTo(target);
|
|
2712
|
+
}
|
|
2713
|
+
collapse() {
|
|
2714
|
+
if (this.destroyed) return Promise.resolve();
|
|
2715
|
+
const ids = this.allowedIdsBySize();
|
|
2716
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2717
|
+
const target = nonZero ?? ids[0];
|
|
2718
|
+
if (!target) return Promise.resolve();
|
|
2719
|
+
return this.snapTo(target);
|
|
2720
|
+
}
|
|
2721
|
+
setRadius(r) {
|
|
2722
|
+
if (this.destroyed) return;
|
|
2723
|
+
this.element.style.setProperty(
|
|
2724
|
+
"--bs-radius",
|
|
2725
|
+
typeof r === "number" ? `${r}px` : r
|
|
2726
|
+
);
|
|
2727
|
+
}
|
|
2728
|
+
setMaxHeight(h) {
|
|
2729
|
+
if (this.destroyed) return;
|
|
2730
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2731
|
+
const axis = layoutAxis(this.mode);
|
|
2732
|
+
this.element.style.setProperty(
|
|
2733
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2734
|
+
value
|
|
2735
|
+
);
|
|
2736
|
+
if (typeof h === "number") {
|
|
2737
|
+
this.maxHeightCap = h;
|
|
2738
|
+
this.clampToMaxHeight();
|
|
2739
|
+
} else if (typeof window !== "undefined") {
|
|
2740
|
+
const probe2 = document.createElement("div");
|
|
2741
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2742
|
+
document.body.appendChild(probe2);
|
|
2743
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2744
|
+
probe2.remove();
|
|
2745
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2746
|
+
this.clampToMaxHeight();
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
clampToMaxHeight() {
|
|
2750
|
+
if (this.maxHeightCap === void 0) return;
|
|
2751
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2752
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2753
|
+
}
|
|
2754
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2755
|
+
this.applySize(this.maxHeightCap);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2589
2758
|
setAllowed(ids, snap) {
|
|
2590
2759
|
if (this.destroyed) return;
|
|
2591
2760
|
this.snaps.setAllowedIds(ids);
|
|
@@ -2719,8 +2888,53 @@ var BottomSheetEngine = class {
|
|
|
2719
2888
|
}
|
|
2720
2889
|
this.updateAriaSlider();
|
|
2721
2890
|
}
|
|
2891
|
+
recompute() {
|
|
2892
|
+
if (this.destroyed) return;
|
|
2893
|
+
this.snaps.recompute();
|
|
2894
|
+
this.scrim.invalidateOpacityCache();
|
|
2895
|
+
if (this.gesture?.isDragging) return;
|
|
2896
|
+
const current = this.snaps.findById(this.activeId);
|
|
2897
|
+
if (current) {
|
|
2898
|
+
this.size = current.size;
|
|
2899
|
+
this.applySize(this.size);
|
|
2900
|
+
this.updateAriaSlider();
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
measureFitSize() {
|
|
2904
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2905
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2906
|
+
const content = this.scrollContainer;
|
|
2907
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2908
|
+
if (typeof window === "undefined") return natural;
|
|
2909
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2910
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2911
|
+
}
|
|
2912
|
+
installFitObserver() {
|
|
2913
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2914
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2915
|
+
return;
|
|
2916
|
+
const targets = [this.handle];
|
|
2917
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2918
|
+
targets.push(this.scrollContainer);
|
|
2919
|
+
}
|
|
2920
|
+
let raf = 0;
|
|
2921
|
+
const ro = new ResizeObserver(() => {
|
|
2922
|
+
if (raf) return;
|
|
2923
|
+
raf = requestAnimationFrame(() => {
|
|
2924
|
+
raf = 0;
|
|
2925
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2926
|
+
this.recompute();
|
|
2927
|
+
});
|
|
2928
|
+
});
|
|
2929
|
+
for (const t of targets) ro.observe(t);
|
|
2930
|
+
this.teardowns.add(() => {
|
|
2931
|
+
ro.disconnect();
|
|
2932
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2933
|
+
});
|
|
2934
|
+
}
|
|
2722
2935
|
destroy() {
|
|
2723
2936
|
this.destroyed = true;
|
|
2937
|
+
this.opening = false;
|
|
2724
2938
|
this.currentAbort.abort();
|
|
2725
2939
|
this.currentViewTransition?.skipTransition?.();
|
|
2726
2940
|
this.currentViewTransition = null;
|
|
@@ -2770,6 +2984,36 @@ var BottomSheetEngine = class {
|
|
|
2770
2984
|
frozen = true;
|
|
2771
2985
|
return cancelled;
|
|
2772
2986
|
}
|
|
2987
|
+
emitBeforeClose(reason) {
|
|
2988
|
+
let cancelled = false;
|
|
2989
|
+
let frozen = false;
|
|
2990
|
+
this.emit("before-close", {
|
|
2991
|
+
reason,
|
|
2992
|
+
cancel: () => {
|
|
2993
|
+
if (frozen) {
|
|
2994
|
+
console.warn(
|
|
2995
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
2996
|
+
);
|
|
2997
|
+
return;
|
|
2998
|
+
}
|
|
2999
|
+
cancelled = true;
|
|
3000
|
+
}
|
|
3001
|
+
});
|
|
3002
|
+
frozen = true;
|
|
3003
|
+
return cancelled;
|
|
3004
|
+
}
|
|
3005
|
+
applyAutoAriaLabelledBy() {
|
|
3006
|
+
if (typeof document === "undefined") return;
|
|
3007
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3008
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3009
|
+
const scope = this.handle ?? this.element;
|
|
3010
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3011
|
+
if (!titled) return;
|
|
3012
|
+
if (!titled.id) {
|
|
3013
|
+
titled.id = nextInstanceId("bs-title");
|
|
3014
|
+
}
|
|
3015
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3016
|
+
}
|
|
2773
3017
|
recomputeSnaps() {
|
|
2774
3018
|
const seen = /* @__PURE__ */ new Set();
|
|
2775
3019
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2805,11 +3049,8 @@ var BottomSheetEngine = class {
|
|
|
2805
3049
|
},
|
|
2806
3050
|
setIsTop: (isTop) => {
|
|
2807
3051
|
this.isTopSheet = isTop;
|
|
2808
|
-
if (this.backdrop) {
|
|
2809
|
-
this.backdrop.style.display = isTop ? "" : "none";
|
|
2810
|
-
}
|
|
2811
3052
|
},
|
|
2812
|
-
isOpen: () => this.size > 0,
|
|
3053
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
2813
3054
|
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2814
3055
|
}));
|
|
2815
3056
|
}
|
|
@@ -2841,6 +3082,7 @@ var BottomSheetEngine = class {
|
|
|
2841
3082
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2842
3083
|
return buf;
|
|
2843
3084
|
},
|
|
3085
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2844
3086
|
cancelAnimation: () => this.animation.cancel(),
|
|
2845
3087
|
applySize: (size) => this.applySize(size),
|
|
2846
3088
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2920,8 +3162,9 @@ var BottomSheetEngine = class {
|
|
|
2920
3162
|
if (this.lifecycle.closeOnEscape) {
|
|
2921
3163
|
const onKey = (e) => {
|
|
2922
3164
|
if (this.destroyed || e.defaultPrevented) return;
|
|
3165
|
+
if (!this.canDismiss()) return;
|
|
2923
3166
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2924
|
-
void this.close();
|
|
3167
|
+
void this.close("escape");
|
|
2925
3168
|
}
|
|
2926
3169
|
};
|
|
2927
3170
|
document.addEventListener("keydown", onKey);
|
|
@@ -2984,20 +3227,31 @@ var BottomSheetEngine = class {
|
|
|
2984
3227
|
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2985
3228
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2986
3229
|
this.activeId = target.id;
|
|
3230
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3231
|
+
this.opening = true;
|
|
3232
|
+
sheetStack.promote(this.id);
|
|
3233
|
+
}
|
|
2987
3234
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3235
|
+
this.opening = false;
|
|
2988
3236
|
if (signal.aborted) return;
|
|
2989
3237
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2990
3238
|
this.updateAriaSlider();
|
|
2991
|
-
this.emit("snap", {
|
|
3239
|
+
this.emit("snap", {
|
|
3240
|
+
id: target.id,
|
|
3241
|
+
size: target.size,
|
|
3242
|
+
progress: this.computeProgress(target.size)
|
|
3243
|
+
});
|
|
2992
3244
|
this.haptic();
|
|
2993
3245
|
if (previousSnapSize === 0 && target.size > 0) {
|
|
2994
3246
|
this.emit("open", { id: target.id });
|
|
2995
3247
|
this.handleOpen();
|
|
2996
3248
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3249
|
+
this.emit("opened", { id: target.id });
|
|
2997
3250
|
}
|
|
2998
3251
|
if (target.size === 0) {
|
|
2999
3252
|
this.emit("close", void 0);
|
|
3000
3253
|
this.handleClose();
|
|
3254
|
+
this.emit("closed", void 0);
|
|
3001
3255
|
}
|
|
3002
3256
|
});
|
|
3003
3257
|
}
|
|
@@ -3066,17 +3320,24 @@ var BottomSheetEngine = class {
|
|
|
3066
3320
|
const target = this.snaps.findById(this.activeId);
|
|
3067
3321
|
if (!target) return;
|
|
3068
3322
|
this.updateAriaSlider();
|
|
3069
|
-
this.emit("snap", {
|
|
3323
|
+
this.emit("snap", {
|
|
3324
|
+
id: target.id,
|
|
3325
|
+
size: target.size,
|
|
3326
|
+
progress: this.computeProgress(target.size)
|
|
3327
|
+
});
|
|
3070
3328
|
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3071
3329
|
this.emit("open", { id: target.id });
|
|
3072
3330
|
this.handleOpen();
|
|
3073
3331
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3332
|
+
this.emit("opened", { id: target.id });
|
|
3074
3333
|
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3075
3334
|
this.emit("close", void 0);
|
|
3076
3335
|
this.handleClose();
|
|
3336
|
+
this.emit("closed", void 0);
|
|
3077
3337
|
}
|
|
3078
3338
|
}
|
|
3079
3339
|
handleClose() {
|
|
3340
|
+
this.opening = false;
|
|
3080
3341
|
this.lifecycle.release();
|
|
3081
3342
|
sheetStack.update();
|
|
3082
3343
|
}
|