@astryxdesign/core 0.7.7-canary.d0b6e0f → 0.7.7-canary.eadd175

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.
@@ -1 +1 @@
1
- {"version":3,"file":"MonthScroller.d.ts","sourceRoot":"","sources":["../../src/DateInput/MonthScroller.tsx"],"names":[],"mappings":"AAqDA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EAOf,MAAM,UAAU,CAAC;AAgNlB,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACxD,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,+BAA+B;IAC/B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,gCAAgC;IAChC,YAAY,EAAE,SAAS,CAAC;IACxB,kCAAkC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,GACT,EAAE,kBAAkB,+BA0fpB;yBArgBe,aAAa"}
1
+ {"version":3,"file":"MonthScroller.d.ts","sourceRoot":"","sources":["../../src/DateInput/MonthScroller.tsx"],"names":[],"mappings":"AAqDA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EAOf,MAAM,UAAU,CAAC;AAiNlB,MAAM,WAAW,mBAAmB;IAClC,0DAA0D;IAC1D,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IACxD,+CAA+C;IAC/C,aAAa,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,+BAA+B;IAC/B,YAAY,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/B,4CAA4C;IAC5C,KAAK,EAAE,SAAS,CAAC;IACjB,2DAA2D;IAC3D,cAAc,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC;IAC7C,gCAAgC;IAChC,YAAY,EAAE,SAAS,CAAC;IACxB,kCAAkC;IAClC,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;CAC1C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,KAAK,EACL,cAAc,EACd,YAAY,EACZ,QAAQ,GACT,EAAE,kBAAkB,+BAmjBpB;yBA9jBe,aAAa"}
@@ -38,6 +38,7 @@ import { colorVars, radiusVars, fontWeightVars, typeScaleVars, durationVars, bor
38
38
  import { focusOutlineStyles } from "../utils/index.js";
39
39
  import { plainDateFormatStandaloneMonthYear } from "../utils/plainDate.js";
40
40
  import { plainDateAddDays, plainDateDayOfWeek, plainDateFormat, plainDateIsEqual, plainDateToISO, DATE_FORMAT_WITH_WEEKDAY } from "../utils/index.js";
41
+ import { reducedMotionFade } from "../motion/reducedMotion.js";
41
42
  import "./tokens.stylex.js";
42
43
  import { dateInputTouchSizes, dateInputTouchGeometry } from "./tokens.stylex.js";
43
44
  import { useOwnScrollGesture } from "./useOwnScrollGesture.js";
@@ -251,7 +252,25 @@ export function MonthScroller({
251
252
  hasPositionedRef.current = true;
252
253
  scroller.scrollLeft = scrollOffsetForRow(initialMonthIndex - minMonthIndex, paneSize, isRTL);
253
254
  }, [paneSize, initialMonthIndex, minMonthIndex, isRTL]);
255
+
256
+ // The Reduced Motion dip of a step on a touch screen, owned here so a
257
+ // second step or the unmount clears it.
258
+ const dipRef = useRef(null);
259
+ const stopDip = useCallback(() => {
260
+ const dip = dipRef.current;
261
+ if (dip != null) {
262
+ window.clearTimeout(dip.timer);
263
+ dip.animation.cancel();
264
+ dipRef.current = null;
265
+ }
266
+ }, []);
267
+ // Synchronizes with the dip's timer and animation: neither outlives the
268
+ // scroller.
269
+ useEffect(() => stopDip, [stopDip]);
254
270
  const scrollToMonth = useCallback((monthIndex, behavior = 'smooth') => {
271
+ // Every step replaces a running dip, whichever way it moves. Otherwise
272
+ // the dip's landing would undo a jump or an immediate step made after it.
273
+ stopDip();
255
274
  const scroller = scrollerRef.current;
256
275
  if (scroller == null || paneSize === 0) {
257
276
  return;
@@ -274,12 +293,63 @@ export function MonthScroller({
274
293
  recenter(scroller, row);
275
294
  return;
276
295
  }
296
+ const left = scrollOffsetForRow(row, paneSize, isRTL);
297
+ // Under reduced motion the month changes without travel: at once on a fine
298
+ // primary pointer, under an opacity dip on a coarse one (reducedMotionFade).
299
+ const fade = behavior === 'smooth' ? reducedMotionFade(scroller) : null;
300
+ if (fade != null) {
301
+ // The window mounts around the target first, and the scroll lands in
302
+ // the layout effect below, as a far jump does. So nothing moves the
303
+ // window after the jump. If the window followed the jump, WebKit would
304
+ // re-snap it one pane further on every frame. A scroll that lands on
305
+ // the centre row reports nothing.
306
+ const land = () => {
307
+ // The landing is the newest steer. An earlier steer whose scroll
308
+ // never arrived would otherwise hide every scroll after it, a
309
+ // trackpad's included. Closing the wheels makes such a steer: it
310
+ // re-asserts the month already in view.
311
+ steeredRowRef.current = null;
312
+ if (row === centerRowRef.current) {
313
+ scroller.scrollTo({
314
+ left,
315
+ behavior: 'auto'
316
+ });
317
+ return;
318
+ }
319
+ pendingScrollRef.current = row;
320
+ centerRowRef.current = row;
321
+ setCenterRow(row);
322
+ };
323
+ if (fade.duration === 0) {
324
+ land();
325
+ return;
326
+ }
327
+ // A second step within the dip has replaced the first (above): only
328
+ // its scroll lands, at its own dip's middle.
329
+ dipRef.current = {
330
+ animation: scroller.animate([{
331
+ opacity: 1
332
+ }, {
333
+ opacity: 0
334
+ }, {
335
+ opacity: 1
336
+ }], {
337
+ duration: fade.duration,
338
+ easing: fade.easing
339
+ }),
340
+ timer: window.setTimeout(() => {
341
+ dipRef.current = null;
342
+ land();
343
+ }, fade.duration / 2)
344
+ };
345
+ return;
346
+ }
277
347
  steeredRowRef.current = row;
278
348
  scroller.scrollTo({
279
- left: scrollOffsetForRow(row, paneSize, isRTL),
349
+ left,
280
350
  behavior
281
351
  });
282
- }, [paneSize, minMonthIndex, rowCount, isRTL, recenter]);
352
+ }, [paneSize, minMonthIndex, rowCount, isRTL, recenter, stopDip]);
283
353
 
284
354
  // Deliberately un-keyed: it runs after every render, costs a null check, and
285
355
  // must fire on whichever render finally mounts the pending row's pane.
@@ -1 +1 @@
1
- {"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../src/motion/animator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"animator.d.ts","sourceRoot":"","sources":["../../src/motion/animator.ts"],"names":[],"mappings":"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"}
@@ -643,7 +643,7 @@ export function createAnimator(element, options = {}) {
643
643
  if (segment == null) {
644
644
  return null;
645
645
  }
646
- if (time >= segment.start + segment.duration) {
646
+ if (time >= endOf(property, segment)) {
647
647
  return null;
648
648
  }
649
649
  return segment;
@@ -676,6 +676,41 @@ export function createAnimator(element, options = {}) {
676
676
  start: segment.start + latest - segment.group.provisional
677
677
  };
678
678
 
679
+ /**
680
+ * When a waiting curve's call had its first frame, which put the curve on
681
+ * screen. Undefined for a curve that does not wait, or whose call has had
682
+ * no first frame.
683
+ */
684
+ const shownSince = (property, segment) => segment.group?.resolved === false ? segment.group.latest?.get(CHANNEL_OF[property]) : undefined;
685
+
686
+ /** A curve's end, dated from its call's first frame while it waits. */
687
+ const endOf = (property, segment) => (datedFromLatest(segment, shownSince(property, segment))?.start ?? segment.start) + segment.duration;
688
+
689
+ /**
690
+ * Takes a curve on screen out of the call that still waits for the
691
+ * browser's start. The curve keeps its course, dated from the call's first
692
+ * frame. A call that has no channel left starts at that frame.
693
+ */
694
+ const leaveWaitingCall = (segment, channel, latest) => {
695
+ const group = segment.group;
696
+ if (group == null) {
697
+ return;
698
+ }
699
+ const index = group.segments.indexOf(segment);
700
+ if (index >= 0) {
701
+ group.segments.splice(index, 1);
702
+ }
703
+ segment.start += latest - group.provisional;
704
+ segment.group = undefined;
705
+ if (!CHANNELS[channel].some(p => segments.get(p)?.group === group)) {
706
+ group.latest?.delete(channel);
707
+ group.channels.delete(channel);
708
+ }
709
+ if (group.channels.size === 0 && group.segments.length === 0) {
710
+ resolveGroup(group, latest);
711
+ }
712
+ };
713
+
679
714
  /**
680
715
  * The value on screen at `time`. Until the browser reports its start, a
681
716
  * held curve shows its first value. A frame that ran without that start
@@ -877,12 +912,25 @@ export function createAnimator(element, options = {}) {
877
912
  // Settled curves become resting values.
878
913
  for (const property of properties) {
879
914
  const segment = segments.get(property);
880
- if (segment != null && time >= segment.start + segment.duration) {
915
+ if (segment != null && time >= endOf(property, segment)) {
881
916
  resting[property] = segment.target;
882
917
  segments.delete(property);
883
918
  }
884
919
  }
885
920
  const moving = properties.filter(p => segments.has(p));
921
+ if (callGroup == null) {
922
+ // A call that starts now rebuilds a channel the compositor has moving
923
+ // since a first frame without a known start. The channel carries on
924
+ // from that frame, with a start of its own, instead of starting its
925
+ // curve again.
926
+ for (const property of moving) {
927
+ const segment = segments.get(property);
928
+ const latest = shownSince(property, segment);
929
+ if (latest != null) {
930
+ leaveWaitingCall(segment, channel, latest);
931
+ }
932
+ }
933
+ }
886
934
  // An explicit call can rebuild a channel while one of its curves still
887
935
  // waits for the browser's start. The animation then joins the current
888
936
  // call, or else that waiting call, with no start of its own.
@@ -1497,7 +1545,9 @@ export function createAnimator(element, options = {}) {
1497
1545
  for (const channel of start === 'commit' ? [] : channels) {
1498
1546
  for (const property of CHANNELS[channel]) {
1499
1547
  const segment = segments.get(property);
1500
- if (segment != null && time < segment.start + segment.duration && (segment.group == null || segment.group.resolved)) {
1548
+ // A call's first frame puts its channels on screen, even before the
1549
+ // browser reports the start. So such a channel is not at rest either.
1550
+ if (segment != null && time < endOf(property, segment) && (segment.group == null || segment.group.resolved || shownSince(property, segment) != null)) {
1501
1551
  return null;
1502
1552
  }
1503
1553
  }
@@ -2885,8 +2935,10 @@ export function createAnimator(element, options = {}) {
2885
2935
  }
2886
2936
  owners.add(segment.owner);
2887
2937
  // A curve still waiting for the browser's start stays in its call:
2888
- // it starts with that call's commit.
2889
- const group = segment.group != null && !segment.group.resolved ? segment.group : undefined;
2938
+ // it starts with that call's commit. A curve whose call had its first
2939
+ // frame is on screen already, so it leaves the call (leaveWaitingCall).
2940
+ const latest = shownSince(property, segment);
2941
+ const group = latest == null && segment.group != null && !segment.group.resolved ? segment.group : undefined;
2890
2942
  const replace = next => {
2891
2943
  if (group != null) {
2892
2944
  const index = group.segments.indexOf(segment);
@@ -2901,6 +2953,9 @@ export function createAnimator(element, options = {}) {
2901
2953
  if (segment.spring != null) {
2902
2954
  const from = valueAt(property, time) + delta;
2903
2955
  const velocity = velocityAt(property, time);
2956
+ if (latest != null) {
2957
+ leaveWaitingCall(segment, CHANNEL_OF[property], latest);
2958
+ }
2904
2959
  const curve = solveSpring(toSpring(segment.spring), {
2905
2960
  from,
2906
2961
  to: segment.target,
@@ -2920,6 +2975,9 @@ export function createAnimator(element, options = {}) {
2920
2975
  spring: segment.spring
2921
2976
  });
2922
2977
  } else {
2978
+ if (latest != null) {
2979
+ leaveWaitingCall(segment, CHANNEL_OF[property], latest);
2980
+ }
2923
2981
  replace({
2924
2982
  ...segment,
2925
2983
  target: segment.target + delta,
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @file paging.ts
3
+ * @input A release velocity, a settle's start, end and velocity, and the UIKit
4
+ * paging constants
5
+ * @output Exports `pagingSettleVelocity`, `solvePaging` (UIKit's paging settle
6
+ * as a curve the animator plays) and `solveAnimatedPageScroll`
7
+ * @position Pure math, with no DOM and no React
8
+ *
9
+ * SYNC: When modified, update:
10
+ * - /packages/core/src/motion/paging.test.ts
11
+ * - /packages/core/src/motion/README.md
12
+ */
13
+ import type { MotionCurve } from './animator.js';
14
+ /**
15
+ * The velocity a paging settle starts at. It is the release velocity that every
16
+ * gesture reads, zeroed below `velocityFloor`. The page choice reads the
17
+ * release velocity itself.
18
+ */
19
+ export declare function pagingSettleVelocity(velocity: number): number;
20
+ /** A paging settle: the curve and where it ends. */
21
+ export interface PagingCurve extends MotionCurve {
22
+ readonly from: number;
23
+ readonly to: number;
24
+ /** Integration steps the settle took. */
25
+ readonly steps: number;
26
+ }
27
+ /**
28
+ * UIKit's paging settle from `from` (px), moving at `velocity` (px/s), onto
29
+ * `to`. It steps `paging.integrator` `stepsPerSecond` times a second and ends
30
+ * exactly on `to`. The same motion returns an overscrolled pager to its first
31
+ * or last page.
32
+ *
33
+ * Positions are content offsets along the paging axis, 0 at page 0 and growing
34
+ * toward later pages. Velocities are px/s of that offset.
35
+ *
36
+ * No closed form reproduces the per-frame stepping, so the settle integrates
37
+ * once into a table, and the curve reads the table. A release needs at most
38
+ * about 400 steps, well under a millisecond of work.
39
+ *
40
+ * The release velocity enters in px per millisecond per step, as UIKit hands it
41
+ * to the integrator. At 960 steps a second, the content starts at 96 % of the
42
+ * finger's speed, as in UIKit.
43
+ */
44
+ export declare function solvePaging({ from, velocity, to, }: {
45
+ from: number;
46
+ velocity: number;
47
+ to: number;
48
+ }): PagingCurve;
49
+ /**
50
+ * `setContentOffset(_:animated:)`: `paging.animatedScroll.duration` on a
51
+ * sinusoidal ease-in-out, whatever the distance. UIKit starts it from the
52
+ * current offset and drops any velocity, as here.
53
+ */
54
+ export declare function solveAnimatedPageScroll({ from, to, }: {
55
+ from: number;
56
+ to: number;
57
+ }): MotionCurve;
58
+ //# sourceMappingURL=paging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paging.d.ts","sourceRoot":"","sources":["../../src/motion/paging.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,YAAY,CAAC;AAG5C;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,oDAAoD;AACpD,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,EAAE,GACH,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,WAAW,CA6Cd;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,EAAE,GACH,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,GAAG,WAAW,CAmBd"}
@@ -0,0 +1,128 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file paging.ts
5
+ * @input A release velocity, a settle's start, end and velocity, and the UIKit
6
+ * paging constants
7
+ * @output Exports `pagingSettleVelocity`, `solvePaging` (UIKit's paging settle
8
+ * as a curve the animator plays) and `solveAnimatedPageScroll`
9
+ * @position Pure math, with no DOM and no React
10
+ *
11
+ * SYNC: When modified, update:
12
+ * - /packages/core/src/motion/paging.test.ts
13
+ * - /packages/core/src/motion/README.md
14
+ */
15
+
16
+ import { paging } from "./uikit/paging.js";
17
+
18
+ /**
19
+ * The velocity a paging settle starts at. It is the release velocity that every
20
+ * gesture reads, zeroed below `velocityFloor`. The page choice reads the
21
+ * release velocity itself.
22
+ */
23
+ export function pagingSettleVelocity(velocity) {
24
+ return Math.abs(velocity) < paging.release.velocityFloor ? 0 : velocity;
25
+ }
26
+
27
+ /** A paging settle: the curve and where it ends. */
28
+
29
+ /**
30
+ * UIKit's paging settle from `from` (px), moving at `velocity` (px/s), onto
31
+ * `to`. It steps `paging.integrator` `stepsPerSecond` times a second and ends
32
+ * exactly on `to`. The same motion returns an overscrolled pager to its first
33
+ * or last page.
34
+ *
35
+ * Positions are content offsets along the paging axis, 0 at page 0 and growing
36
+ * toward later pages. Velocities are px/s of that offset.
37
+ *
38
+ * No closed form reproduces the per-frame stepping, so the settle integrates
39
+ * once into a table, and the curve reads the table. A release needs at most
40
+ * about 400 steps, well under a millisecond of work.
41
+ *
42
+ * The release velocity enters in px per millisecond per step, as UIKit hands it
43
+ * to the integrator. At 960 steps a second, the content starts at 96 % of the
44
+ * finger's speed, as in UIKit.
45
+ */
46
+ export function solvePaging({
47
+ from,
48
+ velocity,
49
+ to
50
+ }) {
51
+ const {
52
+ springPull,
53
+ friction,
54
+ stepsPerSecond,
55
+ restDistance,
56
+ restSpeed
57
+ } = paging.integrator;
58
+ const xs = [from];
59
+ const vs = [velocity / 1000];
60
+ let x = from;
61
+ let v = velocity / 1000;
62
+ // ~10 s of steps: far beyond any settle (≈ 0.35 s from rest).
63
+ const maxSteps = stepsPerSecond * 10;
64
+ let steps = 0;
65
+ while (steps < maxSteps) {
66
+ if (Math.abs(to - x) < restDistance && Math.abs(v) < restSpeed) {
67
+ break;
68
+ }
69
+ v = (v + (to - x) * springPull) * friction;
70
+ x += v;
71
+ steps += 1;
72
+ xs.push(x);
73
+ vs.push(v);
74
+ }
75
+ xs[xs.length - 1] = to;
76
+ vs[vs.length - 1] = 0;
77
+ const duration = steps / stepsPerSecond;
78
+ const last = xs.length - 1;
79
+ const read = (table, t) => {
80
+ if (!(t > 0)) {
81
+ return table[0];
82
+ }
83
+ const s = t * stepsPerSecond;
84
+ if (s >= last) {
85
+ return table[last];
86
+ }
87
+ const i = Math.floor(s);
88
+ const f = s - i;
89
+ return table[i] + (table[i + 1] - table[i]) * f;
90
+ };
91
+ return {
92
+ from,
93
+ to,
94
+ steps,
95
+ duration,
96
+ at: t => read(xs, t),
97
+ // px per step × steps per second
98
+ velocity: t => read(vs, t) * stepsPerSecond
99
+ };
100
+ }
101
+
102
+ /**
103
+ * `setContentOffset(_:animated:)`: `paging.animatedScroll.duration` on a
104
+ * sinusoidal ease-in-out, whatever the distance. UIKit starts it from the
105
+ * current offset and drops any velocity, as here.
106
+ */
107
+ export function solveAnimatedPageScroll({
108
+ from,
109
+ to
110
+ }) {
111
+ const {
112
+ duration
113
+ } = paging.animatedScroll;
114
+ const distance = to - from;
115
+ return {
116
+ duration,
117
+ at: t => {
118
+ const u = Math.min(1, Math.max(0, t / duration));
119
+ return from + distance * (1 - Math.cos(Math.PI * u)) / 2;
120
+ },
121
+ velocity: t => {
122
+ if (t <= 0 || t >= duration) {
123
+ return 0;
124
+ }
125
+ return distance * Math.PI / (2 * duration) * Math.sin(Math.PI * t / duration);
126
+ }
127
+ };
128
+ }
@@ -0,0 +1,160 @@
1
+ /**
2
+ * @file paging.ts
3
+ * @input Nothing; data only
4
+ * @output Exports `paging`, the measured constants of a paging UIScrollView
5
+ * @position The paging domain of the UIKit constants table (motion/uikit). Only
6
+ * core reads it, so the `uikit` namespace does not re-export it
7
+ *
8
+ * SYNC: When modified, update:
9
+ * - /packages/core/src/motion/MEASUREMENTS.md (measurement tasks)
10
+ * - /packages/core/src/motion/paging.ts and paging.test.ts
11
+ */
12
+ export declare const paging: {
13
+ /**
14
+ * After the lift, one model moves the content: the settle onto the chosen
15
+ * page and the return from an overscroll. Each display frame runs floor(frame
16
+ * interval in ms) steps of 1 ms:
17
+ *
18
+ * v = (v + (target − x) · springPull) · friction; x += v (v: pt per step)
19
+ *
20
+ * A 60 Hz frame runs 16 steps, not 16.67. With these values, the model
21
+ * replays eight captured releases to 0.20 pt RMS. It replays five overscroll
22
+ * returns to 0.16–0.33 pt RMS (402 pt pages, iOS 26.2, 3× screen). Without
23
+ * the floor, the error is 1.0 pt RMS, with a systematic shape.
24
+ */
25
+ readonly integrator: {
26
+ /**
27
+ * Velocity added per 1 ms step, per point of distance to the target page
28
+ * (pt per step²).
29
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026.
30
+ * `_pagingSpringPull` reads the same on a 402 pt paging UIScrollView and
31
+ * on UIPageViewController's scroll view. It replays 8 captured settles to
32
+ * 0.20 pt RMS.
33
+ */
34
+ readonly springPull: 0.000284858;
35
+ /**
36
+ * Velocity kept per step after the pull (`_pagingFriction`, equal to
37
+ * `_defaultPagingFriction`).
38
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. Both read
39
+ * the same on the two scroll views of `springPull`, and they replay with
40
+ * it.
41
+ */
42
+ readonly friction: 0.970815;
43
+ /**
44
+ * Integration steps per second: floor(16.67 ms) = 16 steps per 60 Hz frame,
45
+ * and floor(8.33 ms) = 8 per 120 Hz frame, so 960.
46
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. In a 60 fps
47
+ * log of 8 releases at rest, floored stepping fits to 0.20 pt RMS.
48
+ * Unfloored stepping fits to 1.0 pt RMS.
49
+ */
50
+ readonly stepsPerSecond: 960;
51
+ /**
52
+ * A settle ends exactly on the page once the remaining distance is below
53
+ * this many points and the step velocity is below `restSpeed`.
54
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. The
55
+ * captured settles jump the last 0.33 pt onto the page about 0.35 s after
56
+ * a release at rest.
57
+ */
58
+ readonly restDistance: 0.5;
59
+ /**
60
+ * Step velocity (pt per step) below which a settle may end.
61
+ * @source GUESS — the captured settles end at about 0.04 pt per step;
62
+ * the threshold is not observable more finely at 60 fps
63
+ * @measure M-PG12
64
+ */
65
+ readonly restSpeed: 0.05;
66
+ };
67
+ readonly release: {
68
+ /**
69
+ * Released slower than `advanceSpeed`, the scroll view settles on the page
70
+ * nearest the content position: past half a page, the next one.
71
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. In releases
72
+ * at rest from page 1, content at 48.5 % of the page stays, and 57.5 %
73
+ * goes to the next page. On a second 402 pt pager, 45 % stays and 55 %
74
+ * advances.
75
+ */
76
+ readonly commitFraction: 0.5;
77
+ /**
78
+ * Released at least this fast (pt/s), the scroll view pages in the
79
+ * direction of the velocity, from any content position. A flick from 6 % of
80
+ * the page advances. The speed is UIPanGestureRecognizer's velocity at the
81
+ * last movement, and it never decays. The scroll view's
82
+ * `_horizontalVelocity` equals it at every sample. A drag held still for
83
+ * 397 ms before the lift still pages at the speed it had.
84
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. Steady
85
+ * releases at 10, 25 and 40 % of a 402 pt page: 292.7, 295.3 and 298.6
86
+ * pt/s stay; 310.7, 316.4 and 329.9 advance. The result is the same at
87
+ * every position: a threshold, not a projection.
88
+ */
89
+ readonly advanceSpeed: 300;
90
+ /**
91
+ * A settle velocity slower than this (pt/s) is zeroed, so the settle starts
92
+ * at rest. It is paging's own tuning on the one release velocity that every
93
+ * gesture reads.
94
+ * @source GUESS — the middle of the measured (200, 249] bracket. In the
95
+ * UIKit lab (iOS 26.2 simulator, Oct 23 2026),
96
+ * `scrollViewWillEndDragging` reads 0 for steady releases at 175 and 200
97
+ * pt/s. It reads 0.249 pt/ms for a release at 249 pt/s.
98
+ * @measure M-PG13
99
+ */
100
+ readonly velocityFloor: 225;
101
+ /**
102
+ * Pages a release may travel from the page the drag started on, at any
103
+ * speed and drag distance.
104
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. A drag of
105
+ * 1.5 pages from page 1 lands on page 2 at release speeds of 0, 600 and
106
+ * 3000 pt/s.
107
+ */
108
+ readonly maxPagesFromStart: 1;
109
+ };
110
+ /**
111
+ * A finger that lands on a settling pager does not stop it at once. The
112
+ * settle runs on for about this long, then the content holds under the
113
+ * finger. Lifted without a move, the content settles again on the nearest
114
+ * page.
115
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. After
116
+ * touch-downs 60 and 160 ms into a settle, the content moved on for 82.6
117
+ * and 87.5 ms (5 frames), then held.
118
+ */
119
+ readonly catchStopMs: 85;
120
+ /**
121
+ * A horizontal pager's pan begins only for a drag within atan(1 ÷ this) of
122
+ * horizontal (26.6° for 2). A steeper drag goes to the vertical scroll around
123
+ * it. Between 26.6° and 45°, neither moves.
124
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. A scroll
125
+ * view's directional lock holds the major axis up to 25° and frees it from
126
+ * 30°. An inline calendar pager in a sheet pages at 20° from horizontal. At
127
+ * 35° and 45°, it moves neither itself nor the sheet, and it leaves 55° to
128
+ * the sheet.
129
+ */
130
+ readonly panAxisRatio: 2;
131
+ readonly animatedScroll: {
132
+ /**
133
+ * `setContentOffset(_:animated:)` duration. It is the same for one page and
134
+ * for five, as for a page control's tap.
135
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026.
136
+ * `_contentOffsetAnimationDuration` reads 0.3, and five animated moves of
137
+ * 1 to 5 pages each last 0.30 s.
138
+ */
139
+ readonly duration: 0.3;
140
+ /**
141
+ * Its curve is a sinusoidal ease-in-out: x = from + (to − from) · (1 − cos
142
+ * πu) ÷ 2, for u = t ÷ duration.
143
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. The five
144
+ * moves fit the sinusoid to 0.14–0.51 pt RMS, and a 2010 pt move fits to
145
+ * 0.20 pt. The curve easeInEaseOut (0.42, 0, 0.58, 1) misses by 7.7 pt.
146
+ */
147
+ readonly curve: "sineInOut";
148
+ };
149
+ /**
150
+ * Past the first or last page, the content follows the finger through the
151
+ * scroll view's rubber band (scroll.rubberBand.coefficient), with d = the
152
+ * page width. It returns on the integrator above.
153
+ * @source measured: UIKit lab, iOS 26.2 simulator, Oct 23 2026. A pan of 90
154
+ * pt past page 0 shows 42.7–45 pt, and 290 pt shows 114.3 pt. The formula
155
+ * gives 44.1 and 114.2, with c 0.55 and d 402. The return replays on the
156
+ * integrator to 0.16–0.33 pt RMS.
157
+ */
158
+ readonly rubberBandDimension: "pageWidth";
159
+ };
160
+ //# sourceMappingURL=paging.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paging.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/paging.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,MAAM;IACjB;;;;;;;;;;;OAWG;;QAED;;;;;;;WAOG;;QAEH;;;;;;WAMG;;QAEH;;;;;;WAMG;;QAEH;;;;;;WAMG;;QAEH;;;;;WAKG;;;;QAIH;;;;;;;WAOG;;QAEH;;;;;;;;;;;WAWG;;QAEH;;;;;;;;;WASG;;QAEH;;;;;;WAMG;;;IAGL;;;;;;;;OAQG;;IAEH;;;;;;;;;OASG;;;QAGD;;;;;;WAMG;;QAEH;;;;;;WAMG;;;IAGL;;;;;;;;OAQG;;CAEK,CAAC"}