@surdeddd/bottom-sheet 0.23.2 → 0.23.4

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 (62) hide show
  1. package/README.md +18 -16
  2. package/README.ru.md +697 -0
  3. package/dist/{BottomSheetCore-CQStdVy2.d.cts → BottomSheetCore-C5tJYVMY.d.cts} +4 -1
  4. package/dist/{BottomSheetCore-9i-Uh6T3.d.ts → BottomSheetCore-DxSrC4QC.d.ts} +4 -1
  5. package/dist/{BottomSheetEngine-CsQWHLNb.d.cts → BottomSheetEngine-B3F9qukX.d.cts} +1 -1
  6. package/dist/{BottomSheetEngine-Dn6h-7gF.d.ts → BottomSheetEngine-BchzgqGG.d.ts} +1 -1
  7. package/dist/core.cjs +43 -13
  8. package/dist/core.d.cts +2 -2
  9. package/dist/core.d.ts +2 -2
  10. package/dist/core.js +43 -13
  11. package/dist/debug.d.cts +3 -2
  12. package/dist/debug.d.ts +3 -2
  13. package/dist/{default-features-DkG9aho0.d.cts → default-features-BGiCSmV1.d.cts} +1 -1
  14. package/dist/{default-features-C3cilcW9.d.ts → default-features-DwVTzDwP.d.ts} +1 -1
  15. package/dist/element.cjs +107 -21
  16. package/dist/element.d.cts +5 -3
  17. package/dist/element.d.ts +5 -3
  18. package/dist/element.iife.global.js +2 -2
  19. package/dist/element.js +107 -21
  20. package/dist/features.cjs +56 -3
  21. package/dist/features.d.cts +3 -3
  22. package/dist/features.d.ts +3 -3
  23. package/dist/features.js +56 -3
  24. package/dist/{index-CnsJQZp2.d.ts → index-C7TSQkVK.d.cts} +3 -2
  25. package/dist/{index-CVGC5B5D.d.cts → index-CdM1tke5.d.ts} +3 -2
  26. package/dist/index.cjs +96 -16
  27. package/dist/index.d.cts +7 -6
  28. package/dist/index.d.ts +7 -6
  29. package/dist/index.js +96 -16
  30. package/dist/integrations/formik.d.cts +3 -2
  31. package/dist/integrations/formik.d.ts +3 -2
  32. package/dist/integrations/react-hook-form.d.cts +3 -2
  33. package/dist/integrations/react-hook-form.d.ts +3 -2
  34. package/dist/overlay.d.cts +2 -1
  35. package/dist/overlay.d.ts +2 -1
  36. package/dist/preact.d.cts +2 -2
  37. package/dist/preact.d.ts +2 -2
  38. package/dist/qwik-lib/index.qwik.cjs +87 -16
  39. package/dist/qwik-lib/index.qwik.mjs +87 -16
  40. package/dist/qwik.cjs +96 -16
  41. package/dist/qwik.d.cts +5 -3
  42. package/dist/qwik.d.ts +5 -3
  43. package/dist/qwik.js +96 -16
  44. package/dist/react.cjs +96 -16
  45. package/dist/react.d.cts +8 -5
  46. package/dist/react.d.ts +8 -5
  47. package/dist/react.js +96 -16
  48. package/dist/solid.cjs +96 -16
  49. package/dist/solid.d.cts +4 -1
  50. package/dist/solid.d.ts +4 -1
  51. package/dist/solid.js +96 -16
  52. package/dist/solid.source.jsx +96 -16
  53. package/dist/svelte-core.cjs +98 -16
  54. package/dist/svelte-core.js +97 -17
  55. package/dist/svelte-src/BottomSheet.svelte +1 -1
  56. package/dist/svelte.cjs +97 -18
  57. package/dist/svelte.js +97 -18
  58. package/dist/vue.cjs +96 -16
  59. package/dist/vue.js +96 -16
  60. package/dist/webgl.d.cts +3 -2
  61. package/dist/webgl.d.ts +3 -2
  62. package/package.json +32 -34
package/dist/element.js CHANGED
@@ -1,8 +1,13 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
- var __esm = (fn, res) => function __init() {
5
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
4
+ var __esm = (fn, res, err) => function __init() {
5
+ if (err) throw err[0];
6
+ try {
7
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ } catch (e) {
9
+ throw err = [e], e;
10
+ }
6
11
  };
7
12
  var __export = (target, all) => {
8
13
  for (var name in all)
@@ -97,9 +102,10 @@ function buildTransformTemplate(axis) {
97
102
  return (offset) => `translate3d(${offset}px, 0, 0)`;
98
103
  }
99
104
  }
100
- var layoutAxis;
105
+ var offsetFromMatrix, layoutAxis;
101
106
  var init_transform = __esm({
102
107
  "src/core/primitives/transform.ts"() {
108
+ offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
103
109
  layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
104
110
  }
105
111
  });
@@ -1286,7 +1292,7 @@ var init_animation = __esm({
1286
1292
  }
1287
1293
  const step = (now) => {
1288
1294
  if (cancelled) return;
1289
- const elapsed = now - start;
1295
+ const elapsed = Math.max(0, now - start);
1290
1296
  const t = Math.min(elapsed / duration, 1);
1291
1297
  const value = from + (to - from) * easing(t);
1292
1298
  onUpdate(value);
@@ -1344,8 +1350,8 @@ var init_spring = __esm({
1344
1350
  resolveFn = resolve;
1345
1351
  const step = (now) => {
1346
1352
  if (cancelled) return;
1347
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1348
- lastTime = now;
1353
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1354
+ lastTime = Math.max(lastTime, now);
1349
1355
  const steps = Math.max(1, Math.ceil(dt * 240));
1350
1356
  const subDt = dt / steps;
1351
1357
  let stepsLeft = steps;
@@ -1458,10 +1464,11 @@ function sampleTweenSettle(from, to, durationMs, easing) {
1458
1464
  durationMs
1459
1465
  };
1460
1466
  }
1461
- var SIM_HZ, SAMPLE_STRIDE, MAX_SIM_MS;
1467
+ var SETTLE_ANIMATION_ID, SIM_HZ, SAMPLE_STRIDE, MAX_SIM_MS;
1462
1468
  var init_waapi_settle = __esm({
1463
1469
  "src/core/animation/waapi-settle.ts"() {
1464
1470
  init_spring();
1471
+ SETTLE_ANIMATION_ID = "bs-settle";
1465
1472
  SIM_HZ = 240;
1466
1473
  SAMPLE_STRIDE = 4;
1467
1474
  MAX_SIM_MS = 3e3;
@@ -1487,6 +1494,7 @@ var init_animation_runner = __esm({
1487
1494
  __publicField(this, "isDragging");
1488
1495
  __publicField(this, "applyAux");
1489
1496
  __publicField(this, "getTransformFor");
1497
+ __publicField(this, "readShownSize");
1490
1498
  __publicField(this, "settleWaapi");
1491
1499
  __publicField(this, "currentWaapi", null);
1492
1500
  __publicField(this, "animationKind");
@@ -1506,6 +1514,7 @@ var init_animation_runner = __esm({
1506
1514
  this.isDragging = deps.isDragging;
1507
1515
  this.applyAux = deps.applyAux;
1508
1516
  this.getTransformFor = deps.getTransformFor;
1517
+ this.readShownSize = deps.readShownSize;
1509
1518
  this.settleWaapi = opts.settleAnimation === "waapi";
1510
1519
  const preset = resolveAnimationPreset(opts.animation);
1511
1520
  this.animationKind = preset.kind;
@@ -1538,10 +1547,12 @@ var init_animation_runner = __esm({
1538
1547
  const entry = this.currentWaapi;
1539
1548
  this.currentWaapi = null;
1540
1549
  entry.stop();
1550
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1541
1551
  try {
1542
1552
  entry.anim.cancel();
1543
1553
  } catch {
1544
1554
  }
1555
+ this.applySizeFn(size);
1545
1556
  }
1546
1557
  cancel() {
1547
1558
  this.currentTween?.cancel();
@@ -1551,6 +1562,7 @@ var init_animation_runner = __esm({
1551
1562
  async animateTo(target, velocityPxPerMs) {
1552
1563
  if (target === this.getSize()) {
1553
1564
  if (!this.isAnimating && !this.isDragging()) {
1565
+ this.applySizeFn(target);
1554
1566
  this.element.style.willChange = "";
1555
1567
  }
1556
1568
  return;
@@ -1587,6 +1599,7 @@ var init_animation_runner = __esm({
1587
1599
  return;
1588
1600
  }
1589
1601
  }
1602
+ let current = false;
1590
1603
  if (this.animationKind === "spring") {
1591
1604
  const spring = runSpring({
1592
1605
  from: this.getSize(),
@@ -1597,7 +1610,8 @@ var init_animation_runner = __esm({
1597
1610
  });
1598
1611
  this.currentSpring = spring;
1599
1612
  await spring.promise;
1600
- if (this.currentSpring === spring) this.currentSpring = null;
1613
+ current = this.currentSpring === spring;
1614
+ if (current) this.currentSpring = null;
1601
1615
  } else {
1602
1616
  const tw = tween({
1603
1617
  from: this.getSize(),
@@ -1608,11 +1622,15 @@ var init_animation_runner = __esm({
1608
1622
  });
1609
1623
  this.currentTween = tw;
1610
1624
  await tw.promise;
1611
- if (this.currentTween === tw) this.currentTween = null;
1625
+ current = this.currentTween === tw;
1626
+ if (current) this.currentTween = null;
1612
1627
  }
1613
1628
  if (!this.isAnimating) {
1614
1629
  this.getRootEl()?.removeAttribute("data-animating");
1615
- if (!this.isDragging()) this.element.style.willChange = "";
1630
+ if (!this.isDragging()) {
1631
+ if (current) this.applySizeFn(this.getSize());
1632
+ this.element.style.willChange = "";
1633
+ }
1616
1634
  }
1617
1635
  }
1618
1636
  async runWaapiSettle(samples, target) {
@@ -1626,11 +1644,11 @@ var init_animation_runner = __esm({
1626
1644
  easing: "linear",
1627
1645
  fill: "forwards"
1628
1646
  });
1647
+ anim.id = SETTLE_ANIMATION_ID;
1629
1648
  let stopped = false;
1630
1649
  let auxRaf = 0;
1631
1650
  const lastIdx = samples.values.length - 1;
1632
- const auxTick = () => {
1633
- if (stopped) return;
1651
+ const sizeNow = () => {
1634
1652
  const at = Math.min(
1635
1653
  (Number(anim.currentTime) || 0) / samples.stepMs,
1636
1654
  lastIdx
@@ -1638,7 +1656,11 @@ var init_animation_runner = __esm({
1638
1656
  const idx = Math.floor(at);
1639
1657
  const from = samples.values[idx];
1640
1658
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1641
- applyAux(from + (to - from) * (at - idx));
1659
+ return from + (to - from) * (at - idx);
1660
+ };
1661
+ const auxTick = () => {
1662
+ if (stopped) return;
1663
+ applyAux(sizeNow());
1642
1664
  auxRaf = requestAnimationFrame(auxTick);
1643
1665
  };
1644
1666
  auxRaf = requestAnimationFrame(auxTick);
@@ -1647,7 +1669,8 @@ var init_animation_runner = __esm({
1647
1669
  stop: () => {
1648
1670
  stopped = true;
1649
1671
  cancelAnimationFrame(auxRaf);
1650
- }
1672
+ },
1673
+ sizeNow
1651
1674
  };
1652
1675
  this.currentWaapi = entry;
1653
1676
  try {
@@ -2886,6 +2909,7 @@ var init_BottomSheetCore = __esm({
2886
2909
  __publicField(this, "closeOnBack");
2887
2910
  __publicField(this, "routedTo");
2888
2911
  __publicField(this, "fitContentToSnap");
2912
+ __publicField(this, "settleAnimation");
2889
2913
  __publicField(this, "persistent");
2890
2914
  __publicField(this, "disableCloseFlag");
2891
2915
  __publicField(this, "disableDragFlag");
@@ -2990,6 +3014,11 @@ var init_BottomSheetCore = __esm({
2990
3014
  const cap = this.snaps.getMaxAxisSize();
2991
3015
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2992
3016
  return this.transformTemplate(cap - shown);
3017
+ },
3018
+ readShownSize: () => {
3019
+ const shown = getComputedStyle(this.element).transform;
3020
+ if (!shown || shown === "none") return void 0;
3021
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2993
3022
  }
2994
3023
  },
2995
3024
  resolved.animation
@@ -3004,6 +3033,7 @@ var init_BottomSheetCore = __esm({
3004
3033
  this.closeOnBack = resolved.closeOnBack;
3005
3034
  this.routedTo = opts.routedTo;
3006
3035
  this.fitContentToSnap = opts.fitContentToSnap === true;
3036
+ this.settleAnimation = opts.settleAnimation;
3007
3037
  this.persistent = resolved.persistent;
3008
3038
  this.disableCloseFlag = resolved.disableClose;
3009
3039
  this.disableDragFlag = resolved.disableDrag;
@@ -3106,7 +3136,8 @@ var init_BottomSheetCore = __esm({
3106
3136
  closeOnRouteChange: this.closeOnRouteChange,
3107
3137
  persistKey: this.persistKey,
3108
3138
  autoCollapseAfter,
3109
- fitContentToSnap: this.fitContentToSnap
3139
+ fitContentToSnap: this.fitContentToSnap,
3140
+ settleAnimation: this.settleAnimation
3110
3141
  },
3111
3142
  isDestroyed: () => this.destroyed,
3112
3143
  isDragging: () => this.isDraggingAny(),
@@ -3998,7 +4029,11 @@ var init_BottomSheetCore = __esm({
3998
4029
  const offset = cap - clamped;
3999
4030
  const style = this.element.style;
4000
4031
  if (!skipTransform) style.transform = this.transformTemplate(offset);
4001
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
4032
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
4033
+ clamped,
4034
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
4035
+ );
4036
+ if (sizeChanged) {
4002
4037
  style.setProperty("--bs-size", `${clamped}px`);
4003
4038
  if (this.scrimParent) {
4004
4039
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -4025,7 +4060,7 @@ var init_BottomSheetCore = __esm({
4025
4060
  }
4026
4061
  }
4027
4062
  this.scrim.applyOpacity(progress, progressChanged);
4028
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
4063
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
4029
4064
  this.progressPayload.value = progress;
4030
4065
  this.progressPayload.size = clamped;
4031
4066
  this.emit("progress", this.progressPayload);
@@ -4569,10 +4604,14 @@ function contentFitFeature() {
4569
4604
  return;
4570
4605
  }
4571
4606
  const sheet = ctx.element;
4607
+ const waapi = ctx.options.settleAnimation === "waapi";
4572
4608
  let inset = 0;
4573
4609
  let unpaddedMax = -1;
4574
4610
  let top = 0;
4575
4611
  let resting = false;
4612
+ let liftMax = 0;
4613
+ let followed = null;
4614
+ let follower = null;
4576
4615
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4577
4616
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4578
4617
  const follow = (size) => {
@@ -4586,8 +4625,45 @@ function contentFitFeature() {
4586
4625
  top = limit;
4587
4626
  }
4588
4627
  };
4628
+ const unfollow = () => {
4629
+ follower?.cancel();
4630
+ follower = null;
4631
+ followed = null;
4632
+ };
4633
+ const followSettle = () => {
4634
+ if (followed?.playState === "running") return;
4635
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4636
+ const footer = sheet.querySelector(".bs-footer");
4637
+ if (!settleAnim || !footer) return;
4638
+ const effect = settleAnim.effect;
4639
+ unfollow();
4640
+ const own = footer.animate(
4641
+ effect.getKeyframes().map((k) => ({
4642
+ offset: k.computedOffset,
4643
+ transform: `translateY(${-Math.min(
4644
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4645
+ liftMax
4646
+ )}px)`
4647
+ })),
4648
+ {
4649
+ duration: effect.getTiming().duration,
4650
+ easing: "linear",
4651
+ fill: "forwards"
4652
+ }
4653
+ );
4654
+ follower = own;
4655
+ followed = settleAnim;
4656
+ const done = () => {
4657
+ if (followed === settleAnim) unfollow();
4658
+ };
4659
+ settleAnim.ready.then(() => {
4660
+ if (follower === own) own.startTime = settleAnim.startTime;
4661
+ }, done);
4662
+ settleAnim.finished.then(done, done);
4663
+ };
4589
4664
  const settle = () => {
4590
4665
  if (ctx.isDestroyed()) return;
4666
+ unfollow();
4591
4667
  const size = ctx.getSize();
4592
4668
  if (!resting) {
4593
4669
  unpaddedMax = -1;
@@ -4595,7 +4671,6 @@ function contentFitFeature() {
4595
4671
  }
4596
4672
  inset = hiddenAt(size);
4597
4673
  put(INSET_VAR, inset);
4598
- put(SIZE_VAR, size);
4599
4674
  put(CAP_VAR, ctx.getMaxAxisSize());
4600
4675
  if (!resting) {
4601
4676
  resting = true;
@@ -4607,9 +4682,13 @@ function contentFitFeature() {
4607
4682
  if (resting) {
4608
4683
  resting = false;
4609
4684
  sheet.setAttribute(FIT_ATTR, "moving");
4610
- put(LIFT_VAR, scroller.offsetHeight);
4685
+ liftMax = scroller.offsetHeight;
4686
+ put(LIFT_VAR, liftMax);
4611
4687
  }
4612
4688
  follow(size);
4689
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4690
+ followSettle();
4691
+ }
4613
4692
  };
4614
4693
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4615
4694
  const whenIdle = () => {
@@ -4622,13 +4701,20 @@ function contentFitFeature() {
4622
4701
  );
4623
4702
  const offSnap = ctx.on("snap", settle);
4624
4703
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4704
+ const offBeforeSnap = ctx.on("before-snap", () => {
4705
+ queueMicrotask(() => {
4706
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4707
+ });
4708
+ });
4625
4709
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4626
4710
  observer?.observe(document.documentElement);
4627
4711
  window.addEventListener("orientationchange", whenIdle);
4628
4712
  return () => {
4713
+ unfollow();
4629
4714
  offProgress();
4630
4715
  offSnap();
4631
4716
  offDragStart();
4717
+ offBeforeSnap();
4632
4718
  observer?.disconnect();
4633
4719
  window.removeEventListener("orientationchange", whenIdle);
4634
4720
  sheet.removeAttribute(FIT_ATTR);
@@ -4639,11 +4725,11 @@ function contentFitFeature() {
4639
4725
  }
4640
4726
  };
4641
4727
  }
4642
- var INSET_VAR, SIZE_VAR, CAP_VAR, LIFT_VAR, FIT_ATTR;
4728
+ var INSET_VAR, CAP_VAR, LIFT_VAR, FIT_ATTR;
4643
4729
  var init_content_fit = __esm({
4644
4730
  "src/core/features/content-fit.ts"() {
4731
+ init_waapi_settle();
4645
4732
  INSET_VAR = "--bs-content-inset";
4646
- SIZE_VAR = "--bs-size";
4647
4733
  CAP_VAR = "--bs-max-size";
4648
4734
  LIFT_VAR = "--bs-footer-lift-max";
4649
4735
  FIT_ATTR = "data-bs-fit-content";
package/dist/features.cjs CHANGED
@@ -468,9 +468,11 @@ function visualViewportFeature() {
468
468
  };
469
469
  }
470
470
 
471
+ // src/core/animation/waapi-settle.ts
472
+ var SETTLE_ANIMATION_ID = "bs-settle";
473
+
471
474
  // src/core/features/content-fit.ts
472
475
  var INSET_VAR = "--bs-content-inset";
473
- var SIZE_VAR = "--bs-size";
474
476
  var CAP_VAR = "--bs-max-size";
475
477
  var LIFT_VAR = "--bs-footer-lift-max";
476
478
  var FIT_ATTR = "data-bs-fit-content";
@@ -483,10 +485,14 @@ function contentFitFeature() {
483
485
  return;
484
486
  }
485
487
  const sheet = ctx.element;
488
+ const waapi = ctx.options.settleAnimation === "waapi";
486
489
  let inset = 0;
487
490
  let unpaddedMax = -1;
488
491
  let top = 0;
489
492
  let resting = false;
493
+ let liftMax = 0;
494
+ let followed = null;
495
+ let follower = null;
490
496
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
491
497
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
492
498
  const follow = (size) => {
@@ -500,8 +506,45 @@ function contentFitFeature() {
500
506
  top = limit;
501
507
  }
502
508
  };
509
+ const unfollow = () => {
510
+ follower?.cancel();
511
+ follower = null;
512
+ followed = null;
513
+ };
514
+ const followSettle = () => {
515
+ if (followed?.playState === "running") return;
516
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
517
+ const footer = sheet.querySelector(".bs-footer");
518
+ if (!settleAnim || !footer) return;
519
+ const effect = settleAnim.effect;
520
+ unfollow();
521
+ const own = footer.animate(
522
+ effect.getKeyframes().map((k) => ({
523
+ offset: k.computedOffset,
524
+ transform: `translateY(${-Math.min(
525
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
526
+ liftMax
527
+ )}px)`
528
+ })),
529
+ {
530
+ duration: effect.getTiming().duration,
531
+ easing: "linear",
532
+ fill: "forwards"
533
+ }
534
+ );
535
+ follower = own;
536
+ followed = settleAnim;
537
+ const done = () => {
538
+ if (followed === settleAnim) unfollow();
539
+ };
540
+ settleAnim.ready.then(() => {
541
+ if (follower === own) own.startTime = settleAnim.startTime;
542
+ }, done);
543
+ settleAnim.finished.then(done, done);
544
+ };
503
545
  const settle = () => {
504
546
  if (ctx.isDestroyed()) return;
547
+ unfollow();
505
548
  const size = ctx.getSize();
506
549
  if (!resting) {
507
550
  unpaddedMax = -1;
@@ -509,7 +552,6 @@ function contentFitFeature() {
509
552
  }
510
553
  inset = hiddenAt(size);
511
554
  put(INSET_VAR, inset);
512
- put(SIZE_VAR, size);
513
555
  put(CAP_VAR, ctx.getMaxAxisSize());
514
556
  if (!resting) {
515
557
  resting = true;
@@ -521,9 +563,13 @@ function contentFitFeature() {
521
563
  if (resting) {
522
564
  resting = false;
523
565
  sheet.setAttribute(FIT_ATTR, "moving");
524
- put(LIFT_VAR, scroller.offsetHeight);
566
+ liftMax = scroller.offsetHeight;
567
+ put(LIFT_VAR, liftMax);
525
568
  }
526
569
  follow(size);
570
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
571
+ followSettle();
572
+ }
527
573
  };
528
574
  const moving = () => ctx.isAnimating() || ctx.isDragging();
529
575
  const whenIdle = () => {
@@ -536,13 +582,20 @@ function contentFitFeature() {
536
582
  );
537
583
  const offSnap = ctx.on("snap", settle);
538
584
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
585
+ const offBeforeSnap = ctx.on("before-snap", () => {
586
+ queueMicrotask(() => {
587
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
588
+ });
589
+ });
539
590
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
540
591
  observer?.observe(document.documentElement);
541
592
  window.addEventListener("orientationchange", whenIdle);
542
593
  return () => {
594
+ unfollow();
543
595
  offProgress();
544
596
  offSnap();
545
597
  offDragStart();
598
+ offBeforeSnap();
546
599
  observer?.disconnect();
547
600
  window.removeEventListener("orientationchange", whenIdle);
548
601
  sheet.removeAttribute(FIT_ATTR);
@@ -1,6 +1,6 @@
1
- export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-DkG9aho0.cjs';
2
- import { E as EngineFeature } from './BottomSheetCore-CQStdVy2.cjs';
3
- export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-CQStdVy2.cjs';
1
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-BGiCSmV1.cjs';
2
+ import { E as EngineFeature } from './BottomSheetCore-C5tJYVMY.cjs';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-C5tJYVMY.cjs';
4
4
  import './transform-jVfAikE9.cjs';
5
5
 
6
6
  declare function contentFitFeature(): EngineFeature;
@@ -1,6 +1,6 @@
1
- export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-C3cilcW9.js';
2
- import { E as EngineFeature } from './BottomSheetCore-9i-Uh6T3.js';
3
- export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-9i-Uh6T3.js';
1
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-DwVTzDwP.js';
2
+ import { E as EngineFeature } from './BottomSheetCore-DxSrC4QC.js';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-DxSrC4QC.js';
4
4
  import './transform-jVfAikE9.js';
5
5
 
6
6
  declare function contentFitFeature(): EngineFeature;
package/dist/features.js CHANGED
@@ -466,9 +466,11 @@ function visualViewportFeature() {
466
466
  };
467
467
  }
468
468
 
469
+ // src/core/animation/waapi-settle.ts
470
+ var SETTLE_ANIMATION_ID = "bs-settle";
471
+
469
472
  // src/core/features/content-fit.ts
470
473
  var INSET_VAR = "--bs-content-inset";
471
- var SIZE_VAR = "--bs-size";
472
474
  var CAP_VAR = "--bs-max-size";
473
475
  var LIFT_VAR = "--bs-footer-lift-max";
474
476
  var FIT_ATTR = "data-bs-fit-content";
@@ -481,10 +483,14 @@ function contentFitFeature() {
481
483
  return;
482
484
  }
483
485
  const sheet = ctx.element;
486
+ const waapi = ctx.options.settleAnimation === "waapi";
484
487
  let inset = 0;
485
488
  let unpaddedMax = -1;
486
489
  let top = 0;
487
490
  let resting = false;
491
+ let liftMax = 0;
492
+ let followed = null;
493
+ let follower = null;
488
494
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
489
495
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
490
496
  const follow = (size) => {
@@ -498,8 +504,45 @@ function contentFitFeature() {
498
504
  top = limit;
499
505
  }
500
506
  };
507
+ const unfollow = () => {
508
+ follower?.cancel();
509
+ follower = null;
510
+ followed = null;
511
+ };
512
+ const followSettle = () => {
513
+ if (followed?.playState === "running") return;
514
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
515
+ const footer = sheet.querySelector(".bs-footer");
516
+ if (!settleAnim || !footer) return;
517
+ const effect = settleAnim.effect;
518
+ unfollow();
519
+ const own = footer.animate(
520
+ effect.getKeyframes().map((k) => ({
521
+ offset: k.computedOffset,
522
+ transform: `translateY(${-Math.min(
523
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
524
+ liftMax
525
+ )}px)`
526
+ })),
527
+ {
528
+ duration: effect.getTiming().duration,
529
+ easing: "linear",
530
+ fill: "forwards"
531
+ }
532
+ );
533
+ follower = own;
534
+ followed = settleAnim;
535
+ const done = () => {
536
+ if (followed === settleAnim) unfollow();
537
+ };
538
+ settleAnim.ready.then(() => {
539
+ if (follower === own) own.startTime = settleAnim.startTime;
540
+ }, done);
541
+ settleAnim.finished.then(done, done);
542
+ };
501
543
  const settle = () => {
502
544
  if (ctx.isDestroyed()) return;
545
+ unfollow();
503
546
  const size = ctx.getSize();
504
547
  if (!resting) {
505
548
  unpaddedMax = -1;
@@ -507,7 +550,6 @@ function contentFitFeature() {
507
550
  }
508
551
  inset = hiddenAt(size);
509
552
  put(INSET_VAR, inset);
510
- put(SIZE_VAR, size);
511
553
  put(CAP_VAR, ctx.getMaxAxisSize());
512
554
  if (!resting) {
513
555
  resting = true;
@@ -519,9 +561,13 @@ function contentFitFeature() {
519
561
  if (resting) {
520
562
  resting = false;
521
563
  sheet.setAttribute(FIT_ATTR, "moving");
522
- put(LIFT_VAR, scroller.offsetHeight);
564
+ liftMax = scroller.offsetHeight;
565
+ put(LIFT_VAR, liftMax);
523
566
  }
524
567
  follow(size);
568
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
569
+ followSettle();
570
+ }
525
571
  };
526
572
  const moving = () => ctx.isAnimating() || ctx.isDragging();
527
573
  const whenIdle = () => {
@@ -534,13 +580,20 @@ function contentFitFeature() {
534
580
  );
535
581
  const offSnap = ctx.on("snap", settle);
536
582
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
583
+ const offBeforeSnap = ctx.on("before-snap", () => {
584
+ queueMicrotask(() => {
585
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
586
+ });
587
+ });
537
588
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
538
589
  observer?.observe(document.documentElement);
539
590
  window.addEventListener("orientationchange", whenIdle);
540
591
  return () => {
592
+ unfollow();
541
593
  offProgress();
542
594
  offSnap();
543
595
  offDragStart();
596
+ offBeforeSnap();
544
597
  observer?.disconnect();
545
598
  window.removeEventListener("orientationchange", whenIdle);
546
599
  sheet.removeAttribute(FIT_ATTR);
@@ -1,4 +1,4 @@
1
- import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-9i-Uh6T3.js';
1
+ import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-C5tJYVMY.cjs';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
@@ -6,4 +6,5 @@ type ResolvedSnap = {
6
6
  };
7
7
  declare const resolveSnapList: (points: SnapPointDef[], mode: SheetMode, measureFit?: () => number) => ResolvedSnap[];
8
8
 
9
- export { type ResolvedSnap as R, resolveSnapList as r };
9
+ export { resolveSnapList as r };
10
+ export type { ResolvedSnap as R };
@@ -1,4 +1,4 @@
1
- import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-CQStdVy2.cjs';
1
+ import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-DxSrC4QC.js';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
@@ -6,4 +6,5 @@ type ResolvedSnap = {
6
6
  };
7
7
  declare const resolveSnapList: (points: SnapPointDef[], mode: SheetMode, measureFit?: () => number) => ResolvedSnap[];
8
8
 
9
- export { type ResolvedSnap as R, resolveSnapList as r };
9
+ export { resolveSnapList as r };
10
+ export type { ResolvedSnap as R };