@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.
Files changed (61) hide show
  1. package/README.md +3 -3
  2. package/dist/{BottomSheetCore-9i-Uh6T3.d.ts → BottomSheetCore-COvILxmR.d.ts} +2 -0
  3. package/dist/{BottomSheetCore-CQStdVy2.d.cts → BottomSheetCore-CaJwHnxY.d.cts} +2 -0
  4. package/dist/{BottomSheetEngine-CsQWHLNb.d.cts → BottomSheetEngine-C_1aPJsU.d.cts} +1 -1
  5. package/dist/{BottomSheetEngine-Dn6h-7gF.d.ts → BottomSheetEngine-CsgCcCSO.d.ts} +1 -1
  6. package/dist/core.cjs +43 -13
  7. package/dist/core.d.cts +2 -2
  8. package/dist/core.d.ts +2 -2
  9. package/dist/core.js +43 -13
  10. package/dist/debug.d.cts +1 -1
  11. package/dist/debug.d.ts +1 -1
  12. package/dist/{default-features-C3cilcW9.d.ts → default-features-BJx7J0NH.d.ts} +1 -1
  13. package/dist/{default-features-DkG9aho0.d.cts → default-features-CTJb8Wdk.d.cts} +1 -1
  14. package/dist/element.cjs +103 -20
  15. package/dist/element.d.cts +2 -2
  16. package/dist/element.d.ts +2 -2
  17. package/dist/element.iife.global.js +2 -2
  18. package/dist/element.js +103 -20
  19. package/dist/features.cjs +58 -3
  20. package/dist/features.d.cts +3 -3
  21. package/dist/features.d.ts +3 -3
  22. package/dist/features.js +58 -3
  23. package/dist/{index-CVGC5B5D.d.cts → index-BBrJJjy5.d.cts} +1 -1
  24. package/dist/{index-CnsJQZp2.d.ts → index-CXN7t3rr.d.ts} +1 -1
  25. package/dist/index.cjs +98 -16
  26. package/dist/index.d.cts +5 -5
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.js +98 -16
  29. package/dist/integrations/formik.d.cts +1 -1
  30. package/dist/integrations/formik.d.ts +1 -1
  31. package/dist/integrations/react-hook-form.d.cts +1 -1
  32. package/dist/integrations/react-hook-form.d.ts +1 -1
  33. package/dist/preact.d.cts +2 -2
  34. package/dist/preact.d.ts +2 -2
  35. package/dist/qwik-lib/index.qwik.cjs +89 -16
  36. package/dist/qwik-lib/index.qwik.mjs +89 -16
  37. package/dist/qwik.cjs +98 -16
  38. package/dist/qwik.d.cts +2 -2
  39. package/dist/qwik.d.ts +2 -2
  40. package/dist/qwik.js +98 -16
  41. package/dist/react.cjs +98 -16
  42. package/dist/react.d.cts +3 -3
  43. package/dist/react.d.ts +3 -3
  44. package/dist/react.js +98 -16
  45. package/dist/solid.cjs +98 -16
  46. package/dist/solid.d.cts +2 -0
  47. package/dist/solid.d.ts +2 -0
  48. package/dist/solid.js +98 -16
  49. package/dist/solid.source.jsx +98 -16
  50. package/dist/styles.css +8 -6
  51. package/dist/svelte-core.cjs +98 -16
  52. package/dist/svelte-core.js +98 -16
  53. package/dist/svelte.cjs +98 -16
  54. package/dist/svelte.js +98 -16
  55. package/dist/vue.cjs +98 -16
  56. package/dist/vue.js +98 -16
  57. package/dist/webgl.cjs +192 -42
  58. package/dist/webgl.d.cts +1 -1
  59. package/dist/webgl.d.ts +1 -1
  60. package/dist/webgl.js +192 -42
  61. package/package.json +12 -12
package/dist/svelte.js CHANGED
@@ -88,6 +88,7 @@ function buildTransformTemplate(axis) {
88
88
  return (offset) => `translate3d(${offset}px, 0, 0)`;
89
89
  }
90
90
  }
91
+ var offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
91
92
  var layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
92
93
 
93
94
  // src/core/primitives/instance-id.ts
@@ -1173,7 +1174,7 @@ var tween = ({
1173
1174
  }
1174
1175
  const step = (now) => {
1175
1176
  if (cancelled) return;
1176
- const elapsed = now - start;
1177
+ const elapsed = Math.max(0, now - start);
1177
1178
  const t = Math.min(elapsed / duration, 1);
1178
1179
  const value = from + (to - from) * easing(t);
1179
1180
  onUpdate(value);
@@ -1226,8 +1227,8 @@ var runSpring = ({
1226
1227
  resolveFn = resolve;
1227
1228
  const step = (now) => {
1228
1229
  if (cancelled) return;
1229
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1230
- lastTime = now;
1230
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1231
+ lastTime = Math.max(lastTime, now);
1231
1232
  const steps = Math.max(1, Math.ceil(dt * 240));
1232
1233
  const subDt = dt / steps;
1233
1234
  let stepsLeft = steps;
@@ -1291,6 +1292,7 @@ function resolveAnimationPreset(animation) {
1291
1292
  }
1292
1293
 
1293
1294
  // src/core/animation/waapi-settle.ts
1295
+ var SETTLE_ANIMATION_ID = "bs-settle";
1294
1296
  var SIM_HZ = 240;
1295
1297
  var SAMPLE_STRIDE = 4;
1296
1298
  var MAX_SIM_MS = 3e3;
@@ -1348,6 +1350,7 @@ var AnimationRunner = class {
1348
1350
  __publicField(this, "isDragging");
1349
1351
  __publicField(this, "applyAux");
1350
1352
  __publicField(this, "getTransformFor");
1353
+ __publicField(this, "readShownSize");
1351
1354
  __publicField(this, "settleWaapi");
1352
1355
  __publicField(this, "currentWaapi", null);
1353
1356
  __publicField(this, "animationKind");
@@ -1367,6 +1370,7 @@ var AnimationRunner = class {
1367
1370
  this.isDragging = deps.isDragging;
1368
1371
  this.applyAux = deps.applyAux;
1369
1372
  this.getTransformFor = deps.getTransformFor;
1373
+ this.readShownSize = deps.readShownSize;
1370
1374
  this.settleWaapi = opts.settleAnimation === "waapi";
1371
1375
  const preset = resolveAnimationPreset(opts.animation);
1372
1376
  this.animationKind = preset.kind;
@@ -1399,10 +1403,12 @@ var AnimationRunner = class {
1399
1403
  const entry = this.currentWaapi;
1400
1404
  this.currentWaapi = null;
1401
1405
  entry.stop();
1406
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1402
1407
  try {
1403
1408
  entry.anim.cancel();
1404
1409
  } catch {
1405
1410
  }
1411
+ this.applySizeFn(size);
1406
1412
  }
1407
1413
  cancel() {
1408
1414
  this.currentTween?.cancel();
@@ -1412,6 +1418,7 @@ var AnimationRunner = class {
1412
1418
  async animateTo(target, velocityPxPerMs) {
1413
1419
  if (target === this.getSize()) {
1414
1420
  if (!this.isAnimating && !this.isDragging()) {
1421
+ this.applySizeFn(target);
1415
1422
  this.element.style.willChange = "";
1416
1423
  }
1417
1424
  return;
@@ -1448,6 +1455,7 @@ var AnimationRunner = class {
1448
1455
  return;
1449
1456
  }
1450
1457
  }
1458
+ let current = false;
1451
1459
  if (this.animationKind === "spring") {
1452
1460
  const spring = runSpring({
1453
1461
  from: this.getSize(),
@@ -1458,7 +1466,8 @@ var AnimationRunner = class {
1458
1466
  });
1459
1467
  this.currentSpring = spring;
1460
1468
  await spring.promise;
1461
- if (this.currentSpring === spring) this.currentSpring = null;
1469
+ current = this.currentSpring === spring;
1470
+ if (current) this.currentSpring = null;
1462
1471
  } else {
1463
1472
  const tw = tween({
1464
1473
  from: this.getSize(),
@@ -1469,11 +1478,15 @@ var AnimationRunner = class {
1469
1478
  });
1470
1479
  this.currentTween = tw;
1471
1480
  await tw.promise;
1472
- if (this.currentTween === tw) this.currentTween = null;
1481
+ current = this.currentTween === tw;
1482
+ if (current) this.currentTween = null;
1473
1483
  }
1474
1484
  if (!this.isAnimating) {
1475
1485
  this.getRootEl()?.removeAttribute("data-animating");
1476
- if (!this.isDragging()) this.element.style.willChange = "";
1486
+ if (!this.isDragging()) {
1487
+ if (current) this.applySizeFn(this.getSize());
1488
+ this.element.style.willChange = "";
1489
+ }
1477
1490
  }
1478
1491
  }
1479
1492
  async runWaapiSettle(samples, target) {
@@ -1487,11 +1500,11 @@ var AnimationRunner = class {
1487
1500
  easing: "linear",
1488
1501
  fill: "forwards"
1489
1502
  });
1503
+ anim.id = SETTLE_ANIMATION_ID;
1490
1504
  let stopped = false;
1491
1505
  let auxRaf = 0;
1492
1506
  const lastIdx = samples.values.length - 1;
1493
- const auxTick = () => {
1494
- if (stopped) return;
1507
+ const sizeNow = () => {
1495
1508
  const at = Math.min(
1496
1509
  (Number(anim.currentTime) || 0) / samples.stepMs,
1497
1510
  lastIdx
@@ -1499,7 +1512,11 @@ var AnimationRunner = class {
1499
1512
  const idx = Math.floor(at);
1500
1513
  const from = samples.values[idx];
1501
1514
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1502
- applyAux(from + (to - from) * (at - idx));
1515
+ return from + (to - from) * (at - idx);
1516
+ };
1517
+ const auxTick = () => {
1518
+ if (stopped) return;
1519
+ applyAux(sizeNow());
1503
1520
  auxRaf = requestAnimationFrame(auxTick);
1504
1521
  };
1505
1522
  auxRaf = requestAnimationFrame(auxTick);
@@ -1508,7 +1525,8 @@ var AnimationRunner = class {
1508
1525
  stop: () => {
1509
1526
  stopped = true;
1510
1527
  cancelAnimationFrame(auxRaf);
1511
- }
1528
+ },
1529
+ sizeNow
1512
1530
  };
1513
1531
  this.currentWaapi = entry;
1514
1532
  try {
@@ -2611,6 +2629,7 @@ var BottomSheetCore = class {
2611
2629
  __publicField(this, "closeOnBack");
2612
2630
  __publicField(this, "routedTo");
2613
2631
  __publicField(this, "fitContentToSnap");
2632
+ __publicField(this, "settleAnimation");
2614
2633
  __publicField(this, "persistent");
2615
2634
  __publicField(this, "disableCloseFlag");
2616
2635
  __publicField(this, "disableDragFlag");
@@ -2715,6 +2734,11 @@ var BottomSheetCore = class {
2715
2734
  const cap = this.snaps.getMaxAxisSize();
2716
2735
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2717
2736
  return this.transformTemplate(cap - shown);
2737
+ },
2738
+ readShownSize: () => {
2739
+ const shown = getComputedStyle(this.element).transform;
2740
+ if (!shown || shown === "none") return void 0;
2741
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2718
2742
  }
2719
2743
  },
2720
2744
  resolved.animation
@@ -2729,6 +2753,7 @@ var BottomSheetCore = class {
2729
2753
  this.closeOnBack = resolved.closeOnBack;
2730
2754
  this.routedTo = opts.routedTo;
2731
2755
  this.fitContentToSnap = opts.fitContentToSnap === true;
2756
+ this.settleAnimation = opts.settleAnimation;
2732
2757
  this.persistent = resolved.persistent;
2733
2758
  this.disableCloseFlag = resolved.disableClose;
2734
2759
  this.disableDragFlag = resolved.disableDrag;
@@ -2831,7 +2856,8 @@ var BottomSheetCore = class {
2831
2856
  closeOnRouteChange: this.closeOnRouteChange,
2832
2857
  persistKey: this.persistKey,
2833
2858
  autoCollapseAfter,
2834
- fitContentToSnap: this.fitContentToSnap
2859
+ fitContentToSnap: this.fitContentToSnap,
2860
+ settleAnimation: this.settleAnimation
2835
2861
  },
2836
2862
  isDestroyed: () => this.destroyed,
2837
2863
  isDragging: () => this.isDraggingAny(),
@@ -3723,7 +3749,11 @@ var BottomSheetCore = class {
3723
3749
  const offset = cap - clamped;
3724
3750
  const style = this.element.style;
3725
3751
  if (!skipTransform) style.transform = this.transformTemplate(offset);
3726
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3752
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
3753
+ clamped,
3754
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
3755
+ );
3756
+ if (sizeChanged) {
3727
3757
  style.setProperty("--bs-size", `${clamped}px`);
3728
3758
  if (this.scrimParent) {
3729
3759
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -3750,7 +3780,7 @@ var BottomSheetCore = class {
3750
3780
  }
3751
3781
  }
3752
3782
  this.scrim.applyOpacity(progress, progressChanged);
3753
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
3783
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
3754
3784
  this.progressPayload.value = progress;
3755
3785
  this.progressPayload.size = clamped;
3756
3786
  this.emit("progress", this.progressPayload);
@@ -4247,7 +4277,6 @@ function visualViewportFeature() {
4247
4277
 
4248
4278
  // src/core/features/content-fit.ts
4249
4279
  var INSET_VAR = "--bs-content-inset";
4250
- var SIZE_VAR = "--bs-size";
4251
4280
  var CAP_VAR = "--bs-max-size";
4252
4281
  var LIFT_VAR = "--bs-footer-lift-max";
4253
4282
  var FIT_ATTR = "data-bs-fit-content";
@@ -4260,10 +4289,14 @@ function contentFitFeature() {
4260
4289
  return;
4261
4290
  }
4262
4291
  const sheet = ctx.element;
4292
+ const waapi = ctx.options.settleAnimation === "waapi";
4263
4293
  let inset = 0;
4264
4294
  let unpaddedMax = -1;
4265
4295
  let top = 0;
4266
4296
  let resting = false;
4297
+ let liftMax = 0;
4298
+ let followed = null;
4299
+ let follower = null;
4267
4300
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4268
4301
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4269
4302
  const follow = (size) => {
@@ -4277,8 +4310,45 @@ function contentFitFeature() {
4277
4310
  top = limit;
4278
4311
  }
4279
4312
  };
4313
+ const unfollow = () => {
4314
+ follower?.cancel();
4315
+ follower = null;
4316
+ followed = null;
4317
+ };
4318
+ const followSettle = () => {
4319
+ if (followed?.playState === "running") return;
4320
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4321
+ const footer = sheet.querySelector(".bs-footer");
4322
+ if (!settleAnim || !footer) return;
4323
+ const effect = settleAnim.effect;
4324
+ unfollow();
4325
+ const own = footer.animate(
4326
+ effect.getKeyframes().map((k) => ({
4327
+ offset: k.computedOffset,
4328
+ transform: `translateY(${-Math.min(
4329
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4330
+ liftMax
4331
+ )}px)`
4332
+ })),
4333
+ {
4334
+ duration: effect.getTiming().duration,
4335
+ easing: "linear",
4336
+ fill: "forwards"
4337
+ }
4338
+ );
4339
+ follower = own;
4340
+ followed = settleAnim;
4341
+ const done = () => {
4342
+ if (followed === settleAnim) unfollow();
4343
+ };
4344
+ settleAnim.ready.then(() => {
4345
+ if (follower === own) own.startTime = settleAnim.startTime;
4346
+ }, done);
4347
+ settleAnim.finished.then(done, done);
4348
+ };
4280
4349
  const settle = () => {
4281
4350
  if (ctx.isDestroyed()) return;
4351
+ unfollow();
4282
4352
  const size = ctx.getSize();
4283
4353
  if (!resting) {
4284
4354
  unpaddedMax = -1;
@@ -4286,7 +4356,6 @@ function contentFitFeature() {
4286
4356
  }
4287
4357
  inset = hiddenAt(size);
4288
4358
  put(INSET_VAR, inset);
4289
- put(SIZE_VAR, size);
4290
4359
  put(CAP_VAR, ctx.getMaxAxisSize());
4291
4360
  if (!resting) {
4292
4361
  resting = true;
@@ -4298,9 +4367,13 @@ function contentFitFeature() {
4298
4367
  if (resting) {
4299
4368
  resting = false;
4300
4369
  sheet.setAttribute(FIT_ATTR, "moving");
4301
- put(LIFT_VAR, scroller.offsetHeight);
4370
+ liftMax = scroller.offsetHeight;
4371
+ put(LIFT_VAR, liftMax);
4302
4372
  }
4303
4373
  follow(size);
4374
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4375
+ followSettle();
4376
+ }
4304
4377
  };
4305
4378
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4306
4379
  const whenIdle = () => {
@@ -4312,12 +4385,21 @@ function contentFitFeature() {
4312
4385
  (p) => moving() ? move(p.size) : settle()
4313
4386
  );
4314
4387
  const offSnap = ctx.on("snap", settle);
4388
+ const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4389
+ const offBeforeSnap = ctx.on("before-snap", () => {
4390
+ queueMicrotask(() => {
4391
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4392
+ });
4393
+ });
4315
4394
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4316
4395
  observer?.observe(document.documentElement);
4317
4396
  window.addEventListener("orientationchange", whenIdle);
4318
4397
  return () => {
4398
+ unfollow();
4319
4399
  offProgress();
4320
4400
  offSnap();
4401
+ offDragStart();
4402
+ offBeforeSnap();
4321
4403
  observer?.disconnect();
4322
4404
  window.removeEventListener("orientationchange", whenIdle);
4323
4405
  sheet.removeAttribute(FIT_ATTR);
package/dist/vue.cjs CHANGED
@@ -88,6 +88,7 @@ function buildTransformTemplate(axis) {
88
88
  return (offset) => `translate3d(${offset}px, 0, 0)`;
89
89
  }
90
90
  }
91
+ var offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
91
92
  var layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
92
93
 
93
94
  // src/core/primitives/instance-id.ts
@@ -1173,7 +1174,7 @@ var tween = ({
1173
1174
  }
1174
1175
  const step = (now) => {
1175
1176
  if (cancelled) return;
1176
- const elapsed = now - start;
1177
+ const elapsed = Math.max(0, now - start);
1177
1178
  const t = Math.min(elapsed / duration, 1);
1178
1179
  const value = from + (to - from) * easing(t);
1179
1180
  onUpdate(value);
@@ -1226,8 +1227,8 @@ var runSpring = ({
1226
1227
  resolveFn = resolve;
1227
1228
  const step = (now) => {
1228
1229
  if (cancelled) return;
1229
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1230
- lastTime = now;
1230
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1231
+ lastTime = Math.max(lastTime, now);
1231
1232
  const steps = Math.max(1, Math.ceil(dt * 240));
1232
1233
  const subDt = dt / steps;
1233
1234
  let stepsLeft = steps;
@@ -1291,6 +1292,7 @@ function resolveAnimationPreset(animation) {
1291
1292
  }
1292
1293
 
1293
1294
  // src/core/animation/waapi-settle.ts
1295
+ var SETTLE_ANIMATION_ID = "bs-settle";
1294
1296
  var SIM_HZ = 240;
1295
1297
  var SAMPLE_STRIDE = 4;
1296
1298
  var MAX_SIM_MS = 3e3;
@@ -1348,6 +1350,7 @@ var AnimationRunner = class {
1348
1350
  __publicField(this, "isDragging");
1349
1351
  __publicField(this, "applyAux");
1350
1352
  __publicField(this, "getTransformFor");
1353
+ __publicField(this, "readShownSize");
1351
1354
  __publicField(this, "settleWaapi");
1352
1355
  __publicField(this, "currentWaapi", null);
1353
1356
  __publicField(this, "animationKind");
@@ -1367,6 +1370,7 @@ var AnimationRunner = class {
1367
1370
  this.isDragging = deps.isDragging;
1368
1371
  this.applyAux = deps.applyAux;
1369
1372
  this.getTransformFor = deps.getTransformFor;
1373
+ this.readShownSize = deps.readShownSize;
1370
1374
  this.settleWaapi = opts.settleAnimation === "waapi";
1371
1375
  const preset = resolveAnimationPreset(opts.animation);
1372
1376
  this.animationKind = preset.kind;
@@ -1399,10 +1403,12 @@ var AnimationRunner = class {
1399
1403
  const entry = this.currentWaapi;
1400
1404
  this.currentWaapi = null;
1401
1405
  entry.stop();
1406
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1402
1407
  try {
1403
1408
  entry.anim.cancel();
1404
1409
  } catch {
1405
1410
  }
1411
+ this.applySizeFn(size);
1406
1412
  }
1407
1413
  cancel() {
1408
1414
  this.currentTween?.cancel();
@@ -1412,6 +1418,7 @@ var AnimationRunner = class {
1412
1418
  async animateTo(target, velocityPxPerMs) {
1413
1419
  if (target === this.getSize()) {
1414
1420
  if (!this.isAnimating && !this.isDragging()) {
1421
+ this.applySizeFn(target);
1415
1422
  this.element.style.willChange = "";
1416
1423
  }
1417
1424
  return;
@@ -1448,6 +1455,7 @@ var AnimationRunner = class {
1448
1455
  return;
1449
1456
  }
1450
1457
  }
1458
+ let current = false;
1451
1459
  if (this.animationKind === "spring") {
1452
1460
  const spring = runSpring({
1453
1461
  from: this.getSize(),
@@ -1458,7 +1466,8 @@ var AnimationRunner = class {
1458
1466
  });
1459
1467
  this.currentSpring = spring;
1460
1468
  await spring.promise;
1461
- if (this.currentSpring === spring) this.currentSpring = null;
1469
+ current = this.currentSpring === spring;
1470
+ if (current) this.currentSpring = null;
1462
1471
  } else {
1463
1472
  const tw = tween({
1464
1473
  from: this.getSize(),
@@ -1469,11 +1478,15 @@ var AnimationRunner = class {
1469
1478
  });
1470
1479
  this.currentTween = tw;
1471
1480
  await tw.promise;
1472
- if (this.currentTween === tw) this.currentTween = null;
1481
+ current = this.currentTween === tw;
1482
+ if (current) this.currentTween = null;
1473
1483
  }
1474
1484
  if (!this.isAnimating) {
1475
1485
  this.getRootEl()?.removeAttribute("data-animating");
1476
- if (!this.isDragging()) this.element.style.willChange = "";
1486
+ if (!this.isDragging()) {
1487
+ if (current) this.applySizeFn(this.getSize());
1488
+ this.element.style.willChange = "";
1489
+ }
1477
1490
  }
1478
1491
  }
1479
1492
  async runWaapiSettle(samples, target) {
@@ -1487,11 +1500,11 @@ var AnimationRunner = class {
1487
1500
  easing: "linear",
1488
1501
  fill: "forwards"
1489
1502
  });
1503
+ anim.id = SETTLE_ANIMATION_ID;
1490
1504
  let stopped = false;
1491
1505
  let auxRaf = 0;
1492
1506
  const lastIdx = samples.values.length - 1;
1493
- const auxTick = () => {
1494
- if (stopped) return;
1507
+ const sizeNow = () => {
1495
1508
  const at = Math.min(
1496
1509
  (Number(anim.currentTime) || 0) / samples.stepMs,
1497
1510
  lastIdx
@@ -1499,7 +1512,11 @@ var AnimationRunner = class {
1499
1512
  const idx = Math.floor(at);
1500
1513
  const from = samples.values[idx];
1501
1514
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1502
- applyAux(from + (to - from) * (at - idx));
1515
+ return from + (to - from) * (at - idx);
1516
+ };
1517
+ const auxTick = () => {
1518
+ if (stopped) return;
1519
+ applyAux(sizeNow());
1503
1520
  auxRaf = requestAnimationFrame(auxTick);
1504
1521
  };
1505
1522
  auxRaf = requestAnimationFrame(auxTick);
@@ -1508,7 +1525,8 @@ var AnimationRunner = class {
1508
1525
  stop: () => {
1509
1526
  stopped = true;
1510
1527
  cancelAnimationFrame(auxRaf);
1511
- }
1528
+ },
1529
+ sizeNow
1512
1530
  };
1513
1531
  this.currentWaapi = entry;
1514
1532
  try {
@@ -2611,6 +2629,7 @@ var BottomSheetCore = class {
2611
2629
  __publicField(this, "closeOnBack");
2612
2630
  __publicField(this, "routedTo");
2613
2631
  __publicField(this, "fitContentToSnap");
2632
+ __publicField(this, "settleAnimation");
2614
2633
  __publicField(this, "persistent");
2615
2634
  __publicField(this, "disableCloseFlag");
2616
2635
  __publicField(this, "disableDragFlag");
@@ -2715,6 +2734,11 @@ var BottomSheetCore = class {
2715
2734
  const cap = this.snaps.getMaxAxisSize();
2716
2735
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2717
2736
  return this.transformTemplate(cap - shown);
2737
+ },
2738
+ readShownSize: () => {
2739
+ const shown = getComputedStyle(this.element).transform;
2740
+ if (!shown || shown === "none") return void 0;
2741
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2718
2742
  }
2719
2743
  },
2720
2744
  resolved.animation
@@ -2729,6 +2753,7 @@ var BottomSheetCore = class {
2729
2753
  this.closeOnBack = resolved.closeOnBack;
2730
2754
  this.routedTo = opts.routedTo;
2731
2755
  this.fitContentToSnap = opts.fitContentToSnap === true;
2756
+ this.settleAnimation = opts.settleAnimation;
2732
2757
  this.persistent = resolved.persistent;
2733
2758
  this.disableCloseFlag = resolved.disableClose;
2734
2759
  this.disableDragFlag = resolved.disableDrag;
@@ -2831,7 +2856,8 @@ var BottomSheetCore = class {
2831
2856
  closeOnRouteChange: this.closeOnRouteChange,
2832
2857
  persistKey: this.persistKey,
2833
2858
  autoCollapseAfter,
2834
- fitContentToSnap: this.fitContentToSnap
2859
+ fitContentToSnap: this.fitContentToSnap,
2860
+ settleAnimation: this.settleAnimation
2835
2861
  },
2836
2862
  isDestroyed: () => this.destroyed,
2837
2863
  isDragging: () => this.isDraggingAny(),
@@ -3723,7 +3749,11 @@ var BottomSheetCore = class {
3723
3749
  const offset = cap - clamped;
3724
3750
  const style = this.element.style;
3725
3751
  if (!skipTransform) style.transform = this.transformTemplate(offset);
3726
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3752
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
3753
+ clamped,
3754
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
3755
+ );
3756
+ if (sizeChanged) {
3727
3757
  style.setProperty("--bs-size", `${clamped}px`);
3728
3758
  if (this.scrimParent) {
3729
3759
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -3750,7 +3780,7 @@ var BottomSheetCore = class {
3750
3780
  }
3751
3781
  }
3752
3782
  this.scrim.applyOpacity(progress, progressChanged);
3753
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
3783
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
3754
3784
  this.progressPayload.value = progress;
3755
3785
  this.progressPayload.size = clamped;
3756
3786
  this.emit("progress", this.progressPayload);
@@ -4247,7 +4277,6 @@ function visualViewportFeature() {
4247
4277
 
4248
4278
  // src/core/features/content-fit.ts
4249
4279
  var INSET_VAR = "--bs-content-inset";
4250
- var SIZE_VAR = "--bs-size";
4251
4280
  var CAP_VAR = "--bs-max-size";
4252
4281
  var LIFT_VAR = "--bs-footer-lift-max";
4253
4282
  var FIT_ATTR = "data-bs-fit-content";
@@ -4260,10 +4289,14 @@ function contentFitFeature() {
4260
4289
  return;
4261
4290
  }
4262
4291
  const sheet = ctx.element;
4292
+ const waapi = ctx.options.settleAnimation === "waapi";
4263
4293
  let inset = 0;
4264
4294
  let unpaddedMax = -1;
4265
4295
  let top = 0;
4266
4296
  let resting = false;
4297
+ let liftMax = 0;
4298
+ let followed = null;
4299
+ let follower = null;
4267
4300
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4268
4301
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4269
4302
  const follow = (size) => {
@@ -4277,8 +4310,45 @@ function contentFitFeature() {
4277
4310
  top = limit;
4278
4311
  }
4279
4312
  };
4313
+ const unfollow = () => {
4314
+ follower?.cancel();
4315
+ follower = null;
4316
+ followed = null;
4317
+ };
4318
+ const followSettle = () => {
4319
+ if (followed?.playState === "running") return;
4320
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4321
+ const footer = sheet.querySelector(".bs-footer");
4322
+ if (!settleAnim || !footer) return;
4323
+ const effect = settleAnim.effect;
4324
+ unfollow();
4325
+ const own = footer.animate(
4326
+ effect.getKeyframes().map((k) => ({
4327
+ offset: k.computedOffset,
4328
+ transform: `translateY(${-Math.min(
4329
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4330
+ liftMax
4331
+ )}px)`
4332
+ })),
4333
+ {
4334
+ duration: effect.getTiming().duration,
4335
+ easing: "linear",
4336
+ fill: "forwards"
4337
+ }
4338
+ );
4339
+ follower = own;
4340
+ followed = settleAnim;
4341
+ const done = () => {
4342
+ if (followed === settleAnim) unfollow();
4343
+ };
4344
+ settleAnim.ready.then(() => {
4345
+ if (follower === own) own.startTime = settleAnim.startTime;
4346
+ }, done);
4347
+ settleAnim.finished.then(done, done);
4348
+ };
4280
4349
  const settle = () => {
4281
4350
  if (ctx.isDestroyed()) return;
4351
+ unfollow();
4282
4352
  const size = ctx.getSize();
4283
4353
  if (!resting) {
4284
4354
  unpaddedMax = -1;
@@ -4286,7 +4356,6 @@ function contentFitFeature() {
4286
4356
  }
4287
4357
  inset = hiddenAt(size);
4288
4358
  put(INSET_VAR, inset);
4289
- put(SIZE_VAR, size);
4290
4359
  put(CAP_VAR, ctx.getMaxAxisSize());
4291
4360
  if (!resting) {
4292
4361
  resting = true;
@@ -4298,9 +4367,13 @@ function contentFitFeature() {
4298
4367
  if (resting) {
4299
4368
  resting = false;
4300
4369
  sheet.setAttribute(FIT_ATTR, "moving");
4301
- put(LIFT_VAR, scroller.offsetHeight);
4370
+ liftMax = scroller.offsetHeight;
4371
+ put(LIFT_VAR, liftMax);
4302
4372
  }
4303
4373
  follow(size);
4374
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4375
+ followSettle();
4376
+ }
4304
4377
  };
4305
4378
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4306
4379
  const whenIdle = () => {
@@ -4312,12 +4385,21 @@ function contentFitFeature() {
4312
4385
  (p) => moving() ? move(p.size) : settle()
4313
4386
  );
4314
4387
  const offSnap = ctx.on("snap", settle);
4388
+ const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4389
+ const offBeforeSnap = ctx.on("before-snap", () => {
4390
+ queueMicrotask(() => {
4391
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4392
+ });
4393
+ });
4315
4394
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4316
4395
  observer?.observe(document.documentElement);
4317
4396
  window.addEventListener("orientationchange", whenIdle);
4318
4397
  return () => {
4398
+ unfollow();
4319
4399
  offProgress();
4320
4400
  offSnap();
4401
+ offDragStart();
4402
+ offBeforeSnap();
4321
4403
  observer?.disconnect();
4322
4404
  window.removeEventListener("orientationchange", whenIdle);
4323
4405
  sheet.removeAttribute(FIT_ATTR);