@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
package/dist/element.js CHANGED
@@ -97,9 +97,10 @@ function buildTransformTemplate(axis) {
97
97
  return (offset) => `translate3d(${offset}px, 0, 0)`;
98
98
  }
99
99
  }
100
- var layoutAxis;
100
+ var offsetFromMatrix, layoutAxis;
101
101
  var init_transform = __esm({
102
102
  "src/core/primitives/transform.ts"() {
103
+ offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
103
104
  layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
104
105
  }
105
106
  });
@@ -1286,7 +1287,7 @@ var init_animation = __esm({
1286
1287
  }
1287
1288
  const step = (now) => {
1288
1289
  if (cancelled) return;
1289
- const elapsed = now - start;
1290
+ const elapsed = Math.max(0, now - start);
1290
1291
  const t = Math.min(elapsed / duration, 1);
1291
1292
  const value = from + (to - from) * easing(t);
1292
1293
  onUpdate(value);
@@ -1344,8 +1345,8 @@ var init_spring = __esm({
1344
1345
  resolveFn = resolve;
1345
1346
  const step = (now) => {
1346
1347
  if (cancelled) return;
1347
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1348
- lastTime = now;
1348
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1349
+ lastTime = Math.max(lastTime, now);
1349
1350
  const steps = Math.max(1, Math.ceil(dt * 240));
1350
1351
  const subDt = dt / steps;
1351
1352
  let stepsLeft = steps;
@@ -1458,10 +1459,11 @@ function sampleTweenSettle(from, to, durationMs, easing) {
1458
1459
  durationMs
1459
1460
  };
1460
1461
  }
1461
- var SIM_HZ, SAMPLE_STRIDE, MAX_SIM_MS;
1462
+ var SETTLE_ANIMATION_ID, SIM_HZ, SAMPLE_STRIDE, MAX_SIM_MS;
1462
1463
  var init_waapi_settle = __esm({
1463
1464
  "src/core/animation/waapi-settle.ts"() {
1464
1465
  init_spring();
1466
+ SETTLE_ANIMATION_ID = "bs-settle";
1465
1467
  SIM_HZ = 240;
1466
1468
  SAMPLE_STRIDE = 4;
1467
1469
  MAX_SIM_MS = 3e3;
@@ -1487,6 +1489,7 @@ var init_animation_runner = __esm({
1487
1489
  __publicField(this, "isDragging");
1488
1490
  __publicField(this, "applyAux");
1489
1491
  __publicField(this, "getTransformFor");
1492
+ __publicField(this, "readShownSize");
1490
1493
  __publicField(this, "settleWaapi");
1491
1494
  __publicField(this, "currentWaapi", null);
1492
1495
  __publicField(this, "animationKind");
@@ -1506,6 +1509,7 @@ var init_animation_runner = __esm({
1506
1509
  this.isDragging = deps.isDragging;
1507
1510
  this.applyAux = deps.applyAux;
1508
1511
  this.getTransformFor = deps.getTransformFor;
1512
+ this.readShownSize = deps.readShownSize;
1509
1513
  this.settleWaapi = opts.settleAnimation === "waapi";
1510
1514
  const preset = resolveAnimationPreset(opts.animation);
1511
1515
  this.animationKind = preset.kind;
@@ -1538,10 +1542,12 @@ var init_animation_runner = __esm({
1538
1542
  const entry = this.currentWaapi;
1539
1543
  this.currentWaapi = null;
1540
1544
  entry.stop();
1545
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1541
1546
  try {
1542
1547
  entry.anim.cancel();
1543
1548
  } catch {
1544
1549
  }
1550
+ this.applySizeFn(size);
1545
1551
  }
1546
1552
  cancel() {
1547
1553
  this.currentTween?.cancel();
@@ -1551,6 +1557,7 @@ var init_animation_runner = __esm({
1551
1557
  async animateTo(target, velocityPxPerMs) {
1552
1558
  if (target === this.getSize()) {
1553
1559
  if (!this.isAnimating && !this.isDragging()) {
1560
+ this.applySizeFn(target);
1554
1561
  this.element.style.willChange = "";
1555
1562
  }
1556
1563
  return;
@@ -1587,6 +1594,7 @@ var init_animation_runner = __esm({
1587
1594
  return;
1588
1595
  }
1589
1596
  }
1597
+ let current = false;
1590
1598
  if (this.animationKind === "spring") {
1591
1599
  const spring = runSpring({
1592
1600
  from: this.getSize(),
@@ -1597,7 +1605,8 @@ var init_animation_runner = __esm({
1597
1605
  });
1598
1606
  this.currentSpring = spring;
1599
1607
  await spring.promise;
1600
- if (this.currentSpring === spring) this.currentSpring = null;
1608
+ current = this.currentSpring === spring;
1609
+ if (current) this.currentSpring = null;
1601
1610
  } else {
1602
1611
  const tw = tween({
1603
1612
  from: this.getSize(),
@@ -1608,11 +1617,15 @@ var init_animation_runner = __esm({
1608
1617
  });
1609
1618
  this.currentTween = tw;
1610
1619
  await tw.promise;
1611
- if (this.currentTween === tw) this.currentTween = null;
1620
+ current = this.currentTween === tw;
1621
+ if (current) this.currentTween = null;
1612
1622
  }
1613
1623
  if (!this.isAnimating) {
1614
1624
  this.getRootEl()?.removeAttribute("data-animating");
1615
- if (!this.isDragging()) this.element.style.willChange = "";
1625
+ if (!this.isDragging()) {
1626
+ if (current) this.applySizeFn(this.getSize());
1627
+ this.element.style.willChange = "";
1628
+ }
1616
1629
  }
1617
1630
  }
1618
1631
  async runWaapiSettle(samples, target) {
@@ -1626,11 +1639,11 @@ var init_animation_runner = __esm({
1626
1639
  easing: "linear",
1627
1640
  fill: "forwards"
1628
1641
  });
1642
+ anim.id = SETTLE_ANIMATION_ID;
1629
1643
  let stopped = false;
1630
1644
  let auxRaf = 0;
1631
1645
  const lastIdx = samples.values.length - 1;
1632
- const auxTick = () => {
1633
- if (stopped) return;
1646
+ const sizeNow = () => {
1634
1647
  const at = Math.min(
1635
1648
  (Number(anim.currentTime) || 0) / samples.stepMs,
1636
1649
  lastIdx
@@ -1638,7 +1651,11 @@ var init_animation_runner = __esm({
1638
1651
  const idx = Math.floor(at);
1639
1652
  const from = samples.values[idx];
1640
1653
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1641
- applyAux(from + (to - from) * (at - idx));
1654
+ return from + (to - from) * (at - idx);
1655
+ };
1656
+ const auxTick = () => {
1657
+ if (stopped) return;
1658
+ applyAux(sizeNow());
1642
1659
  auxRaf = requestAnimationFrame(auxTick);
1643
1660
  };
1644
1661
  auxRaf = requestAnimationFrame(auxTick);
@@ -1647,7 +1664,8 @@ var init_animation_runner = __esm({
1647
1664
  stop: () => {
1648
1665
  stopped = true;
1649
1666
  cancelAnimationFrame(auxRaf);
1650
- }
1667
+ },
1668
+ sizeNow
1651
1669
  };
1652
1670
  this.currentWaapi = entry;
1653
1671
  try {
@@ -2886,6 +2904,7 @@ var init_BottomSheetCore = __esm({
2886
2904
  __publicField(this, "closeOnBack");
2887
2905
  __publicField(this, "routedTo");
2888
2906
  __publicField(this, "fitContentToSnap");
2907
+ __publicField(this, "settleAnimation");
2889
2908
  __publicField(this, "persistent");
2890
2909
  __publicField(this, "disableCloseFlag");
2891
2910
  __publicField(this, "disableDragFlag");
@@ -2990,6 +3009,11 @@ var init_BottomSheetCore = __esm({
2990
3009
  const cap = this.snaps.getMaxAxisSize();
2991
3010
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2992
3011
  return this.transformTemplate(cap - shown);
3012
+ },
3013
+ readShownSize: () => {
3014
+ const shown = getComputedStyle(this.element).transform;
3015
+ if (!shown || shown === "none") return void 0;
3016
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2993
3017
  }
2994
3018
  },
2995
3019
  resolved.animation
@@ -3004,6 +3028,7 @@ var init_BottomSheetCore = __esm({
3004
3028
  this.closeOnBack = resolved.closeOnBack;
3005
3029
  this.routedTo = opts.routedTo;
3006
3030
  this.fitContentToSnap = opts.fitContentToSnap === true;
3031
+ this.settleAnimation = opts.settleAnimation;
3007
3032
  this.persistent = resolved.persistent;
3008
3033
  this.disableCloseFlag = resolved.disableClose;
3009
3034
  this.disableDragFlag = resolved.disableDrag;
@@ -3106,7 +3131,8 @@ var init_BottomSheetCore = __esm({
3106
3131
  closeOnRouteChange: this.closeOnRouteChange,
3107
3132
  persistKey: this.persistKey,
3108
3133
  autoCollapseAfter,
3109
- fitContentToSnap: this.fitContentToSnap
3134
+ fitContentToSnap: this.fitContentToSnap,
3135
+ settleAnimation: this.settleAnimation
3110
3136
  },
3111
3137
  isDestroyed: () => this.destroyed,
3112
3138
  isDragging: () => this.isDraggingAny(),
@@ -3998,7 +4024,11 @@ var init_BottomSheetCore = __esm({
3998
4024
  const offset = cap - clamped;
3999
4025
  const style = this.element.style;
4000
4026
  if (!skipTransform) style.transform = this.transformTemplate(offset);
4001
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
4027
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
4028
+ clamped,
4029
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
4030
+ );
4031
+ if (sizeChanged) {
4002
4032
  style.setProperty("--bs-size", `${clamped}px`);
4003
4033
  if (this.scrimParent) {
4004
4034
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -4025,7 +4055,7 @@ var init_BottomSheetCore = __esm({
4025
4055
  }
4026
4056
  }
4027
4057
  this.scrim.applyOpacity(progress, progressChanged);
4028
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
4058
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
4029
4059
  this.progressPayload.value = progress;
4030
4060
  this.progressPayload.size = clamped;
4031
4061
  this.emit("progress", this.progressPayload);
@@ -4569,10 +4599,14 @@ function contentFitFeature() {
4569
4599
  return;
4570
4600
  }
4571
4601
  const sheet = ctx.element;
4602
+ const waapi = ctx.options.settleAnimation === "waapi";
4572
4603
  let inset = 0;
4573
4604
  let unpaddedMax = -1;
4574
4605
  let top = 0;
4575
4606
  let resting = false;
4607
+ let liftMax = 0;
4608
+ let followed = null;
4609
+ let follower = null;
4576
4610
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4577
4611
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4578
4612
  const follow = (size) => {
@@ -4586,8 +4620,45 @@ function contentFitFeature() {
4586
4620
  top = limit;
4587
4621
  }
4588
4622
  };
4623
+ const unfollow = () => {
4624
+ follower?.cancel();
4625
+ follower = null;
4626
+ followed = null;
4627
+ };
4628
+ const followSettle = () => {
4629
+ if (followed?.playState === "running") return;
4630
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4631
+ const footer = sheet.querySelector(".bs-footer");
4632
+ if (!settleAnim || !footer) return;
4633
+ const effect = settleAnim.effect;
4634
+ unfollow();
4635
+ const own = footer.animate(
4636
+ effect.getKeyframes().map((k) => ({
4637
+ offset: k.computedOffset,
4638
+ transform: `translateY(${-Math.min(
4639
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4640
+ liftMax
4641
+ )}px)`
4642
+ })),
4643
+ {
4644
+ duration: effect.getTiming().duration,
4645
+ easing: "linear",
4646
+ fill: "forwards"
4647
+ }
4648
+ );
4649
+ follower = own;
4650
+ followed = settleAnim;
4651
+ const done = () => {
4652
+ if (followed === settleAnim) unfollow();
4653
+ };
4654
+ settleAnim.ready.then(() => {
4655
+ if (follower === own) own.startTime = settleAnim.startTime;
4656
+ }, done);
4657
+ settleAnim.finished.then(done, done);
4658
+ };
4589
4659
  const settle = () => {
4590
4660
  if (ctx.isDestroyed()) return;
4661
+ unfollow();
4591
4662
  const size = ctx.getSize();
4592
4663
  if (!resting) {
4593
4664
  unpaddedMax = -1;
@@ -4595,7 +4666,6 @@ function contentFitFeature() {
4595
4666
  }
4596
4667
  inset = hiddenAt(size);
4597
4668
  put(INSET_VAR, inset);
4598
- put(SIZE_VAR, size);
4599
4669
  put(CAP_VAR, ctx.getMaxAxisSize());
4600
4670
  if (!resting) {
4601
4671
  resting = true;
@@ -4607,9 +4677,13 @@ function contentFitFeature() {
4607
4677
  if (resting) {
4608
4678
  resting = false;
4609
4679
  sheet.setAttribute(FIT_ATTR, "moving");
4610
- put(LIFT_VAR, scroller.offsetHeight);
4680
+ liftMax = scroller.offsetHeight;
4681
+ put(LIFT_VAR, liftMax);
4611
4682
  }
4612
4683
  follow(size);
4684
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4685
+ followSettle();
4686
+ }
4613
4687
  };
4614
4688
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4615
4689
  const whenIdle = () => {
@@ -4622,13 +4696,20 @@ function contentFitFeature() {
4622
4696
  );
4623
4697
  const offSnap = ctx.on("snap", settle);
4624
4698
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4699
+ const offBeforeSnap = ctx.on("before-snap", () => {
4700
+ queueMicrotask(() => {
4701
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4702
+ });
4703
+ });
4625
4704
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4626
4705
  observer?.observe(document.documentElement);
4627
4706
  window.addEventListener("orientationchange", whenIdle);
4628
4707
  return () => {
4708
+ unfollow();
4629
4709
  offProgress();
4630
4710
  offSnap();
4631
4711
  offDragStart();
4712
+ offBeforeSnap();
4632
4713
  observer?.disconnect();
4633
4714
  window.removeEventListener("orientationchange", whenIdle);
4634
4715
  sheet.removeAttribute(FIT_ATTR);
@@ -4639,11 +4720,11 @@ function contentFitFeature() {
4639
4720
  }
4640
4721
  };
4641
4722
  }
4642
- var INSET_VAR, SIZE_VAR, CAP_VAR, LIFT_VAR, FIT_ATTR;
4723
+ var INSET_VAR, CAP_VAR, LIFT_VAR, FIT_ATTR;
4643
4724
  var init_content_fit = __esm({
4644
4725
  "src/core/features/content-fit.ts"() {
4726
+ init_waapi_settle();
4645
4727
  INSET_VAR = "--bs-content-inset";
4646
- SIZE_VAR = "--bs-size";
4647
4728
  CAP_VAR = "--bs-max-size";
4648
4729
  LIFT_VAR = "--bs-footer-lift-max";
4649
4730
  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-CTJb8Wdk.cjs';
2
+ import { E as EngineFeature } from './BottomSheetCore-CaJwHnxY.cjs';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-CaJwHnxY.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-BJx7J0NH.js';
2
+ import { E as EngineFeature } from './BottomSheetCore-COvILxmR.js';
3
+ export { a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage } from './BottomSheetCore-COvILxmR.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-CQStdVy2.cjs';
1
+ import { e as SnapPointDef, f as SheetMode } from './BottomSheetCore-CaJwHnxY.cjs';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;
@@ -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-COvILxmR.js';
2
2
 
3
3
  type ResolvedSnap = {
4
4
  id: string;