@surdeddd/bottom-sheet 0.23.2 → 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 (57) hide show
  1. package/dist/{BottomSheetCore-9i-Uh6T3.d.ts → BottomSheetCore-COvILxmR.d.ts} +2 -0
  2. package/dist/{BottomSheetCore-CQStdVy2.d.cts → BottomSheetCore-CaJwHnxY.d.cts} +2 -0
  3. package/dist/{BottomSheetEngine-CsQWHLNb.d.cts → BottomSheetEngine-C_1aPJsU.d.cts} +1 -1
  4. package/dist/{BottomSheetEngine-Dn6h-7gF.d.ts → BottomSheetEngine-CsgCcCSO.d.ts} +1 -1
  5. package/dist/core.cjs +43 -13
  6. package/dist/core.d.cts +2 -2
  7. package/dist/core.d.ts +2 -2
  8. package/dist/core.js +43 -13
  9. package/dist/debug.d.cts +1 -1
  10. package/dist/debug.d.ts +1 -1
  11. package/dist/{default-features-C3cilcW9.d.ts → default-features-BJx7J0NH.d.ts} +1 -1
  12. package/dist/{default-features-DkG9aho0.d.cts → default-features-CTJb8Wdk.d.cts} +1 -1
  13. package/dist/element.cjs +100 -19
  14. package/dist/element.d.cts +2 -2
  15. package/dist/element.d.ts +2 -2
  16. package/dist/element.iife.global.js +2 -2
  17. package/dist/element.js +100 -19
  18. package/dist/features.cjs +56 -3
  19. package/dist/features.d.cts +3 -3
  20. package/dist/features.d.ts +3 -3
  21. package/dist/features.js +56 -3
  22. package/dist/{index-CVGC5B5D.d.cts → index-BBrJJjy5.d.cts} +1 -1
  23. package/dist/{index-CnsJQZp2.d.ts → index-CXN7t3rr.d.ts} +1 -1
  24. package/dist/index.cjs +96 -16
  25. package/dist/index.d.cts +5 -5
  26. package/dist/index.d.ts +5 -5
  27. package/dist/index.js +96 -16
  28. package/dist/integrations/formik.d.cts +1 -1
  29. package/dist/integrations/formik.d.ts +1 -1
  30. package/dist/integrations/react-hook-form.d.cts +1 -1
  31. package/dist/integrations/react-hook-form.d.ts +1 -1
  32. package/dist/preact.d.cts +2 -2
  33. package/dist/preact.d.ts +2 -2
  34. package/dist/qwik-lib/index.qwik.cjs +87 -16
  35. package/dist/qwik-lib/index.qwik.mjs +87 -16
  36. package/dist/qwik.cjs +96 -16
  37. package/dist/qwik.d.cts +2 -2
  38. package/dist/qwik.d.ts +2 -2
  39. package/dist/qwik.js +96 -16
  40. package/dist/react.cjs +96 -16
  41. package/dist/react.d.cts +3 -3
  42. package/dist/react.d.ts +3 -3
  43. package/dist/react.js +96 -16
  44. package/dist/solid.cjs +96 -16
  45. package/dist/solid.d.cts +2 -0
  46. package/dist/solid.d.ts +2 -0
  47. package/dist/solid.js +96 -16
  48. package/dist/solid.source.jsx +96 -16
  49. package/dist/svelte-core.cjs +96 -16
  50. package/dist/svelte-core.js +96 -16
  51. package/dist/svelte.cjs +96 -16
  52. package/dist/svelte.js +96 -16
  53. package/dist/vue.cjs +96 -16
  54. package/dist/vue.js +96 -16
  55. package/dist/webgl.d.cts +1 -1
  56. package/dist/webgl.d.ts +1 -1
  57. package/package.json +11 -11
@@ -86,6 +86,7 @@ function buildTransformTemplate(axis) {
86
86
  return (offset) => `translate3d(${offset}px, 0, 0)`;
87
87
  }
88
88
  }
89
+ var offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
89
90
  var layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
90
91
 
91
92
  // src/core/primitives/instance-id.ts
@@ -1171,7 +1172,7 @@ var tween = ({
1171
1172
  }
1172
1173
  const step = (now) => {
1173
1174
  if (cancelled) return;
1174
- const elapsed = now - start;
1175
+ const elapsed = Math.max(0, now - start);
1175
1176
  const t = Math.min(elapsed / duration, 1);
1176
1177
  const value = from + (to - from) * easing(t);
1177
1178
  onUpdate(value);
@@ -1224,8 +1225,8 @@ var runSpring = ({
1224
1225
  resolveFn = resolve;
1225
1226
  const step = (now) => {
1226
1227
  if (cancelled) return;
1227
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1228
- lastTime = now;
1228
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1229
+ lastTime = Math.max(lastTime, now);
1229
1230
  const steps = Math.max(1, Math.ceil(dt * 240));
1230
1231
  const subDt = dt / steps;
1231
1232
  let stepsLeft = steps;
@@ -1289,6 +1290,7 @@ function resolveAnimationPreset(animation) {
1289
1290
  }
1290
1291
 
1291
1292
  // src/core/animation/waapi-settle.ts
1293
+ var SETTLE_ANIMATION_ID = "bs-settle";
1292
1294
  var SIM_HZ = 240;
1293
1295
  var SAMPLE_STRIDE = 4;
1294
1296
  var MAX_SIM_MS = 3e3;
@@ -1346,6 +1348,7 @@ var AnimationRunner = class {
1346
1348
  __publicField(this, "isDragging");
1347
1349
  __publicField(this, "applyAux");
1348
1350
  __publicField(this, "getTransformFor");
1351
+ __publicField(this, "readShownSize");
1349
1352
  __publicField(this, "settleWaapi");
1350
1353
  __publicField(this, "currentWaapi", null);
1351
1354
  __publicField(this, "animationKind");
@@ -1365,6 +1368,7 @@ var AnimationRunner = class {
1365
1368
  this.isDragging = deps.isDragging;
1366
1369
  this.applyAux = deps.applyAux;
1367
1370
  this.getTransformFor = deps.getTransformFor;
1371
+ this.readShownSize = deps.readShownSize;
1368
1372
  this.settleWaapi = opts.settleAnimation === "waapi";
1369
1373
  const preset = resolveAnimationPreset(opts.animation);
1370
1374
  this.animationKind = preset.kind;
@@ -1397,10 +1401,12 @@ var AnimationRunner = class {
1397
1401
  const entry = this.currentWaapi;
1398
1402
  this.currentWaapi = null;
1399
1403
  entry.stop();
1404
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1400
1405
  try {
1401
1406
  entry.anim.cancel();
1402
1407
  } catch {
1403
1408
  }
1409
+ this.applySizeFn(size);
1404
1410
  }
1405
1411
  cancel() {
1406
1412
  this.currentTween?.cancel();
@@ -1410,6 +1416,7 @@ var AnimationRunner = class {
1410
1416
  async animateTo(target, velocityPxPerMs) {
1411
1417
  if (target === this.getSize()) {
1412
1418
  if (!this.isAnimating && !this.isDragging()) {
1419
+ this.applySizeFn(target);
1413
1420
  this.element.style.willChange = "";
1414
1421
  }
1415
1422
  return;
@@ -1446,6 +1453,7 @@ var AnimationRunner = class {
1446
1453
  return;
1447
1454
  }
1448
1455
  }
1456
+ let current = false;
1449
1457
  if (this.animationKind === "spring") {
1450
1458
  const spring = runSpring({
1451
1459
  from: this.getSize(),
@@ -1456,7 +1464,8 @@ var AnimationRunner = class {
1456
1464
  });
1457
1465
  this.currentSpring = spring;
1458
1466
  await spring.promise;
1459
- if (this.currentSpring === spring) this.currentSpring = null;
1467
+ current = this.currentSpring === spring;
1468
+ if (current) this.currentSpring = null;
1460
1469
  } else {
1461
1470
  const tw = tween({
1462
1471
  from: this.getSize(),
@@ -1467,11 +1476,15 @@ var AnimationRunner = class {
1467
1476
  });
1468
1477
  this.currentTween = tw;
1469
1478
  await tw.promise;
1470
- if (this.currentTween === tw) this.currentTween = null;
1479
+ current = this.currentTween === tw;
1480
+ if (current) this.currentTween = null;
1471
1481
  }
1472
1482
  if (!this.isAnimating) {
1473
1483
  this.getRootEl()?.removeAttribute("data-animating");
1474
- if (!this.isDragging()) this.element.style.willChange = "";
1484
+ if (!this.isDragging()) {
1485
+ if (current) this.applySizeFn(this.getSize());
1486
+ this.element.style.willChange = "";
1487
+ }
1475
1488
  }
1476
1489
  }
1477
1490
  async runWaapiSettle(samples, target) {
@@ -1485,11 +1498,11 @@ var AnimationRunner = class {
1485
1498
  easing: "linear",
1486
1499
  fill: "forwards"
1487
1500
  });
1501
+ anim.id = SETTLE_ANIMATION_ID;
1488
1502
  let stopped = false;
1489
1503
  let auxRaf = 0;
1490
1504
  const lastIdx = samples.values.length - 1;
1491
- const auxTick = () => {
1492
- if (stopped) return;
1505
+ const sizeNow = () => {
1493
1506
  const at = Math.min(
1494
1507
  (Number(anim.currentTime) || 0) / samples.stepMs,
1495
1508
  lastIdx
@@ -1497,7 +1510,11 @@ var AnimationRunner = class {
1497
1510
  const idx = Math.floor(at);
1498
1511
  const from = samples.values[idx];
1499
1512
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1500
- applyAux(from + (to - from) * (at - idx));
1513
+ return from + (to - from) * (at - idx);
1514
+ };
1515
+ const auxTick = () => {
1516
+ if (stopped) return;
1517
+ applyAux(sizeNow());
1501
1518
  auxRaf = requestAnimationFrame(auxTick);
1502
1519
  };
1503
1520
  auxRaf = requestAnimationFrame(auxTick);
@@ -1506,7 +1523,8 @@ var AnimationRunner = class {
1506
1523
  stop: () => {
1507
1524
  stopped = true;
1508
1525
  cancelAnimationFrame(auxRaf);
1509
- }
1526
+ },
1527
+ sizeNow
1510
1528
  };
1511
1529
  this.currentWaapi = entry;
1512
1530
  try {
@@ -2609,6 +2627,7 @@ var BottomSheetCore = class {
2609
2627
  __publicField(this, "closeOnBack");
2610
2628
  __publicField(this, "routedTo");
2611
2629
  __publicField(this, "fitContentToSnap");
2630
+ __publicField(this, "settleAnimation");
2612
2631
  __publicField(this, "persistent");
2613
2632
  __publicField(this, "disableCloseFlag");
2614
2633
  __publicField(this, "disableDragFlag");
@@ -2713,6 +2732,11 @@ var BottomSheetCore = class {
2713
2732
  const cap = this.snaps.getMaxAxisSize();
2714
2733
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2715
2734
  return this.transformTemplate(cap - shown);
2735
+ },
2736
+ readShownSize: () => {
2737
+ const shown = getComputedStyle(this.element).transform;
2738
+ if (!shown || shown === "none") return void 0;
2739
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2716
2740
  }
2717
2741
  },
2718
2742
  resolved.animation
@@ -2727,6 +2751,7 @@ var BottomSheetCore = class {
2727
2751
  this.closeOnBack = resolved.closeOnBack;
2728
2752
  this.routedTo = opts.routedTo;
2729
2753
  this.fitContentToSnap = opts.fitContentToSnap === true;
2754
+ this.settleAnimation = opts.settleAnimation;
2730
2755
  this.persistent = resolved.persistent;
2731
2756
  this.disableCloseFlag = resolved.disableClose;
2732
2757
  this.disableDragFlag = resolved.disableDrag;
@@ -2829,7 +2854,8 @@ var BottomSheetCore = class {
2829
2854
  closeOnRouteChange: this.closeOnRouteChange,
2830
2855
  persistKey: this.persistKey,
2831
2856
  autoCollapseAfter,
2832
- fitContentToSnap: this.fitContentToSnap
2857
+ fitContentToSnap: this.fitContentToSnap,
2858
+ settleAnimation: this.settleAnimation
2833
2859
  },
2834
2860
  isDestroyed: () => this.destroyed,
2835
2861
  isDragging: () => this.isDraggingAny(),
@@ -3721,7 +3747,11 @@ var BottomSheetCore = class {
3721
3747
  const offset = cap - clamped;
3722
3748
  const style = this.element.style;
3723
3749
  if (!skipTransform) style.transform = this.transformTemplate(offset);
3724
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3750
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
3751
+ clamped,
3752
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
3753
+ );
3754
+ if (sizeChanged) {
3725
3755
  style.setProperty("--bs-size", `${clamped}px`);
3726
3756
  if (this.scrimParent) {
3727
3757
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -3748,7 +3778,7 @@ var BottomSheetCore = class {
3748
3778
  }
3749
3779
  }
3750
3780
  this.scrim.applyOpacity(progress, progressChanged);
3751
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
3781
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
3752
3782
  this.progressPayload.value = progress;
3753
3783
  this.progressPayload.size = clamped;
3754
3784
  this.emit("progress", this.progressPayload);
@@ -4245,7 +4275,6 @@ function visualViewportFeature() {
4245
4275
 
4246
4276
  // src/core/features/content-fit.ts
4247
4277
  var INSET_VAR = "--bs-content-inset";
4248
- var SIZE_VAR = "--bs-size";
4249
4278
  var CAP_VAR = "--bs-max-size";
4250
4279
  var LIFT_VAR = "--bs-footer-lift-max";
4251
4280
  var FIT_ATTR = "data-bs-fit-content";
@@ -4258,10 +4287,14 @@ function contentFitFeature() {
4258
4287
  return;
4259
4288
  }
4260
4289
  const sheet = ctx.element;
4290
+ const waapi = ctx.options.settleAnimation === "waapi";
4261
4291
  let inset = 0;
4262
4292
  let unpaddedMax = -1;
4263
4293
  let top = 0;
4264
4294
  let resting = false;
4295
+ let liftMax = 0;
4296
+ let followed = null;
4297
+ let follower = null;
4265
4298
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4266
4299
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4267
4300
  const follow = (size) => {
@@ -4275,8 +4308,45 @@ function contentFitFeature() {
4275
4308
  top = limit;
4276
4309
  }
4277
4310
  };
4311
+ const unfollow = () => {
4312
+ follower?.cancel();
4313
+ follower = null;
4314
+ followed = null;
4315
+ };
4316
+ const followSettle = () => {
4317
+ if (followed?.playState === "running") return;
4318
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4319
+ const footer = sheet.querySelector(".bs-footer");
4320
+ if (!settleAnim || !footer) return;
4321
+ const effect = settleAnim.effect;
4322
+ unfollow();
4323
+ const own = footer.animate(
4324
+ effect.getKeyframes().map((k) => ({
4325
+ offset: k.computedOffset,
4326
+ transform: `translateY(${-Math.min(
4327
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4328
+ liftMax
4329
+ )}px)`
4330
+ })),
4331
+ {
4332
+ duration: effect.getTiming().duration,
4333
+ easing: "linear",
4334
+ fill: "forwards"
4335
+ }
4336
+ );
4337
+ follower = own;
4338
+ followed = settleAnim;
4339
+ const done = () => {
4340
+ if (followed === settleAnim) unfollow();
4341
+ };
4342
+ settleAnim.ready.then(() => {
4343
+ if (follower === own) own.startTime = settleAnim.startTime;
4344
+ }, done);
4345
+ settleAnim.finished.then(done, done);
4346
+ };
4278
4347
  const settle = () => {
4279
4348
  if (ctx.isDestroyed()) return;
4349
+ unfollow();
4280
4350
  const size = ctx.getSize();
4281
4351
  if (!resting) {
4282
4352
  unpaddedMax = -1;
@@ -4284,7 +4354,6 @@ function contentFitFeature() {
4284
4354
  }
4285
4355
  inset = hiddenAt(size);
4286
4356
  put(INSET_VAR, inset);
4287
- put(SIZE_VAR, size);
4288
4357
  put(CAP_VAR, ctx.getMaxAxisSize());
4289
4358
  if (!resting) {
4290
4359
  resting = true;
@@ -4296,9 +4365,13 @@ function contentFitFeature() {
4296
4365
  if (resting) {
4297
4366
  resting = false;
4298
4367
  sheet.setAttribute(FIT_ATTR, "moving");
4299
- put(LIFT_VAR, scroller.offsetHeight);
4368
+ liftMax = scroller.offsetHeight;
4369
+ put(LIFT_VAR, liftMax);
4300
4370
  }
4301
4371
  follow(size);
4372
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4373
+ followSettle();
4374
+ }
4302
4375
  };
4303
4376
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4304
4377
  const whenIdle = () => {
@@ -4311,13 +4384,20 @@ function contentFitFeature() {
4311
4384
  );
4312
4385
  const offSnap = ctx.on("snap", settle);
4313
4386
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4387
+ const offBeforeSnap = ctx.on("before-snap", () => {
4388
+ queueMicrotask(() => {
4389
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4390
+ });
4391
+ });
4314
4392
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4315
4393
  observer?.observe(document.documentElement);
4316
4394
  window.addEventListener("orientationchange", whenIdle);
4317
4395
  return () => {
4396
+ unfollow();
4318
4397
  offProgress();
4319
4398
  offSnap();
4320
4399
  offDragStart();
4400
+ offBeforeSnap();
4321
4401
  observer?.disconnect();
4322
4402
  window.removeEventListener("orientationchange", whenIdle);
4323
4403
  sheet.removeAttribute(FIT_ATTR);
package/dist/svelte.cjs CHANGED
@@ -110,6 +110,7 @@ function buildTransformTemplate(axis) {
110
110
  return (offset) => `translate3d(${offset}px, 0, 0)`;
111
111
  }
112
112
  }
113
+ var offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
113
114
  var layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
114
115
 
115
116
  // src/core/primitives/instance-id.ts
@@ -1195,7 +1196,7 @@ var tween = ({
1195
1196
  }
1196
1197
  const step = (now) => {
1197
1198
  if (cancelled) return;
1198
- const elapsed = now - start;
1199
+ const elapsed = Math.max(0, now - start);
1199
1200
  const t = Math.min(elapsed / duration, 1);
1200
1201
  const value = from + (to - from) * easing(t);
1201
1202
  onUpdate(value);
@@ -1248,8 +1249,8 @@ var runSpring = ({
1248
1249
  resolveFn = resolve;
1249
1250
  const step = (now) => {
1250
1251
  if (cancelled) return;
1251
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1252
- lastTime = now;
1252
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1253
+ lastTime = Math.max(lastTime, now);
1253
1254
  const steps = Math.max(1, Math.ceil(dt * 240));
1254
1255
  const subDt = dt / steps;
1255
1256
  let stepsLeft = steps;
@@ -1313,6 +1314,7 @@ function resolveAnimationPreset(animation) {
1313
1314
  }
1314
1315
 
1315
1316
  // src/core/animation/waapi-settle.ts
1317
+ var SETTLE_ANIMATION_ID = "bs-settle";
1316
1318
  var SIM_HZ = 240;
1317
1319
  var SAMPLE_STRIDE = 4;
1318
1320
  var MAX_SIM_MS = 3e3;
@@ -1370,6 +1372,7 @@ var AnimationRunner = class {
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 @@ var AnimationRunner = class {
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;
@@ -1421,10 +1425,12 @@ var AnimationRunner = class {
1421
1425
  const entry = this.currentWaapi;
1422
1426
  this.currentWaapi = null;
1423
1427
  entry.stop();
1428
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1424
1429
  try {
1425
1430
  entry.anim.cancel();
1426
1431
  } catch {
1427
1432
  }
1433
+ this.applySizeFn(size);
1428
1434
  }
1429
1435
  cancel() {
1430
1436
  this.currentTween?.cancel();
@@ -1434,6 +1440,7 @@ var AnimationRunner = class {
1434
1440
  async animateTo(target, velocityPxPerMs) {
1435
1441
  if (target === this.getSize()) {
1436
1442
  if (!this.isAnimating && !this.isDragging()) {
1443
+ this.applySizeFn(target);
1437
1444
  this.element.style.willChange = "";
1438
1445
  }
1439
1446
  return;
@@ -1470,6 +1477,7 @@ var AnimationRunner = class {
1470
1477
  return;
1471
1478
  }
1472
1479
  }
1480
+ let current = false;
1473
1481
  if (this.animationKind === "spring") {
1474
1482
  const spring = runSpring({
1475
1483
  from: this.getSize(),
@@ -1480,7 +1488,8 @@ var AnimationRunner = class {
1480
1488
  });
1481
1489
  this.currentSpring = spring;
1482
1490
  await spring.promise;
1483
- if (this.currentSpring === spring) this.currentSpring = null;
1491
+ current = this.currentSpring === spring;
1492
+ if (current) this.currentSpring = null;
1484
1493
  } else {
1485
1494
  const tw = tween({
1486
1495
  from: this.getSize(),
@@ -1491,11 +1500,15 @@ var AnimationRunner = class {
1491
1500
  });
1492
1501
  this.currentTween = tw;
1493
1502
  await tw.promise;
1494
- if (this.currentTween === tw) this.currentTween = null;
1503
+ current = this.currentTween === tw;
1504
+ if (current) this.currentTween = null;
1495
1505
  }
1496
1506
  if (!this.isAnimating) {
1497
1507
  this.getRootEl()?.removeAttribute("data-animating");
1498
- if (!this.isDragging()) this.element.style.willChange = "";
1508
+ if (!this.isDragging()) {
1509
+ if (current) this.applySizeFn(this.getSize());
1510
+ this.element.style.willChange = "";
1511
+ }
1499
1512
  }
1500
1513
  }
1501
1514
  async runWaapiSettle(samples, target) {
@@ -1509,11 +1522,11 @@ var AnimationRunner = class {
1509
1522
  easing: "linear",
1510
1523
  fill: "forwards"
1511
1524
  });
1525
+ anim.id = SETTLE_ANIMATION_ID;
1512
1526
  let stopped = false;
1513
1527
  let auxRaf = 0;
1514
1528
  const lastIdx = samples.values.length - 1;
1515
- const auxTick = () => {
1516
- if (stopped) return;
1529
+ const sizeNow = () => {
1517
1530
  const at = Math.min(
1518
1531
  (Number(anim.currentTime) || 0) / samples.stepMs,
1519
1532
  lastIdx
@@ -1521,7 +1534,11 @@ var AnimationRunner = class {
1521
1534
  const idx = Math.floor(at);
1522
1535
  const from = samples.values[idx];
1523
1536
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1524
- applyAux(from + (to - from) * (at - idx));
1537
+ return from + (to - from) * (at - idx);
1538
+ };
1539
+ const auxTick = () => {
1540
+ if (stopped) return;
1541
+ applyAux(sizeNow());
1525
1542
  auxRaf = requestAnimationFrame(auxTick);
1526
1543
  };
1527
1544
  auxRaf = requestAnimationFrame(auxTick);
@@ -1530,7 +1547,8 @@ var AnimationRunner = class {
1530
1547
  stop: () => {
1531
1548
  stopped = true;
1532
1549
  cancelAnimationFrame(auxRaf);
1533
- }
1550
+ },
1551
+ sizeNow
1534
1552
  };
1535
1553
  this.currentWaapi = entry;
1536
1554
  try {
@@ -2633,6 +2651,7 @@ var BottomSheetCore = class {
2633
2651
  __publicField(this, "closeOnBack");
2634
2652
  __publicField(this, "routedTo");
2635
2653
  __publicField(this, "fitContentToSnap");
2654
+ __publicField(this, "settleAnimation");
2636
2655
  __publicField(this, "persistent");
2637
2656
  __publicField(this, "disableCloseFlag");
2638
2657
  __publicField(this, "disableDragFlag");
@@ -2737,6 +2756,11 @@ var BottomSheetCore = class {
2737
2756
  const cap = this.snaps.getMaxAxisSize();
2738
2757
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2739
2758
  return this.transformTemplate(cap - shown);
2759
+ },
2760
+ readShownSize: () => {
2761
+ const shown = getComputedStyle(this.element).transform;
2762
+ if (!shown || shown === "none") return void 0;
2763
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2740
2764
  }
2741
2765
  },
2742
2766
  resolved.animation
@@ -2751,6 +2775,7 @@ var BottomSheetCore = class {
2751
2775
  this.closeOnBack = resolved.closeOnBack;
2752
2776
  this.routedTo = opts.routedTo;
2753
2777
  this.fitContentToSnap = opts.fitContentToSnap === true;
2778
+ this.settleAnimation = opts.settleAnimation;
2754
2779
  this.persistent = resolved.persistent;
2755
2780
  this.disableCloseFlag = resolved.disableClose;
2756
2781
  this.disableDragFlag = resolved.disableDrag;
@@ -2853,7 +2878,8 @@ var BottomSheetCore = class {
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(),
@@ -3745,7 +3771,11 @@ var BottomSheetCore = class {
3745
3771
  const offset = cap - clamped;
3746
3772
  const style = this.element.style;
3747
3773
  if (!skipTransform) style.transform = this.transformTemplate(offset);
3748
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3774
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
3775
+ clamped,
3776
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
3777
+ );
3778
+ if (sizeChanged) {
3749
3779
  style.setProperty("--bs-size", `${clamped}px`);
3750
3780
  if (this.scrimParent) {
3751
3781
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -3772,7 +3802,7 @@ var BottomSheetCore = class {
3772
3802
  }
3773
3803
  }
3774
3804
  this.scrim.applyOpacity(progress, progressChanged);
3775
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
3805
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
3776
3806
  this.progressPayload.value = progress;
3777
3807
  this.progressPayload.size = clamped;
3778
3808
  this.emit("progress", this.progressPayload);
@@ -4269,7 +4299,6 @@ function visualViewportFeature() {
4269
4299
 
4270
4300
  // src/core/features/content-fit.ts
4271
4301
  var INSET_VAR = "--bs-content-inset";
4272
- var SIZE_VAR = "--bs-size";
4273
4302
  var CAP_VAR = "--bs-max-size";
4274
4303
  var LIFT_VAR = "--bs-footer-lift-max";
4275
4304
  var FIT_ATTR = "data-bs-fit-content";
@@ -4282,10 +4311,14 @@ function contentFitFeature() {
4282
4311
  return;
4283
4312
  }
4284
4313
  const sheet = ctx.element;
4314
+ const waapi = ctx.options.settleAnimation === "waapi";
4285
4315
  let inset = 0;
4286
4316
  let unpaddedMax = -1;
4287
4317
  let top = 0;
4288
4318
  let resting = false;
4319
+ let liftMax = 0;
4320
+ let followed = null;
4321
+ let follower = null;
4289
4322
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4290
4323
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4291
4324
  const follow = (size) => {
@@ -4299,8 +4332,45 @@ function contentFitFeature() {
4299
4332
  top = limit;
4300
4333
  }
4301
4334
  };
4335
+ const unfollow = () => {
4336
+ follower?.cancel();
4337
+ follower = null;
4338
+ followed = null;
4339
+ };
4340
+ const followSettle = () => {
4341
+ if (followed?.playState === "running") return;
4342
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4343
+ const footer = sheet.querySelector(".bs-footer");
4344
+ if (!settleAnim || !footer) return;
4345
+ const effect = settleAnim.effect;
4346
+ unfollow();
4347
+ const own = footer.animate(
4348
+ effect.getKeyframes().map((k) => ({
4349
+ offset: k.computedOffset,
4350
+ transform: `translateY(${-Math.min(
4351
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4352
+ liftMax
4353
+ )}px)`
4354
+ })),
4355
+ {
4356
+ duration: effect.getTiming().duration,
4357
+ easing: "linear",
4358
+ fill: "forwards"
4359
+ }
4360
+ );
4361
+ follower = own;
4362
+ followed = settleAnim;
4363
+ const done = () => {
4364
+ if (followed === settleAnim) unfollow();
4365
+ };
4366
+ settleAnim.ready.then(() => {
4367
+ if (follower === own) own.startTime = settleAnim.startTime;
4368
+ }, done);
4369
+ settleAnim.finished.then(done, done);
4370
+ };
4302
4371
  const settle = () => {
4303
4372
  if (ctx.isDestroyed()) return;
4373
+ unfollow();
4304
4374
  const size = ctx.getSize();
4305
4375
  if (!resting) {
4306
4376
  unpaddedMax = -1;
@@ -4308,7 +4378,6 @@ function contentFitFeature() {
4308
4378
  }
4309
4379
  inset = hiddenAt(size);
4310
4380
  put(INSET_VAR, inset);
4311
- put(SIZE_VAR, size);
4312
4381
  put(CAP_VAR, ctx.getMaxAxisSize());
4313
4382
  if (!resting) {
4314
4383
  resting = true;
@@ -4320,9 +4389,13 @@ function contentFitFeature() {
4320
4389
  if (resting) {
4321
4390
  resting = false;
4322
4391
  sheet.setAttribute(FIT_ATTR, "moving");
4323
- put(LIFT_VAR, scroller.offsetHeight);
4392
+ liftMax = scroller.offsetHeight;
4393
+ put(LIFT_VAR, liftMax);
4324
4394
  }
4325
4395
  follow(size);
4396
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4397
+ followSettle();
4398
+ }
4326
4399
  };
4327
4400
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4328
4401
  const whenIdle = () => {
@@ -4335,13 +4408,20 @@ function contentFitFeature() {
4335
4408
  );
4336
4409
  const offSnap = ctx.on("snap", settle);
4337
4410
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4411
+ const offBeforeSnap = ctx.on("before-snap", () => {
4412
+ queueMicrotask(() => {
4413
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4414
+ });
4415
+ });
4338
4416
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4339
4417
  observer?.observe(document.documentElement);
4340
4418
  window.addEventListener("orientationchange", whenIdle);
4341
4419
  return () => {
4420
+ unfollow();
4342
4421
  offProgress();
4343
4422
  offSnap();
4344
4423
  offDragStart();
4424
+ offBeforeSnap();
4345
4425
  observer?.disconnect();
4346
4426
  window.removeEventListener("orientationchange", whenIdle);
4347
4427
  sheet.removeAttribute(FIT_ATTR);