@kyralabs/m3e-motion 1.2.0 → 1.3.0

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.
package/dist/index.d.ts CHANGED
@@ -39,6 +39,42 @@ interface LinearEasing {
39
39
  }
40
40
  declare function springToLinear(spec: SpringSpec, options?: LinearEasingOptions): LinearEasing;
41
41
 
42
+ declare class SpringAnimatable {
43
+ #private;
44
+ readonly visibilityThreshold: number;
45
+ /**
46
+ * @param value initial value, at rest.
47
+ * @param visibilityThreshold Compose's visibility threshold: 0.01 for Float animations
48
+ * (`Spring.DefaultDisplacementThreshold`), 1 for an Int one.
49
+ */
50
+ constructor(value: number, visibilityThreshold?: number);
51
+ get value(): number;
52
+ /** Units per second. */
53
+ get velocity(): number;
54
+ get target(): number;
55
+ get isRunning(): boolean;
56
+ /** Jumps to `value` and stops. */
57
+ snapTo(value: number): void;
58
+ /**
59
+ * Animates to `target` from the value and velocity at `now` (ms); a null spec (e.g. a spatial
60
+ * spring under reduced motion) jumps there.
61
+ */
62
+ animateTo(target: number, spec: SpringSpec | null, now: number): void;
63
+ /** Advances to `now` (ms) and returns the value; the animation ends once its duration is up. */
64
+ sample(now: number): number;
65
+ }
66
+
67
+ /** `Int.VectorConverter` reads an animated Int by truncating the float toward zero. */
68
+ declare const animatedInt: (value: number) => number;
69
+ /** Whether item `index` (0 = top) shows at stagger value `stagger` (0 … `itemCount`). */
70
+ declare const fabMenuItemVisible: (index: number, itemCount: number, stagger: number) => boolean;
71
+
72
+ /**
73
+ * The item index `key` moves focus to from `current` (−1: none focused) among `count` items, or
74
+ * null when the key does not navigate.
75
+ */
76
+ declare function menuNavigationTarget(key: string, count: number, current: number): number | null;
77
+
42
78
  interface LoadingIndicatorTiming {
43
79
  /** `MorphIntervalMillis`: how often a morph starts. */
44
80
  readonly morphIntervalMillis: number;
@@ -116,6 +152,63 @@ declare class SpringSimulation {
116
152
  updateValues(lastDisplacement: number, lastVelocity: number, timeElapsed: number): Motion;
117
153
  }
118
154
 
155
+ /** Where a menu opens relative to its anchor (MenuAnchorPosition.Below…End). */
156
+ type MenuAnchorPosition = 'below' | 'above' | 'start' | 'end' | 'left' | 'right';
157
+ interface MenuRect {
158
+ readonly left: number;
159
+ readonly top: number;
160
+ readonly right: number;
161
+ readonly bottom: number;
162
+ }
163
+ interface MenuPositionInput {
164
+ /** Anchor bounds in viewport px. */
165
+ anchor: MenuRect;
166
+ /** Viewport (window) size in px. */
167
+ window: {
168
+ readonly width: number;
169
+ readonly height: number;
170
+ };
171
+ /** Untransformed menu size in px. */
172
+ menu: {
173
+ readonly width: number;
174
+ readonly height: number;
175
+ };
176
+ /** Layout direction of the anchor (`direction: rtl`). */
177
+ rtl: boolean;
178
+ /** Default `below`. */
179
+ position?: MenuAnchorPosition | undefined;
180
+ /** DpOffset: x is mirrored in RTL. Default 0, 0. */
181
+ offset?: {
182
+ readonly x: number;
183
+ readonly y: number;
184
+ } | undefined;
185
+ /** Kept from the window top/bottom (MenuVerticalMargin). */
186
+ verticalMargin: number;
187
+ /** Kept from the window left/right (MenuHorizontalMargin; 0 for the baseline DropdownMenu). */
188
+ horizontalMargin: number;
189
+ }
190
+ interface MenuPositionResult {
191
+ /** Menu left edge in viewport px. */
192
+ x: number;
193
+ /** Menu top edge in viewport px. */
194
+ y: number;
195
+ /** Transform origin as fractions of the menu size (0 = left/top, 1 = right/bottom). */
196
+ originX: number;
197
+ originY: number;
198
+ }
199
+ /** calculateTransformOrigin (Menu.kt L2216). */
200
+ declare function menuTransformOrigin(anchor: MenuRect, menu: MenuRect): {
201
+ originX: number;
202
+ originY: number;
203
+ };
204
+ /**
205
+ * Where Compose's DropdownMenuPositionProvider places a menu: the first x and y candidates of the
206
+ * MenuAnchorPosition that keep the menu inside the window margins (below the anchor, then above it,
207
+ * then centered on its top, then against the nearer window edge), plus the transform origin the
208
+ * open/close scale animates from.
209
+ */
210
+ declare function menuPosition(input: MenuPositionInput): MenuPositionResult;
211
+
119
212
  /** How the bar reacts to its scroll container (TopAppBarDefaults.*ScrollBehavior). */
120
213
  type AppBarScrollBehavior = 'pinned' | 'enter-always';
121
214
  interface AppBarScrollState {
@@ -157,4 +250,31 @@ declare function scrollAppBar(state: AppBarScrollState, behavior: AppBarScrollBe
157
250
  */
158
251
  declare function settleTarget(state: AppBarScrollState): number | null;
159
252
 
160
- export { type AppBarScrollBehavior, type AppBarScrollState, DEFAULT_DISPLACEMENT_THRESHOLD, type IndeterminateFrame, type LinearEasing, type LinearEasingOptions, type LoadingIndicatorTiming, type Motion, SpringSimulation, type SpringSpec, appBarScrollState, collapsedFraction, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, indeterminateFrame, initialIndeterminateFrame, isScrolledUnder, morphSpringDurationMillis, overlappedFraction, scrollAppBar, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, withHeight, withHeightOffset };
253
+ interface ButtonGroupItemSize {
254
+ /** Resting width (Compose: the item's max intrinsic width). */
255
+ readonly width: number;
256
+ /**
257
+ * Most this item may be compressed by a pressed neighbor (Compose `compressionLimit`: the end
258
+ * content padding of the item, `ButtonDefaults.ContentPadding` by default).
259
+ */
260
+ readonly compressionLimit: number;
261
+ }
262
+ /**
263
+ * Number of leading items that fit in `maxWidth` (ButtonGroupMeasurePolicy L673-L716). When all
264
+ * items and their spacing fit, every item shows; otherwise the overflow indicator's width is
265
+ * reserved and items are added while each one fits in what is left (each after the first also
266
+ * pays one `spacing`, the gap before the next item or the indicator).
267
+ */
268
+ declare function buttonGroupVisibleCount(widths: readonly number[], spacing: number, maxWidth: number, overflowWidth: number): number;
269
+ /**
270
+ * Widths of the visible items while some are pressed (ButtonGroupMeasurePolicy L718-L769).
271
+ * `pressed[i]` is item i's press animation value (0 at rest, 1 fully expanded; it overshoots on a
272
+ * bouncy spring). A pressed middle item grows by `pressed × min(expandedRatio × width / 2, both
273
+ * neighbors' compression limits)` on each side, taken from each neighbor; the first and last items
274
+ * grow by `pressed × min(expandedRatio × width, neighbor's limit)` taken from their only neighbor.
275
+ * Items are processed in order on the running widths, as Compose does, so the total width stays
276
+ * constant. `visibleCount` is the number of items shown (the rest are in the overflow menu).
277
+ */
278
+ declare function buttonGroupWidths(items: readonly ButtonGroupItemSize[], pressed: readonly number[], expandedRatio: number, visibleCount?: number): number[];
279
+
280
+ export { type AppBarScrollBehavior, type AppBarScrollState, type ButtonGroupItemSize, DEFAULT_DISPLACEMENT_THRESHOLD, type IndeterminateFrame, type LinearEasing, type LinearEasingOptions, type LoadingIndicatorTiming, type MenuAnchorPosition, type MenuPositionInput, type MenuPositionResult, type MenuRect, type Motion, SpringAnimatable, SpringSimulation, type SpringSpec, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, collapsedFraction, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, fabMenuItemVisible, indeterminateFrame, initialIndeterminateFrame, isScrolledUnder, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, overlappedFraction, scrollAppBar, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, withHeight, withHeightOffset };
package/dist/index.js CHANGED
@@ -336,6 +336,107 @@ function springToLinear(spec, options = {}) {
336
336
  return { easing: `linear(${body.join(", ")})`, durationMillis, stops, maxError };
337
337
  }
338
338
 
339
+ // src/animatable.ts
340
+ var SpringAnimatable = class {
341
+ /**
342
+ * @param value initial value, at rest.
343
+ * @param visibilityThreshold Compose's visibility threshold: 0.01 for Float animations
344
+ * (`Spring.DefaultDisplacementThreshold`), 1 for an Int one.
345
+ */
346
+ constructor(value, visibilityThreshold = DEFAULT_DISPLACEMENT_THRESHOLD) {
347
+ this.visibilityThreshold = visibilityThreshold;
348
+ this.#value = value;
349
+ this.#target = value;
350
+ }
351
+ visibilityThreshold;
352
+ #value;
353
+ #velocity = 0;
354
+ #target;
355
+ #from = 0;
356
+ #velocity0 = 0;
357
+ #start = 0;
358
+ #duration = 0;
359
+ #spec = null;
360
+ get value() {
361
+ return this.#value;
362
+ }
363
+ /** Units per second. */
364
+ get velocity() {
365
+ return this.#velocity;
366
+ }
367
+ get target() {
368
+ return this.#target;
369
+ }
370
+ get isRunning() {
371
+ return this.#spec !== null;
372
+ }
373
+ /** Jumps to `value` and stops. */
374
+ snapTo(value) {
375
+ this.#spec = null;
376
+ this.#value = value;
377
+ this.#target = value;
378
+ this.#velocity = 0;
379
+ }
380
+ /**
381
+ * Animates to `target` from the value and velocity at `now` (ms); a null spec (e.g. a spatial
382
+ * spring under reduced motion) jumps there.
383
+ */
384
+ animateTo(target, spec, now) {
385
+ this.sample(now);
386
+ if (spec === null) {
387
+ this.snapTo(target);
388
+ return;
389
+ }
390
+ this.#from = this.#value;
391
+ this.#velocity0 = this.#velocity;
392
+ this.#target = target;
393
+ this.#start = now;
394
+ this.#spec = spec;
395
+ this.#duration = springDurationMillis(
396
+ spec,
397
+ this.#from,
398
+ target,
399
+ this.#velocity0,
400
+ this.visibilityThreshold
401
+ );
402
+ if (this.#duration <= 0) this.snapTo(target);
403
+ }
404
+ /** Advances to `now` (ms) and returns the value; the animation ends once its duration is up. */
405
+ sample(now) {
406
+ const spec = this.#spec;
407
+ if (spec === null) return this.#value;
408
+ const elapsed = Math.max(0, now - this.#start);
409
+ if (elapsed >= this.#duration) {
410
+ this.snapTo(this.#target);
411
+ return this.#value;
412
+ }
413
+ this.#value = springValue(spec, elapsed, this.#from, this.#target, this.#velocity0);
414
+ this.#velocity = springVelocity(spec, elapsed, this.#from, this.#target, this.#velocity0);
415
+ return this.#value;
416
+ }
417
+ };
418
+
419
+ // src/fab-menu.ts
420
+ var animatedInt = (value) => Math.trunc(value);
421
+ var fabMenuItemVisible = (index, itemCount, stagger) => index >= itemCount - animatedInt(stagger);
422
+
423
+ // src/menu-navigation.ts
424
+ function menuNavigationTarget(key, count, current) {
425
+ if (count === 0) return null;
426
+ switch (key) {
427
+ case "ArrowDown":
428
+ return current < 0 ? 0 : (current + 1) % count;
429
+ case "ArrowUp":
430
+ return current < 0 ? count - 1 : (current - 1 + count) % count;
431
+ case "Home":
432
+ return 0;
433
+ case "End":
434
+ return count - 1;
435
+ default:
436
+ return null;
437
+ }
438
+ }
439
+
339
440
  // src/loading-indicator.ts
340
441
  var FULL_ROTATION = 360;
341
442
  var QUARTER_ROTATION = FULL_ROTATION / 4;
@@ -364,6 +465,113 @@ function indeterminateFrame(elapsedMillis, morphCount, timing) {
364
465
  };
365
466
  }
366
467
 
468
+ // src/menu-position.ts
469
+ var round2 = Math.round;
470
+ var alignH = (bias, size, space, rtl) => round2((space - size) / 2 * (1 + (rtl ? -bias : bias)));
471
+ var alignV = (bias, size, space) => round2((space - size) / 2 * (1 + bias));
472
+ var START = -1;
473
+ var END = 1;
474
+ var TOP = -1;
475
+ var CENTER = 0;
476
+ var BOTTOM = 1;
477
+ var anchorH = (menuBias, anchorBias) => (anchor, _width, menuWidth, rtl) => anchor.left + alignH(anchorBias, 0, anchor.right - anchor.left, rtl) - alignH(menuBias, 0, menuWidth, rtl);
478
+ var anchorV = (menuBias, anchorBias) => (anchor, _height, menuHeight) => anchor.top + alignV(anchorBias, 0, anchor.bottom - anchor.top) - alignV(menuBias, 0, menuHeight);
479
+ var startToAnchorStart = anchorH(START, START);
480
+ var startToAnchorEnd = anchorH(START, END);
481
+ var endToAnchorEnd = anchorH(END, END);
482
+ var endToAnchorStart = anchorH(END, START);
483
+ var leftToWindowLeft = (_a, width, menuWidth) => alignH(START, menuWidth, width, false);
484
+ var rightToWindowRight = (_a, width, menuWidth) => alignH(END, menuWidth, width, false);
485
+ var topToAnchorBottom = anchorV(TOP, BOTTOM);
486
+ var topToAnchorTop = anchorV(TOP, TOP);
487
+ var bottomToAnchorTop = anchorV(BOTTOM, TOP);
488
+ var bottomToAnchorBottom = anchorV(BOTTOM, BOTTOM);
489
+ var centerToAnchorTop = anchorV(CENTER, TOP);
490
+ var topToWindowTop = (_a, height, menuHeight) => alignV(TOP, menuHeight, height);
491
+ var bottomToWindowBottom = (_a, height, menuHeight) => alignV(BOTTOM, menuHeight, height);
492
+ var centerX = (r) => (r.left + r.right) / 2;
493
+ var centerY = (r) => (r.top + r.bottom) / 2;
494
+ var windowX = (anchor, width) => centerX(anchor) < width / 2 ? leftToWindowLeft : rightToWindowRight;
495
+ var windowY = (anchor, height) => centerY(anchor) < height / 2 ? topToWindowTop : bottomToWindowBottom;
496
+ function candidates(position, anchor, width, height) {
497
+ const wx = windowX(anchor, width);
498
+ const wy = windowY(anchor, height);
499
+ switch (position) {
500
+ case "above":
501
+ return [
502
+ [startToAnchorStart, endToAnchorEnd, wx],
503
+ [bottomToAnchorTop, topToAnchorBottom, centerToAnchorTop, wy]
504
+ ];
505
+ // Left and Start (Right and End) list the same candidates; Start/End resolve against the
506
+ // layout direction inside the candidates, Left/Right too (Menu.kt keeps them identical).
507
+ case "left":
508
+ case "start":
509
+ return [
510
+ [endToAnchorStart, startToAnchorEnd, wx],
511
+ [topToAnchorTop, bottomToAnchorBottom, wy]
512
+ ];
513
+ case "right":
514
+ case "end":
515
+ return [
516
+ [startToAnchorEnd, endToAnchorStart, wx],
517
+ [topToAnchorTop, bottomToAnchorBottom, wy]
518
+ ];
519
+ // 'below' (unrecognized values too).
520
+ default:
521
+ return [
522
+ [startToAnchorStart, endToAnchorEnd, wx],
523
+ [topToAnchorBottom, bottomToAnchorTop, centerToAnchorTop, wy]
524
+ ];
525
+ }
526
+ }
527
+ var coerceIn = (v, min, max) => Math.min(Math.max(v, min), max);
528
+ function pick(values, size, space, margin, center) {
529
+ for (const [i, candidate] of values.entries()) {
530
+ if (candidate >= margin && candidate + size <= space - margin) return candidate;
531
+ if (i === values.length - 1) {
532
+ return size >= space - 2 * margin ? center() : coerceIn(candidate, margin, space - margin - size);
533
+ }
534
+ }
535
+ return 0;
536
+ }
537
+ function menuTransformOrigin(anchor, menu) {
538
+ const menuWidth = menu.right - menu.left;
539
+ const menuHeight = menu.bottom - menu.top;
540
+ const originX = menu.left >= anchor.right ? 0 : menu.right <= anchor.left ? 1 : menuWidth === 0 ? 0 : ((Math.max(anchor.left, menu.left) + Math.min(anchor.right, menu.right)) / 2 - menu.left) / menuWidth;
541
+ const originY = menu.top >= anchor.bottom ? 0 : menu.bottom <= anchor.top ? 1 : menuHeight === 0 ? 0 : ((Math.max(anchor.top, menu.top) + Math.min(anchor.bottom, menu.bottom)) / 2 - menu.top) / menuHeight;
542
+ return { originX, originY };
543
+ }
544
+ function menuPosition(input) {
545
+ const { anchor, window: win, menu, rtl, verticalMargin, horizontalMargin } = input;
546
+ const offset = input.offset ?? { x: 0, y: 0 };
547
+ const [xs, ys] = candidates(input.position ?? "below", anchor, win.width, win.height);
548
+ const offsetX = offset.x * (rtl ? -1 : 1);
549
+ const x = pick(
550
+ xs.map((c) => c(anchor, win.width, menu.width, rtl) + offsetX),
551
+ menu.width,
552
+ win.width,
553
+ horizontalMargin,
554
+ () => alignH(CENTER, menu.width, win.width, rtl)
555
+ );
556
+ const y = pick(
557
+ ys.map((c) => c(anchor, win.height, menu.height) + offset.y),
558
+ menu.height,
559
+ win.height,
560
+ verticalMargin,
561
+ () => alignV(CENTER, menu.height, win.height)
562
+ );
563
+ return {
564
+ x,
565
+ y,
566
+ ...menuTransformOrigin(anchor, {
567
+ left: x,
568
+ top: y,
569
+ right: x + menu.width,
570
+ bottom: y + menu.height
571
+ })
572
+ };
573
+ }
574
+
367
575
  // src/app-bar-scroll.ts
368
576
  function appBarScrollState(height) {
369
577
  return { heightOffsetLimit: -height, heightOffset: 0, contentOffset: 0, atStart: true };
@@ -398,6 +606,52 @@ function settleTarget(state) {
398
606
  return fraction < 0.5 ? 0 : state.heightOffsetLimit;
399
607
  }
400
608
 
401
- export { DEFAULT_DISPLACEMENT_THRESHOLD, SpringSimulation, appBarScrollState, collapsedFraction, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, indeterminateFrame, initialIndeterminateFrame, isScrolledUnder, morphSpringDurationMillis, overlappedFraction, scrollAppBar, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, withHeight, withHeightOffset };
609
+ // src/button-group.ts
610
+ function buttonGroupVisibleCount(widths, spacing, maxWidth, overflowWidth) {
611
+ const desired = widths.reduce((sum, w) => sum + w, 0) + spacing * (widths.length - 1);
612
+ if (desired <= maxWidth) return widths.length;
613
+ let remaining = maxWidth - overflowWidth;
614
+ let last = 0;
615
+ for (const width of widths) {
616
+ if (width > remaining) break;
617
+ remaining -= width + spacing;
618
+ last++;
619
+ }
620
+ return last;
621
+ }
622
+ function buttonGroupWidths(items, pressed, expandedRatio, visibleCount = items.length) {
623
+ const widths = items.map((item) => item.width);
624
+ const w = (i) => widths[i] ?? 0;
625
+ const limit = (i) => items[i]?.compressionLimit ?? 0;
626
+ const last = Math.min(visibleCount, items.length);
627
+ if (items.length <= 1) return widths.slice(0, last);
628
+ for (let index = 0; index < last; index++) {
629
+ const value = pressed[index] ?? 0;
630
+ if (value === 0) continue;
631
+ let growth;
632
+ if (index >= 1 && index < last - 1) {
633
+ const target = value * Math.min(expandedRatio * w(index) / 2, limit(index - 1), limit(index + 1));
634
+ const left = Math.min(target, w(index - 1));
635
+ const right = Math.min(target, w(index + 1));
636
+ widths[index - 1] = w(index - 1) - left;
637
+ widths[index + 1] = w(index + 1) - right;
638
+ growth = left + right;
639
+ } else if (index === 0) {
640
+ const target = value * Math.min(expandedRatio * w(index), limit(index + 1));
641
+ const right = Math.min(target, w(index + 1));
642
+ widths[index + 1] = w(index + 1) - right;
643
+ growth = right;
644
+ } else {
645
+ const target = value * Math.min(expandedRatio * w(index), limit(index - 1));
646
+ const left = Math.min(target, w(index - 1));
647
+ widths[index - 1] = w(index - 1) - left;
648
+ growth = left;
649
+ }
650
+ widths[index] = w(index) + growth;
651
+ }
652
+ return widths.slice(0, last);
653
+ }
654
+
655
+ export { DEFAULT_DISPLACEMENT_THRESHOLD, SpringAnimatable, SpringSimulation, animatedInt, appBarScrollState, buttonGroupVisibleCount, buttonGroupWidths, collapsedFraction, dampingCoefficient, dampingRatioFromCoefficient, estimateAnimationDurationMillis, estimateAnimationDurationMillisDouble, fabMenuItemVisible, indeterminateFrame, initialIndeterminateFrame, isScrolledUnder, menuNavigationTarget, menuPosition, menuTransformOrigin, morphSpringDurationMillis, overlappedFraction, scrollAppBar, settleTarget, springDurationMillis, springToLinear, springValue, springVelocity, withHeight, withHeightOffset };
402
656
  //# sourceMappingURL=index.js.map
403
657
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/spring-estimation.ts","../src/spring-simulation.ts","../src/spring.ts","../src/linear.ts","../src/loading-indicator.ts","../src/app-bar-scroll.ts"],"names":["f32","dampingCoefficient"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringEstimation.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// The Float overload's arguments are rounded to float32 (Math.fround) before widening to Double,\n// as in Kotlin. Durations are Long milliseconds: Kotlin's Double.toLong() (truncation, NaN → 0,\n// saturating) is reproduced by `toLong`.\n\n/** Maximum duration in Milliseconds. This takes into account that the duration will be converted to nanos. */\n// Long.MAX_VALUE / Long.MIN_VALUE as doubles (2^63 is what Kotlin's Long.toDouble() yields).\nconst LONG_MAX = 2 ** 63;\nconst LONG_MIN = -(2 ** 63);\nconst MAX_LONG_MILLIS = 9_223_372_036_854; // Long.MAX_VALUE / 1_000_000 (integer division)\n\nconst toLong = (x: number): number =>\n Number.isNaN(x) ? 0 : x >= LONG_MAX ? LONG_MAX : x <= LONG_MIN ? LONG_MIN : Math.trunc(x);\n\n/**\n * Returns the estimated time that the spring will last be at [delta]. Arguments are Kotlin\n * `Float`s (rounded to float32).\n */\nexport function estimateAnimationDurationMillis(\n stiffness: number,\n dampingRatio: number,\n initialVelocity: number,\n initialDisplacement: number,\n delta: number,\n): number {\n const f32 = Math.fround;\n if (f32(dampingRatio) === 0) {\n // No damping, duration is infinite (max value).\n return MAX_LONG_MILLIS;\n }\n\n return estimateAnimationDurationMillisDouble(\n f32(stiffness),\n f32(dampingRatio),\n f32(initialVelocity),\n f32(initialDisplacement),\n f32(delta),\n );\n}\n\n/** Returns the estimated time that the spring will last be at [delta] (Double overload). */\nexport function estimateAnimationDurationMillisDouble(\n stiffness: number,\n dampingRatio: number,\n initialVelocity: number,\n initialDisplacement: number,\n delta: number,\n): number {\n const dampingCoefficient = 2.0 * dampingRatio * Math.sqrt(stiffness);\n\n // Compute the roots of the polynomial [a]x^2+[b]x+[c]=0 which may be complex.\n // Here a is set to the constant 1.0, and folded into the other computations\n const partialRoot = dampingCoefficient * dampingCoefficient - 4.0 * stiffness;\n const partialRootReal = partialRoot < 0.0 ? 0.0 : Math.sqrt(partialRoot);\n const partialRootImaginary = partialRoot < 0.0 ? Math.sqrt(Math.abs(partialRoot)) : 0.0;\n\n const firstRootReal = (-dampingCoefficient + partialRootReal) * 0.5;\n const firstRootImaginary = partialRootImaginary * 0.5;\n const secondRootReal = (-dampingCoefficient - partialRootReal) * 0.5;\n\n return estimateDurationInternal(\n firstRootReal,\n firstRootImaginary,\n secondRootReal,\n dampingRatio,\n initialVelocity,\n initialDisplacement,\n delta,\n );\n}\n\n/**\n * In the under-damped case we simply calculate the envelope of the function. The general solution\n * is of the form x(t) = c_1*e^(r*t)*cos(...) + c_2*e^(r*t)sin(...) which simplifies to x(t) =\n * c*e^(r*t)*cos(...) where c*e^(r*t) is the envelope of x(t)\n */\nfunction estimateUnderDamped(\n firstRootReal: number,\n firstRootImaginary: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r = firstRootReal;\n const c1 = p0;\n const c2 = (v0 - r * c1) / firstRootImaginary;\n const c = Math.sqrt(c1 * c1 + c2 * c2);\n\n return Math.log(delta / c) / r;\n}\n\nconst isNotFinite = (x: number) => !Number.isFinite(x);\n\nconst iterateNewtonsMethod = (\n x: number,\n fn: (t: number) => number,\n fnPrime: (t: number) => number,\n): number => x - fn(x) / fnPrime(x);\n\n/**\n * In the critically-damped case we apply Newton-Raphson's iterative numerical method of solving the\n * equation x(t) = c_1*e^(r*t) + c_2*t*e^(r*t)\n */\nfunction estimateCriticallyDamped(\n firstRootReal: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r = firstRootReal;\n const c1 = p0;\n const c2 = v0 - r * c1;\n\n // For our initial guess, determine the max t of c_1*e^(r*t) = delta and\n // c_2*t*e^(r*t) = delta\n const t1 = Math.log(Math.abs(delta / c1)) / r;\n const t2 =\n (() => {\n // Application of Lambert's W function to solve te^t\n const guess = Math.log(Math.abs(delta / c2));\n let t = guess;\n for (let i = 0; i <= 5; i++) {\n t = guess - Math.log(Math.abs(t / r));\n }\n return t;\n })() / r;\n let tCurr = isNotFinite(t1) ? t2 : isNotFinite(t2) ? t1 : Math.max(t1, t2);\n\n // Calculate the inflection time. This is important if the inflection is in t > 0\n const tInflection = -(r * c1 + c2) / (r * c2);\n const xInflection = c1 * Math.exp(r * tInflection) + c2 * tInflection * Math.exp(r * tInflection);\n\n // For inflection that does not exist in real time, we always solve for x(t)=delta. Note\n // the system is manipulated such that p0 is always positive.\n let signedDelta: number;\n if (Number.isNaN(tInflection) || tInflection <= 0.0) {\n signedDelta = -delta;\n } else if (tInflection > 0.0 && -xInflection < delta) {\n // In this scenario the first crossing with the threshold is to be found. Note that\n // the inflection does not exceed delta. As such, we search from the left.\n if (c2 < 0 && c1 > 0) {\n tCurr = 0.0;\n }\n signedDelta = -delta;\n } else {\n // In this scenario there are three total crossings of the threshold, once from\n // above, and then once when the inflection exceeds the threshold and then one last\n // one when x(t) finally decays to zero. The point of determining concavity is to\n // find the final crossing.\n //\n // By finding a point between when concavity changes, and when the inflection point is,\n // Newton's method will always converge onto the rightmost point (in this case),\n // the one that we are interested in.\n tCurr = -(2.0 / r) - c1 / c2;\n signedDelta = delta;\n }\n\n let tDelta = Number.MAX_VALUE;\n let iterations = 0;\n while (tDelta > 0.001 && iterations < 100) {\n iterations++;\n const tLast = tCurr;\n tCurr = iterateNewtonsMethod(\n tCurr,\n (t) => (c1 + c2 * t) * Math.exp(r * t) + signedDelta,\n (t) => (c2 * (r * t + 1) + c1 * r) * Math.exp(r * t),\n );\n tDelta = Math.abs(tLast - tCurr);\n }\n\n return tCurr;\n}\n\n/**\n * In the over-damped case we apply Newton-Raphson's iterative numerical method of solving the\n * equation x(t) = c_1*e^(r_1*t) + c_2*e^(r_2*t)\n */\nfunction estimateOverDamped(\n firstRootReal: number,\n secondRootReal: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r1 = firstRootReal;\n const r2 = secondRootReal;\n const c2 = (r1 * p0 - v0) / (r1 - r2);\n const c1 = p0 - c2;\n\n // For our initial guess, determine the max t of c_1*e^(r_1*t) = delta and\n // c_2*e^(r_2*t) = delta\n const t1 = Math.log(Math.abs(delta / c1)) / r1;\n const t2 = Math.log(Math.abs(delta / c2)) / r2;\n\n let tCurr = isNotFinite(t1) ? t2 : isNotFinite(t2) ? t1 : Math.max(t1, t2);\n\n // Calculate the inflection time. This is important if the inflection is in t > 0\n const tInflection = Math.log((c1 * r1) / (-c2 * r2)) / (r2 - r1);\n const xInflection = () => c1 * Math.exp(r1 * tInflection) + c2 * Math.exp(r2 * tInflection);\n\n // For inflection that does not exist in real time, we always solve for x(t)=delta. Note\n // the system is manipulated such that p0 is always positive.\n let signedDelta: number;\n if (Number.isNaN(tInflection) || tInflection <= 0.0) {\n signedDelta = -delta;\n } else if (tInflection > 0.0 && -xInflection() < delta) {\n // In this scenario the first crossing with the threshold is to be found. Note that\n // the inflection does not exceed delta. As such, we search from the left.\n if (c2 > 0.0 && c1 < 0.0) {\n tCurr = 0.0;\n }\n signedDelta = -delta;\n } else {\n // In this scenario there are three total crossings of the threshold, once from\n // above, and then once when the inflection exceeds the threshold and then one last\n // one when x(t) finally decays to zero. The point of determining concavity is to\n // find the final crossing.\n //\n // By finding a point between when concavity changes, and when the inflection point is,\n // Newton's method will always converge onto the rightmost point (in this case),\n // the one that we are interested in.\n tCurr = Math.log(-(c2 * r2 * r2) / (c1 * r1 * r1)) / (r1 - r2);\n signedDelta = delta;\n }\n\n // For a good initial guess, simply return\n if (Math.abs(c1 * r1 * Math.exp(r1 * tCurr) + c2 * r2 * Math.exp(r2 * tCurr)) < 0.0001) {\n return tCurr;\n }\n let tDelta = Number.MAX_VALUE;\n\n // Cap iterations for safety - Experimentally this method takes <= 5 iterations\n let iterations = 0;\n while (tDelta > 0.001 && iterations < 100) {\n iterations++;\n const tLast = tCurr;\n tCurr = iterateNewtonsMethod(\n tCurr,\n (t) => c1 * Math.exp(r1 * t) + c2 * Math.exp(r2 * t) + signedDelta,\n (t) => c1 * r1 * Math.exp(r1 * t) + c2 * r2 * Math.exp(r2 * t),\n );\n tDelta = Math.abs(tLast - tCurr);\n }\n\n return tCurr;\n}\n\n// Applies Newton-Raphson's method to solve for the estimated time the spring mass system will\n// last be at [delta].\nfunction estimateDurationInternal(\n firstRootReal: number,\n firstRootImaginary: number,\n secondRootReal: number,\n dampingRatio: number,\n initialVelocity: number,\n initialPosition: number,\n delta: number,\n): number {\n if (initialPosition === 0.0 && initialVelocity === 0.0) {\n return 0;\n }\n\n const v0 = initialPosition < 0 ? -initialVelocity : initialVelocity;\n const p0 = Math.abs(initialPosition);\n\n const seconds =\n dampingRatio > 1.0\n ? estimateOverDamped(firstRootReal, secondRootReal, p0, v0, delta)\n : dampingRatio < 1.0\n ? estimateUnderDamped(firstRootReal, firstRootImaginary, p0, v0, delta)\n : estimateCriticallyDamped(firstRootReal, p0, v0, delta);\n return toLong(seconds * 1000.0);\n}\n","/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// Precision follows the Kotlin source: parameters and results are Float (Math.fround), the\n// solution is computed in Double, and time is whole milliseconds.\n\nconst f32 = Math.fround;\n\n/** `Spring.StiffnessVeryLow` / `Spring.DampingRatioNoBouncy` (VectorizedAnimationSpec.kt L813, L839). */\nconst STIFFNESS_VERY_LOW = 50;\nconst DAMPING_RATIO_NO_BOUNCY = 1;\n\nexport interface Motion {\n value: number;\n velocity: number;\n}\n\n/**\n * Spring Simulation simulates spring physics, and allows you to query the motion (i.e. value and\n * velocity) at certain time in the future based on the starting velocity and value.\n *\n * By configuring the stiffness and damping ratio, callers can create a spring with the look and\n * feel suits their use case. Stiffness corresponds to the spring constant. The stiffer the spring\n * is, the harder it is to stretch it, the faster it undergoes dampening.\n *\n * Spring damping ratio describes how oscillations in a system decay after a disturbance. When\n * damping ratio > 1* (i.e. over-damped), the object will quickly return to the rest position\n * without overshooting. If damping ratio equals to 1 (i.e. critically damped), the object will\n * return to equilibrium within the shortest amount of time. When damping ratio is less than 1 (i.e.\n * under-damped), the mass tends to overshoot, and return, and overshoot again. Without any damping\n * (i.e. damping ratio = 0), the mass will oscillate forever.\n */\nexport class SpringSimulation {\n // Natural frequency\n #naturalFreq = Math.sqrt(STIFFNESS_VERY_LOW);\n #dampingRatio = DAMPING_RATIO_NO_BOUNCY;\n #finalPosition: number;\n\n constructor(finalPosition: number) {\n this.#finalPosition = f32(finalPosition);\n }\n\n get finalPosition(): number {\n return this.#finalPosition;\n }\n\n set finalPosition(value: number) {\n this.#finalPosition = f32(value);\n }\n\n /** Stiffness of the spring. */\n get stiffness(): number {\n return f32(this.#naturalFreq * this.#naturalFreq);\n }\n\n set stiffness(value: number) {\n // Upstream checks the *current* stiffness here (always positive), so the new value is not\n // validated; kept as-is for parity.\n if (this.stiffness <= 0) {\n throw new RangeError('Spring stiffness constant must be positive.');\n }\n this.#naturalFreq = Math.sqrt(f32(value));\n }\n\n /** Returns the damping ratio of the spring. */\n get dampingRatio(): number {\n return this.#dampingRatio;\n }\n\n set dampingRatio(value: number) {\n if (value < 0) {\n throw new RangeError('Damping ratio must be non-negative');\n }\n this.#dampingRatio = f32(value);\n }\n\n getAcceleration(lastDisplacement: number, lastVelocity: number): number {\n const adjustedDisplacement = f32(f32(lastDisplacement) - this.#finalPosition);\n\n const k = this.#naturalFreq * this.#naturalFreq;\n const c = 2.0 * this.#naturalFreq * this.#dampingRatio;\n\n return f32(-k * adjustedDisplacement - c * f32(lastVelocity));\n }\n\n /**\n * Internal only call for Spring to calculate the spring position/velocity using an analytical\n * approach.\n */\n updateValues(lastDisplacement: number, lastVelocity: number, timeElapsed: number): Motion {\n const dampingRatio = this.#dampingRatio;\n const naturalFreq = this.#naturalFreq;\n const velocity0 = f32(lastVelocity);\n const adjustedDisplacement = f32(f32(lastDisplacement) - this.#finalPosition);\n const deltaT = Math.trunc(timeElapsed) / 1000.0; // unit: seconds\n const dampingRatioSquared = dampingRatio * dampingRatio;\n const r = -dampingRatio * naturalFreq;\n\n let displacement: number;\n let currentVelocity: number;\n\n if (dampingRatio > 1) {\n // Over damping\n const s = naturalFreq * Math.sqrt(dampingRatioSquared - 1);\n const gammaPlus = r + s;\n const gammaMinus = r - s;\n\n // Overdamped\n const coeffB = (gammaMinus * adjustedDisplacement - velocity0) / (gammaMinus - gammaPlus);\n const coeffA = adjustedDisplacement - coeffB;\n displacement = coeffA * Math.exp(gammaMinus * deltaT) + coeffB * Math.exp(gammaPlus * deltaT);\n currentVelocity =\n coeffA * gammaMinus * Math.exp(gammaMinus * deltaT) +\n coeffB * gammaPlus * Math.exp(gammaPlus * deltaT);\n } else if (dampingRatio === 1.0) {\n // Critically damped\n const coeffA = adjustedDisplacement;\n const coeffB = velocity0 + naturalFreq * adjustedDisplacement;\n const nFdT = -naturalFreq * deltaT;\n displacement = (coeffA + coeffB * deltaT) * Math.exp(nFdT);\n currentVelocity =\n (coeffA + coeffB * deltaT) * Math.exp(nFdT) * -naturalFreq + coeffB * Math.exp(nFdT);\n } else {\n const dampedFreq = naturalFreq * Math.sqrt(1 - dampingRatioSquared);\n // Underdamped\n const cosCoeff = adjustedDisplacement;\n const sinCoeff = (1 / dampedFreq) * (-r * adjustedDisplacement + velocity0);\n const dFdT = dampedFreq * deltaT;\n displacement = Math.exp(r * deltaT) * (cosCoeff * Math.cos(dFdT) + sinCoeff * Math.sin(dFdT));\n currentVelocity =\n displacement * r +\n Math.exp(r * deltaT) *\n (-dampedFreq * cosCoeff * Math.sin(dFdT) + dampedFreq * sinCoeff * Math.cos(dFdT));\n }\n\n return {\n value: f32(displacement + this.#finalPosition),\n velocity: f32(currentVelocity),\n };\n }\n}\n","// Spring helpers with Compose `FloatSpringSpec` semantics (animation-core FloatAnimationSpec.kt\n// L133–187 @19991f2c), built on the ported SpringSimulation / SpringEstimation.\nimport { estimateAnimationDurationMillis } from './spring-estimation.js';\nimport { SpringSimulation } from './spring-simulation.js';\n\n/** A Material motion-scheme spring (`dampingRatio` ζ, `stiffness` k; mass 1). */\nexport interface SpringSpec {\n readonly dampingRatio: number;\n readonly stiffness: number;\n}\n\n/** `Spring.DefaultDisplacementThreshold` (VectorizedAnimationSpec.kt L842). */\nexport const DEFAULT_DISPLACEMENT_THRESHOLD = 0.01;\n\nconst f32 = Math.fround;\n\nfunction simulation(spec: SpringSpec, targetValue: number): SpringSimulation {\n const sim = new SpringSimulation(targetValue);\n sim.dampingRatio = spec.dampingRatio;\n sim.stiffness = spec.stiffness;\n return sim;\n}\n\n/** Value at `playTimeMillis` (whole milliseconds, as in Compose). */\nexport function springValue(\n spec: SpringSpec,\n playTimeMillis: number,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n): number {\n return simulation(spec, targetValue).updateValues(initialValue, initialVelocity, playTimeMillis)\n .value;\n}\n\n/** Velocity (units/s) at `playTimeMillis`. */\nexport function springVelocity(\n spec: SpringSpec,\n playTimeMillis: number,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n): number {\n return simulation(spec, targetValue).updateValues(initialValue, initialVelocity, playTimeMillis)\n .velocity;\n}\n\n/**\n * Duration until the spring stays within `visibilityThreshold` of the target, as Compose computes\n * it (`FloatSpringSpec.getDurationNanos` / 1e6).\n */\nexport function springDurationMillis(\n spec: SpringSpec,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n visibilityThreshold = DEFAULT_DISPLACEMENT_THRESHOLD,\n): number {\n const sim = simulation(spec, targetValue);\n const threshold = f32(visibilityThreshold);\n return estimateAnimationDurationMillis(\n sim.stiffness,\n sim.dampingRatio,\n f32(f32(initialVelocity) / threshold),\n f32(f32(f32(initialValue) - f32(targetValue)) / threshold),\n 1,\n );\n}\n\n/**\n * Damping coefficient c = 2ζ√(k·m), for physics engines parameterized by stiffness/damping/mass\n * (e.g. Motion's `{ type: 'spring', stiffness, damping, mass }`).\n */\nexport function dampingCoefficient(spec: SpringSpec, mass = 1): number {\n return 2 * spec.dampingRatio * Math.sqrt(spec.stiffness * mass);\n}\n\n/** Inverse of {@link dampingCoefficient}: ζ = c / (2√(k·m)). */\nexport function dampingRatioFromCoefficient(damping: number, stiffness: number, mass = 1): number {\n return damping / (2 * Math.sqrt(stiffness * mass));\n}\n","// CSS `linear()` approximation of a spring (FOUNDATIONS §4).\n//\n// - Duration: Compose's own settle estimate (`FloatSpringSpec.getDurationNanos`) for a 0 → 1\n// animation at a visibility threshold of 0.001 (0.1% of the travel; e.g. Compose's 0.1 dp\n// Dp threshold over a 100 dp move).\n// - Samples: the exact spring at every whole millisecond (Compose's time resolution), last stop\n// forced to 1 so the animation lands on its target.\n// - Stops: Ramer–Douglas–Peucker in (progress, value) space with the smallest tolerance that fits\n// `maxStops`.\n//\n// Limits (FOUNDATIONS §4): no velocity carry-over on interruption and a fixed duration; use the JS\n// spring for drags, rapid toggles and other interruptible motion.\nimport { type SpringSpec, springDurationMillis } from './spring.js';\nimport { SpringSimulation } from './spring-simulation.js';\n\nexport interface LinearEasingOptions {\n /** Fraction of the travel considered settled. Default 0.001. */\n visibilityThreshold?: number;\n /** Maximum stops in the `linear()` function (FOUNDATIONS §4: ≤ 40). Default 40. */\n maxStops?: number;\n}\n\nexport interface LinearEasing {\n /** e.g. `linear(0, 0.1234 5%, …, 1)` */\n easing: string;\n durationMillis: number;\n /** `[progress 0–1, value]` pairs after rounding. */\n stops: readonly (readonly [number, number])[];\n /** Max |linear(t) − spring(t)| over every millisecond sample. */\n maxError: number;\n}\n\nconst round = (n: number, digits: number) => {\n const r = Number(n.toFixed(digits));\n return Object.is(r, -0) ? 0 : r;\n};\n\ntype Point = readonly [number, number];\n\nfunction at<T>(list: readonly T[], i: number): T {\n const item = list[i];\n if (item === undefined) throw new RangeError(`index ${String(i)} out of range`);\n return item;\n}\n\n/** Ramer–Douglas–Peucker: indices of points to keep (vertical distance, monotone x). */\nfunction simplify(points: readonly Point[], tolerance: number): number[] {\n const keep = new Set<number>([0, points.length - 1]);\n const stack: [number, number][] = [[0, points.length - 1]];\n for (let range = stack.pop(); range; range = stack.pop()) {\n const [a, b] = range;\n const [x0, y0] = at(points, a);\n const [x1, y1] = at(points, b);\n let worst = -1;\n let worstDistance = tolerance;\n for (let i = a + 1; i < b; i++) {\n const [x, y] = at(points, i);\n const expected = y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);\n const distance = Math.abs(y - expected);\n if (distance > worstDistance) {\n worst = i;\n worstDistance = distance;\n }\n }\n if (worst !== -1) {\n keep.add(worst);\n stack.push([a, worst], [worst, b]);\n }\n }\n return [...keep].sort((x, y) => x - y);\n}\n\nfunction interpolate(stops: readonly Point[], x: number): number {\n for (let i = 1; i < stops.length; i++) {\n const [x1, y1] = at(stops, i);\n const [x0, y0] = at(stops, i - 1);\n if (x <= x1) return x1 === x0 ? y1 : y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);\n }\n return at(stops, stops.length - 1)[1];\n}\n\nexport function springToLinear(spec: SpringSpec, options: LinearEasingOptions = {}): LinearEasing {\n const { visibilityThreshold = 0.001, maxStops = 40 } = options;\n if (maxStops < 2) throw new RangeError('maxStops must be at least 2');\n const durationMillis = Math.max(1, springDurationMillis(spec, 0, 1, 0, visibilityThreshold));\n\n const sim = new SpringSimulation(1);\n sim.dampingRatio = spec.dampingRatio;\n sim.stiffness = spec.stiffness;\n const samples: Point[] = [];\n for (let t = 0; t <= durationMillis; t++) {\n samples.push([t / durationMillis, sim.updateValues(0, 0, t).value]);\n }\n samples[samples.length - 1] = [1, 1];\n\n // Smallest tolerance (bisection) whose simplification fits maxStops.\n let lo = 0;\n let hi = 0.5;\n let best = simplify(samples, hi);\n for (let i = 0; i < 40; i++) {\n const mid = (lo + hi) / 2;\n const kept = simplify(samples, mid);\n if (kept.length <= maxStops) {\n best = kept;\n hi = mid;\n } else {\n lo = mid;\n }\n }\n\n const stops = best.map((i) => {\n const [x, y] = at(samples, i);\n return [round(x, 4), round(y, 4)] as const;\n });\n const maxError = samples.reduce(\n (m, [x, y]) => Math.max(m, Math.abs(interpolate(stops, x) - y)),\n 0,\n );\n const body = stops.map(([x, y], i) =>\n i === 0 || i === stops.length - 1 ? String(y) : `${String(y)} ${String(round(x * 100, 2))}%`,\n );\n return { easing: `linear(${body.join(', ')})`, durationMillis, stops, maxError };\n}\n","/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/LoadingIndicator.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// The indeterminate LoadingIndicator's LaunchedEffect (L391–451) as a pure function of elapsed\n// time. Compose runs two coroutines:\n// - every MorphIntervalMillis a spring animates the morph progress 0 → 1; when it finishes, the\n// indicator advances to the next morph, snaps the progress to 0 and adds a quarter turn to the\n// morph rotation. The loop then waits for the rest of the interval (or for the spring, if it is\n// slower than the interval);\n// - a linear global rotation turns 360° every GlobalRotationDurationMillis, restarting.\n// The drawn rotation is `progress × 90 + morphRotationTargetAngle + globalRotation` (L473).\n// The interval, rotation duration and spring are tokens (components/loading-indicator-motion.css).\n\nimport { type SpringSpec, springDurationMillis, springValue } from './spring.js';\n\nconst FULL_ROTATION = 360;\nconst QUARTER_ROTATION = FULL_ROTATION / 4;\n\nexport interface LoadingIndicatorTiming {\n /** `MorphIntervalMillis`: how often a morph starts. */\n readonly morphIntervalMillis: number;\n /** `GlobalRotationDurationMillis`: one linear turn. */\n readonly rotationDurationMillis: number;\n /** The morph spring (`morphAnimationSpec`). */\n readonly spring: SpringSpec;\n /** The morph spring's `visibilityThreshold`; it decides when the spring finishes. */\n readonly visibilityThreshold: number;\n}\n\n/** What the indicator draws: a morph at a progress, rotated clockwise about the center. */\nexport interface IndeterminateFrame {\n morphIndex: number;\n /** The raw spring value: it overshoots past 1, as in Compose (the morph extrapolates). */\n morphProgress: number;\n /** Degrees, clockwise. */\n rotation: number;\n}\n\n/**\n * The first frame (and the one held under reduced motion): the first morph at 0, rotated by the\n * initial `morphRotationTargetAngle` (a quarter turn).\n */\nexport const initialIndeterminateFrame: Readonly<IndeterminateFrame> = {\n morphIndex: 0,\n morphProgress: 0,\n rotation: QUARTER_ROTATION,\n};\n\n/** How long one morph spring runs (Compose's `FloatSpringSpec.getDurationNanos`), in ms. */\nexport const morphSpringDurationMillis = (timing: LoadingIndicatorTiming): number =>\n springDurationMillis(timing.spring, 0, 1, 0, timing.visibilityThreshold);\n\n/**\n * The frame of an indeterminate loading indicator [elapsedMillis] after it started, cycling\n * through [morphCount] morphs.\n */\nexport function indeterminateFrame(\n elapsedMillis: number,\n morphCount: number,\n timing: LoadingIndicatorTiming,\n): IndeterminateFrame {\n const t = Math.max(0, elapsedMillis);\n const springMillis = morphSpringDurationMillis(timing);\n // `delay(MorphIntervalMillis)` then `deferred.await()`: the next morph starts after both.\n const period = Math.max(timing.morphIntervalMillis, springMillis);\n const completed = Math.floor(t / period);\n const local = t - completed * period;\n const running = local < springMillis;\n // Each finished spring advances the index and adds a quarter turn (starting at a quarter turn).\n const finished = running ? completed : completed + 1;\n const morphIndex = finished % morphCount;\n const targetAngle = (QUARTER_ROTATION * (finished + 1)) % FULL_ROTATION;\n // Compose samples the spring at whole milliseconds of play time.\n const morphProgress = running ? springValue(timing.spring, Math.floor(local), 0, 1) : 0;\n const globalRotation =\n (FULL_ROTATION * Math.floor(t % timing.rotationDurationMillis)) / timing.rotationDurationMillis;\n return {\n morphIndex,\n morphProgress,\n rotation: morphProgress * QUARTER_ROTATION + targetAngle + globalRotation,\n };\n}\n","/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// TopAppBarState (L2050-2130), the pinned and enter-always scroll behaviors (L3267-3303,\n// L3400-3455) and the settle decision of settleAppBar (L3542-3589), adapted to DOM scrolling.\n// Compose receives nested\n// scroll deltas and can consume them; the web observes `scrollTop` after the browser scrolled, so\n// every delta goes to both the bar and the content, and momentum comes from the browser instead\n// of flingAnimationSpec. Offsets are in CSS px; y grows downward, so collapsing is negative.\n\n/** How the bar reacts to its scroll container (TopAppBarDefaults.*ScrollBehavior). */\nexport type AppBarScrollBehavior = 'pinned' | 'enter-always';\n\nexport interface AppBarScrollState {\n /** Most negative height offset: minus the bar's full height (adjustHeightOffsetLimit). */\n readonly heightOffsetLimit: number;\n /** Current height offset, between heightOffsetLimit and 0. */\n readonly heightOffset: number;\n /** Content scrolled under the bar (minus the scroll position). */\n readonly contentOffset: number;\n /** Whether the scrolling content is at its start (scroll position 0). */\n readonly atStart: boolean;\n}\n\n/** A fully expanded bar of `height` px over unscrolled content. */\nexport function appBarScrollState(height: number): AppBarScrollState {\n return { heightOffsetLimit: -height, heightOffset: 0, contentOffset: 0, atStart: true };\n}\n\n/** TopAppBarState.heightOffset setter: coerced between heightOffsetLimit and 0. */\nexport function withHeightOffset(state: AppBarScrollState, offset: number): AppBarScrollState {\n return { ...state, heightOffset: Math.min(Math.max(offset, state.heightOffsetLimit), 0) };\n}\n\n/** A new bar height (onSizeChanged → adjustHeightOffsetLimit), keeping the offset in range. */\nexport function withHeight(state: AppBarScrollState, height: number): AppBarScrollState {\n return withHeightOffset({ ...state, heightOffsetLimit: -height }, state.heightOffset);\n}\n\n/** 0 = fully expanded, 1 = fully collapsed (TopAppBarState.collapsedFraction). */\nexport function collapsedFraction(state: AppBarScrollState): number {\n // `+ 0` turns the -0 of 0 / -height into 0.\n return state.heightOffsetLimit !== 0 ? state.heightOffset / state.heightOffsetLimit + 0 : 0;\n}\n\n/** Share of the visible bar overlapping scrolled content (TopAppBarState.overlappedFraction). */\nexport function overlappedFraction(state: AppBarScrollState): number {\n if (!state.atStart && state.contentOffset === 0) return 1;\n if (state.heightOffsetLimit === 0) return 0;\n const limit = state.heightOffsetLimit;\n const clamped = Math.min(Math.max(limit + Math.abs(state.contentOffset), limit), 0);\n return 1 - clamped / limit;\n}\n\n/**\n * Whether the bar shows its scrolled container color: SingleRowTopAppBar targets the scrolled\n * color once `overlappedFraction > 0.01f` (L2689-2693).\n */\nexport function isScrolledUnder(state: AppBarScrollState): boolean {\n return overlappedFraction(state) > 0.01;\n}\n\n/**\n * Applies a scroll position change. `delta` is the previous minus the new scroll position\n * (positive when the content is pulled down, like Compose's `available.y`).\n * - pinned: only the content offset moves (PinnedScrollBehavior.onPostScroll).\n * - enter-always: the bar also collapses/expands by the same amount\n * (EnterAlwaysScrollBehavior.onPreScroll: `heightOffset += available.y`).\n */\nexport function scrollAppBar(\n state: AppBarScrollState,\n behavior: AppBarScrollBehavior,\n scrollTop: number,\n delta: number,\n): AppBarScrollState {\n const next: AppBarScrollState = { ...state, contentOffset: -scrollTop, atStart: scrollTop <= 0 };\n return behavior === 'enter-always' ? withHeightOffset(next, state.heightOffset + delta) : next;\n}\n\n/**\n * Where a partially collapsed bar snaps when scrolling stops (settleAppBar): fully expanded below\n * half, fully collapsed from half, or null when it is already (within 1%) settled.\n */\nexport function settleTarget(state: AppBarScrollState): number | null {\n const fraction = collapsedFraction(state);\n if (fraction < 0.01 || fraction === 1) return null;\n if (!(state.heightOffset < 0 && state.heightOffset > state.heightOffsetLimit)) return null;\n return fraction < 0.5 ? 0 : state.heightOffsetLimit;\n}\n"]}
1
+ {"version":3,"sources":["../src/spring-estimation.ts","../src/spring-simulation.ts","../src/spring.ts","../src/linear.ts","../src/animatable.ts","../src/fab-menu.ts","../src/menu-navigation.ts","../src/loading-indicator.ts","../src/menu-position.ts","../src/app-bar-scroll.ts","../src/button-group.ts"],"names":["f32","dampingCoefficient","round"],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringEstimation.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// The Float overload's arguments are rounded to float32 (Math.fround) before widening to Double,\n// as in Kotlin. Durations are Long milliseconds: Kotlin's Double.toLong() (truncation, NaN → 0,\n// saturating) is reproduced by `toLong`.\n\n/** Maximum duration in Milliseconds. This takes into account that the duration will be converted to nanos. */\n// Long.MAX_VALUE / Long.MIN_VALUE as doubles (2^63 is what Kotlin's Long.toDouble() yields).\nconst LONG_MAX = 2 ** 63;\nconst LONG_MIN = -(2 ** 63);\nconst MAX_LONG_MILLIS = 9_223_372_036_854; // Long.MAX_VALUE / 1_000_000 (integer division)\n\nconst toLong = (x: number): number =>\n Number.isNaN(x) ? 0 : x >= LONG_MAX ? LONG_MAX : x <= LONG_MIN ? LONG_MIN : Math.trunc(x);\n\n/**\n * Returns the estimated time that the spring will last be at [delta]. Arguments are Kotlin\n * `Float`s (rounded to float32).\n */\nexport function estimateAnimationDurationMillis(\n stiffness: number,\n dampingRatio: number,\n initialVelocity: number,\n initialDisplacement: number,\n delta: number,\n): number {\n const f32 = Math.fround;\n if (f32(dampingRatio) === 0) {\n // No damping, duration is infinite (max value).\n return MAX_LONG_MILLIS;\n }\n\n return estimateAnimationDurationMillisDouble(\n f32(stiffness),\n f32(dampingRatio),\n f32(initialVelocity),\n f32(initialDisplacement),\n f32(delta),\n );\n}\n\n/** Returns the estimated time that the spring will last be at [delta] (Double overload). */\nexport function estimateAnimationDurationMillisDouble(\n stiffness: number,\n dampingRatio: number,\n initialVelocity: number,\n initialDisplacement: number,\n delta: number,\n): number {\n const dampingCoefficient = 2.0 * dampingRatio * Math.sqrt(stiffness);\n\n // Compute the roots of the polynomial [a]x^2+[b]x+[c]=0 which may be complex.\n // Here a is set to the constant 1.0, and folded into the other computations\n const partialRoot = dampingCoefficient * dampingCoefficient - 4.0 * stiffness;\n const partialRootReal = partialRoot < 0.0 ? 0.0 : Math.sqrt(partialRoot);\n const partialRootImaginary = partialRoot < 0.0 ? Math.sqrt(Math.abs(partialRoot)) : 0.0;\n\n const firstRootReal = (-dampingCoefficient + partialRootReal) * 0.5;\n const firstRootImaginary = partialRootImaginary * 0.5;\n const secondRootReal = (-dampingCoefficient - partialRootReal) * 0.5;\n\n return estimateDurationInternal(\n firstRootReal,\n firstRootImaginary,\n secondRootReal,\n dampingRatio,\n initialVelocity,\n initialDisplacement,\n delta,\n );\n}\n\n/**\n * In the under-damped case we simply calculate the envelope of the function. The general solution\n * is of the form x(t) = c_1*e^(r*t)*cos(...) + c_2*e^(r*t)sin(...) which simplifies to x(t) =\n * c*e^(r*t)*cos(...) where c*e^(r*t) is the envelope of x(t)\n */\nfunction estimateUnderDamped(\n firstRootReal: number,\n firstRootImaginary: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r = firstRootReal;\n const c1 = p0;\n const c2 = (v0 - r * c1) / firstRootImaginary;\n const c = Math.sqrt(c1 * c1 + c2 * c2);\n\n return Math.log(delta / c) / r;\n}\n\nconst isNotFinite = (x: number) => !Number.isFinite(x);\n\nconst iterateNewtonsMethod = (\n x: number,\n fn: (t: number) => number,\n fnPrime: (t: number) => number,\n): number => x - fn(x) / fnPrime(x);\n\n/**\n * In the critically-damped case we apply Newton-Raphson's iterative numerical method of solving the\n * equation x(t) = c_1*e^(r*t) + c_2*t*e^(r*t)\n */\nfunction estimateCriticallyDamped(\n firstRootReal: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r = firstRootReal;\n const c1 = p0;\n const c2 = v0 - r * c1;\n\n // For our initial guess, determine the max t of c_1*e^(r*t) = delta and\n // c_2*t*e^(r*t) = delta\n const t1 = Math.log(Math.abs(delta / c1)) / r;\n const t2 =\n (() => {\n // Application of Lambert's W function to solve te^t\n const guess = Math.log(Math.abs(delta / c2));\n let t = guess;\n for (let i = 0; i <= 5; i++) {\n t = guess - Math.log(Math.abs(t / r));\n }\n return t;\n })() / r;\n let tCurr = isNotFinite(t1) ? t2 : isNotFinite(t2) ? t1 : Math.max(t1, t2);\n\n // Calculate the inflection time. This is important if the inflection is in t > 0\n const tInflection = -(r * c1 + c2) / (r * c2);\n const xInflection = c1 * Math.exp(r * tInflection) + c2 * tInflection * Math.exp(r * tInflection);\n\n // For inflection that does not exist in real time, we always solve for x(t)=delta. Note\n // the system is manipulated such that p0 is always positive.\n let signedDelta: number;\n if (Number.isNaN(tInflection) || tInflection <= 0.0) {\n signedDelta = -delta;\n } else if (tInflection > 0.0 && -xInflection < delta) {\n // In this scenario the first crossing with the threshold is to be found. Note that\n // the inflection does not exceed delta. As such, we search from the left.\n if (c2 < 0 && c1 > 0) {\n tCurr = 0.0;\n }\n signedDelta = -delta;\n } else {\n // In this scenario there are three total crossings of the threshold, once from\n // above, and then once when the inflection exceeds the threshold and then one last\n // one when x(t) finally decays to zero. The point of determining concavity is to\n // find the final crossing.\n //\n // By finding a point between when concavity changes, and when the inflection point is,\n // Newton's method will always converge onto the rightmost point (in this case),\n // the one that we are interested in.\n tCurr = -(2.0 / r) - c1 / c2;\n signedDelta = delta;\n }\n\n let tDelta = Number.MAX_VALUE;\n let iterations = 0;\n while (tDelta > 0.001 && iterations < 100) {\n iterations++;\n const tLast = tCurr;\n tCurr = iterateNewtonsMethod(\n tCurr,\n (t) => (c1 + c2 * t) * Math.exp(r * t) + signedDelta,\n (t) => (c2 * (r * t + 1) + c1 * r) * Math.exp(r * t),\n );\n tDelta = Math.abs(tLast - tCurr);\n }\n\n return tCurr;\n}\n\n/**\n * In the over-damped case we apply Newton-Raphson's iterative numerical method of solving the\n * equation x(t) = c_1*e^(r_1*t) + c_2*e^(r_2*t)\n */\nfunction estimateOverDamped(\n firstRootReal: number,\n secondRootReal: number,\n p0: number,\n v0: number,\n delta: number,\n): number {\n const r1 = firstRootReal;\n const r2 = secondRootReal;\n const c2 = (r1 * p0 - v0) / (r1 - r2);\n const c1 = p0 - c2;\n\n // For our initial guess, determine the max t of c_1*e^(r_1*t) = delta and\n // c_2*e^(r_2*t) = delta\n const t1 = Math.log(Math.abs(delta / c1)) / r1;\n const t2 = Math.log(Math.abs(delta / c2)) / r2;\n\n let tCurr = isNotFinite(t1) ? t2 : isNotFinite(t2) ? t1 : Math.max(t1, t2);\n\n // Calculate the inflection time. This is important if the inflection is in t > 0\n const tInflection = Math.log((c1 * r1) / (-c2 * r2)) / (r2 - r1);\n const xInflection = () => c1 * Math.exp(r1 * tInflection) + c2 * Math.exp(r2 * tInflection);\n\n // For inflection that does not exist in real time, we always solve for x(t)=delta. Note\n // the system is manipulated such that p0 is always positive.\n let signedDelta: number;\n if (Number.isNaN(tInflection) || tInflection <= 0.0) {\n signedDelta = -delta;\n } else if (tInflection > 0.0 && -xInflection() < delta) {\n // In this scenario the first crossing with the threshold is to be found. Note that\n // the inflection does not exceed delta. As such, we search from the left.\n if (c2 > 0.0 && c1 < 0.0) {\n tCurr = 0.0;\n }\n signedDelta = -delta;\n } else {\n // In this scenario there are three total crossings of the threshold, once from\n // above, and then once when the inflection exceeds the threshold and then one last\n // one when x(t) finally decays to zero. The point of determining concavity is to\n // find the final crossing.\n //\n // By finding a point between when concavity changes, and when the inflection point is,\n // Newton's method will always converge onto the rightmost point (in this case),\n // the one that we are interested in.\n tCurr = Math.log(-(c2 * r2 * r2) / (c1 * r1 * r1)) / (r1 - r2);\n signedDelta = delta;\n }\n\n // For a good initial guess, simply return\n if (Math.abs(c1 * r1 * Math.exp(r1 * tCurr) + c2 * r2 * Math.exp(r2 * tCurr)) < 0.0001) {\n return tCurr;\n }\n let tDelta = Number.MAX_VALUE;\n\n // Cap iterations for safety - Experimentally this method takes <= 5 iterations\n let iterations = 0;\n while (tDelta > 0.001 && iterations < 100) {\n iterations++;\n const tLast = tCurr;\n tCurr = iterateNewtonsMethod(\n tCurr,\n (t) => c1 * Math.exp(r1 * t) + c2 * Math.exp(r2 * t) + signedDelta,\n (t) => c1 * r1 * Math.exp(r1 * t) + c2 * r2 * Math.exp(r2 * t),\n );\n tDelta = Math.abs(tLast - tCurr);\n }\n\n return tCurr;\n}\n\n// Applies Newton-Raphson's method to solve for the estimated time the spring mass system will\n// last be at [delta].\nfunction estimateDurationInternal(\n firstRootReal: number,\n firstRootImaginary: number,\n secondRootReal: number,\n dampingRatio: number,\n initialVelocity: number,\n initialPosition: number,\n delta: number,\n): number {\n if (initialPosition === 0.0 && initialVelocity === 0.0) {\n return 0;\n }\n\n const v0 = initialPosition < 0 ? -initialVelocity : initialVelocity;\n const p0 = Math.abs(initialPosition);\n\n const seconds =\n dampingRatio > 1.0\n ? estimateOverDamped(firstRootReal, secondRootReal, p0, v0, delta)\n : dampingRatio < 1.0\n ? estimateUnderDamped(firstRootReal, firstRootImaginary, p0, v0, delta)\n : estimateCriticallyDamped(firstRootReal, p0, v0, delta);\n return toLong(seconds * 1000.0);\n}\n","/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/animation/animation-core/src/commonMain/kotlin/androidx/compose/animation/core/SpringSimulation.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// Precision follows the Kotlin source: parameters and results are Float (Math.fround), the\n// solution is computed in Double, and time is whole milliseconds.\n\nconst f32 = Math.fround;\n\n/** `Spring.StiffnessVeryLow` / `Spring.DampingRatioNoBouncy` (VectorizedAnimationSpec.kt L813, L839). */\nconst STIFFNESS_VERY_LOW = 50;\nconst DAMPING_RATIO_NO_BOUNCY = 1;\n\nexport interface Motion {\n value: number;\n velocity: number;\n}\n\n/**\n * Spring Simulation simulates spring physics, and allows you to query the motion (i.e. value and\n * velocity) at certain time in the future based on the starting velocity and value.\n *\n * By configuring the stiffness and damping ratio, callers can create a spring with the look and\n * feel suits their use case. Stiffness corresponds to the spring constant. The stiffer the spring\n * is, the harder it is to stretch it, the faster it undergoes dampening.\n *\n * Spring damping ratio describes how oscillations in a system decay after a disturbance. When\n * damping ratio > 1* (i.e. over-damped), the object will quickly return to the rest position\n * without overshooting. If damping ratio equals to 1 (i.e. critically damped), the object will\n * return to equilibrium within the shortest amount of time. When damping ratio is less than 1 (i.e.\n * under-damped), the mass tends to overshoot, and return, and overshoot again. Without any damping\n * (i.e. damping ratio = 0), the mass will oscillate forever.\n */\nexport class SpringSimulation {\n // Natural frequency\n #naturalFreq = Math.sqrt(STIFFNESS_VERY_LOW);\n #dampingRatio = DAMPING_RATIO_NO_BOUNCY;\n #finalPosition: number;\n\n constructor(finalPosition: number) {\n this.#finalPosition = f32(finalPosition);\n }\n\n get finalPosition(): number {\n return this.#finalPosition;\n }\n\n set finalPosition(value: number) {\n this.#finalPosition = f32(value);\n }\n\n /** Stiffness of the spring. */\n get stiffness(): number {\n return f32(this.#naturalFreq * this.#naturalFreq);\n }\n\n set stiffness(value: number) {\n // Upstream checks the *current* stiffness here (always positive), so the new value is not\n // validated; kept as-is for parity.\n if (this.stiffness <= 0) {\n throw new RangeError('Spring stiffness constant must be positive.');\n }\n this.#naturalFreq = Math.sqrt(f32(value));\n }\n\n /** Returns the damping ratio of the spring. */\n get dampingRatio(): number {\n return this.#dampingRatio;\n }\n\n set dampingRatio(value: number) {\n if (value < 0) {\n throw new RangeError('Damping ratio must be non-negative');\n }\n this.#dampingRatio = f32(value);\n }\n\n getAcceleration(lastDisplacement: number, lastVelocity: number): number {\n const adjustedDisplacement = f32(f32(lastDisplacement) - this.#finalPosition);\n\n const k = this.#naturalFreq * this.#naturalFreq;\n const c = 2.0 * this.#naturalFreq * this.#dampingRatio;\n\n return f32(-k * adjustedDisplacement - c * f32(lastVelocity));\n }\n\n /**\n * Internal only call for Spring to calculate the spring position/velocity using an analytical\n * approach.\n */\n updateValues(lastDisplacement: number, lastVelocity: number, timeElapsed: number): Motion {\n const dampingRatio = this.#dampingRatio;\n const naturalFreq = this.#naturalFreq;\n const velocity0 = f32(lastVelocity);\n const adjustedDisplacement = f32(f32(lastDisplacement) - this.#finalPosition);\n const deltaT = Math.trunc(timeElapsed) / 1000.0; // unit: seconds\n const dampingRatioSquared = dampingRatio * dampingRatio;\n const r = -dampingRatio * naturalFreq;\n\n let displacement: number;\n let currentVelocity: number;\n\n if (dampingRatio > 1) {\n // Over damping\n const s = naturalFreq * Math.sqrt(dampingRatioSquared - 1);\n const gammaPlus = r + s;\n const gammaMinus = r - s;\n\n // Overdamped\n const coeffB = (gammaMinus * adjustedDisplacement - velocity0) / (gammaMinus - gammaPlus);\n const coeffA = adjustedDisplacement - coeffB;\n displacement = coeffA * Math.exp(gammaMinus * deltaT) + coeffB * Math.exp(gammaPlus * deltaT);\n currentVelocity =\n coeffA * gammaMinus * Math.exp(gammaMinus * deltaT) +\n coeffB * gammaPlus * Math.exp(gammaPlus * deltaT);\n } else if (dampingRatio === 1.0) {\n // Critically damped\n const coeffA = adjustedDisplacement;\n const coeffB = velocity0 + naturalFreq * adjustedDisplacement;\n const nFdT = -naturalFreq * deltaT;\n displacement = (coeffA + coeffB * deltaT) * Math.exp(nFdT);\n currentVelocity =\n (coeffA + coeffB * deltaT) * Math.exp(nFdT) * -naturalFreq + coeffB * Math.exp(nFdT);\n } else {\n const dampedFreq = naturalFreq * Math.sqrt(1 - dampingRatioSquared);\n // Underdamped\n const cosCoeff = adjustedDisplacement;\n const sinCoeff = (1 / dampedFreq) * (-r * adjustedDisplacement + velocity0);\n const dFdT = dampedFreq * deltaT;\n displacement = Math.exp(r * deltaT) * (cosCoeff * Math.cos(dFdT) + sinCoeff * Math.sin(dFdT));\n currentVelocity =\n displacement * r +\n Math.exp(r * deltaT) *\n (-dampedFreq * cosCoeff * Math.sin(dFdT) + dampedFreq * sinCoeff * Math.cos(dFdT));\n }\n\n return {\n value: f32(displacement + this.#finalPosition),\n velocity: f32(currentVelocity),\n };\n }\n}\n","// Spring helpers with Compose `FloatSpringSpec` semantics (animation-core FloatAnimationSpec.kt\n// L133–187 @19991f2c), built on the ported SpringSimulation / SpringEstimation.\nimport { estimateAnimationDurationMillis } from './spring-estimation.js';\nimport { SpringSimulation } from './spring-simulation.js';\n\n/** A Material motion-scheme spring (`dampingRatio` ζ, `stiffness` k; mass 1). */\nexport interface SpringSpec {\n readonly dampingRatio: number;\n readonly stiffness: number;\n}\n\n/** `Spring.DefaultDisplacementThreshold` (VectorizedAnimationSpec.kt L842). */\nexport const DEFAULT_DISPLACEMENT_THRESHOLD = 0.01;\n\nconst f32 = Math.fround;\n\nfunction simulation(spec: SpringSpec, targetValue: number): SpringSimulation {\n const sim = new SpringSimulation(targetValue);\n sim.dampingRatio = spec.dampingRatio;\n sim.stiffness = spec.stiffness;\n return sim;\n}\n\n/** Value at `playTimeMillis` (whole milliseconds, as in Compose). */\nexport function springValue(\n spec: SpringSpec,\n playTimeMillis: number,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n): number {\n return simulation(spec, targetValue).updateValues(initialValue, initialVelocity, playTimeMillis)\n .value;\n}\n\n/** Velocity (units/s) at `playTimeMillis`. */\nexport function springVelocity(\n spec: SpringSpec,\n playTimeMillis: number,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n): number {\n return simulation(spec, targetValue).updateValues(initialValue, initialVelocity, playTimeMillis)\n .velocity;\n}\n\n/**\n * Duration until the spring stays within `visibilityThreshold` of the target, as Compose computes\n * it (`FloatSpringSpec.getDurationNanos` / 1e6).\n */\nexport function springDurationMillis(\n spec: SpringSpec,\n initialValue: number,\n targetValue: number,\n initialVelocity = 0,\n visibilityThreshold = DEFAULT_DISPLACEMENT_THRESHOLD,\n): number {\n const sim = simulation(spec, targetValue);\n const threshold = f32(visibilityThreshold);\n return estimateAnimationDurationMillis(\n sim.stiffness,\n sim.dampingRatio,\n f32(f32(initialVelocity) / threshold),\n f32(f32(f32(initialValue) - f32(targetValue)) / threshold),\n 1,\n );\n}\n\n/**\n * Damping coefficient c = 2ζ√(k·m), for physics engines parameterized by stiffness/damping/mass\n * (e.g. Motion's `{ type: 'spring', stiffness, damping, mass }`).\n */\nexport function dampingCoefficient(spec: SpringSpec, mass = 1): number {\n return 2 * spec.dampingRatio * Math.sqrt(spec.stiffness * mass);\n}\n\n/** Inverse of {@link dampingCoefficient}: ζ = c / (2√(k·m)). */\nexport function dampingRatioFromCoefficient(damping: number, stiffness: number, mass = 1): number {\n return damping / (2 * Math.sqrt(stiffness * mass));\n}\n","// CSS `linear()` approximation of a spring (FOUNDATIONS §4).\n//\n// - Duration: Compose's own settle estimate (`FloatSpringSpec.getDurationNanos`) for a 0 → 1\n// animation at a visibility threshold of 0.001 (0.1% of the travel; e.g. Compose's 0.1 dp\n// Dp threshold over a 100 dp move).\n// - Samples: the exact spring at every whole millisecond (Compose's time resolution), last stop\n// forced to 1 so the animation lands on its target.\n// - Stops: Ramer–Douglas–Peucker in (progress, value) space with the smallest tolerance that fits\n// `maxStops`.\n//\n// Limits (FOUNDATIONS §4): no velocity carry-over on interruption and a fixed duration; use the JS\n// spring for drags, rapid toggles and other interruptible motion.\nimport { type SpringSpec, springDurationMillis } from './spring.js';\nimport { SpringSimulation } from './spring-simulation.js';\n\nexport interface LinearEasingOptions {\n /** Fraction of the travel considered settled. Default 0.001. */\n visibilityThreshold?: number;\n /** Maximum stops in the `linear()` function (FOUNDATIONS §4: ≤ 40). Default 40. */\n maxStops?: number;\n}\n\nexport interface LinearEasing {\n /** e.g. `linear(0, 0.1234 5%, …, 1)` */\n easing: string;\n durationMillis: number;\n /** `[progress 0–1, value]` pairs after rounding. */\n stops: readonly (readonly [number, number])[];\n /** Max |linear(t) − spring(t)| over every millisecond sample. */\n maxError: number;\n}\n\nconst round = (n: number, digits: number) => {\n const r = Number(n.toFixed(digits));\n return Object.is(r, -0) ? 0 : r;\n};\n\ntype Point = readonly [number, number];\n\nfunction at<T>(list: readonly T[], i: number): T {\n const item = list[i];\n if (item === undefined) throw new RangeError(`index ${String(i)} out of range`);\n return item;\n}\n\n/** Ramer–Douglas–Peucker: indices of points to keep (vertical distance, monotone x). */\nfunction simplify(points: readonly Point[], tolerance: number): number[] {\n const keep = new Set<number>([0, points.length - 1]);\n const stack: [number, number][] = [[0, points.length - 1]];\n for (let range = stack.pop(); range; range = stack.pop()) {\n const [a, b] = range;\n const [x0, y0] = at(points, a);\n const [x1, y1] = at(points, b);\n let worst = -1;\n let worstDistance = tolerance;\n for (let i = a + 1; i < b; i++) {\n const [x, y] = at(points, i);\n const expected = y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);\n const distance = Math.abs(y - expected);\n if (distance > worstDistance) {\n worst = i;\n worstDistance = distance;\n }\n }\n if (worst !== -1) {\n keep.add(worst);\n stack.push([a, worst], [worst, b]);\n }\n }\n return [...keep].sort((x, y) => x - y);\n}\n\nfunction interpolate(stops: readonly Point[], x: number): number {\n for (let i = 1; i < stops.length; i++) {\n const [x1, y1] = at(stops, i);\n const [x0, y0] = at(stops, i - 1);\n if (x <= x1) return x1 === x0 ? y1 : y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);\n }\n return at(stops, stops.length - 1)[1];\n}\n\nexport function springToLinear(spec: SpringSpec, options: LinearEasingOptions = {}): LinearEasing {\n const { visibilityThreshold = 0.001, maxStops = 40 } = options;\n if (maxStops < 2) throw new RangeError('maxStops must be at least 2');\n const durationMillis = Math.max(1, springDurationMillis(spec, 0, 1, 0, visibilityThreshold));\n\n const sim = new SpringSimulation(1);\n sim.dampingRatio = spec.dampingRatio;\n sim.stiffness = spec.stiffness;\n const samples: Point[] = [];\n for (let t = 0; t <= durationMillis; t++) {\n samples.push([t / durationMillis, sim.updateValues(0, 0, t).value]);\n }\n samples[samples.length - 1] = [1, 1];\n\n // Smallest tolerance (bisection) whose simplification fits maxStops.\n let lo = 0;\n let hi = 0.5;\n let best = simplify(samples, hi);\n for (let i = 0; i < 40; i++) {\n const mid = (lo + hi) / 2;\n const kept = simplify(samples, mid);\n if (kept.length <= maxStops) {\n best = kept;\n hi = mid;\n } else {\n lo = mid;\n }\n }\n\n const stops = best.map((i) => {\n const [x, y] = at(samples, i);\n return [round(x, 4), round(y, 4)] as const;\n });\n const maxError = samples.reduce(\n (m, [x, y]) => Math.max(m, Math.abs(interpolate(stops, x) - y)),\n 0,\n );\n const body = stops.map(([x, y], i) =>\n i === 0 || i === stops.length - 1 ? String(y) : `${String(y)} ${String(round(x * 100, 2))}%`,\n );\n return { easing: `linear(${body.join(', ')})`, durationMillis, stops, maxError };\n}\n","// An interruptible spring value with Compose `Animatable` semantics (animation-core Animatable.kt\n// @19991f2c): `animateTo` starts from the current value *and velocity*, the animation runs for\n// Compose's own duration estimate (FloatSpringSpec.getDurationNanos at the visibility threshold)\n// and then rests exactly on the target. Time is injected, so callers drive it from their frame loop\n// (m3e-elements) and tests can step it deterministically.\nimport {\n DEFAULT_DISPLACEMENT_THRESHOLD,\n type SpringSpec,\n springDurationMillis,\n springValue,\n springVelocity,\n} from './spring.js';\n\nexport class SpringAnimatable {\n #value: number;\n #velocity = 0;\n #target: number;\n #from = 0;\n #velocity0 = 0;\n #start = 0;\n #duration = 0;\n #spec: SpringSpec | null = null;\n\n /**\n * @param value initial value, at rest.\n * @param visibilityThreshold Compose's visibility threshold: 0.01 for Float animations\n * (`Spring.DefaultDisplacementThreshold`), 1 for an Int one.\n */\n constructor(\n value: number,\n readonly visibilityThreshold: number = DEFAULT_DISPLACEMENT_THRESHOLD,\n ) {\n this.#value = value;\n this.#target = value;\n }\n\n get value(): number {\n return this.#value;\n }\n\n /** Units per second. */\n get velocity(): number {\n return this.#velocity;\n }\n\n get target(): number {\n return this.#target;\n }\n\n get isRunning(): boolean {\n return this.#spec !== null;\n }\n\n /** Jumps to `value` and stops. */\n snapTo(value: number): void {\n this.#spec = null;\n this.#value = value;\n this.#target = value;\n this.#velocity = 0;\n }\n\n /**\n * Animates to `target` from the value and velocity at `now` (ms); a null spec (e.g. a spatial\n * spring under reduced motion) jumps there.\n */\n animateTo(target: number, spec: SpringSpec | null, now: number): void {\n this.sample(now);\n if (spec === null) {\n this.snapTo(target);\n return;\n }\n this.#from = this.#value;\n this.#velocity0 = this.#velocity;\n this.#target = target;\n this.#start = now;\n this.#spec = spec;\n this.#duration = springDurationMillis(\n spec,\n this.#from,\n target,\n this.#velocity0,\n this.visibilityThreshold,\n );\n if (this.#duration <= 0) this.snapTo(target);\n }\n\n /** Advances to `now` (ms) and returns the value; the animation ends once its duration is up. */\n sample(now: number): number {\n const spec = this.#spec;\n if (spec === null) return this.#value;\n const elapsed = Math.max(0, now - this.#start);\n if (elapsed >= this.#duration) {\n this.snapTo(this.#target);\n return this.#value;\n }\n this.#value = springValue(spec, elapsed, this.#from, this.#target, this.#velocity0);\n this.#velocity = springVelocity(spec, elapsed, this.#from, this.#target, this.#velocity0);\n return this.#value;\n }\n}\n","// FAB menu item stagger, as Compose's FloatingActionButtonMenuItemColumn lays it out\n// (FloatingActionButtonMenu.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898 L250–307): an Int\n// Animatable runs 0 ↔ the item count on the slow effects spring (visibility threshold 1, L208–218),\n// and item `index` (0 = top) is visible while `index >= itemCount - value` (L283), so items appear\n// from the bottom (next to the toggle) up and disappear top first. Each item then springs its own\n// width (fast spatial) and alpha (fast effects) toward 1 or 0 when its visibility flips (L339–376).\n// Shared by m3e-elements and m3e-react.\n\n/** `Int.VectorConverter` reads an animated Int by truncating the float toward zero. */\nexport const animatedInt = (value: number): number => Math.trunc(value);\n\n/** Whether item `index` (0 = top) shows at stagger value `stagger` (0 … `itemCount`). */\nexport const fabMenuItemVisible = (index: number, itemCount: number, stagger: number): boolean =>\n index >= itemCount - animatedInt(stagger);\n","// Arrow-key navigation among menu items (WAI-ARIA APG menu pattern, as React Aria's useMenu\n// keyboard delegate does it): ArrowDown / ArrowUp move to the next / previous item and wrap, Home and\n// End jump to the first / last. Pure index math shared by m3e-elements and m3e-react.\n//\n// Scoped to the FAB menu for now (COMPONENT_SPEC §6). Follow-up: unify with the Menus component's\n// keyboard helpers (COMPONENT_SPEC §21) once both are on main.\n\n/**\n * The item index `key` moves focus to from `current` (−1: none focused) among `count` items, or\n * null when the key does not navigate.\n */\nexport function menuNavigationTarget(key: string, count: number, current: number): number | null {\n if (count === 0) return null;\n switch (key) {\n case 'ArrowDown':\n return current < 0 ? 0 : (current + 1) % count;\n case 'ArrowUp':\n return current < 0 ? count - 1 : (current - 1 + count) % count;\n case 'Home':\n return 0;\n case 'End':\n return count - 1;\n default:\n return null;\n }\n}\n","/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/LoadingIndicator.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// The indeterminate LoadingIndicator's LaunchedEffect (L391–451) as a pure function of elapsed\n// time. Compose runs two coroutines:\n// - every MorphIntervalMillis a spring animates the morph progress 0 → 1; when it finishes, the\n// indicator advances to the next morph, snaps the progress to 0 and adds a quarter turn to the\n// morph rotation. The loop then waits for the rest of the interval (or for the spring, if it is\n// slower than the interval);\n// - a linear global rotation turns 360° every GlobalRotationDurationMillis, restarting.\n// The drawn rotation is `progress × 90 + morphRotationTargetAngle + globalRotation` (L473).\n// The interval, rotation duration and spring are tokens (components/loading-indicator-motion.css).\n\nimport { type SpringSpec, springDurationMillis, springValue } from './spring.js';\n\nconst FULL_ROTATION = 360;\nconst QUARTER_ROTATION = FULL_ROTATION / 4;\n\nexport interface LoadingIndicatorTiming {\n /** `MorphIntervalMillis`: how often a morph starts. */\n readonly morphIntervalMillis: number;\n /** `GlobalRotationDurationMillis`: one linear turn. */\n readonly rotationDurationMillis: number;\n /** The morph spring (`morphAnimationSpec`). */\n readonly spring: SpringSpec;\n /** The morph spring's `visibilityThreshold`; it decides when the spring finishes. */\n readonly visibilityThreshold: number;\n}\n\n/** What the indicator draws: a morph at a progress, rotated clockwise about the center. */\nexport interface IndeterminateFrame {\n morphIndex: number;\n /** The raw spring value: it overshoots past 1, as in Compose (the morph extrapolates). */\n morphProgress: number;\n /** Degrees, clockwise. */\n rotation: number;\n}\n\n/**\n * The first frame (and the one held under reduced motion): the first morph at 0, rotated by the\n * initial `morphRotationTargetAngle` (a quarter turn).\n */\nexport const initialIndeterminateFrame: Readonly<IndeterminateFrame> = {\n morphIndex: 0,\n morphProgress: 0,\n rotation: QUARTER_ROTATION,\n};\n\n/** How long one morph spring runs (Compose's `FloatSpringSpec.getDurationNanos`), in ms. */\nexport const morphSpringDurationMillis = (timing: LoadingIndicatorTiming): number =>\n springDurationMillis(timing.spring, 0, 1, 0, timing.visibilityThreshold);\n\n/**\n * The frame of an indeterminate loading indicator [elapsedMillis] after it started, cycling\n * through [morphCount] morphs.\n */\nexport function indeterminateFrame(\n elapsedMillis: number,\n morphCount: number,\n timing: LoadingIndicatorTiming,\n): IndeterminateFrame {\n const t = Math.max(0, elapsedMillis);\n const springMillis = morphSpringDurationMillis(timing);\n // `delay(MorphIntervalMillis)` then `deferred.await()`: the next morph starts after both.\n const period = Math.max(timing.morphIntervalMillis, springMillis);\n const completed = Math.floor(t / period);\n const local = t - completed * period;\n const running = local < springMillis;\n // Each finished spring advances the index and adds a quarter turn (starting at a quarter turn).\n const finished = running ? completed : completed + 1;\n const morphIndex = finished % morphCount;\n const targetAngle = (QUARTER_ROTATION * (finished + 1)) % FULL_ROTATION;\n // Compose samples the spring at whole milliseconds of play time.\n const morphProgress = running ? springValue(timing.spring, Math.floor(local), 0, 1) : 0;\n const globalRotation =\n (FULL_ROTATION * Math.floor(t % timing.rotationDurationMillis)) / timing.rotationDurationMillis;\n return {\n morphIndex,\n morphProgress,\n rotation: morphProgress * QUARTER_ROTATION + targetAngle + globalRotation,\n };\n}\n","/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/internal/MenuPosition.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n// and compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Menu.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// MenuPosition, AnchorAlignmentOffsetPosition and WindowAlignmentMarginPosition (MenuPosition.kt\n// L50-L275), DropdownMenuPositionProvider.positioningLogic (L317-L392), the MenuAnchorPosition\n// candidate lists (Menu.kt L1507-L1785) and calculateTransformOrigin (Menu.kt L2216-L2242). Coordinates are CSS px relative to the viewport\n// (\"window\"); Compose works in integer px, the web keeps fractions. Alignment.align is\n// BiasAlignment's `round((space - size) / 2 * (1 + bias))` (Kotlin roundToInt = Math.round).\n\n/** Where a menu opens relative to its anchor (MenuAnchorPosition.Below…End). */\nexport type MenuAnchorPosition = 'below' | 'above' | 'start' | 'end' | 'left' | 'right';\n\nexport interface MenuRect {\n readonly left: number;\n readonly top: number;\n readonly right: number;\n readonly bottom: number;\n}\n\nexport interface MenuPositionInput {\n /** Anchor bounds in viewport px. */\n anchor: MenuRect;\n /** Viewport (window) size in px. */\n window: { readonly width: number; readonly height: number };\n /** Untransformed menu size in px. */\n menu: { readonly width: number; readonly height: number };\n /** Layout direction of the anchor (`direction: rtl`). */\n rtl: boolean;\n /** Default `below`. */\n position?: MenuAnchorPosition | undefined;\n /** DpOffset: x is mirrored in RTL. Default 0, 0. */\n offset?: { readonly x: number; readonly y: number } | undefined;\n /** Kept from the window top/bottom (MenuVerticalMargin). */\n verticalMargin: number;\n /** Kept from the window left/right (MenuHorizontalMargin; 0 for the baseline DropdownMenu). */\n horizontalMargin: number;\n}\n\nexport interface MenuPositionResult {\n /** Menu left edge in viewport px. */\n x: number;\n /** Menu top edge in viewport px. */\n y: number;\n /** Transform origin as fractions of the menu size (0 = left/top, 1 = right/bottom). */\n originX: number;\n originY: number;\n}\n\ntype Horizontal = (anchor: MenuRect, width: number, menuWidth: number, rtl: boolean) => number;\ntype Vertical = (anchor: MenuRect, height: number, menuHeight: number) => number;\n\nconst round = Math.round;\n\n/** BiasAlignment.Horizontal.align (Start = -1, CenterHorizontally = 0, End = 1). */\nconst alignH = (bias: number, size: number, space: number, rtl: boolean) =>\n round(((space - size) / 2) * (1 + (rtl ? -bias : bias)));\n/** BiasAlignment.Vertical.align (Top = -1, CenterVertically = 0, Bottom = 1). */\nconst alignV = (bias: number, size: number, space: number) =>\n round(((space - size) / 2) * (1 + bias));\n\nconst START = -1;\nconst END = 1;\nconst TOP = -1;\nconst CENTER = 0;\nconst BOTTOM = 1;\n\n/** AnchorAlignmentOffsetPosition.Horizontal. */\nconst anchorH =\n (menuBias: number, anchorBias: number): Horizontal =>\n (anchor, _width, menuWidth, rtl) =>\n anchor.left +\n alignH(anchorBias, 0, anchor.right - anchor.left, rtl) -\n alignH(menuBias, 0, menuWidth, rtl);\n\n/** AnchorAlignmentOffsetPosition.Vertical. */\nconst anchorV =\n (menuBias: number, anchorBias: number): Vertical =>\n (anchor, _height, menuHeight) =>\n anchor.top +\n alignV(anchorBias, 0, anchor.bottom - anchor.top) -\n alignV(menuBias, 0, menuHeight);\n\nconst startToAnchorStart = anchorH(START, START);\nconst startToAnchorEnd = anchorH(START, END);\nconst endToAnchorEnd = anchorH(END, END);\nconst endToAnchorStart = anchorH(END, START);\n/** WindowAlignmentMarginPosition.Horizontal with AbsoluteAlignment.Left / Right (ignore RTL). */\nconst leftToWindowLeft: Horizontal = (_a, width, menuWidth) =>\n alignH(START, menuWidth, width, false);\nconst rightToWindowRight: Horizontal = (_a, width, menuWidth) =>\n alignH(END, menuWidth, width, false);\n\nconst topToAnchorBottom = anchorV(TOP, BOTTOM);\nconst topToAnchorTop = anchorV(TOP, TOP);\nconst bottomToAnchorTop = anchorV(BOTTOM, TOP);\nconst bottomToAnchorBottom = anchorV(BOTTOM, BOTTOM);\nconst centerToAnchorTop = anchorV(CENTER, TOP);\nconst topToWindowTop: Vertical = (_a, height, menuHeight) => alignV(TOP, menuHeight, height);\nconst bottomToWindowBottom: Vertical = (_a, height, menuHeight) =>\n alignV(BOTTOM, menuHeight, height);\n\nconst centerX = (r: MenuRect) => (r.left + r.right) / 2;\nconst centerY = (r: MenuRect) => (r.top + r.bottom) / 2;\n\n/** The window-edge fallback every MenuAnchorPosition ends its x list with. */\nconst windowX = (anchor: MenuRect, width: number) =>\n centerX(anchor) < width / 2 ? leftToWindowLeft : rightToWindowRight;\nconst windowY = (anchor: MenuRect, height: number) =>\n centerY(anchor) < height / 2 ? topToWindowTop : bottomToWindowBottom;\n\n/** MenuAnchorPosition.{Below, Above, Left, Right, Start, End}: candidate x and y lists, in order. */\nfunction candidates(\n position: MenuAnchorPosition,\n anchor: MenuRect,\n width: number,\n height: number,\n): [Horizontal[], Vertical[]] {\n const wx = windowX(anchor, width);\n const wy = windowY(anchor, height);\n switch (position) {\n case 'above':\n return [\n [startToAnchorStart, endToAnchorEnd, wx],\n [bottomToAnchorTop, topToAnchorBottom, centerToAnchorTop, wy],\n ];\n // Left and Start (Right and End) list the same candidates; Start/End resolve against the\n // layout direction inside the candidates, Left/Right too (Menu.kt keeps them identical).\n case 'left':\n case 'start':\n return [\n [endToAnchorStart, startToAnchorEnd, wx],\n [topToAnchorTop, bottomToAnchorBottom, wy],\n ];\n case 'right':\n case 'end':\n return [\n [startToAnchorEnd, endToAnchorStart, wx],\n [topToAnchorTop, bottomToAnchorBottom, wy],\n ];\n // 'below' (unrecognized values too).\n default:\n return [\n [startToAnchorStart, endToAnchorEnd, wx],\n [topToAnchorBottom, bottomToAnchorTop, centerToAnchorTop, wy],\n ];\n }\n}\n\nconst coerceIn = (v: number, min: number, max: number) => Math.min(Math.max(v, min), max);\n\n/** First candidate that fits between the margins; else the last one coerced (or centered). */\nfunction pick(\n values: readonly number[],\n size: number,\n space: number,\n margin: number,\n center: () => number,\n): number {\n for (const [i, candidate] of values.entries()) {\n if (candidate >= margin && candidate + size <= space - margin) return candidate;\n if (i === values.length - 1) {\n return size >= space - 2 * margin\n ? center()\n : coerceIn(candidate, margin, space - margin - size);\n }\n }\n return 0;\n}\n\n/** calculateTransformOrigin (Menu.kt L2216). */\nexport function menuTransformOrigin(\n anchor: MenuRect,\n menu: MenuRect,\n): { originX: number; originY: number } {\n const menuWidth = menu.right - menu.left;\n const menuHeight = menu.bottom - menu.top;\n const originX =\n menu.left >= anchor.right\n ? 0\n : menu.right <= anchor.left\n ? 1\n : menuWidth === 0\n ? 0\n : ((Math.max(anchor.left, menu.left) + Math.min(anchor.right, menu.right)) / 2 -\n menu.left) /\n menuWidth;\n const originY =\n menu.top >= anchor.bottom\n ? 0\n : menu.bottom <= anchor.top\n ? 1\n : menuHeight === 0\n ? 0\n : ((Math.max(anchor.top, menu.top) + Math.min(anchor.bottom, menu.bottom)) / 2 -\n menu.top) /\n menuHeight;\n return { originX, originY };\n}\n\n/**\n * Where Compose's DropdownMenuPositionProvider places a menu: the first x and y candidates of the\n * MenuAnchorPosition that keep the menu inside the window margins (below the anchor, then above it,\n * then centered on its top, then against the nearer window edge), plus the transform origin the\n * open/close scale animates from.\n */\nexport function menuPosition(input: MenuPositionInput): MenuPositionResult {\n const { anchor, window: win, menu, rtl, verticalMargin, horizontalMargin } = input;\n const offset = input.offset ?? { x: 0, y: 0 };\n const [xs, ys] = candidates(input.position ?? 'below', anchor, win.width, win.height);\n const offsetX = offset.x * (rtl ? -1 : 1);\n const x = pick(\n xs.map((c) => c(anchor, win.width, menu.width, rtl) + offsetX),\n menu.width,\n win.width,\n horizontalMargin,\n () => alignH(CENTER, menu.width, win.width, rtl),\n );\n const y = pick(\n ys.map((c) => c(anchor, win.height, menu.height) + offset.y),\n menu.height,\n win.height,\n verticalMargin,\n () => alignV(CENTER, menu.height, win.height),\n );\n return {\n x,\n y,\n ...menuTransformOrigin(anchor, {\n left: x,\n top: y,\n right: x + menu.width,\n bottom: y + menu.height,\n }),\n };\n}\n","/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AppBar.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// TopAppBarState (L2050-2130), the pinned and enter-always scroll behaviors (L3267-3303,\n// L3400-3455) and the settle decision of settleAppBar (L3542-3589), adapted to DOM scrolling.\n// Compose receives nested\n// scroll deltas and can consume them; the web observes `scrollTop` after the browser scrolled, so\n// every delta goes to both the bar and the content, and momentum comes from the browser instead\n// of flingAnimationSpec. Offsets are in CSS px; y grows downward, so collapsing is negative.\n\n/** How the bar reacts to its scroll container (TopAppBarDefaults.*ScrollBehavior). */\nexport type AppBarScrollBehavior = 'pinned' | 'enter-always';\n\nexport interface AppBarScrollState {\n /** Most negative height offset: minus the bar's full height (adjustHeightOffsetLimit). */\n readonly heightOffsetLimit: number;\n /** Current height offset, between heightOffsetLimit and 0. */\n readonly heightOffset: number;\n /** Content scrolled under the bar (minus the scroll position). */\n readonly contentOffset: number;\n /** Whether the scrolling content is at its start (scroll position 0). */\n readonly atStart: boolean;\n}\n\n/** A fully expanded bar of `height` px over unscrolled content. */\nexport function appBarScrollState(height: number): AppBarScrollState {\n return { heightOffsetLimit: -height, heightOffset: 0, contentOffset: 0, atStart: true };\n}\n\n/** TopAppBarState.heightOffset setter: coerced between heightOffsetLimit and 0. */\nexport function withHeightOffset(state: AppBarScrollState, offset: number): AppBarScrollState {\n return { ...state, heightOffset: Math.min(Math.max(offset, state.heightOffsetLimit), 0) };\n}\n\n/** A new bar height (onSizeChanged → adjustHeightOffsetLimit), keeping the offset in range. */\nexport function withHeight(state: AppBarScrollState, height: number): AppBarScrollState {\n return withHeightOffset({ ...state, heightOffsetLimit: -height }, state.heightOffset);\n}\n\n/** 0 = fully expanded, 1 = fully collapsed (TopAppBarState.collapsedFraction). */\nexport function collapsedFraction(state: AppBarScrollState): number {\n // `+ 0` turns the -0 of 0 / -height into 0.\n return state.heightOffsetLimit !== 0 ? state.heightOffset / state.heightOffsetLimit + 0 : 0;\n}\n\n/** Share of the visible bar overlapping scrolled content (TopAppBarState.overlappedFraction). */\nexport function overlappedFraction(state: AppBarScrollState): number {\n if (!state.atStart && state.contentOffset === 0) return 1;\n if (state.heightOffsetLimit === 0) return 0;\n const limit = state.heightOffsetLimit;\n const clamped = Math.min(Math.max(limit + Math.abs(state.contentOffset), limit), 0);\n return 1 - clamped / limit;\n}\n\n/**\n * Whether the bar shows its scrolled container color: SingleRowTopAppBar targets the scrolled\n * color once `overlappedFraction > 0.01f` (L2689-2693).\n */\nexport function isScrolledUnder(state: AppBarScrollState): boolean {\n return overlappedFraction(state) > 0.01;\n}\n\n/**\n * Applies a scroll position change. `delta` is the previous minus the new scroll position\n * (positive when the content is pulled down, like Compose's `available.y`).\n * - pinned: only the content offset moves (PinnedScrollBehavior.onPostScroll).\n * - enter-always: the bar also collapses/expands by the same amount\n * (EnterAlwaysScrollBehavior.onPreScroll: `heightOffset += available.y`).\n */\nexport function scrollAppBar(\n state: AppBarScrollState,\n behavior: AppBarScrollBehavior,\n scrollTop: number,\n delta: number,\n): AppBarScrollState {\n const next: AppBarScrollState = { ...state, contentOffset: -scrollTop, atStart: scrollTop <= 0 };\n return behavior === 'enter-always' ? withHeightOffset(next, state.heightOffset + delta) : next;\n}\n\n/**\n * Where a partially collapsed bar snaps when scrolling stops (settleAppBar): fully expanded below\n * half, fully collapsed from half, or null when it is already (within 1%) settled.\n */\nexport function settleTarget(state: AppBarScrollState): number | null {\n const fraction = collapsedFraction(state);\n if (fraction < 0.01 || fraction === 1) return null;\n if (!(state.heightOffset < 0 && state.heightOffset > state.heightOffsetLimit)) return null;\n return fraction < 0.5 ? 0 : state.heightOffsetLimit;\n}\n","/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n// Ported to TypeScript by Kyra Labs from compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ButtonGroup.kt@19991f2c0858aadfcb442ce02b2c8e4743c96898\n//\n// ButtonGroupMeasurePolicy.measure (L554-L812): how many items fit before the overflow indicator\n// (L673-L716) and the expand/compress pass that grows a pressed item and shrinks its neighbors\n// (L718-L769). Widths are CSS px; Compose rounds each growth to whole device px (roundToInt), the\n// web keeps fractions so the animation does not step.\n\nexport interface ButtonGroupItemSize {\n /** Resting width (Compose: the item's max intrinsic width). */\n readonly width: number;\n /**\n * Most this item may be compressed by a pressed neighbor (Compose `compressionLimit`: the end\n * content padding of the item, `ButtonDefaults.ContentPadding` by default).\n */\n readonly compressionLimit: number;\n}\n\n/**\n * Number of leading items that fit in `maxWidth` (ButtonGroupMeasurePolicy L673-L716). When all\n * items and their spacing fit, every item shows; otherwise the overflow indicator's width is\n * reserved and items are added while each one fits in what is left (each after the first also\n * pays one `spacing`, the gap before the next item or the indicator).\n */\nexport function buttonGroupVisibleCount(\n widths: readonly number[],\n spacing: number,\n maxWidth: number,\n overflowWidth: number,\n): number {\n const desired = widths.reduce((sum, w) => sum + w, 0) + spacing * (widths.length - 1);\n if (desired <= maxWidth) return widths.length;\n let remaining = maxWidth - overflowWidth;\n let last = 0;\n for (const width of widths) {\n if (width > remaining) break;\n remaining -= width + spacing;\n last++;\n }\n return last;\n}\n\n/**\n * Widths of the visible items while some are pressed (ButtonGroupMeasurePolicy L718-L769).\n * `pressed[i]` is item i's press animation value (0 at rest, 1 fully expanded; it overshoots on a\n * bouncy spring). A pressed middle item grows by `pressed × min(expandedRatio × width / 2, both\n * neighbors' compression limits)` on each side, taken from each neighbor; the first and last items\n * grow by `pressed × min(expandedRatio × width, neighbor's limit)` taken from their only neighbor.\n * Items are processed in order on the running widths, as Compose does, so the total width stays\n * constant. `visibleCount` is the number of items shown (the rest are in the overflow menu).\n */\nexport function buttonGroupWidths(\n items: readonly ButtonGroupItemSize[],\n pressed: readonly number[],\n expandedRatio: number,\n visibleCount: number = items.length,\n): number[] {\n const widths = items.map((item) => item.width);\n const w = (i: number) => widths[i] ?? 0;\n const limit = (i: number) => items[i]?.compressionLimit ?? 0;\n const last = Math.min(visibleCount, items.length);\n if (items.length <= 1) return widths.slice(0, last);\n for (let index = 0; index < last; index++) {\n const value = pressed[index] ?? 0;\n if (value === 0) continue;\n let growth: number;\n if (index >= 1 && index < last - 1) {\n // A middle item compresses both neighbors.\n const target =\n value * Math.min((expandedRatio * w(index)) / 2, limit(index - 1), limit(index + 1));\n const left = Math.min(target, w(index - 1));\n const right = Math.min(target, w(index + 1));\n widths[index - 1] = w(index - 1) - left;\n widths[index + 1] = w(index + 1) - right;\n growth = left + right;\n } else if (index === 0) {\n // The first item compresses the next one.\n const target = value * Math.min(expandedRatio * w(index), limit(index + 1));\n const right = Math.min(target, w(index + 1));\n widths[index + 1] = w(index + 1) - right;\n growth = right;\n } else {\n // The last item compresses the previous one.\n const target = value * Math.min(expandedRatio * w(index), limit(index - 1));\n const left = Math.min(target, w(index - 1));\n widths[index - 1] = w(index - 1) - left;\n growth = left;\n }\n widths[index] = w(index) + growth;\n }\n return widths.slice(0, last);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kyralabs/m3e-motion",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Spring and easing math for m3exp-web (internal-first).",
5
5
  "keywords": [
6
6
  "material-design",