@surdeddd/bottom-sheet 0.3.0 → 0.4.1
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 +490 -91
- 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 +490 -91
- package/dist/index.cjs +347 -80
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +347 -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 +358 -81
- package/dist/qwik.d.cts +4 -2
- package/dist/qwik.d.ts +4 -2
- package/dist/qwik.js +358 -81
- package/dist/react.cjs +451 -89
- package/dist/react.d.cts +29 -4
- package/dist/react.d.ts +29 -4
- package/dist/react.js +451 -89
- package/dist/solid.cjs +347 -80
- package/dist/solid.d.cts +38 -2
- package/dist/solid.d.ts +38 -2
- package/dist/solid.js +347 -80
- package/dist/solid.source.jsx +347 -80
- package/dist/styles.css +68 -55
- package/dist/svelte-core.cjs +352 -80
- package/dist/svelte-core.js +352 -80
- package/dist/svelte-src/BottomSheet.svelte +113 -15
- package/dist/svelte.cjs +474 -133
- package/dist/svelte.d.cts +21 -0
- package/dist/svelte.d.ts +21 -0
- package/dist/svelte.js +474 -133
- package/dist/vue.cjs +610 -109
- package/dist/vue.d.cts +51 -2
- package/dist/vue.d.ts +51 -2
- package/dist/vue.js +611 -110
- package/package.json +8 -8
package/dist/index.cjs
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
|
}
|
|
@@ -161,7 +170,9 @@ var PERCENT = /^(-?\d+(?:\.\d+)?)%$/;
|
|
|
161
170
|
var resolveSnap = (point, mode, measureFit) => {
|
|
162
171
|
if (typeof point === "number") return Math.max(0, point);
|
|
163
172
|
if (point === "full") return viewportSize(mode);
|
|
164
|
-
if (point === "fit"
|
|
173
|
+
if (point === "fit" || point === "content") {
|
|
174
|
+
return Math.max(0, measureFit?.() ?? 0);
|
|
175
|
+
}
|
|
165
176
|
const pctMatch = point.match(PERCENT);
|
|
166
177
|
if (pctMatch) {
|
|
167
178
|
const pct = parseFloat(pctMatch[1]) / 100;
|
|
@@ -398,6 +409,42 @@ function notifyLinkedSheets(sheets, self) {
|
|
|
398
409
|
}
|
|
399
410
|
|
|
400
411
|
// src/core/features/route.ts
|
|
412
|
+
var closers = [];
|
|
413
|
+
var handlerInstalled = false;
|
|
414
|
+
var suppress = 0;
|
|
415
|
+
var ensureHandler = () => {
|
|
416
|
+
if (handlerInstalled || typeof window === "undefined") return;
|
|
417
|
+
handlerInstalled = true;
|
|
418
|
+
window.addEventListener("popstate", () => {
|
|
419
|
+
if (suppress > 0) {
|
|
420
|
+
suppress -= 1;
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
let target = null;
|
|
424
|
+
for (let i = closers.length - 1; i >= 0; i -= 1) {
|
|
425
|
+
const c = closers[i];
|
|
426
|
+
if (!c.isOpen()) continue;
|
|
427
|
+
if (!target) target = c;
|
|
428
|
+
if (c.isTop()) {
|
|
429
|
+
target = c;
|
|
430
|
+
break;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
if (!target) return;
|
|
434
|
+
target.consumed = true;
|
|
435
|
+
const idx = closers.indexOf(target);
|
|
436
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
437
|
+
target.close();
|
|
438
|
+
});
|
|
439
|
+
};
|
|
440
|
+
var programmaticBack = () => {
|
|
441
|
+
suppress += 1;
|
|
442
|
+
try {
|
|
443
|
+
history.back();
|
|
444
|
+
} catch {
|
|
445
|
+
suppress = Math.max(0, suppress - 1);
|
|
446
|
+
}
|
|
447
|
+
};
|
|
401
448
|
function installRoute(deps) {
|
|
402
449
|
if (typeof window === "undefined") {
|
|
403
450
|
return () => {
|
|
@@ -407,82 +454,81 @@ function installRoute(deps) {
|
|
|
407
454
|
return () => {
|
|
408
455
|
};
|
|
409
456
|
}
|
|
410
|
-
let
|
|
411
|
-
let
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
457
|
+
let pushed = false;
|
|
458
|
+
let closer = null;
|
|
459
|
+
const teardownEntry = () => {
|
|
460
|
+
if (closer) {
|
|
461
|
+
const idx = closers.indexOf(closer);
|
|
462
|
+
if (idx !== -1) closers.splice(idx, 1);
|
|
463
|
+
}
|
|
464
|
+
const wasConsumed = closer?.consumed ?? false;
|
|
465
|
+
closer = null;
|
|
466
|
+
if (pushed && !wasConsumed) {
|
|
467
|
+
pushed = false;
|
|
468
|
+
programmaticBack();
|
|
469
|
+
} else {
|
|
470
|
+
pushed = false;
|
|
420
471
|
}
|
|
421
472
|
};
|
|
422
473
|
const onOpen = () => {
|
|
423
|
-
if (
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
}
|
|
437
|
-
};
|
|
438
|
-
window.addEventListener("popstate", onPop);
|
|
439
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
440
|
-
} else if (deps.closeOnBack && !detachPopstate) {
|
|
441
|
-
try {
|
|
474
|
+
if (closer) return;
|
|
475
|
+
closer = {
|
|
476
|
+
isOpen: () => !deps.isDestroyed() && deps.getSize() > 0,
|
|
477
|
+
isTop: () => deps.isTopSheet(),
|
|
478
|
+
close: () => void deps.close(),
|
|
479
|
+
consumed: false
|
|
480
|
+
};
|
|
481
|
+
ensureHandler();
|
|
482
|
+
closers.push(closer);
|
|
483
|
+
try {
|
|
484
|
+
if (deps.routedTo !== void 0) {
|
|
485
|
+
history.pushState({ __bsRouted: deps.sheetId }, "", deps.routedTo);
|
|
486
|
+
} else {
|
|
442
487
|
history.pushState({ __bsSheet: deps.sheetId }, "");
|
|
443
|
-
closeOnBackPushed = true;
|
|
444
|
-
} catch {
|
|
445
488
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const state = history.state;
|
|
450
|
-
if (state?.__bsSheet !== deps.sheetId) closeOnBackPushed = false;
|
|
451
|
-
void deps.close();
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
window.addEventListener("popstate", onPop);
|
|
455
|
-
detachPopstate = () => window.removeEventListener("popstate", onPop);
|
|
456
|
-
}
|
|
457
|
-
};
|
|
458
|
-
const onClose = () => {
|
|
459
|
-
detachPopstate?.();
|
|
460
|
-
detachPopstate = null;
|
|
461
|
-
if (routePushed) {
|
|
462
|
-
routePushed = false;
|
|
463
|
-
if (deps.routedTo !== void 0) popOurMarker("__bsRouted", deps.routedTo);
|
|
464
|
-
}
|
|
465
|
-
if (closeOnBackPushed) {
|
|
466
|
-
closeOnBackPushed = false;
|
|
467
|
-
popOurMarker("__bsSheet", deps.sheetId);
|
|
489
|
+
pushed = true;
|
|
490
|
+
} catch {
|
|
491
|
+
pushed = false;
|
|
468
492
|
}
|
|
469
493
|
};
|
|
470
494
|
const unsubscribeOpen = deps.on("open", onOpen);
|
|
471
|
-
const unsubscribeClose = deps.on("close",
|
|
495
|
+
const unsubscribeClose = deps.on("close", teardownEntry);
|
|
472
496
|
if (deps.getSize() > 0) onOpen();
|
|
473
497
|
return () => {
|
|
474
498
|
unsubscribeOpen();
|
|
475
499
|
unsubscribeClose();
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
500
|
+
teardownEntry();
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
function installRouteChange(deps) {
|
|
504
|
+
if (typeof window === "undefined" || typeof history === "undefined") {
|
|
505
|
+
return () => {
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
const onChange = () => {
|
|
509
|
+
if (deps.isDestroyed() || deps.getSize() <= 0) return;
|
|
510
|
+
void deps.close();
|
|
511
|
+
};
|
|
512
|
+
const wrap = (key) => {
|
|
513
|
+
const original = history[key];
|
|
514
|
+
const patched = function(...args) {
|
|
515
|
+
original.apply(this, args);
|
|
516
|
+
onChange();
|
|
517
|
+
};
|
|
518
|
+
history[key] = patched;
|
|
519
|
+
return () => {
|
|
520
|
+
if (history[key] === patched) {
|
|
521
|
+
history[key] = original;
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
};
|
|
525
|
+
window.addEventListener("popstate", onChange);
|
|
526
|
+
const restorePush = wrap("pushState");
|
|
527
|
+
const restoreReplace = wrap("replaceState");
|
|
528
|
+
return () => {
|
|
529
|
+
window.removeEventListener("popstate", onChange);
|
|
530
|
+
restorePush();
|
|
531
|
+
restoreReplace();
|
|
486
532
|
};
|
|
487
533
|
}
|
|
488
534
|
|
|
@@ -790,6 +836,7 @@ function applyOverlayPosition(ws, mode, position, inset) {
|
|
|
790
836
|
|
|
791
837
|
// src/core/controllers/scrim-controller.ts
|
|
792
838
|
var VALID_CSS_LENGTH = /^-?\d+(?:\.\d+)?(?:px|em|rem|%)$/;
|
|
839
|
+
var DEFAULT_SCRIM_DIM = "rgba(0, 0, 0, 0.4)";
|
|
793
840
|
var ScrimController = class {
|
|
794
841
|
constructor(deps, opts) {
|
|
795
842
|
__publicField(this, "screenComponent");
|
|
@@ -828,9 +875,11 @@ var ScrimController = class {
|
|
|
828
875
|
this.backdropRange = opts.backdropRange ?? preset?.range ?? [0, 1];
|
|
829
876
|
this.screenRange = opts.screenRange ?? preset?.range ?? [0, 1];
|
|
830
877
|
this.scrimTapToCloseEnabled = opts.scrimTapToClose ?? false;
|
|
878
|
+
const explicitColor = opts.scrimColor ?? preset?.color;
|
|
879
|
+
const effectiveColor = explicitColor ?? (this.scrimMode !== "off" && !this.backdrop ? DEFAULT_SCRIM_DIM : void 0);
|
|
831
880
|
if (this.screenComponent) {
|
|
832
881
|
this.applyScrimStyles({
|
|
833
|
-
color:
|
|
882
|
+
color: effectiveColor,
|
|
834
883
|
blur: opts.scrimBlur ?? preset?.blur,
|
|
835
884
|
interactive: opts.scrimInteractive ?? preset?.interactive ?? false
|
|
836
885
|
});
|
|
@@ -1604,7 +1653,7 @@ var LifecycleController = class {
|
|
|
1604
1653
|
this.releaseScrollLock = null;
|
|
1605
1654
|
this.inertSiblings.remove();
|
|
1606
1655
|
if (this.returnFocus) {
|
|
1607
|
-
const target = typeof this.returnFocus === "function" ? this.returnFocus() : this.returnFocus;
|
|
1656
|
+
const target = typeof this.returnFocus === "function" ? this.returnFocus() : typeof this.returnFocus === "string" ? typeof document !== "undefined" ? document.querySelector(this.returnFocus) : null : this.returnFocus;
|
|
1608
1657
|
target?.focus?.();
|
|
1609
1658
|
}
|
|
1610
1659
|
}
|
|
@@ -1772,6 +1821,7 @@ var GestureController = class {
|
|
|
1772
1821
|
__publicField(this, "dragStartSize", 0);
|
|
1773
1822
|
__publicField(this, "currentPointerKind", "touch");
|
|
1774
1823
|
__publicField(this, "keyboardDismissed", false);
|
|
1824
|
+
__publicField(this, "dragSuppressed", false);
|
|
1775
1825
|
__publicField(this, "dragPayload", { size: 0, delta: 0 });
|
|
1776
1826
|
this.deps = deps;
|
|
1777
1827
|
}
|
|
@@ -1782,6 +1832,11 @@ var GestureController = class {
|
|
|
1782
1832
|
if (this.detach) return this.detach;
|
|
1783
1833
|
this.detach = installGestures(this.deps.handle, this.deps.mode, {
|
|
1784
1834
|
onStart: (_coord, kind) => {
|
|
1835
|
+
if (this.deps.getDisableDrag?.()) {
|
|
1836
|
+
this.dragSuppressed = true;
|
|
1837
|
+
return;
|
|
1838
|
+
}
|
|
1839
|
+
this.dragSuppressed = false;
|
|
1785
1840
|
this.deps.cancelAnimation();
|
|
1786
1841
|
this.isDragging_ = true;
|
|
1787
1842
|
this.dragStartSize = this.deps.getDragContext().size;
|
|
@@ -1792,6 +1847,7 @@ var GestureController = class {
|
|
|
1792
1847
|
this.deps.emit("dragstart", { size: this.dragStartSize });
|
|
1793
1848
|
},
|
|
1794
1849
|
onMove: (delta) => {
|
|
1850
|
+
if (this.dragSuppressed) return;
|
|
1795
1851
|
const ctx = this.deps.getDragContext();
|
|
1796
1852
|
const { min, max } = ctx.range;
|
|
1797
1853
|
const maxAxis = ctx.maxAxisSize;
|
|
@@ -1815,6 +1871,10 @@ var GestureController = class {
|
|
|
1815
1871
|
}
|
|
1816
1872
|
},
|
|
1817
1873
|
onEnd: (delta, velocity, kind) => {
|
|
1874
|
+
if (this.dragSuppressed) {
|
|
1875
|
+
this.dragSuppressed = false;
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1818
1878
|
this.isDragging_ = false;
|
|
1819
1879
|
this.keyboardDismissed = false;
|
|
1820
1880
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -1825,6 +1885,10 @@ var GestureController = class {
|
|
|
1825
1885
|
this.deps.settleAfterDrag(delta, velocity, kind);
|
|
1826
1886
|
},
|
|
1827
1887
|
onCancel: () => {
|
|
1888
|
+
if (this.dragSuppressed) {
|
|
1889
|
+
this.dragSuppressed = false;
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1828
1892
|
this.isDragging_ = false;
|
|
1829
1893
|
this.keyboardDismissed = false;
|
|
1830
1894
|
this.deps.getRoot()?.removeAttribute("data-dragging");
|
|
@@ -2204,6 +2268,12 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2204
2268
|
dragThreshold: opts.dragThreshold ?? DEFAULT_DRAG_THRESHOLD,
|
|
2205
2269
|
rubberBandEnabled: opts.rubberBand ?? true,
|
|
2206
2270
|
closeOnBack: opts.closeOnBack ?? false,
|
|
2271
|
+
persistent: opts.persistent ?? false,
|
|
2272
|
+
disableClose: opts.disableClose ?? false,
|
|
2273
|
+
disableDrag: opts.disableDrag ?? false,
|
|
2274
|
+
closeOnRouteChange: opts.closeOnRouteChange ?? false,
|
|
2275
|
+
radius: opts.radius,
|
|
2276
|
+
maxHeight: opts.maxHeight,
|
|
2207
2277
|
initialAllowed,
|
|
2208
2278
|
initialId,
|
|
2209
2279
|
scrim: {
|
|
@@ -2230,7 +2300,8 @@ function resolveEngineOptions(opts, extras) {
|
|
|
2230
2300
|
closeOnEscape: opts.closeOnEscape,
|
|
2231
2301
|
lockBodyScroll: opts.lockBodyScroll,
|
|
2232
2302
|
inertSiblings: opts.inertSiblings,
|
|
2233
|
-
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings
|
|
2303
|
+
shouldApplyInertSiblings: extras?.shouldApplyInertSiblings,
|
|
2304
|
+
returnFocus: opts.returnFocusTo
|
|
2234
2305
|
}
|
|
2235
2306
|
};
|
|
2236
2307
|
}
|
|
@@ -2275,6 +2346,11 @@ var BottomSheetEngine = class {
|
|
|
2275
2346
|
__publicField(this, "lifecycle");
|
|
2276
2347
|
__publicField(this, "closeOnBack");
|
|
2277
2348
|
__publicField(this, "routedTo");
|
|
2349
|
+
__publicField(this, "persistent");
|
|
2350
|
+
__publicField(this, "disableCloseFlag");
|
|
2351
|
+
__publicField(this, "disableDragFlag");
|
|
2352
|
+
__publicField(this, "closeOnRouteChange");
|
|
2353
|
+
__publicField(this, "maxHeightCap");
|
|
2278
2354
|
__publicField(this, "snapPointsRaw");
|
|
2279
2355
|
__publicField(this, "snaps");
|
|
2280
2356
|
__publicField(this, "activeId");
|
|
@@ -2287,6 +2363,7 @@ var BottomSheetEngine = class {
|
|
|
2287
2363
|
__publicField(this, "sizeWriteSentinel", new WriteSentinel());
|
|
2288
2364
|
__publicField(this, "progressWriteSentinel", new WriteSentinel());
|
|
2289
2365
|
__publicField(this, "isTopSheet", true);
|
|
2366
|
+
__publicField(this, "opening", false);
|
|
2290
2367
|
__publicField(this, "progressPayload", {
|
|
2291
2368
|
value: 0,
|
|
2292
2369
|
size: 0
|
|
@@ -2343,7 +2420,8 @@ var BottomSheetEngine = class {
|
|
|
2343
2420
|
void this.snapTo(id);
|
|
2344
2421
|
},
|
|
2345
2422
|
close: () => {
|
|
2346
|
-
|
|
2423
|
+
if (!this.canDismiss()) return;
|
|
2424
|
+
void this.close("backdrop");
|
|
2347
2425
|
}
|
|
2348
2426
|
},
|
|
2349
2427
|
resolved.scrim
|
|
@@ -2367,6 +2445,10 @@ var BottomSheetEngine = class {
|
|
|
2367
2445
|
);
|
|
2368
2446
|
this.closeOnBack = resolved.closeOnBack;
|
|
2369
2447
|
this.routedTo = opts.routedTo;
|
|
2448
|
+
this.persistent = resolved.persistent;
|
|
2449
|
+
this.disableCloseFlag = resolved.disableClose;
|
|
2450
|
+
this.disableDragFlag = resolved.disableDrag;
|
|
2451
|
+
this.closeOnRouteChange = resolved.closeOnRouteChange;
|
|
2370
2452
|
this.stackEffectEnabled = opts.stackEffect ?? false;
|
|
2371
2453
|
this.snapPointsRaw = opts.snapPoints;
|
|
2372
2454
|
this.persistKey = opts.persistKey;
|
|
@@ -2380,7 +2462,7 @@ var BottomSheetEngine = class {
|
|
|
2380
2462
|
this.snapPointsRaw,
|
|
2381
2463
|
resolved.initialAllowed,
|
|
2382
2464
|
this.mode,
|
|
2383
|
-
() =>
|
|
2465
|
+
() => this.measureFitSize(),
|
|
2384
2466
|
(maxAxisSize) => {
|
|
2385
2467
|
this.element.style[layoutAxis(this.mode)] = `${maxAxisSize}px`;
|
|
2386
2468
|
}
|
|
@@ -2414,6 +2496,19 @@ var BottomSheetEngine = class {
|
|
|
2414
2496
|
io.observe(this.element);
|
|
2415
2497
|
this.teardowns.add(() => io.disconnect());
|
|
2416
2498
|
}
|
|
2499
|
+
this.installFitObserver();
|
|
2500
|
+
if (resolved.radius !== void 0) this.setRadius(resolved.radius);
|
|
2501
|
+
if (resolved.maxHeight !== void 0) this.setMaxHeight(resolved.maxHeight);
|
|
2502
|
+
this.applyAutoAriaLabelledBy();
|
|
2503
|
+
if (this.closeOnRouteChange) {
|
|
2504
|
+
this.teardowns.add(
|
|
2505
|
+
installRouteChange({
|
|
2506
|
+
isDestroyed: () => this.destroyed,
|
|
2507
|
+
getSize: () => this.size,
|
|
2508
|
+
close: () => this.close()
|
|
2509
|
+
})
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2417
2512
|
if (this.persistKey) {
|
|
2418
2513
|
this.teardowns.add(installPersist(this, this.persistKey));
|
|
2419
2514
|
}
|
|
@@ -2438,7 +2533,7 @@ var BottomSheetEngine = class {
|
|
|
2438
2533
|
isTopSheet: () => this.isTopSheet,
|
|
2439
2534
|
getSize: () => this.size,
|
|
2440
2535
|
isDestroyed: () => this.destroyed,
|
|
2441
|
-
close: () => this.close(),
|
|
2536
|
+
close: () => this.close("back"),
|
|
2442
2537
|
on: (event, fn) => this.on(event, fn),
|
|
2443
2538
|
sheetId: this.id
|
|
2444
2539
|
})
|
|
@@ -2532,6 +2627,10 @@ var BottomSheetEngine = class {
|
|
|
2532
2627
|
const previousSize = this.size;
|
|
2533
2628
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2534
2629
|
this.activeId = id;
|
|
2630
|
+
if (wasClosed && target.size > 0) {
|
|
2631
|
+
this.opening = true;
|
|
2632
|
+
sheetStack.promote(this.id);
|
|
2633
|
+
}
|
|
2535
2634
|
if (this.animation.viewTransitionsAvailable) {
|
|
2536
2635
|
this.currentViewTransition?.skipTransition?.();
|
|
2537
2636
|
const vt = document.startViewTransition(() => {
|
|
@@ -2546,19 +2645,26 @@ var BottomSheetEngine = class {
|
|
|
2546
2645
|
} else {
|
|
2547
2646
|
await this.animation.animateTo(target.size, velocityPxPerMs);
|
|
2548
2647
|
}
|
|
2648
|
+
this.opening = false;
|
|
2549
2649
|
externalSignal?.removeEventListener("abort", onExternalAbort);
|
|
2550
2650
|
if (signal.aborted) return;
|
|
2551
2651
|
this.scrollCache.restore(id, previousSize, target.size);
|
|
2552
2652
|
this.updateAriaSlider();
|
|
2553
|
-
this.emit("snap", {
|
|
2653
|
+
this.emit("snap", {
|
|
2654
|
+
id,
|
|
2655
|
+
size: target.size,
|
|
2656
|
+
progress: this.computeProgress(target.size)
|
|
2657
|
+
});
|
|
2554
2658
|
if (wasClosed && target.size > 0) {
|
|
2555
2659
|
this.emit("open", { id });
|
|
2556
2660
|
this.handleOpen();
|
|
2557
2661
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
2662
|
+
this.emit("opened", { id });
|
|
2558
2663
|
}
|
|
2559
2664
|
if (target.size === 0) {
|
|
2560
2665
|
this.emit("close", void 0);
|
|
2561
2666
|
this.handleClose();
|
|
2667
|
+
this.emit("closed", void 0);
|
|
2562
2668
|
}
|
|
2563
2669
|
}
|
|
2564
2670
|
async dragTo(targetSize, velocityOrOpts = 0) {
|
|
@@ -2583,11 +2689,74 @@ var BottomSheetEngine = class {
|
|
|
2583
2689
|
const target = id ?? this.snaps.getAllowedIds().find((a) => a !== "closed") ?? this.activeId;
|
|
2584
2690
|
return this.snapTo(target);
|
|
2585
2691
|
}
|
|
2586
|
-
close() {
|
|
2692
|
+
close(reason = "programmatic") {
|
|
2587
2693
|
if (this.destroyed) return Promise.resolve();
|
|
2694
|
+
if (this.disableCloseFlag) return Promise.resolve();
|
|
2695
|
+
if (this.size > 0 && this.emitBeforeClose(reason)) return Promise.resolve();
|
|
2588
2696
|
const closedId = this.snapPointsRaw.find((p) => p.id === "closed")?.id ?? this.snaps.getAllowedIds()[0];
|
|
2589
2697
|
return this.snapTo(closedId ?? this.activeId);
|
|
2590
2698
|
}
|
|
2699
|
+
canDismiss() {
|
|
2700
|
+
return !this.persistent && !this.disableCloseFlag && !this.destroyed;
|
|
2701
|
+
}
|
|
2702
|
+
isTop() {
|
|
2703
|
+
return this.isTopSheet;
|
|
2704
|
+
}
|
|
2705
|
+
depth() {
|
|
2706
|
+
return sheetStack.depthOf(this.id);
|
|
2707
|
+
}
|
|
2708
|
+
expand() {
|
|
2709
|
+
if (this.destroyed) return Promise.resolve();
|
|
2710
|
+
const ids = this.allowedIdsBySize();
|
|
2711
|
+
const target = ids[ids.length - 1];
|
|
2712
|
+
if (!target) return Promise.resolve();
|
|
2713
|
+
return this.snapTo(target);
|
|
2714
|
+
}
|
|
2715
|
+
collapse() {
|
|
2716
|
+
if (this.destroyed) return Promise.resolve();
|
|
2717
|
+
const ids = this.allowedIdsBySize();
|
|
2718
|
+
const nonZero = ids.find((id) => (this.snaps.findById(id)?.size ?? 0) > 0);
|
|
2719
|
+
const target = nonZero ?? ids[0];
|
|
2720
|
+
if (!target) return Promise.resolve();
|
|
2721
|
+
return this.snapTo(target);
|
|
2722
|
+
}
|
|
2723
|
+
setRadius(r) {
|
|
2724
|
+
if (this.destroyed) return;
|
|
2725
|
+
this.element.style.setProperty(
|
|
2726
|
+
"--bs-radius",
|
|
2727
|
+
typeof r === "number" ? `${r}px` : r
|
|
2728
|
+
);
|
|
2729
|
+
}
|
|
2730
|
+
setMaxHeight(h) {
|
|
2731
|
+
if (this.destroyed) return;
|
|
2732
|
+
const value = typeof h === "number" ? `${h}px` : h;
|
|
2733
|
+
const axis = layoutAxis(this.mode);
|
|
2734
|
+
this.element.style.setProperty(
|
|
2735
|
+
axis === "height" ? "maxHeight" : "maxWidth",
|
|
2736
|
+
value
|
|
2737
|
+
);
|
|
2738
|
+
if (typeof h === "number") {
|
|
2739
|
+
this.maxHeightCap = h;
|
|
2740
|
+
this.clampToMaxHeight();
|
|
2741
|
+
} else if (typeof window !== "undefined") {
|
|
2742
|
+
const probe2 = document.createElement("div");
|
|
2743
|
+
probe2.style.cssText = `position:absolute;visibility:hidden;pointer-events:none;${axis === "height" ? "height" : "width"}:${value};`;
|
|
2744
|
+
document.body.appendChild(probe2);
|
|
2745
|
+
const measured = axis === "height" ? probe2.offsetHeight : probe2.offsetWidth;
|
|
2746
|
+
probe2.remove();
|
|
2747
|
+
this.maxHeightCap = measured > 0 ? measured : void 0;
|
|
2748
|
+
this.clampToMaxHeight();
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
clampToMaxHeight() {
|
|
2752
|
+
if (this.maxHeightCap === void 0) return;
|
|
2753
|
+
if (this.snaps.getMaxAxisSize() > this.maxHeightCap) {
|
|
2754
|
+
this.snaps.setMaxAxisSize(this.maxHeightCap);
|
|
2755
|
+
}
|
|
2756
|
+
if (this.size > this.maxHeightCap && !this.gesture?.isDragging) {
|
|
2757
|
+
this.applySize(this.maxHeightCap);
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2591
2760
|
setAllowed(ids, snap) {
|
|
2592
2761
|
if (this.destroyed) return;
|
|
2593
2762
|
this.snaps.setAllowedIds(ids);
|
|
@@ -2721,8 +2890,53 @@ var BottomSheetEngine = class {
|
|
|
2721
2890
|
}
|
|
2722
2891
|
this.updateAriaSlider();
|
|
2723
2892
|
}
|
|
2893
|
+
recompute() {
|
|
2894
|
+
if (this.destroyed) return;
|
|
2895
|
+
this.snaps.recompute();
|
|
2896
|
+
this.scrim.invalidateOpacityCache();
|
|
2897
|
+
if (this.gesture?.isDragging) return;
|
|
2898
|
+
const current = this.snaps.findById(this.activeId);
|
|
2899
|
+
if (current) {
|
|
2900
|
+
this.size = current.size;
|
|
2901
|
+
this.applySize(this.size);
|
|
2902
|
+
this.updateAriaSlider();
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
measureFitSize() {
|
|
2906
|
+
const vertical = layoutAxis(this.mode) === "height";
|
|
2907
|
+
const handleSize = vertical ? this.handle.offsetHeight : this.handle.offsetWidth;
|
|
2908
|
+
const content = this.scrollContainer;
|
|
2909
|
+
const natural = content ? handleSize + (vertical ? content.scrollHeight : content.scrollWidth) : handleSize;
|
|
2910
|
+
if (typeof window === "undefined") return natural;
|
|
2911
|
+
const viewport = vertical ? window.innerHeight : window.innerWidth;
|
|
2912
|
+
return viewport > 0 ? Math.min(natural, viewport) : natural;
|
|
2913
|
+
}
|
|
2914
|
+
installFitObserver() {
|
|
2915
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
2916
|
+
if (!this.snapPointsRaw.some((p) => p.size === "fit" || p.size === "content"))
|
|
2917
|
+
return;
|
|
2918
|
+
const targets = [this.handle];
|
|
2919
|
+
if (this.scrollContainer && this.scrollContainer !== this.handle) {
|
|
2920
|
+
targets.push(this.scrollContainer);
|
|
2921
|
+
}
|
|
2922
|
+
let raf = 0;
|
|
2923
|
+
const ro = new ResizeObserver(() => {
|
|
2924
|
+
if (raf) return;
|
|
2925
|
+
raf = requestAnimationFrame(() => {
|
|
2926
|
+
raf = 0;
|
|
2927
|
+
if (this.destroyed || this.gesture?.isDragging) return;
|
|
2928
|
+
this.recompute();
|
|
2929
|
+
});
|
|
2930
|
+
});
|
|
2931
|
+
for (const t of targets) ro.observe(t);
|
|
2932
|
+
this.teardowns.add(() => {
|
|
2933
|
+
ro.disconnect();
|
|
2934
|
+
if (raf) cancelAnimationFrame(raf);
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2724
2937
|
destroy() {
|
|
2725
2938
|
this.destroyed = true;
|
|
2939
|
+
this.opening = false;
|
|
2726
2940
|
this.currentAbort.abort();
|
|
2727
2941
|
this.currentViewTransition?.skipTransition?.();
|
|
2728
2942
|
this.currentViewTransition = null;
|
|
@@ -2772,6 +2986,36 @@ var BottomSheetEngine = class {
|
|
|
2772
2986
|
frozen = true;
|
|
2773
2987
|
return cancelled;
|
|
2774
2988
|
}
|
|
2989
|
+
emitBeforeClose(reason) {
|
|
2990
|
+
let cancelled = false;
|
|
2991
|
+
let frozen = false;
|
|
2992
|
+
this.emit("before-close", {
|
|
2993
|
+
reason,
|
|
2994
|
+
cancel: () => {
|
|
2995
|
+
if (frozen) {
|
|
2996
|
+
console.warn(
|
|
2997
|
+
"[BottomSheet] before-close.cancel() called asynchronously \u2014 ignored. cancel() must be invoked synchronously inside the listener."
|
|
2998
|
+
);
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
cancelled = true;
|
|
3002
|
+
}
|
|
3003
|
+
});
|
|
3004
|
+
frozen = true;
|
|
3005
|
+
return cancelled;
|
|
3006
|
+
}
|
|
3007
|
+
applyAutoAriaLabelledBy() {
|
|
3008
|
+
if (typeof document === "undefined") return;
|
|
3009
|
+
if (!this.lifecycle.focusTrapEnabled) return;
|
|
3010
|
+
if (this.element.getAttribute("aria-labelledby")) return;
|
|
3011
|
+
const scope = this.handle ?? this.element;
|
|
3012
|
+
const titled = scope.querySelector("[data-bs-title]") ?? scope.querySelector("h1,h2,h3,h4,h5,h6");
|
|
3013
|
+
if (!titled) return;
|
|
3014
|
+
if (!titled.id) {
|
|
3015
|
+
titled.id = nextInstanceId("bs-title");
|
|
3016
|
+
}
|
|
3017
|
+
this.element.setAttribute("aria-labelledby", titled.id);
|
|
3018
|
+
}
|
|
2775
3019
|
recomputeSnaps() {
|
|
2776
3020
|
const seen = /* @__PURE__ */ new Set();
|
|
2777
3021
|
for (const p of this.snapPointsRaw) {
|
|
@@ -2807,11 +3051,8 @@ var BottomSheetEngine = class {
|
|
|
2807
3051
|
},
|
|
2808
3052
|
setIsTop: (isTop) => {
|
|
2809
3053
|
this.isTopSheet = isTop;
|
|
2810
|
-
if (this.backdrop) {
|
|
2811
|
-
this.backdrop.style.display = isTop ? "" : "none";
|
|
2812
|
-
}
|
|
2813
3054
|
},
|
|
2814
|
-
isOpen: () => this.size > 0,
|
|
3055
|
+
isOpen: () => this.size > 0 || this.opening,
|
|
2815
3056
|
setDepth: (depth) => this.applyStackDepth(depth)
|
|
2816
3057
|
}));
|
|
2817
3058
|
}
|
|
@@ -2843,6 +3084,7 @@ var BottomSheetEngine = class {
|
|
|
2843
3084
|
buf.rubberBandEnabled = this.rubberBandEnabled;
|
|
2844
3085
|
return buf;
|
|
2845
3086
|
},
|
|
3087
|
+
getDisableDrag: () => this.disableDragFlag,
|
|
2846
3088
|
cancelAnimation: () => this.animation.cancel(),
|
|
2847
3089
|
applySize: (size) => this.applySize(size),
|
|
2848
3090
|
animateTo: (size, velocity) => this.animation.animateTo(size, velocity),
|
|
@@ -2922,8 +3164,9 @@ var BottomSheetEngine = class {
|
|
|
2922
3164
|
if (this.lifecycle.closeOnEscape) {
|
|
2923
3165
|
const onKey = (e) => {
|
|
2924
3166
|
if (this.destroyed || e.defaultPrevented) return;
|
|
3167
|
+
if (!this.canDismiss()) return;
|
|
2925
3168
|
if (e.key === "Escape" && this.isTopSheet && this.size > 0) {
|
|
2926
|
-
void this.close();
|
|
3169
|
+
void this.close("escape");
|
|
2927
3170
|
}
|
|
2928
3171
|
};
|
|
2929
3172
|
document.addEventListener("keydown", onKey);
|
|
@@ -2986,20 +3229,31 @@ var BottomSheetEngine = class {
|
|
|
2986
3229
|
const previousSnapSize = this.snaps.findById(previousId)?.size;
|
|
2987
3230
|
this.scrollCache.cache(previousId, previousSize, target.size);
|
|
2988
3231
|
this.activeId = target.id;
|
|
3232
|
+
if (previousSnapSize === 0 && target.size > 0) {
|
|
3233
|
+
this.opening = true;
|
|
3234
|
+
sheetStack.promote(this.id);
|
|
3235
|
+
}
|
|
2989
3236
|
void this.animation.animateTo(target.size, velocity).then(() => {
|
|
3237
|
+
this.opening = false;
|
|
2990
3238
|
if (signal.aborted) return;
|
|
2991
3239
|
this.scrollCache.restore(target.id, previousSize, target.size);
|
|
2992
3240
|
this.updateAriaSlider();
|
|
2993
|
-
this.emit("snap", {
|
|
3241
|
+
this.emit("snap", {
|
|
3242
|
+
id: target.id,
|
|
3243
|
+
size: target.size,
|
|
3244
|
+
progress: this.computeProgress(target.size)
|
|
3245
|
+
});
|
|
2994
3246
|
this.haptic();
|
|
2995
3247
|
if (previousSnapSize === 0 && target.size > 0) {
|
|
2996
3248
|
this.emit("open", { id: target.id });
|
|
2997
3249
|
this.handleOpen();
|
|
2998
3250
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3251
|
+
this.emit("opened", { id: target.id });
|
|
2999
3252
|
}
|
|
3000
3253
|
if (target.size === 0) {
|
|
3001
3254
|
this.emit("close", void 0);
|
|
3002
3255
|
this.handleClose();
|
|
3256
|
+
this.emit("closed", void 0);
|
|
3003
3257
|
}
|
|
3004
3258
|
});
|
|
3005
3259
|
}
|
|
@@ -3024,6 +3278,9 @@ var BottomSheetEngine = class {
|
|
|
3024
3278
|
if (this.anchorHost && this.anchorHost !== this.scrimParent) {
|
|
3025
3279
|
this.anchorHost.style.setProperty("--bs-size", `${size}px`);
|
|
3026
3280
|
}
|
|
3281
|
+
if (this.rootEl && this.rootEl !== this.scrimParent && this.rootEl !== this.anchorHost) {
|
|
3282
|
+
this.rootEl.style.setProperty("--bs-size", `${size}px`);
|
|
3283
|
+
}
|
|
3027
3284
|
}
|
|
3028
3285
|
const progress = this.computeProgress(size);
|
|
3029
3286
|
const progressChanged = this.progressWriteSentinel.shouldWrite(
|
|
@@ -3035,6 +3292,9 @@ var BottomSheetEngine = class {
|
|
|
3035
3292
|
if (this.anchorHost) {
|
|
3036
3293
|
this.anchorHost.style.setProperty("--bs-progress", String(progress));
|
|
3037
3294
|
}
|
|
3295
|
+
if (this.rootEl && this.rootEl !== this.anchorHost) {
|
|
3296
|
+
this.rootEl.style.setProperty("--bs-progress", String(progress));
|
|
3297
|
+
}
|
|
3038
3298
|
}
|
|
3039
3299
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
3040
3300
|
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
@@ -3068,17 +3328,24 @@ var BottomSheetEngine = class {
|
|
|
3068
3328
|
const target = this.snaps.findById(this.activeId);
|
|
3069
3329
|
if (!target) return;
|
|
3070
3330
|
this.updateAriaSlider();
|
|
3071
|
-
this.emit("snap", {
|
|
3331
|
+
this.emit("snap", {
|
|
3332
|
+
id: target.id,
|
|
3333
|
+
size: target.size,
|
|
3334
|
+
progress: this.computeProgress(target.size)
|
|
3335
|
+
});
|
|
3072
3336
|
if (target.size > 0 && !this.lifecycle.isInstalled) {
|
|
3073
3337
|
this.emit("open", { id: target.id });
|
|
3074
3338
|
this.handleOpen();
|
|
3075
3339
|
notifyLinkedSheets(this.linkedSheets, this);
|
|
3340
|
+
this.emit("opened", { id: target.id });
|
|
3076
3341
|
} else if (target.size === 0 && this.lifecycle.isInstalled) {
|
|
3077
3342
|
this.emit("close", void 0);
|
|
3078
3343
|
this.handleClose();
|
|
3344
|
+
this.emit("closed", void 0);
|
|
3079
3345
|
}
|
|
3080
3346
|
}
|
|
3081
3347
|
handleClose() {
|
|
3348
|
+
this.opening = false;
|
|
3082
3349
|
this.lifecycle.release();
|
|
3083
3350
|
sheetStack.update();
|
|
3084
3351
|
}
|