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