@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/index.cjs CHANGED
@@ -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/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-CsQWHLNb.cjs';
2
- import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-CQStdVy2.cjs';
3
- export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-CQStdVy2.cjs';
4
- export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-DkG9aho0.cjs';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-CVGC5B5D.cjs';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-C_1aPJsU.cjs';
2
+ import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-CaJwHnxY.cjs';
3
+ export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-CaJwHnxY.cjs';
4
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-CTJb8Wdk.cjs';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-BBrJJjy5.cjs';
6
6
  import './transform-jVfAikE9.cjs';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { B as BottomSheetEngine } from './BottomSheetEngine-Dn6h-7gF.js';
2
- import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-9i-Uh6T3.js';
3
- export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-9i-Uh6T3.js';
4
- export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-C3cilcW9.js';
5
- export { R as ResolvedSnap, r as resolveSnapList } from './index-CnsJQZp2.js';
1
+ export { B as BottomSheetEngine } from './BottomSheetEngine-CsgCcCSO.js';
2
+ import { h as SnapPoint, f as SheetMode, g as EngineOptions, P as PhysicalSheetMode, j as ScrimOverlayPosition } from './BottomSheetCore-COvILxmR.js';
3
+ export { k as AnchorAnimationPreset, l as AnchorAnimationSpec, m as AnchorHandle, A as AnchorOptions, n as AnchorPosition, o as AnchorState, B as BottomSheetCore, C as CloseReason, E as EngineFeature, a as EngineFeatureContext, b as EngineFeatureOptions, c as EngineFeatureStage, d as EngineState, L as LogicalSheetMode, p as Plugin, q as SCRIM_PRESETS, r as ScrimOverlayOptions, s as ScrimPreset, t as ScrimPresetConfig, u as ScrimStageDef, i as ScrimStagesOptions, v as ScrimUpdate, S as SheetEventMap, w as SnapId, e as SnapPointDef, T as TeardownScope, x as runAnchorTransition } from './BottomSheetCore-COvILxmR.js';
4
+ export { a as autoCollapseFeature, c as contentSwipeFeature, d as defaultEngineFeatures, p as persistFeature, r as routeFeature, v as visualViewportFeature } from './default-features-BJx7J0NH.js';
5
+ export { R as ResolvedSnap, r as resolveSnapList } from './index-CXN7t3rr.js';
6
6
  import './transform-jVfAikE9.js';
7
7
 
8
8
  declare const resolveSnap: (point: SnapPoint | string, mode: SheetMode, measureFit?: () => number) => number;
package/dist/index.js CHANGED
@@ -84,6 +84,7 @@ function buildTransformTemplate(axis) {
84
84
  return (offset) => `translate3d(${offset}px, 0, 0)`;
85
85
  }
86
86
  }
87
+ var offsetFromMatrix = (axis, m) => axis === "bottom" ? m.m42 : axis === "top" ? -m.m42 : axis === "left" ? -m.m41 : m.m41;
87
88
  var layoutAxis = (axis) => axis === "left" || axis === "right" ? "width" : "height";
88
89
 
89
90
  // src/core/primitives/instance-id.ts
@@ -1169,7 +1170,7 @@ var tween = ({
1169
1170
  }
1170
1171
  const step = (now) => {
1171
1172
  if (cancelled) return;
1172
- const elapsed = now - start;
1173
+ const elapsed = Math.max(0, now - start);
1173
1174
  const t = Math.min(elapsed / duration, 1);
1174
1175
  const value = from + (to - from) * easing(t);
1175
1176
  onUpdate(value);
@@ -1222,8 +1223,8 @@ var runSpring = ({
1222
1223
  resolveFn = resolve;
1223
1224
  const step = (now) => {
1224
1225
  if (cancelled) return;
1225
- const dt = Math.min((now - lastTime) / 1e3, MAX_DT);
1226
- lastTime = now;
1226
+ const dt = Math.min(Math.max(0, now - lastTime) / 1e3, MAX_DT);
1227
+ lastTime = Math.max(lastTime, now);
1227
1228
  const steps = Math.max(1, Math.ceil(dt * 240));
1228
1229
  const subDt = dt / steps;
1229
1230
  let stepsLeft = steps;
@@ -1287,6 +1288,7 @@ function resolveAnimationPreset(animation) {
1287
1288
  }
1288
1289
 
1289
1290
  // src/core/animation/waapi-settle.ts
1291
+ var SETTLE_ANIMATION_ID = "bs-settle";
1290
1292
  var SIM_HZ = 240;
1291
1293
  var SAMPLE_STRIDE = 4;
1292
1294
  var MAX_SIM_MS = 3e3;
@@ -1344,6 +1346,7 @@ var AnimationRunner = class {
1344
1346
  __publicField(this, "isDragging");
1345
1347
  __publicField(this, "applyAux");
1346
1348
  __publicField(this, "getTransformFor");
1349
+ __publicField(this, "readShownSize");
1347
1350
  __publicField(this, "settleWaapi");
1348
1351
  __publicField(this, "currentWaapi", null);
1349
1352
  __publicField(this, "animationKind");
@@ -1363,6 +1366,7 @@ var AnimationRunner = class {
1363
1366
  this.isDragging = deps.isDragging;
1364
1367
  this.applyAux = deps.applyAux;
1365
1368
  this.getTransformFor = deps.getTransformFor;
1369
+ this.readShownSize = deps.readShownSize;
1366
1370
  this.settleWaapi = opts.settleAnimation === "waapi";
1367
1371
  const preset = resolveAnimationPreset(opts.animation);
1368
1372
  this.animationKind = preset.kind;
@@ -1395,10 +1399,12 @@ var AnimationRunner = class {
1395
1399
  const entry = this.currentWaapi;
1396
1400
  this.currentWaapi = null;
1397
1401
  entry.stop();
1402
+ const size = this.readShownSize?.() ?? entry.sizeNow();
1398
1403
  try {
1399
1404
  entry.anim.cancel();
1400
1405
  } catch {
1401
1406
  }
1407
+ this.applySizeFn(size);
1402
1408
  }
1403
1409
  cancel() {
1404
1410
  this.currentTween?.cancel();
@@ -1408,6 +1414,7 @@ var AnimationRunner = class {
1408
1414
  async animateTo(target, velocityPxPerMs) {
1409
1415
  if (target === this.getSize()) {
1410
1416
  if (!this.isAnimating && !this.isDragging()) {
1417
+ this.applySizeFn(target);
1411
1418
  this.element.style.willChange = "";
1412
1419
  }
1413
1420
  return;
@@ -1444,6 +1451,7 @@ var AnimationRunner = class {
1444
1451
  return;
1445
1452
  }
1446
1453
  }
1454
+ let current = false;
1447
1455
  if (this.animationKind === "spring") {
1448
1456
  const spring = runSpring({
1449
1457
  from: this.getSize(),
@@ -1454,7 +1462,8 @@ var AnimationRunner = class {
1454
1462
  });
1455
1463
  this.currentSpring = spring;
1456
1464
  await spring.promise;
1457
- if (this.currentSpring === spring) this.currentSpring = null;
1465
+ current = this.currentSpring === spring;
1466
+ if (current) this.currentSpring = null;
1458
1467
  } else {
1459
1468
  const tw = tween({
1460
1469
  from: this.getSize(),
@@ -1465,11 +1474,15 @@ var AnimationRunner = class {
1465
1474
  });
1466
1475
  this.currentTween = tw;
1467
1476
  await tw.promise;
1468
- if (this.currentTween === tw) this.currentTween = null;
1477
+ current = this.currentTween === tw;
1478
+ if (current) this.currentTween = null;
1469
1479
  }
1470
1480
  if (!this.isAnimating) {
1471
1481
  this.getRootEl()?.removeAttribute("data-animating");
1472
- if (!this.isDragging()) this.element.style.willChange = "";
1482
+ if (!this.isDragging()) {
1483
+ if (current) this.applySizeFn(this.getSize());
1484
+ this.element.style.willChange = "";
1485
+ }
1473
1486
  }
1474
1487
  }
1475
1488
  async runWaapiSettle(samples, target) {
@@ -1483,11 +1496,11 @@ var AnimationRunner = class {
1483
1496
  easing: "linear",
1484
1497
  fill: "forwards"
1485
1498
  });
1499
+ anim.id = SETTLE_ANIMATION_ID;
1486
1500
  let stopped = false;
1487
1501
  let auxRaf = 0;
1488
1502
  const lastIdx = samples.values.length - 1;
1489
- const auxTick = () => {
1490
- if (stopped) return;
1503
+ const sizeNow = () => {
1491
1504
  const at = Math.min(
1492
1505
  (Number(anim.currentTime) || 0) / samples.stepMs,
1493
1506
  lastIdx
@@ -1495,7 +1508,11 @@ var AnimationRunner = class {
1495
1508
  const idx = Math.floor(at);
1496
1509
  const from = samples.values[idx];
1497
1510
  const to = samples.values[Math.min(idx + 1, lastIdx)];
1498
- applyAux(from + (to - from) * (at - idx));
1511
+ return from + (to - from) * (at - idx);
1512
+ };
1513
+ const auxTick = () => {
1514
+ if (stopped) return;
1515
+ applyAux(sizeNow());
1499
1516
  auxRaf = requestAnimationFrame(auxTick);
1500
1517
  };
1501
1518
  auxRaf = requestAnimationFrame(auxTick);
@@ -1504,7 +1521,8 @@ var AnimationRunner = class {
1504
1521
  stop: () => {
1505
1522
  stopped = true;
1506
1523
  cancelAnimationFrame(auxRaf);
1507
- }
1524
+ },
1525
+ sizeNow
1508
1526
  };
1509
1527
  this.currentWaapi = entry;
1510
1528
  try {
@@ -2607,6 +2625,7 @@ var BottomSheetCore = class {
2607
2625
  __publicField(this, "closeOnBack");
2608
2626
  __publicField(this, "routedTo");
2609
2627
  __publicField(this, "fitContentToSnap");
2628
+ __publicField(this, "settleAnimation");
2610
2629
  __publicField(this, "persistent");
2611
2630
  __publicField(this, "disableCloseFlag");
2612
2631
  __publicField(this, "disableDragFlag");
@@ -2711,6 +2730,11 @@ var BottomSheetCore = class {
2711
2730
  const cap = this.snaps.getMaxAxisSize();
2712
2731
  const shown = cap > 0 && !this.allowOvershoot ? Math.min(size, cap) : size;
2713
2732
  return this.transformTemplate(cap - shown);
2733
+ },
2734
+ readShownSize: () => {
2735
+ const shown = getComputedStyle(this.element).transform;
2736
+ if (!shown || shown === "none") return void 0;
2737
+ return this.snaps.getMaxAxisSize() - offsetFromMatrix(this.mode, new DOMMatrix(shown));
2714
2738
  }
2715
2739
  },
2716
2740
  resolved.animation
@@ -2725,6 +2749,7 @@ var BottomSheetCore = class {
2725
2749
  this.closeOnBack = resolved.closeOnBack;
2726
2750
  this.routedTo = opts.routedTo;
2727
2751
  this.fitContentToSnap = opts.fitContentToSnap === true;
2752
+ this.settleAnimation = opts.settleAnimation;
2728
2753
  this.persistent = resolved.persistent;
2729
2754
  this.disableCloseFlag = resolved.disableClose;
2730
2755
  this.disableDragFlag = resolved.disableDrag;
@@ -2827,7 +2852,8 @@ var BottomSheetCore = class {
2827
2852
  closeOnRouteChange: this.closeOnRouteChange,
2828
2853
  persistKey: this.persistKey,
2829
2854
  autoCollapseAfter,
2830
- fitContentToSnap: this.fitContentToSnap
2855
+ fitContentToSnap: this.fitContentToSnap,
2856
+ settleAnimation: this.settleAnimation
2831
2857
  },
2832
2858
  isDestroyed: () => this.destroyed,
2833
2859
  isDragging: () => this.isDraggingAny(),
@@ -3719,7 +3745,11 @@ var BottomSheetCore = class {
3719
3745
  const offset = cap - clamped;
3720
3746
  const style = this.element.style;
3721
3747
  if (!skipTransform) style.transform = this.transformTemplate(offset);
3722
- if (this.sizeWriteSentinel.shouldWrite(clamped, SIZE_WRITE_EPSILON)) {
3748
+ const sizeChanged = this.sizeWriteSentinel.shouldWrite(
3749
+ clamped,
3750
+ this.animation.isAnimating || this.isDraggingAny() ? SIZE_WRITE_EPSILON : 0
3751
+ );
3752
+ if (sizeChanged) {
3723
3753
  style.setProperty("--bs-size", `${clamped}px`);
3724
3754
  if (this.scrimParent) {
3725
3755
  this.scrimParent.style.setProperty("--bs-size", `${clamped}px`);
@@ -3746,7 +3776,7 @@ var BottomSheetCore = class {
3746
3776
  }
3747
3777
  }
3748
3778
  this.scrim.applyOpacity(progress, progressChanged);
3749
- if (progressChanged && this.bus.listenerCount("progress") > 0) {
3779
+ if ((progressChanged || sizeChanged) && this.bus.listenerCount("progress") > 0) {
3750
3780
  this.progressPayload.value = progress;
3751
3781
  this.progressPayload.size = clamped;
3752
3782
  this.emit("progress", this.progressPayload);
@@ -4243,7 +4273,6 @@ function visualViewportFeature() {
4243
4273
 
4244
4274
  // src/core/features/content-fit.ts
4245
4275
  var INSET_VAR = "--bs-content-inset";
4246
- var SIZE_VAR = "--bs-size";
4247
4276
  var CAP_VAR = "--bs-max-size";
4248
4277
  var LIFT_VAR = "--bs-footer-lift-max";
4249
4278
  var FIT_ATTR = "data-bs-fit-content";
@@ -4256,10 +4285,14 @@ function contentFitFeature() {
4256
4285
  return;
4257
4286
  }
4258
4287
  const sheet = ctx.element;
4288
+ const waapi = ctx.options.settleAnimation === "waapi";
4259
4289
  let inset = 0;
4260
4290
  let unpaddedMax = -1;
4261
4291
  let top = 0;
4262
4292
  let resting = false;
4293
+ let liftMax = 0;
4294
+ let followed = null;
4295
+ let follower = null;
4263
4296
  const put = (name, px) => sheet.style.setProperty(name, `${px}px`);
4264
4297
  const hiddenAt = (size) => sheet.dataset.mode === "bottom" ? Math.max(0, ctx.getMaxAxisSize() - size) : 0;
4265
4298
  const follow = (size) => {
@@ -4273,8 +4306,45 @@ function contentFitFeature() {
4273
4306
  top = limit;
4274
4307
  }
4275
4308
  };
4309
+ const unfollow = () => {
4310
+ follower?.cancel();
4311
+ follower = null;
4312
+ followed = null;
4313
+ };
4314
+ const followSettle = () => {
4315
+ if (followed?.playState === "running") return;
4316
+ const settleAnim = sheet.getAnimations?.().find((a) => a.id === SETTLE_ANIMATION_ID);
4317
+ const footer = sheet.querySelector(".bs-footer");
4318
+ if (!settleAnim || !footer) return;
4319
+ const effect = settleAnim.effect;
4320
+ unfollow();
4321
+ const own = footer.animate(
4322
+ effect.getKeyframes().map((k) => ({
4323
+ offset: k.computedOffset,
4324
+ transform: `translateY(${-Math.min(
4325
+ Math.max(0, parseFloat(String(k.transform).split(",")[1]) || 0),
4326
+ liftMax
4327
+ )}px)`
4328
+ })),
4329
+ {
4330
+ duration: effect.getTiming().duration,
4331
+ easing: "linear",
4332
+ fill: "forwards"
4333
+ }
4334
+ );
4335
+ follower = own;
4336
+ followed = settleAnim;
4337
+ const done = () => {
4338
+ if (followed === settleAnim) unfollow();
4339
+ };
4340
+ settleAnim.ready.then(() => {
4341
+ if (follower === own) own.startTime = settleAnim.startTime;
4342
+ }, done);
4343
+ settleAnim.finished.then(done, done);
4344
+ };
4276
4345
  const settle = () => {
4277
4346
  if (ctx.isDestroyed()) return;
4347
+ unfollow();
4278
4348
  const size = ctx.getSize();
4279
4349
  if (!resting) {
4280
4350
  unpaddedMax = -1;
@@ -4282,7 +4352,6 @@ function contentFitFeature() {
4282
4352
  }
4283
4353
  inset = hiddenAt(size);
4284
4354
  put(INSET_VAR, inset);
4285
- put(SIZE_VAR, size);
4286
4355
  put(CAP_VAR, ctx.getMaxAxisSize());
4287
4356
  if (!resting) {
4288
4357
  resting = true;
@@ -4294,9 +4363,13 @@ function contentFitFeature() {
4294
4363
  if (resting) {
4295
4364
  resting = false;
4296
4365
  sheet.setAttribute(FIT_ATTR, "moving");
4297
- put(LIFT_VAR, scroller.offsetHeight);
4366
+ liftMax = scroller.offsetHeight;
4367
+ put(LIFT_VAR, liftMax);
4298
4368
  }
4299
4369
  follow(size);
4370
+ if (waapi && ctx.isAnimating() && sheet.dataset.mode === "bottom") {
4371
+ followSettle();
4372
+ }
4300
4373
  };
4301
4374
  const moving = () => ctx.isAnimating() || ctx.isDragging();
4302
4375
  const whenIdle = () => {
@@ -4309,13 +4382,20 @@ function contentFitFeature() {
4309
4382
  );
4310
4383
  const offSnap = ctx.on("snap", settle);
4311
4384
  const offDragStart = ctx.on("dragstart", () => move(ctx.getSize()));
4385
+ const offBeforeSnap = ctx.on("before-snap", () => {
4386
+ queueMicrotask(() => {
4387
+ if (!ctx.isDestroyed() && ctx.isAnimating()) move(ctx.getSize());
4388
+ });
4389
+ });
4312
4390
  const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(whenIdle);
4313
4391
  observer?.observe(document.documentElement);
4314
4392
  window.addEventListener("orientationchange", whenIdle);
4315
4393
  return () => {
4394
+ unfollow();
4316
4395
  offProgress();
4317
4396
  offSnap();
4318
4397
  offDragStart();
4398
+ offBeforeSnap();
4319
4399
  observer?.disconnect();
4320
4400
  window.removeEventListener("orientationchange", whenIdle);
4321
4401
  sheet.removeAttribute(FIT_ATTR);
@@ -1,4 +1,4 @@
1
- import { S as SheetEventMap } from '../BottomSheetCore-CQStdVy2.cjs';
1
+ import { S as SheetEventMap } from '../BottomSheetCore-CaJwHnxY.cjs';
2
2
  import '../transform-jVfAikE9.cjs';
3
3
 
4
4
  type FormikStateLike = {
@@ -1,4 +1,4 @@
1
- import { S as SheetEventMap } from '../BottomSheetCore-9i-Uh6T3.js';
1
+ import { S as SheetEventMap } from '../BottomSheetCore-COvILxmR.js';
2
2
  import '../transform-jVfAikE9.js';
3
3
 
4
4
  type FormikStateLike = {
@@ -1,4 +1,4 @@
1
- import { S as SheetEventMap } from '../BottomSheetCore-CQStdVy2.cjs';
1
+ import { S as SheetEventMap } from '../BottomSheetCore-CaJwHnxY.cjs';
2
2
  import '../transform-jVfAikE9.cjs';
3
3
 
4
4
  type RhfFormStateLike = {
@@ -1,4 +1,4 @@
1
- import { S as SheetEventMap } from '../BottomSheetCore-9i-Uh6T3.js';
1
+ import { S as SheetEventMap } from '../BottomSheetCore-COvILxmR.js';
2
2
  import '../transform-jVfAikE9.js';
3
3
 
4
4
  type RhfFormStateLike = {