@surdeddd/bottom-sheet 0.23.1 → 0.23.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/{BottomSheetCore-9i-Uh6T3.d.ts → BottomSheetCore-COvILxmR.d.ts} +2 -0
- package/dist/{BottomSheetCore-CQStdVy2.d.cts → BottomSheetCore-CaJwHnxY.d.cts} +2 -0
- package/dist/{BottomSheetEngine-CsQWHLNb.d.cts → BottomSheetEngine-C_1aPJsU.d.cts} +1 -1
- package/dist/{BottomSheetEngine-Dn6h-7gF.d.ts → BottomSheetEngine-CsgCcCSO.d.ts} +1 -1
- package/dist/core.cjs +43 -13
- package/dist/core.d.cts +2 -2
- package/dist/core.d.ts +2 -2
- package/dist/core.js +43 -13
- package/dist/debug.d.cts +1 -1
- package/dist/debug.d.ts +1 -1
- package/dist/{default-features-C3cilcW9.d.ts → default-features-BJx7J0NH.d.ts} +1 -1
- package/dist/{default-features-DkG9aho0.d.cts → default-features-CTJb8Wdk.d.cts} +1 -1
- package/dist/element.cjs +103 -20
- package/dist/element.d.cts +2 -2
- package/dist/element.d.ts +2 -2
- package/dist/element.iife.global.js +2 -2
- package/dist/element.js +103 -20
- package/dist/features.cjs +58 -3
- package/dist/features.d.cts +3 -3
- package/dist/features.d.ts +3 -3
- package/dist/features.js +58 -3
- package/dist/{index-CVGC5B5D.d.cts → index-BBrJJjy5.d.cts} +1 -1
- package/dist/{index-CnsJQZp2.d.ts → index-CXN7t3rr.d.ts} +1 -1
- package/dist/index.cjs +98 -16
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +98 -16
- 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/preact.d.cts +2 -2
- package/dist/preact.d.ts +2 -2
- package/dist/qwik-lib/index.qwik.cjs +89 -16
- package/dist/qwik-lib/index.qwik.mjs +89 -16
- package/dist/qwik.cjs +98 -16
- package/dist/qwik.d.cts +2 -2
- package/dist/qwik.d.ts +2 -2
- package/dist/qwik.js +98 -16
- package/dist/react.cjs +98 -16
- package/dist/react.d.cts +3 -3
- package/dist/react.d.ts +3 -3
- package/dist/react.js +98 -16
- package/dist/solid.cjs +98 -16
- package/dist/solid.d.cts +2 -0
- package/dist/solid.d.ts +2 -0
- package/dist/solid.js +98 -16
- package/dist/solid.source.jsx +98 -16
- package/dist/styles.css +8 -6
- package/dist/svelte-core.cjs +98 -16
- package/dist/svelte-core.js +98 -16
- package/dist/svelte.cjs +98 -16
- package/dist/svelte.js +98 -16
- package/dist/vue.cjs +98 -16
- package/dist/vue.js +98 -16
- package/dist/webgl.cjs +192 -42
- package/dist/webgl.d.cts +1 -1
- package/dist/webgl.d.ts +1 -1
- package/dist/webgl.js +192 -42
- package/package.json +12 -12
package/dist/preact.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { BottomSheet, BottomSheetFromConfig, BottomSheetFromConfigProps, BottomSheetHandle, BottomSheetProps, HeaderProp, Overlay, OverlayHandle, OverlayProps, SheetConfig, UseBottomSheetRefs, UseBottomSheetReturn, UseOverlayReturn, useBottomSheet, useOverlay } from './react.cjs';
|
|
2
|
-
export { d as EngineState, f as SheetMode, h as SnapPoint, e as SnapPointDef } from './BottomSheetCore-
|
|
2
|
+
export { d as EngineState, f as SheetMode, h as SnapPoint, e as SnapPointDef } from './BottomSheetCore-CaJwHnxY.cjs';
|
|
3
3
|
export { OverlayEdge, OverlayOptions, OverlayState } from './overlay.cjs';
|
|
4
4
|
import 'react';
|
|
5
|
-
import './BottomSheetEngine-
|
|
5
|
+
import './BottomSheetEngine-C_1aPJsU.cjs';
|
|
6
6
|
import './teleport-7uYNiEAT.cjs';
|
|
7
7
|
import './transform-jVfAikE9.cjs';
|
package/dist/preact.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { BottomSheet, BottomSheetFromConfig, BottomSheetFromConfigProps, BottomSheetHandle, BottomSheetProps, HeaderProp, Overlay, OverlayHandle, OverlayProps, SheetConfig, UseBottomSheetRefs, UseBottomSheetReturn, UseOverlayReturn, useBottomSheet, useOverlay } from './react.js';
|
|
2
|
-
export { d as EngineState, f as SheetMode, h as SnapPoint, e as SnapPointDef } from './BottomSheetCore-
|
|
2
|
+
export { d as EngineState, f as SheetMode, h as SnapPoint, e as SnapPointDef } from './BottomSheetCore-COvILxmR.js';
|
|
3
3
|
export { OverlayEdge, OverlayOptions, OverlayState } from './overlay.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import './BottomSheetEngine-
|
|
5
|
+
import './BottomSheetEngine-CsgCcCSO.js';
|
|
6
6
|
import './teleport-7uYNiEAT.js';
|
|
7
7
|
import './transform-jVfAikE9.js';
|
|
@@ -84,6 +84,7 @@ function buildTransformTemplate(axis) {
|
|
|
84
84
|
return (offset) => `translate3d(${offset}px, 0, 0)`;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
const offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
|
|
87
88
|
const layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
|
|
88
89
|
const counters = {};
|
|
89
90
|
function nextInstanceId(prefix) {
|
|
@@ -1181,7 +1182,7 @@ const tween = ({ from, to, duration, easing = easeOutCubic, onUpdate }) => {
|
|
|
1181
1182
|
}
|
|
1182
1183
|
const step = (now) => {
|
|
1183
1184
|
if (cancelled) return;
|
|
1184
|
-
const elapsed = now - start;
|
|
1185
|
+
const elapsed = Math.max(0, now - start);
|
|
1185
1186
|
const t = Math.min(elapsed / duration, 1);
|
|
1186
1187
|
const value = from + (to - from) * easing(t);
|
|
1187
1188
|
onUpdate(value);
|
|
@@ -1229,8 +1230,8 @@ const runSpring = ({ from, to, velocity = 0, config, onUpdate }) => {
|
|
|
1229
1230
|
resolveFn = resolve;
|
|
1230
1231
|
const step = (now) => {
|
|
1231
1232
|
if (cancelled) return;
|
|
1232
|
-
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1233
|
-
lastTime = now;
|
|
1233
|
+
const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
|
|
1234
|
+
lastTime = Math.max(lastTime, now);
|
|
1234
1235
|
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1235
1236
|
const subDt = dt / steps;
|
|
1236
1237
|
let stepsLeft = steps;
|
|
@@ -1310,6 +1311,7 @@ function resolveAnimationPreset(animation) {
|
|
|
1310
1311
|
};
|
|
1311
1312
|
}
|
|
1312
1313
|
}
|
|
1314
|
+
const SETTLE_ANIMATION_ID = "bs-settle";
|
|
1313
1315
|
const SIM_HZ = 240;
|
|
1314
1316
|
const SAMPLE_STRIDE = 4;
|
|
1315
1317
|
const MAX_SIM_MS = 3e3;
|
|
@@ -1370,6 +1372,7 @@ class AnimationRunner {
|
|
|
1370
1372
|
__publicField(this, "isDragging");
|
|
1371
1373
|
__publicField(this, "applyAux");
|
|
1372
1374
|
__publicField(this, "getTransformFor");
|
|
1375
|
+
__publicField(this, "readShownSize");
|
|
1373
1376
|
__publicField(this, "settleWaapi");
|
|
1374
1377
|
__publicField(this, "currentWaapi", null);
|
|
1375
1378
|
__publicField(this, "animationKind");
|
|
@@ -1389,6 +1392,7 @@ class AnimationRunner {
|
|
|
1389
1392
|
this.isDragging = deps.isDragging;
|
|
1390
1393
|
this.applyAux = deps.applyAux;
|
|
1391
1394
|
this.getTransformFor = deps.getTransformFor;
|
|
1395
|
+
this.readShownSize = deps.readShownSize;
|
|
1392
1396
|
this.settleWaapi = opts.settleAnimation === "waapi";
|
|
1393
1397
|
const preset = resolveAnimationPreset(opts.animation);
|
|
1394
1398
|
this.animationKind = preset.kind;
|
|
@@ -1424,10 +1428,12 @@ class AnimationRunner {
|
|
|
1424
1428
|
const entry = this.currentWaapi;
|
|
1425
1429
|
this.currentWaapi = null;
|
|
1426
1430
|
entry.stop();
|
|
1431
|
+
const size = this.readShownSize?.() ?? entry.sizeNow();
|
|
1427
1432
|
try {
|
|
1428
1433
|
entry.anim.cancel();
|
|
1429
1434
|
} catch {
|
|
1430
1435
|
}
|
|
1436
|
+
this.applySizeFn(size);
|
|
1431
1437
|
}
|
|
1432
1438
|
cancel() {
|
|
1433
1439
|
this.currentTween?.cancel();
|
|
@@ -1437,6 +1443,7 @@ class AnimationRunner {
|
|
|
1437
1443
|
async animateTo(target, velocityPxPerMs) {
|
|
1438
1444
|
if (target === this.getSize()) {
|
|
1439
1445
|
if (!this.isAnimating && !this.isDragging()) {
|
|
1446
|
+
this.applySizeFn(target);
|
|
1440
1447
|
this.element.style.willChange = "";
|
|
1441
1448
|
}
|
|
1442
1449
|
return;
|
|
@@ -1463,6 +1470,7 @@ class AnimationRunner {
|
|
|
1463
1470
|
return;
|
|
1464
1471
|
}
|
|
1465
1472
|
}
|
|
1473
|
+
let current = false;
|
|
1466
1474
|
if (this.animationKind === "spring") {
|
|
1467
1475
|
const spring = runSpring({
|
|
1468
1476
|
from: this.getSize(),
|
|
@@ -1473,7 +1481,8 @@ class AnimationRunner {
|
|
|
1473
1481
|
});
|
|
1474
1482
|
this.currentSpring = spring;
|
|
1475
1483
|
await spring.promise;
|
|
1476
|
-
|
|
1484
|
+
current = this.currentSpring === spring;
|
|
1485
|
+
if (current) this.currentSpring = null;
|
|
1477
1486
|
} else {
|
|
1478
1487
|
const tw = tween({
|
|
1479
1488
|
from: this.getSize(),
|
|
@@ -1484,11 +1493,15 @@ class AnimationRunner {
|
|
|
1484
1493
|
});
|
|
1485
1494
|
this.currentTween = tw;
|
|
1486
1495
|
await tw.promise;
|
|
1487
|
-
|
|
1496
|
+
current = this.currentTween === tw;
|
|
1497
|
+
if (current) this.currentTween = null;
|
|
1488
1498
|
}
|
|
1489
1499
|
if (!this.isAnimating) {
|
|
1490
1500
|
this.getRootEl()?.removeAttribute("data-animating");
|
|
1491
|
-
if (!this.isDragging())
|
|
1501
|
+
if (!this.isDragging()) {
|
|
1502
|
+
if (current) this.applySizeFn(this.getSize());
|
|
1503
|
+
this.element.style.willChange = "";
|
|
1504
|
+
}
|
|
1492
1505
|
}
|
|
1493
1506
|
}
|
|
1494
1507
|
async runWaapiSettle(samples, target) {
|
|
@@ -1502,16 +1515,20 @@ class AnimationRunner {
|
|
|
1502
1515
|
easing: "linear",
|
|
1503
1516
|
fill: "forwards"
|
|
1504
1517
|
});
|
|
1518
|
+
anim.id = SETTLE_ANIMATION_ID;
|
|
1505
1519
|
let stopped = false;
|
|
1506
1520
|
let auxRaf = 0;
|
|
1507
1521
|
const lastIdx = samples.values.length - 1;
|
|
1508
|
-
const
|
|
1509
|
-
if (stopped) return;
|
|
1522
|
+
const sizeNow = () => {
|
|
1510
1523
|
const at = Math.min((Number(anim.currentTime) || 0) / samples.stepMs, lastIdx);
|
|
1511
1524
|
const idx = Math.floor(at);
|
|
1512
1525
|
const from = samples.values[idx];
|
|
1513
1526
|
const to = samples.values[Math.min(idx + 1, lastIdx)];
|
|
1514
|
-
|
|
1527
|
+
return from + (to - from) * (at - idx);
|
|
1528
|
+
};
|
|
1529
|
+
const auxTick = () => {
|
|
1530
|
+
if (stopped) return;
|
|
1531
|
+
applyAux(sizeNow());
|
|
1515
1532
|
auxRaf = requestAnimationFrame(auxTick);
|
|
1516
1533
|
};
|
|
1517
1534
|
auxRaf = requestAnimationFrame(auxTick);
|
|
@@ -1520,7 +1537,8 @@ class AnimationRunner {
|
|
|
1520
1537
|
stop: () => {
|
|
1521
1538
|
stopped = true;
|
|
1522
1539
|
cancelAnimationFrame(auxRaf);
|
|
1523
|
-
}
|
|
1540
|
+
},
|
|
1541
|
+
sizeNow
|
|
1524
1542
|
};
|
|
1525
1543
|
this.currentWaapi = entry;
|
|
1526
1544
|
try {
|
|
@@ -2653,6 +2671,7 @@ class BottomSheetCore {
|
|
|
2653
2671
|
__publicField(this, "closeOnBack");
|
|
2654
2672
|
__publicField(this, "routedTo");
|
|
2655
2673
|
__publicField(this, "fitContentToSnap");
|
|
2674
|
+
__publicField(this, "settleAnimation");
|
|
2656
2675
|
__publicField(this, "persistent");
|
|
2657
2676
|
__publicField(this, "disableCloseFlag");
|
|
2658
2677
|
__publicField(this, "disableDragFlag");
|
|
@@ -2754,6 +2773,11 @@ class BottomSheetCore {
|
|
|
2754
2773
|
const cap = this.snaps.getMaxAxisSize();
|
|
2755
2774
|
const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
|
|
2756
2775
|
return this.transformTemplate(cap - shown);
|
|
2776
|
+
},
|
|
2777
|
+
readShownSize: () => {
|
|
2778
|
+
const shown = getComputedStyle(this.element).transform;
|
|
2779
|
+
if (!shown || shown === "none") return void 0;
|
|
2780
|
+
return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
|
|
2757
2781
|
}
|
|
2758
2782
|
}, resolved.animation);
|
|
2759
2783
|
this.lifecycle = new LifecycleController({
|
|
@@ -2763,6 +2787,7 @@ class BottomSheetCore {
|
|
|
2763
2787
|
this.closeOnBack = resolved.closeOnBack;
|
|
2764
2788
|
this.routedTo = opts.routedTo;
|
|
2765
2789
|
this.fitContentToSnap = opts.fitContentToSnap === true;
|
|
2790
|
+
this.settleAnimation = opts.settleAnimation;
|
|
2766
2791
|
this.persistent = resolved.persistent;
|
|
2767
2792
|
this.disableCloseFlag = resolved.disableClose;
|
|
2768
2793
|
this.disableDragFlag = resolved.disableDrag;
|
|
@@ -2855,7 +2880,8 @@ class BottomSheetCore {
|
|
|
2855
2880
|
closeOnRouteChange: this.closeOnRouteChange,
|
|
2856
2881
|
persistKey: this.persistKey,
|
|
2857
2882
|
autoCollapseAfter,
|
|
2858
|
-
fitContentToSnap: this.fitContentToSnap
|
|
2883
|
+
fitContentToSnap: this.fitContentToSnap,
|
|
2884
|
+
settleAnimation: this.settleAnimation
|
|
2859
2885
|
},
|
|
2860
2886
|
isDestroyed: () => this.destroyed,
|
|
2861
2887
|
isDragging: () => this.isDraggingAny(),
|
|
@@ -3726,7 +3752,8 @@ class BottomSheetCore {
|
|
|
3726
3752
|
const offset = cap - clamped;
|
|
3727
3753
|
const style = this.element.style;
|
|
3728
3754
|
if (!skipTransform) style.transform = this.transformTemplate(offset);
|
|
3729
|
-
|
|
3755
|
+
const sizeChanged = this.sizeWriteSentinel.shouldWrite(clamped, this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0);
|
|
3756
|
+
if (sizeChanged) {
|
|
3730
3757
|
style.setProperty("--bs-size", `${clamped}px`);
|
|
3731
3758
|
if (this.scrimParent) {
|
|
3732
3759
|
this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
|
|
@@ -3750,7 +3777,7 @@ class BottomSheetCore {
|
|
|
3750
3777
|
}
|
|
3751
3778
|
}
|
|
3752
3779
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
3753
|
-
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
3780
|
+
if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
|
|
3754
3781
|
this.progressPayload.value = progress;
|
|
3755
3782
|
this.progressPayload.size = clamped;
|
|
3756
3783
|
this.emit("progress", this.progressPayload);
|
|
@@ -4233,7 +4260,6 @@ function visualViewportFeature() {
|
|
|
4233
4260
|
};
|
|
4234
4261
|
}
|
|
4235
4262
|
const INSET_VAR = "--bs-content-inset";
|
|
4236
|
-
const SIZE_VAR = "--bs-size";
|
|
4237
4263
|
const CAP_VAR = "--bs-max-size";
|
|
4238
4264
|
const LIFT_VAR = "--bs-footer-lift-max";
|
|
4239
4265
|
const FIT_ATTR = "data-bs-fit-content";
|
|
@@ -4246,10 +4272,14 @@ function contentFitFeature() {
|
|
|
4246
4272
|
return;
|
|
4247
4273
|
}
|
|
4248
4274
|
const sheet = ctx.element;
|
|
4275
|
+
const waapi = ctx.options.settleAnimation === "waapi";
|
|
4249
4276
|
let inset = 0;
|
|
4250
4277
|
let unpaddedMax = -1;
|
|
4251
4278
|
let top = 0;
|
|
4252
4279
|
let resting = false;
|
|
4280
|
+
let liftMax = 0;
|
|
4281
|
+
let followed = null;
|
|
4282
|
+
let follower = null;
|
|
4253
4283
|
const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
|
|
4254
4284
|
const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
|
|
4255
4285
|
const follow = (size) => {
|
|
@@ -4263,8 +4293,39 @@ function contentFitFeature() {
|
|
|
4263
4293
|
top = limit;
|
|
4264
4294
|
}
|
|
4265
4295
|
};
|
|
4296
|
+
const unfollow = () => {
|
|
4297
|
+
follower?.cancel();
|
|
4298
|
+
follower = null;
|
|
4299
|
+
followed = null;
|
|
4300
|
+
};
|
|
4301
|
+
const followSettle = () => {
|
|
4302
|
+
if (followed?.playState === "running") return;
|
|
4303
|
+
const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
|
|
4304
|
+
const footer = sheet.querySelector(".bs-footer");
|
|
4305
|
+
if (!settleAnim || !footer) return;
|
|
4306
|
+
const effect = settleAnim.effect;
|
|
4307
|
+
unfollow();
|
|
4308
|
+
const own = footer.animate(effect.getKeyframes().map((k) => ({
|
|
4309
|
+
offset: k.computedOffset,
|
|
4310
|
+
transform: `translateY(${-Math.min(Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0), liftMax)}px)`
|
|
4311
|
+
})), {
|
|
4312
|
+
duration: effect.getTiming().duration,
|
|
4313
|
+
easing: "linear",
|
|
4314
|
+
fill: "forwards"
|
|
4315
|
+
});
|
|
4316
|
+
follower = own;
|
|
4317
|
+
followed = settleAnim;
|
|
4318
|
+
const done = () => {
|
|
4319
|
+
if (followed === settleAnim) unfollow();
|
|
4320
|
+
};
|
|
4321
|
+
settleAnim.ready.then(() => {
|
|
4322
|
+
if (follower === own) own.startTime = settleAnim.startTime;
|
|
4323
|
+
}, done);
|
|
4324
|
+
settleAnim.finished.then(done, done);
|
|
4325
|
+
};
|
|
4266
4326
|
const settle = () => {
|
|
4267
4327
|
if (ctx.isDestroyed()) return;
|
|
4328
|
+
unfollow();
|
|
4268
4329
|
const size = ctx.getSize();
|
|
4269
4330
|
if (!resting) {
|
|
4270
4331
|
unpaddedMax = -1;
|
|
@@ -4272,7 +4333,6 @@ function contentFitFeature() {
|
|
|
4272
4333
|
}
|
|
4273
4334
|
inset = hiddenAt(size);
|
|
4274
4335
|
put(INSET_VAR, inset);
|
|
4275
|
-
put(SIZE_VAR, size);
|
|
4276
4336
|
put(CAP_VAR, ctx.getMaxAxisSize());
|
|
4277
4337
|
if (!resting) {
|
|
4278
4338
|
resting = true;
|
|
@@ -4284,9 +4344,13 @@ function contentFitFeature() {
|
|
|
4284
4344
|
if (resting) {
|
|
4285
4345
|
resting = false;
|
|
4286
4346
|
sheet.setAttribute(FIT_ATTR, "moving");
|
|
4287
|
-
|
|
4347
|
+
liftMax = scroller.offsetHeight;
|
|
4348
|
+
put(LIFT_VAR, liftMax);
|
|
4288
4349
|
}
|
|
4289
4350
|
follow(size);
|
|
4351
|
+
if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
|
|
4352
|
+
followSettle();
|
|
4353
|
+
}
|
|
4290
4354
|
};
|
|
4291
4355
|
const moving = () => ctx.isAnimating() || ctx.isDragging();
|
|
4292
4356
|
const whenIdle = () => {
|
|
@@ -4295,12 +4359,21 @@ function contentFitFeature() {
|
|
|
4295
4359
|
settle();
|
|
4296
4360
|
const offProgress = ctx.on("progress", (p) => moving() ? move(p.size) : settle());
|
|
4297
4361
|
const offSnap = ctx.on("snap", settle);
|
|
4362
|
+
const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
|
|
4363
|
+
const offBeforeSnap = ctx.on("before-snap", () => {
|
|
4364
|
+
queueMicrotask(() => {
|
|
4365
|
+
if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
|
|
4366
|
+
});
|
|
4367
|
+
});
|
|
4298
4368
|
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
|
|
4299
4369
|
observer?.observe(document.documentElement);
|
|
4300
4370
|
window.addEventListener("orientationchange", whenIdle);
|
|
4301
4371
|
return () => {
|
|
4372
|
+
unfollow();
|
|
4302
4373
|
offProgress();
|
|
4303
4374
|
offSnap();
|
|
4375
|
+
offDragStart();
|
|
4376
|
+
offBeforeSnap();
|
|
4304
4377
|
observer?.disconnect();
|
|
4305
4378
|
window.removeEventListener("orientationchange", whenIdle);
|
|
4306
4379
|
sheet.removeAttribute(FIT_ATTR);
|
|
@@ -82,6 +82,7 @@ function buildTransformTemplate(axis) {
|
|
|
82
82
|
return (offset) => `translate3d(${offset}px, 0, 0)`;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
const offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
|
|
85
86
|
const layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
|
|
86
87
|
const counters = {};
|
|
87
88
|
function nextInstanceId(prefix) {
|
|
@@ -1179,7 +1180,7 @@ const tween = ({ from, to, duration, easing = easeOutCubic, onUpdate }) => {
|
|
|
1179
1180
|
}
|
|
1180
1181
|
const step = (now) => {
|
|
1181
1182
|
if (cancelled) return;
|
|
1182
|
-
const elapsed = now - start;
|
|
1183
|
+
const elapsed = Math.max(0, now - start);
|
|
1183
1184
|
const t = Math.min(elapsed / duration, 1);
|
|
1184
1185
|
const value = from + (to - from) * easing(t);
|
|
1185
1186
|
onUpdate(value);
|
|
@@ -1227,8 +1228,8 @@ const runSpring = ({ from, to, velocity = 0, config, onUpdate }) => {
|
|
|
1227
1228
|
resolveFn = resolve;
|
|
1228
1229
|
const step = (now) => {
|
|
1229
1230
|
if (cancelled) return;
|
|
1230
|
-
const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
|
|
1231
|
-
lastTime = now;
|
|
1231
|
+
const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
|
|
1232
|
+
lastTime = Math.max(lastTime, now);
|
|
1232
1233
|
const steps = Math.max(1, Math.ceil(dt * 240));
|
|
1233
1234
|
const subDt = dt / steps;
|
|
1234
1235
|
let stepsLeft = steps;
|
|
@@ -1308,6 +1309,7 @@ function resolveAnimationPreset(animation) {
|
|
|
1308
1309
|
};
|
|
1309
1310
|
}
|
|
1310
1311
|
}
|
|
1312
|
+
const SETTLE_ANIMATION_ID = "bs-settle";
|
|
1311
1313
|
const SIM_HZ = 240;
|
|
1312
1314
|
const SAMPLE_STRIDE = 4;
|
|
1313
1315
|
const MAX_SIM_MS = 3e3;
|
|
@@ -1368,6 +1370,7 @@ class AnimationRunner {
|
|
|
1368
1370
|
__publicField(this, "isDragging");
|
|
1369
1371
|
__publicField(this, "applyAux");
|
|
1370
1372
|
__publicField(this, "getTransformFor");
|
|
1373
|
+
__publicField(this, "readShownSize");
|
|
1371
1374
|
__publicField(this, "settleWaapi");
|
|
1372
1375
|
__publicField(this, "currentWaapi", null);
|
|
1373
1376
|
__publicField(this, "animationKind");
|
|
@@ -1387,6 +1390,7 @@ class AnimationRunner {
|
|
|
1387
1390
|
this.isDragging = deps.isDragging;
|
|
1388
1391
|
this.applyAux = deps.applyAux;
|
|
1389
1392
|
this.getTransformFor = deps.getTransformFor;
|
|
1393
|
+
this.readShownSize = deps.readShownSize;
|
|
1390
1394
|
this.settleWaapi = opts.settleAnimation === "waapi";
|
|
1391
1395
|
const preset = resolveAnimationPreset(opts.animation);
|
|
1392
1396
|
this.animationKind = preset.kind;
|
|
@@ -1422,10 +1426,12 @@ class AnimationRunner {
|
|
|
1422
1426
|
const entry = this.currentWaapi;
|
|
1423
1427
|
this.currentWaapi = null;
|
|
1424
1428
|
entry.stop();
|
|
1429
|
+
const size = this.readShownSize?.() ?? entry.sizeNow();
|
|
1425
1430
|
try {
|
|
1426
1431
|
entry.anim.cancel();
|
|
1427
1432
|
} catch {
|
|
1428
1433
|
}
|
|
1434
|
+
this.applySizeFn(size);
|
|
1429
1435
|
}
|
|
1430
1436
|
cancel() {
|
|
1431
1437
|
this.currentTween?.cancel();
|
|
@@ -1435,6 +1441,7 @@ class AnimationRunner {
|
|
|
1435
1441
|
async animateTo(target, velocityPxPerMs) {
|
|
1436
1442
|
if (target === this.getSize()) {
|
|
1437
1443
|
if (!this.isAnimating && !this.isDragging()) {
|
|
1444
|
+
this.applySizeFn(target);
|
|
1438
1445
|
this.element.style.willChange = "";
|
|
1439
1446
|
}
|
|
1440
1447
|
return;
|
|
@@ -1461,6 +1468,7 @@ class AnimationRunner {
|
|
|
1461
1468
|
return;
|
|
1462
1469
|
}
|
|
1463
1470
|
}
|
|
1471
|
+
let current = false;
|
|
1464
1472
|
if (this.animationKind === "spring") {
|
|
1465
1473
|
const spring = runSpring({
|
|
1466
1474
|
from: this.getSize(),
|
|
@@ -1471,7 +1479,8 @@ class AnimationRunner {
|
|
|
1471
1479
|
});
|
|
1472
1480
|
this.currentSpring = spring;
|
|
1473
1481
|
await spring.promise;
|
|
1474
|
-
|
|
1482
|
+
current = this.currentSpring === spring;
|
|
1483
|
+
if (current) this.currentSpring = null;
|
|
1475
1484
|
} else {
|
|
1476
1485
|
const tw = tween({
|
|
1477
1486
|
from: this.getSize(),
|
|
@@ -1482,11 +1491,15 @@ class AnimationRunner {
|
|
|
1482
1491
|
});
|
|
1483
1492
|
this.currentTween = tw;
|
|
1484
1493
|
await tw.promise;
|
|
1485
|
-
|
|
1494
|
+
current = this.currentTween === tw;
|
|
1495
|
+
if (current) this.currentTween = null;
|
|
1486
1496
|
}
|
|
1487
1497
|
if (!this.isAnimating) {
|
|
1488
1498
|
this.getRootEl()?.removeAttribute("data-animating");
|
|
1489
|
-
if (!this.isDragging())
|
|
1499
|
+
if (!this.isDragging()) {
|
|
1500
|
+
if (current) this.applySizeFn(this.getSize());
|
|
1501
|
+
this.element.style.willChange = "";
|
|
1502
|
+
}
|
|
1490
1503
|
}
|
|
1491
1504
|
}
|
|
1492
1505
|
async runWaapiSettle(samples, target) {
|
|
@@ -1500,16 +1513,20 @@ class AnimationRunner {
|
|
|
1500
1513
|
easing: "linear",
|
|
1501
1514
|
fill: "forwards"
|
|
1502
1515
|
});
|
|
1516
|
+
anim.id = SETTLE_ANIMATION_ID;
|
|
1503
1517
|
let stopped = false;
|
|
1504
1518
|
let auxRaf = 0;
|
|
1505
1519
|
const lastIdx = samples.values.length - 1;
|
|
1506
|
-
const
|
|
1507
|
-
if (stopped) return;
|
|
1520
|
+
const sizeNow = () => {
|
|
1508
1521
|
const at = Math.min((Number(anim.currentTime) || 0) / samples.stepMs, lastIdx);
|
|
1509
1522
|
const idx = Math.floor(at);
|
|
1510
1523
|
const from = samples.values[idx];
|
|
1511
1524
|
const to = samples.values[Math.min(idx + 1, lastIdx)];
|
|
1512
|
-
|
|
1525
|
+
return from + (to - from) * (at - idx);
|
|
1526
|
+
};
|
|
1527
|
+
const auxTick = () => {
|
|
1528
|
+
if (stopped) return;
|
|
1529
|
+
applyAux(sizeNow());
|
|
1513
1530
|
auxRaf = requestAnimationFrame(auxTick);
|
|
1514
1531
|
};
|
|
1515
1532
|
auxRaf = requestAnimationFrame(auxTick);
|
|
@@ -1518,7 +1535,8 @@ class AnimationRunner {
|
|
|
1518
1535
|
stop: () => {
|
|
1519
1536
|
stopped = true;
|
|
1520
1537
|
cancelAnimationFrame(auxRaf);
|
|
1521
|
-
}
|
|
1538
|
+
},
|
|
1539
|
+
sizeNow
|
|
1522
1540
|
};
|
|
1523
1541
|
this.currentWaapi = entry;
|
|
1524
1542
|
try {
|
|
@@ -2651,6 +2669,7 @@ class BottomSheetCore {
|
|
|
2651
2669
|
__publicField(this, "closeOnBack");
|
|
2652
2670
|
__publicField(this, "routedTo");
|
|
2653
2671
|
__publicField(this, "fitContentToSnap");
|
|
2672
|
+
__publicField(this, "settleAnimation");
|
|
2654
2673
|
__publicField(this, "persistent");
|
|
2655
2674
|
__publicField(this, "disableCloseFlag");
|
|
2656
2675
|
__publicField(this, "disableDragFlag");
|
|
@@ -2752,6 +2771,11 @@ class BottomSheetCore {
|
|
|
2752
2771
|
const cap = this.snaps.getMaxAxisSize();
|
|
2753
2772
|
const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
|
|
2754
2773
|
return this.transformTemplate(cap - shown);
|
|
2774
|
+
},
|
|
2775
|
+
readShownSize: () => {
|
|
2776
|
+
const shown = getComputedStyle(this.element).transform;
|
|
2777
|
+
if (!shown || shown === "none") return void 0;
|
|
2778
|
+
return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
|
|
2755
2779
|
}
|
|
2756
2780
|
}, resolved.animation);
|
|
2757
2781
|
this.lifecycle = new LifecycleController({
|
|
@@ -2761,6 +2785,7 @@ class BottomSheetCore {
|
|
|
2761
2785
|
this.closeOnBack = resolved.closeOnBack;
|
|
2762
2786
|
this.routedTo = opts.routedTo;
|
|
2763
2787
|
this.fitContentToSnap = opts.fitContentToSnap === true;
|
|
2788
|
+
this.settleAnimation = opts.settleAnimation;
|
|
2764
2789
|
this.persistent = resolved.persistent;
|
|
2765
2790
|
this.disableCloseFlag = resolved.disableClose;
|
|
2766
2791
|
this.disableDragFlag = resolved.disableDrag;
|
|
@@ -2853,7 +2878,8 @@ class BottomSheetCore {
|
|
|
2853
2878
|
closeOnRouteChange: this.closeOnRouteChange,
|
|
2854
2879
|
persistKey: this.persistKey,
|
|
2855
2880
|
autoCollapseAfter,
|
|
2856
|
-
fitContentToSnap: this.fitContentToSnap
|
|
2881
|
+
fitContentToSnap: this.fitContentToSnap,
|
|
2882
|
+
settleAnimation: this.settleAnimation
|
|
2857
2883
|
},
|
|
2858
2884
|
isDestroyed: () => this.destroyed,
|
|
2859
2885
|
isDragging: () => this.isDraggingAny(),
|
|
@@ -3724,7 +3750,8 @@ class BottomSheetCore {
|
|
|
3724
3750
|
const offset = cap - clamped;
|
|
3725
3751
|
const style = this.element.style;
|
|
3726
3752
|
if (!skipTransform) style.transform = this.transformTemplate(offset);
|
|
3727
|
-
|
|
3753
|
+
const sizeChanged = this.sizeWriteSentinel.shouldWrite(clamped, this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0);
|
|
3754
|
+
if (sizeChanged) {
|
|
3728
3755
|
style.setProperty("--bs-size", `${clamped}px`);
|
|
3729
3756
|
if (this.scrimParent) {
|
|
3730
3757
|
this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
|
|
@@ -3748,7 +3775,7 @@ class BottomSheetCore {
|
|
|
3748
3775
|
}
|
|
3749
3776
|
}
|
|
3750
3777
|
this.scrim.applyOpacity(progress, progressChanged);
|
|
3751
|
-
if (progressChanged && this.bus.listenerCount("progress") > 0) {
|
|
3778
|
+
if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
|
|
3752
3779
|
this.progressPayload.value = progress;
|
|
3753
3780
|
this.progressPayload.size = clamped;
|
|
3754
3781
|
this.emit("progress", this.progressPayload);
|
|
@@ -4231,7 +4258,6 @@ function visualViewportFeature() {
|
|
|
4231
4258
|
};
|
|
4232
4259
|
}
|
|
4233
4260
|
const INSET_VAR = "--bs-content-inset";
|
|
4234
|
-
const SIZE_VAR = "--bs-size";
|
|
4235
4261
|
const CAP_VAR = "--bs-max-size";
|
|
4236
4262
|
const LIFT_VAR = "--bs-footer-lift-max";
|
|
4237
4263
|
const FIT_ATTR = "data-bs-fit-content";
|
|
@@ -4244,10 +4270,14 @@ function contentFitFeature() {
|
|
|
4244
4270
|
return;
|
|
4245
4271
|
}
|
|
4246
4272
|
const sheet = ctx.element;
|
|
4273
|
+
const waapi = ctx.options.settleAnimation === "waapi";
|
|
4247
4274
|
let inset = 0;
|
|
4248
4275
|
let unpaddedMax = -1;
|
|
4249
4276
|
let top = 0;
|
|
4250
4277
|
let resting = false;
|
|
4278
|
+
let liftMax = 0;
|
|
4279
|
+
let followed = null;
|
|
4280
|
+
let follower = null;
|
|
4251
4281
|
const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
|
|
4252
4282
|
const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
|
|
4253
4283
|
const follow = (size) => {
|
|
@@ -4261,8 +4291,39 @@ function contentFitFeature() {
|
|
|
4261
4291
|
top = limit;
|
|
4262
4292
|
}
|
|
4263
4293
|
};
|
|
4294
|
+
const unfollow = () => {
|
|
4295
|
+
follower?.cancel();
|
|
4296
|
+
follower = null;
|
|
4297
|
+
followed = null;
|
|
4298
|
+
};
|
|
4299
|
+
const followSettle = () => {
|
|
4300
|
+
if (followed?.playState === "running") return;
|
|
4301
|
+
const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
|
|
4302
|
+
const footer = sheet.querySelector(".bs-footer");
|
|
4303
|
+
if (!settleAnim || !footer) return;
|
|
4304
|
+
const effect = settleAnim.effect;
|
|
4305
|
+
unfollow();
|
|
4306
|
+
const own = footer.animate(effect.getKeyframes().map((k) => ({
|
|
4307
|
+
offset: k.computedOffset,
|
|
4308
|
+
transform: `translateY(${-Math.min(Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0), liftMax)}px)`
|
|
4309
|
+
})), {
|
|
4310
|
+
duration: effect.getTiming().duration,
|
|
4311
|
+
easing: "linear",
|
|
4312
|
+
fill: "forwards"
|
|
4313
|
+
});
|
|
4314
|
+
follower = own;
|
|
4315
|
+
followed = settleAnim;
|
|
4316
|
+
const done = () => {
|
|
4317
|
+
if (followed === settleAnim) unfollow();
|
|
4318
|
+
};
|
|
4319
|
+
settleAnim.ready.then(() => {
|
|
4320
|
+
if (follower === own) own.startTime = settleAnim.startTime;
|
|
4321
|
+
}, done);
|
|
4322
|
+
settleAnim.finished.then(done, done);
|
|
4323
|
+
};
|
|
4264
4324
|
const settle = () => {
|
|
4265
4325
|
if (ctx.isDestroyed()) return;
|
|
4326
|
+
unfollow();
|
|
4266
4327
|
const size = ctx.getSize();
|
|
4267
4328
|
if (!resting) {
|
|
4268
4329
|
unpaddedMax = -1;
|
|
@@ -4270,7 +4331,6 @@ function contentFitFeature() {
|
|
|
4270
4331
|
}
|
|
4271
4332
|
inset = hiddenAt(size);
|
|
4272
4333
|
put(INSET_VAR, inset);
|
|
4273
|
-
put(SIZE_VAR, size);
|
|
4274
4334
|
put(CAP_VAR, ctx.getMaxAxisSize());
|
|
4275
4335
|
if (!resting) {
|
|
4276
4336
|
resting = true;
|
|
@@ -4282,9 +4342,13 @@ function contentFitFeature() {
|
|
|
4282
4342
|
if (resting) {
|
|
4283
4343
|
resting = false;
|
|
4284
4344
|
sheet.setAttribute(FIT_ATTR, "moving");
|
|
4285
|
-
|
|
4345
|
+
liftMax = scroller.offsetHeight;
|
|
4346
|
+
put(LIFT_VAR, liftMax);
|
|
4286
4347
|
}
|
|
4287
4348
|
follow(size);
|
|
4349
|
+
if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
|
|
4350
|
+
followSettle();
|
|
4351
|
+
}
|
|
4288
4352
|
};
|
|
4289
4353
|
const moving = () => ctx.isAnimating() || ctx.isDragging();
|
|
4290
4354
|
const whenIdle = () => {
|
|
@@ -4293,12 +4357,21 @@ function contentFitFeature() {
|
|
|
4293
4357
|
settle();
|
|
4294
4358
|
const offProgress = ctx.on("progress", (p) => moving() ? move(p.size) : settle());
|
|
4295
4359
|
const offSnap = ctx.on("snap", settle);
|
|
4360
|
+
const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
|
|
4361
|
+
const offBeforeSnap = ctx.on("before-snap", () => {
|
|
4362
|
+
queueMicrotask(() => {
|
|
4363
|
+
if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
|
|
4364
|
+
});
|
|
4365
|
+
});
|
|
4296
4366
|
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
|
|
4297
4367
|
observer?.observe(document.documentElement);
|
|
4298
4368
|
window.addEventListener("orientationchange", whenIdle);
|
|
4299
4369
|
return () => {
|
|
4370
|
+
unfollow();
|
|
4300
4371
|
offProgress();
|
|
4301
4372
|
offSnap();
|
|
4373
|
+
offDragStart();
|
|
4374
|
+
offBeforeSnap();
|
|
4302
4375
|
observer?.disconnect();
|
|
4303
4376
|
window.removeEventListener("orientationchange", whenIdle);
|
|
4304
4377
|
sheet.removeAttribute(FIT_ATTR);
|