@astryxdesign/core 0.7.9-canary.12f63f5 → 0.7.9-canary.2ea8f68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/Switch/Switch.d.ts.map +1 -1
  2. package/dist/Switch/Switch.js +13 -10
  3. package/dist/astryx.css +9 -9
  4. package/dist/internal/touch.d.ts +14 -1
  5. package/dist/internal/touch.d.ts.map +1 -1
  6. package/dist/internal/touch.js +20 -2
  7. package/dist/motion/uikit/timing.d.ts +14 -10
  8. package/dist/motion/uikit/timing.d.ts.map +1 -1
  9. package/dist/motion/uikit/timing.js +7 -5
  10. package/dist/privateAttributes/press.stylex.d.ts +2 -2
  11. package/dist/privateAttributes/press.stylex.d.ts.map +1 -1
  12. package/dist/privateAttributes/press.stylex.js +12 -13
  13. package/dist/theme/themeMotion.d.ts +3 -2
  14. package/dist/theme/themeMotion.d.ts.map +1 -1
  15. package/dist/theme/themeMotion.js +3 -2
  16. package/dist/utils/interactionOverlay.stylex.d.ts +3 -8
  17. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  18. package/dist/utils/interactionOverlay.stylex.js +27 -34
  19. package/dist/utils/pressFeedback.d.ts +3 -2
  20. package/dist/utils/pressFeedback.d.ts.map +1 -1
  21. package/dist/utils/pressFeedback.js +8 -8
  22. package/dist/utils/pressGesture.d.ts +6 -6
  23. package/dist/utils/pressGesture.d.ts.map +1 -1
  24. package/dist/utils/pressGesture.js +9 -8
  25. package/package.json +4 -4
  26. package/src/Switch/Switch.tsx +7 -6
  27. package/src/internal/touch.ts +34 -1
  28. package/src/motion/uikit/timing.ts +7 -5
  29. package/src/privateAttributes/press.stylex.ts +9 -10
  30. package/src/theme/themeMotion.ts +3 -2
  31. package/src/utils/interactionOverlay.stylex.ts +17 -25
  32. package/src/utils/pressFeedback.ts +15 -8
  33. package/src/utils/pressGesture.ts +11 -8
  34. package/dist/utils/rowPressLayer.stylex.d.ts +0 -14
  35. package/dist/utils/rowPressLayer.stylex.d.ts.map +0 -1
  36. package/dist/utils/rowPressLayer.stylex.js +0 -25
  37. package/src/utils/rowPressLayer.stylex.ts +0 -27
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/Switch/Switch.tsx"],"names":[],"mappings":"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"}
@@ -33,8 +33,10 @@ import { usePressFeedback } from "../hooks/usePressFeedback.js";
33
33
  import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
34
34
  import english from "../i18n/generated-english/Switch/Switch.generated.js";
35
35
  registerEnglishFallback(english);
36
+ import "../motion/reducedMotion.stylex.js";
37
+ import { reducedMotionFadeConsts } from "../motion/reducedMotion.stylex.js";
36
38
  import "../utils/interactionOverlay.stylex.js";
37
- import { interactionOverlayStyles, pressConsts, pressVars } from "../utils/interactionOverlay.stylex.js";
39
+ import { interactionOverlayStyles, pressVars } from "../utils/interactionOverlay.stylex.js";
38
40
  import { pressHoldsDragProps } from "../privateAttributes/pressHoldsDrag.stylex.js";
39
41
  import { useSwitchTouch } from "./useSwitchTouch.js";
40
42
  import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
@@ -65,14 +67,15 @@ const PRESS_FADING = '[data-astryx-press="fading"]';
65
67
 
66
68
  /**
67
69
  * The shared press release, for the press layers the switch fades on the
68
- * compositor. The clock scales by the theme's tempo, and the curve is the
69
- * controller's own. Switch.test.tsx compares the two.
70
+ * compositor: the theme's exit motion tokens, no longer than the Reduce
71
+ * Motion fade under Reduce Motion. Switch.test.tsx compares them with
72
+ * the overlay's.
70
73
  * SYNC: utils/interactionOverlay.stylex.ts PRESS_RELEASE_DURATION,
71
74
  * PRESS_RELEASE_DURATION_REDUCED and RELEASE_EASE.
72
75
  */
73
- const PRESS_RELEASE_DURATION = `calc(${pressConsts.releaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
74
- const PRESS_RELEASE_DURATION_REDUCED = `min(${pressConsts.releaseMs}ms, calc(${pressConsts.releaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
75
- const PRESS_RELEASE_EASE = 'cubic-bezier(0, 0, 0.2, 1)';
76
+ const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
77
+ const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
78
+ const PRESS_RELEASE_EASE = easeVars['--ease-exit'];
76
79
 
77
80
  // The measured hit insets (utils/hitArea), 0 until measured.
78
81
  const HIT_TOP = 'var(--astryx-hit-inset-top, 0px)';
@@ -262,8 +265,8 @@ const styles = {
262
265
  kLkRvE: "x1my3e5g",
263
266
  k5QlbN: "x2huugr x1ccaw7f",
264
267
  k7EzDT: "xxhzo2e",
265
- kQZAMR: "xvym4rz xigdn9b",
266
- kZiNAr: "xgq6fxe",
268
+ kQZAMR: "xs8z9ty x1e7l4zx",
269
+ kZiNAr: "x15baseh",
267
270
  k8Tatv: "xq2jpp1",
268
271
  k5JduY: "x1s928wv",
269
272
  kc3QkE: "x1h1zc6f x1ep27e9",
@@ -320,8 +323,8 @@ const styles = {
320
323
  kLkRvE: "x1my3e5g",
321
324
  k5QlbN: "x2huugr x1ccaw7f",
322
325
  k7EzDT: "xxhzo2e",
323
- kQZAMR: "xvym4rz xigdn9b",
324
- kZiNAr: "xgq6fxe",
326
+ kQZAMR: "xs8z9ty x1e7l4zx",
327
+ kZiNAr: "x15baseh",
325
328
  k8Tatv: "xq2jpp1",
326
329
  k5JduY: "x1s928wv",
327
330
  kc3QkE: "x1h1zc6f x1ep27e9",
package/dist/astryx.css CHANGED
@@ -2280,10 +2280,10 @@
2280
2280
  @media (max-width: 640px){.xci7e5a.xci7e5a:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--x-fqzwsx)}}
2281
2281
  @supports (-webkit-touch-callout: none){@media (pointer: coarse){.x9w4715.x9w4715.x9w4715:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(max(1rem,var(--text-body-size)) * var(--text-body-leading));height:1lh}}}
2282
2282
  @media (pointer: coarse){@media (forced-colors: active){.x1j61smm.x1j61smm.x1j61smm:not(#\#):not(#\#):not(#\#):not(#\#){width:calc(max(var(--_progress-bar-fill,0%),var(--_progress-bar-min,0px)) + var(--_progress-bar-flip,0) * .01px)}}}
2283
- .x1heh2iz[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-duration:calc(.2s * min(var(--_astryx-motion-tempo,1),1.5))}
2283
+ .xem8lmn[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-exit)}
2284
2284
  .xziyay6[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-fill-mode:both}
2285
2285
  .x14e4jsf[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-name:x10jkm1t-B}
2286
- .xwkbtvz[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-timing-function:cubic-bezier(0,0,.2,1)}
2286
+ .x1t1ddl7[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-timing-function:var(--ease-exit)}
2287
2287
  .x7qqc7o[data-astryx-press="on"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}
2288
2288
  .xf3x42i[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}
2289
2289
  .x1bev2v5[data-astryx-press="on"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background-image:none}
@@ -2317,7 +2317,7 @@
2317
2317
  @starting-style{.x14gflnl.x14gflnl:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateX(100%)}}
2318
2318
  @starting-style{.xrxqmjf.xrxqmjf:dir(rtl):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateX(-100%)}}
2319
2319
  @starting-style{.x1r0dqvm.x1r0dqvm:dir(rtl):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateX(100%)}}
2320
- @media (prefers-reduced-motion: reduce){.x1sgdaq5.x1sgdaq5[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-duration:min(.2s,calc(.2s * var(--_astryx-motion-tempo,1)))}}
2320
+ @media (prefers-reduced-motion: reduce){.xogcwkh.xogcwkh[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-duration:min(var(--duration-exit),200ms)}}
2321
2321
  @media (pointer: coarse){.x6su2wr.x6su2wr[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-name:none}}
2322
2322
  @media (prefers-reduced-motion: reduce) and (not (pointer: coarse)) and (not (pointer: coarse)){.xxsp3er.xxsp3er[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){animation-name:none}}
2323
2323
  @media (forced-colors: active){.x1pjcgc3.x1pjcgc3[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){background-color:Highlight}}
@@ -2504,10 +2504,10 @@
2504
2504
  @media (prefers-reduced-motion: reduce){.x15l12jy.x15l12jy:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{transition-duration:var(--_sheet-scrim-duration,.01s)}}
2505
2505
  @media (pointer: coarse){.xqycr0j.xqycr0j:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{will-change:opacity}}
2506
2506
  @media (pointer: coarse){.x1gybruy.x1gybruy.x1gybruy:where(.x1odsvnm:active *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-color:transparent}}
2507
- @media (pointer: coarse){.xvym4rz.xvym4rz.xvym4rz:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:calc(200ms * min(var(--_astryx-motion-tempo,1),1.5))}}
2507
+ @media (pointer: coarse){.xs8z9ty.xs8z9ty.xs8z9ty:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:var(--duration-exit)}}
2508
2508
  @media (pointer: coarse){.xq2jpp1.xq2jpp1.xq2jpp1:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-fill-mode:both}}
2509
2509
  @media (pointer: coarse){.xxhzo2e.xxhzo2e.xxhzo2e:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-name:x1jn504y-B}}
2510
- @media (pointer: coarse){.xgq6fxe.xgq6fxe.xgq6fxe:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-timing-function:cubic-bezier(0,0,.2,1)}}
2510
+ @media (pointer: coarse){.x15baseh.x15baseh.x15baseh:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-timing-function:var(--ease-exit)}}
2511
2511
  @media (pointer: coarse){.x1dn949c.x1dn949c:is([data-astryx-press="on"],[data-astryx-press="fading"]):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{background-color:var(--color-overlay-pressed)}}
2512
2512
  @media (pointer: coarse){.x1ikgzpo.x1ikgzpo.x1ikgzpo:where(.x1odsvnm[data-astryx-press="on"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-image:var(--_press-paint-image)}}
2513
2513
  @media (pointer: coarse){.xsozn46.xsozn46.xsozn46:where(.x1odsvnm[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-image:var(--_press-paint-image)}}
@@ -2520,7 +2520,7 @@
2520
2520
  @media (pointer: coarse){.xjscm90.xjscm90:is([data-astryx-press="on"],[data-astryx-press="fading"]):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{z-index:-1}}
2521
2521
  @media (pointer: coarse){.x1ocadqd.x1ocadqd.x1ocadqd:is([data-astryx-press="on"],[data-astryx-press="fading"]):where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{content:""}}
2522
2522
  @media (pointer: coarse){.x1995whq.x1995whq.x1995whq:is([data-astryx-press="on"],[data-astryx-press="fading"]):where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{content:none}}
2523
- @media (prefers-reduced-motion: reduce) and (pointer: coarse){@media (pointer: coarse){.xigdn9b.xigdn9b.xigdn9b.xigdn9b:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:min(200ms,calc(200ms * var(--_astryx-motion-tempo,1)))}}}
2523
+ @media (prefers-reduced-motion: reduce) and (pointer: coarse){@media (pointer: coarse){.x1e7l4zx.x1e7l4zx.x1e7l4zx.x1e7l4zx:where(.x1iwu4tg[data-astryx-press="fading"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:min(var(--duration-exit),200ms)}}}
2524
2524
  .xp6skj9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{border-bottom-color:inherit}
2525
2525
  .x1tqw9ds:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-bottom-color:var(--_segmented-after-border-bottom-color,currentcolor)}
2526
2526
  .xg5vybf:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{border-bottom-color:var(--_segmented-lens-border-bottom-color,currentcolor)}
@@ -2596,13 +2596,13 @@
2596
2596
  .x1ea2at[data-astryx-cell-gliding="line"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{position:absolute}
2597
2597
  .x15tr235[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{transition-property:none}
2598
2598
  .x1xg7wox[data-astryx-press="on"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{transition-property:none}
2599
- @media (pointer: coarse){.x16lp0i7.x16lp0i7[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:calc(200ms * min(var(--_astryx-motion-tempo,1),1.5))}}
2599
+ @media (pointer: coarse){.x1osot8d.x1osot8d[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:var(--duration-exit)}}
2600
2600
  @media (pointer: coarse){.x1dn5vsf.x1dn5vsf[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-fill-mode:both}}
2601
- @media (pointer: coarse){.x1gyhjqm.x1gyhjqm[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-timing-function:cubic-bezier(0, 0, 0.2, 1)}}
2601
+ @media (pointer: coarse){.x10t12yn.x10t12yn[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-timing-function:var(--ease-exit)}}
2602
2602
  @media (pointer: coarse){.xr9xsjc.xr9xsjc[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{opacity:0}}
2603
2603
  @media (pointer: coarse){.xw7rim2.xw7rim2[data-astryx-press="on"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{opacity:1}}
2604
2604
  @media (pointer: coarse){.x1bxn267.x1bxn267.x1bxn267:where(:not(:disabled,[aria-disabled="true"]))[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-name:x1jn504y-B}}
2605
- @media (prefers-reduced-motion: reduce){@media (pointer: coarse){.x1bf026e.x1bf026e.x1bf026e[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:min(200ms,calc(200ms * var(--_astryx-motion-tempo,1)))}}}
2605
+ @media (prefers-reduced-motion: reduce){@media (pointer: coarse){.xbkwwzw.xbkwwzw.xbkwwzw[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{animation-duration:min(var(--duration-exit),200ms)}}}
2606
2606
  .x3mysge[data-astryx-table-pinned="carry"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{border-bottom-color:var(--_table-row-divider-app-color,var(--color-border))}
2607
2607
  .x8qyx5[data-astryx-cell-gliding="line"]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-bottom-color:var(--_table-row-glide-color,var(--color-border))}
2608
2608
  .xvlxne[data-astryx-cell-gliding]:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{border-bottom-color:var(--_table-row-glide-color,var(--color-border))}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * @file touch.ts
3
- * @input The gesture core: the arena, the recognizers, and their geometry
3
+ * @input The gesture core: the arena, the recognizers, and their geometry;
4
+ * the pan, the motion animator and the motion math that Lab's
5
+ * useRefreshControl reads
4
6
  * @output `@astryxdesign/core/internal/touch`: the gesture core's primitives
5
7
  * for Lab components, re-exported by name
6
8
  * @position An internal entry reserved for Astryx's own packages:
@@ -23,4 +25,15 @@ export { angleBetween, centroid, distance, travel, unwrapAngle, } from '../gestu
23
25
  export { LongPressGestureRecognizer } from '../gestures/LongPressGestureRecognizer.js';
24
26
  export { TapGestureRecognizer } from '../gestures/TapGestureRecognizer.js';
25
27
  export { DEFAULT_ENVIRONMENT } from '../gestures/types.js';
28
+ export { PanGestureRecognizer } from '../gestures/PanGestureRecognizer.js';
29
+ export type { PanGestureRecognizerOptions } from '../gestures/PanGestureRecognizer.js';
30
+ export type { GestureEventContext, GestureTouch, PointerKind, } from '../gestures/types.js';
31
+ export { useGestureRecognizer } from '../gestures/useGestureRecognizer.js';
32
+ export { createMotionAnimator } from '../motion/animator.js';
33
+ export type { Animator as MotionAnimator, AnimatorOptions as MotionAnimatorOptions, MotionCurve, } from '../motion/animator.js';
34
+ export { cubicBezier } from '../motion/bezier.js';
35
+ export { mapProgress } from '../motion/progress.js';
36
+ export { parseCssEasing, parseMotionRoleValue } from '../motion/roles.js';
37
+ export { rubberBand, rubberBandInverse, rubberBandSlope, } from '../motion/rubberBand.js';
38
+ export { scroll } from '../motion/uikit/scroll.js';
26
39
  //# sourceMappingURL=touch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"touch.d.ts","sourceRoot":"","sources":["../../src/internal/touch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,YAAY,EAAE,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,YAAY,GACb,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,0BAA0B,EAAC,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"touch.d.ts","sourceRoot":"","sources":["../../src/internal/touch.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAC,YAAY,EAAE,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACpE,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,mBAAmB,EACnB,YAAY,GACb,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,0BAA0B,EAAC,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAC,mBAAmB,EAAC,MAAM,mBAAmB,CAAC;AAOtD,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AACtE,YAAY,EAAC,2BAA2B,EAAC,MAAM,kCAAkC,CAAC;AAClF,YAAY,EACV,mBAAmB,EACnB,YAAY,EACZ,WAAW,GACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,oBAAoB,EAAC,MAAM,kCAAkC,CAAC;AAGtE,OAAO,EAAC,oBAAoB,EAAC,MAAM,oBAAoB,CAAC;AACxD,YAAY,EACV,QAAQ,IAAI,cAAc,EAC1B,eAAe,IAAI,qBAAqB,EACxC,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAC,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAC,cAAc,EAAE,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AACrE,OAAO,EACL,UAAU,EACV,iBAAiB,EACjB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,MAAM,EAAC,MAAM,wBAAwB,CAAC"}
@@ -2,7 +2,9 @@
2
2
 
3
3
  /**
4
4
  * @file touch.ts
5
- * @input The gesture core: the arena, the recognizers, and their geometry
5
+ * @input The gesture core: the arena, the recognizers, and their geometry;
6
+ * the pan, the motion animator and the motion math that Lab's
7
+ * useRefreshControl reads
6
8
  * @output `@astryxdesign/core/internal/touch`: the gesture core's primitives
7
9
  * for Lab components, re-exported by name
8
10
  * @position An internal entry reserved for Astryx's own packages:
@@ -25,4 +27,20 @@ export { ALL_NATIVE_TOUCH, GestureRecognizer, isActive, isTerminal, isTransition
25
27
  export { angleBetween, centroid, distance, travel, unwrapAngle } from "../gestures/geometry.js";
26
28
  export { LongPressGestureRecognizer } from "../gestures/LongPressGestureRecognizer.js";
27
29
  export { TapGestureRecognizer } from "../gestures/TapGestureRecognizer.js";
28
- export { DEFAULT_ENVIRONMENT } from "../gestures/types.js";
30
+ export { DEFAULT_ENVIRONMENT } from "../gestures/types.js";
31
+
32
+ // Lab's useRefreshControl reads these: its pull's pan and the hook that
33
+ // starts it. It also reads the motion animator and math, and the scroll
34
+ // view's bounce spring, for its pull, settle and end. Its indicator fades
35
+ // along the settle's curve, and the motion-role parsers read the theme's
36
+ // tokens for its end.
37
+ export { PanGestureRecognizer } from "../gestures/PanGestureRecognizer.js";
38
+ export { useGestureRecognizer } from "../gestures/useGestureRecognizer.js";
39
+ // The animator's internal factory. The public one, `createAnimator`, plays
40
+ // only the theme's state-change motion.
41
+ export { createMotionAnimator } from "../motion/animator.js";
42
+ export { cubicBezier } from "../motion/bezier.js";
43
+ export { mapProgress } from "../motion/progress.js";
44
+ export { parseCssEasing, parseMotionRoleValue } from "../motion/roles.js";
45
+ export { rubberBand, rubberBandInverse, rubberBandSlope } from "../motion/rubberBand.js";
46
+ export { scroll } from "../motion/uikit/scroll.js";
@@ -22,17 +22,19 @@ export declare const press: {
22
22
  */
23
23
  readonly flashMs: 100;
24
24
  /**
25
- * Highlight fade after release: UIKit's deselect cross-fade.
25
+ * Highlight fade after release: UIKit's deselect cross-fade. Reference
26
+ * only, not played: a press release plays the theme's exit motion tokens
27
+ * (`--duration-exit`, `--ease-exit`).
26
28
  * @source measured: Settings and Contacts, iOS 26.2, simulator driven
27
- * with real HID touches at 60 fps (PRESS_FADE_MS / pressConsts.releaseMs,
29
+ * with real HID touches at 60 fps (touch press model,
28
30
  * packages/core/src/utils/pressGesture.ts, 2026-10-06)
29
31
  */
30
32
  readonly highlightOutMs: 200;
31
33
  /**
32
34
  * The highlight fade's curve after release: an ease-out that spends the
33
- * whole clock fading (strength about 0.2 at the midpoint).
34
- * @source GUESS — the release curve the touch press model ships with
35
- * (`RELEASE_EASE`, packages/core/src/utils/interactionOverlay.stylex.ts),
35
+ * whole clock fading (strength about 0.2 at the midpoint). Reference only,
36
+ * not played: a press release plays the theme's `--ease-exit`.
37
+ * @source GUESS — the release curve the touch press model shipped with,
36
38
  * chosen to read as UIKit's deselect cross-fade, not read from UIKit
37
39
  * @measure M-PR1
38
40
  */
@@ -106,17 +108,19 @@ export declare const timing: {
106
108
  */
107
109
  readonly flashMs: 100;
108
110
  /**
109
- * Highlight fade after release: UIKit's deselect cross-fade.
111
+ * Highlight fade after release: UIKit's deselect cross-fade. Reference
112
+ * only, not played: a press release plays the theme's exit motion tokens
113
+ * (`--duration-exit`, `--ease-exit`).
110
114
  * @source measured: Settings and Contacts, iOS 26.2, simulator driven
111
- * with real HID touches at 60 fps (PRESS_FADE_MS / pressConsts.releaseMs,
115
+ * with real HID touches at 60 fps (touch press model,
112
116
  * packages/core/src/utils/pressGesture.ts, 2026-10-06)
113
117
  */
114
118
  readonly highlightOutMs: 200;
115
119
  /**
116
120
  * The highlight fade's curve after release: an ease-out that spends the
117
- * whole clock fading (strength about 0.2 at the midpoint).
118
- * @source GUESS — the release curve the touch press model ships with
119
- * (`RELEASE_EASE`, packages/core/src/utils/interactionOverlay.stylex.ts),
121
+ * whole clock fading (strength about 0.2 at the midpoint). Reference only,
122
+ * not played: a press release plays the theme's `--ease-exit`.
123
+ * @source GUESS — the release curve the touch press model shipped with,
120
124
  * chosen to read as UIKit's deselect cross-fade, not read from UIKit
121
125
  * @measure M-PR1
122
126
  */
@@ -1 +1 @@
1
- {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/timing.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,eAAO,MAAM,KAAK;IAChB;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;OAKG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;OAMG;;CAEK,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;IACjC;;;;;;;;;;;;;OAaG;;IAEH;;;;;;;OAOG;;CAEK,CAAC;AAOX,eAAO,MAAM,MAAM;;QAzFjB;;;;;;;WAOG;;QAEH;;;;;;WAMG;;QAEH;;;;;WAKG;;QAEH;;;;;;;WAOG;;QAEH;;;;;;WAMG;;QAEH;;;;;;WAMG;;;;QA6CD;;;;;;;WAOG;;;QAIH;;;;;;WAMG;;QAEH;;;;;;WAMG;;;IAGL;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;OAKG;;;CAIK,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAqB1C;AAKD;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAIrD"}
1
+ {"version":3,"file":"timing.d.ts","sourceRoot":"","sources":["../../../src/motion/uikit/timing.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,eAAO,MAAM,KAAK;IAChB;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;;OAOG;;IAEH;;;;;;OAMG;;IAEH;;;;;;OAMG;;CAEK,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;IACjC;;;;;;;;;;;;;OAaG;;IAEH;;;;;;;OAOG;;CAEK,CAAC;AAOX,eAAO,MAAM,MAAM;;QA3FjB;;;;;;;WAOG;;QAEH;;;;;;WAMG;;QAEH;;;;;;;WAOG;;QAEH;;;;;;;WAOG;;QAEH;;;;;;WAMG;;QAEH;;;;;;WAMG;;;;QA6CD;;;;;;;WAOG;;;QAIH;;;;;;WAMG;;QAEH;;;;;;WAMG;;;IAGL;;;;;;OAMG;;IAEH;;;;;;;OAOG;;IAEH;;;;;OAKG;;;CAIK,CAAC;AAEX;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAqB1C;AAKD;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,IAAI,CAIrD"}
@@ -50,17 +50,19 @@ export const press = {
50
50
  */
51
51
  flashMs: 100,
52
52
  /**
53
- * Highlight fade after release: UIKit's deselect cross-fade.
53
+ * Highlight fade after release: UIKit's deselect cross-fade. Reference
54
+ * only, not played: a press release plays the theme's exit motion tokens
55
+ * (`--duration-exit`, `--ease-exit`).
54
56
  * @source measured: Settings and Contacts, iOS 26.2, simulator driven
55
- * with real HID touches at 60 fps (PRESS_FADE_MS / pressConsts.releaseMs,
57
+ * with real HID touches at 60 fps (touch press model,
56
58
  * packages/core/src/utils/pressGesture.ts, 2026-10-06)
57
59
  */
58
60
  highlightOutMs: 200,
59
61
  /**
60
62
  * The highlight fade's curve after release: an ease-out that spends the
61
- * whole clock fading (strength about 0.2 at the midpoint).
62
- * @source GUESS — the release curve the touch press model ships with
63
- * (`RELEASE_EASE`, packages/core/src/utils/interactionOverlay.stylex.ts),
63
+ * whole clock fading (strength about 0.2 at the midpoint). Reference only,
64
+ * not played: a press release plays the theme's `--ease-exit`.
65
+ * @source GUESS — the release curve the touch press model shipped with,
64
66
  * chosen to read as UIKit's deselect cross-fade, not read from UIKit
65
67
  * @measure M-PR1
66
68
  */
@@ -94,7 +94,7 @@ export declare const rowPressLayerStyles: Readonly<{
94
94
  readonly "@media (pointer: coarse)": {
95
95
  readonly default: null;
96
96
  readonly "[data-astryx-press=\"fading\"]": {
97
- readonly default: string;
97
+ readonly default: stylex.StyleXVar<"var(--duration-fast)">;
98
98
  readonly "@media (prefers-reduced-motion: reduce)": string;
99
99
  };
100
100
  };
@@ -103,7 +103,7 @@ export declare const rowPressLayerStyles: Readonly<{
103
103
  readonly default: null;
104
104
  readonly "@media (pointer: coarse)": {
105
105
  readonly default: null;
106
- readonly "[data-astryx-press=\"fading\"]": string;
106
+ readonly "[data-astryx-press=\"fading\"]": stylex.StyleXVar<"cubic-bezier(0.3, 0, 0.6, 0.6)">;
107
107
  };
108
108
  };
109
109
  readonly animationFillMode: {
@@ -1 +1 @@
1
- {"version":3,"file":"press.stylex.d.ts","sourceRoot":"","sources":["../../src/privateAttributes/press.stylex.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAsD3C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyK9B,CAAC"}
1
+ {"version":3,"file":"press.stylex.d.ts","sourceRoot":"","sources":["../../src/privateAttributes/press.stylex.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAqD3C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyK9B,CAAC"}
@@ -20,11 +20,11 @@
20
20
 
21
21
  import * as stylex from '@stylexjs/stylex';
22
22
  import "../theme/tokens.stylex.js";
23
- import { colorVars } from "../theme/tokens.stylex.js";
23
+ import { colorVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
24
+ import "../motion/reducedMotion.stylex.js";
25
+ import { reducedMotionFadeConsts } from "../motion/reducedMotion.stylex.js";
24
26
  import "../utils/interactionOverlay.stylex.js";
25
27
  import { pressVars } from "../utils/interactionOverlay.stylex.js";
26
- import "../utils/rowPressLayer.stylex.js";
27
- import { cellPressConsts } from "../utils/rowPressLayer.stylex.js";
28
28
 
29
29
  // The overlay's arm selectors (interactionOverlay.stylex.ts), restated here:
30
30
  // StyleX resolves a style's keys within its own file.
@@ -51,20 +51,19 @@ const pressedOverlayImage = 'var(--_press-paint-image)';
51
51
  const pressRelease = "x10jkm1t-B";
52
52
 
53
53
  /**
54
- * The row layer's clock as CSS. It is the strength release's clock, scaled
55
- * by the theme's `--_astryx-motion-tempo` up to 1.5, so the layer and the
56
- * strength land together.
54
+ * The row layer's clock as CSS: the strength release's clock, the theme's
55
+ * exit duration, so the layer and the strength land together.
57
56
  */
58
- const CELL_RELEASE = `calc(${cellPressConsts.cellReleaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
59
- /** The same clock under Reduce Motion: a tempo may shorten it, never lengthen it. */
60
- const CELL_RELEASE_REDUCED = `min(${cellPressConsts.cellReleaseMs}ms, calc(${cellPressConsts.cellReleaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
57
+ const CELL_RELEASE = durationVars['--duration-exit'];
58
+ /** The same clock under Reduce Motion, no longer than the Reduce Motion fade. */
59
+ const CELL_RELEASE_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
61
60
  const REDUCED_MOTION = '@media (prefers-reduced-motion: reduce)';
62
61
 
63
62
  /** Opacity 1 → 0: the row layer leaves; its fading arm runs it. */
64
63
  const cellRelease = "x1jn504y-B";
65
64
 
66
- /** The release's curve: the table's gentle ease-out. */
67
- const RELEASE_EASE = cellPressConsts.cellReleaseEase;
65
+ /** The release's curve: the theme's exit easing, as the strength's. */
66
+ const RELEASE_EASE = easeVars['--ease-exit'];
68
67
  export const rowPressLayerStyles = {
69
68
  cell: {
70
69
  kKwaWg: "x7ngsy6 x10ogxw0 xubczrd x18xnkjv",
@@ -79,8 +78,8 @@ export const rowPressLayerStyles = {
79
78
  kLkRvE: "x1dn949c",
80
79
  k5QlbN: "xw7rim2 xr9xsjc",
81
80
  k7EzDT: "x1bxn267",
82
- kQZAMR: "x16lp0i7 x1bf026e",
83
- kZiNAr: "x1gyhjqm",
81
+ kQZAMR: "x1osot8d xbkwwzw",
82
+ kZiNAr: "x10t12yn",
84
83
  k8Tatv: "x1dn5vsf",
85
84
  $$css: true
86
85
  },
@@ -45,8 +45,9 @@ export declare const CHARACTER_EASE: {
45
45
  export declare function resolveMotionKnobs(config: ThemeMotionConfig | undefined): ResolvedMotionKnobs;
46
46
  /**
47
47
  * The private custom property a theme with a `tempo` writes beside its
48
- * duration tokens: the press release fade (`utils/interactionOverlay.stylex.ts`)
49
- * multiplies its clock by it.
48
+ * duration tokens, for a style that scales a clock of its own by it
49
+ * (ProgressBar's move). A press release needs none: it plays
50
+ * `--duration-exit`, which already follows the tempo.
50
51
  */
51
52
  export declare const MOTION_TEMPO_PROPERTY = "--_astryx-motion-tempo";
52
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"themeMotion.d.ts","sourceRoot":"","sources":["../../src/theme/themeMotion.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAoB,KAAK,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAC3B,gBAAgB,GAAG,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;CAIgC,CAAC;AAE5D,kEAAkE;AAClE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,mBAAmB,CAErB;AAaD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,6BAA6B,CAAC;AAUlE,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMtE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCxB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1D,GAAG,WAAW,CAyCd"}
1
+ {"version":3,"file":"themeMotion.d.ts","sourceRoot":"","sources":["../../src/theme/themeMotion.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAoB,KAAK,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAGL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AAIvB,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AAEvB;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAC3B,gBAAgB,GAAG,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,CAAC;AAE5D;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;CAIgC,CAAC;AAE5D,kEAAkE;AAClE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,mBAAmB,CAErB;AAaD;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAE9D;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,6BAA6B,CAAC;AAUlE,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMtE;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmCxB;AAED,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrD,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAC,CAAC;IACxD,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1D,GAAG,WAAW,CAyCd"}
@@ -63,8 +63,9 @@ function msOf(value) {
63
63
 
64
64
  /**
65
65
  * The private custom property a theme with a `tempo` writes beside its
66
- * duration tokens: the press release fade (`utils/interactionOverlay.stylex.ts`)
67
- * multiplies its clock by it.
66
+ * duration tokens, for a style that scales a clock of its own by it
67
+ * (ProgressBar's move). A press release needs none: it plays
68
+ * `--duration-exit`, which already follows the tempo.
68
69
  */
69
70
  export const MOTION_TEMPO_PROPERTY = '--_astryx-motion-tempo';
70
71
 
@@ -30,16 +30,11 @@ export declare const pressVars: stylex.VarGroup<Readonly<{
30
30
  '--astryx-press-alpha': stylex.Types.Num<0>;
31
31
  }>, symbol>;
32
32
  /**
33
- * The touch press's clocks that both the stylesheet and the controller read.
34
- *
35
- * `defineConsts`, so the one number is inlined here at build time and is the
36
- * controller's constant at run time (`PRESS_FADE_MS` in pressGesture.ts):
37
- * the release animation and the controller's clock cannot drift apart. When
38
- * that clock runs out, the controller waits for a release animation that a
39
- * busy main thread started late, then removes the attribute.
33
+ * The touch press's measured release clock, kept as a reference value. Press
34
+ * releases now play the theme's `--duration-exit`.
40
35
  */
41
36
  export declare const pressConsts: {
42
- /** How long the release takes, in ms. UIKit's deselect clock. */
37
+ /** UIKit's deselect clock, in ms: the measured reference value. */
43
38
  releaseMs: number;
44
39
  };
45
40
  export declare const interactionOverlayStyles: Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"interactionOverlay.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/interactionOverlay.stylex.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AAmCH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAG3C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS;;WAEpB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW;IACtB,iEAAiE;;CAEjE,CAAC;AAkIH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8HnC,CAAC"}
1
+ {"version":3,"file":"interactionOverlay.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/interactionOverlay.stylex.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;GAeG;AAmCH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAI3C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS;;WAEpB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,WAAW;IACtB,mEAAmE;;CAEnE,CAAC;AA8HH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8HnC,CAAC"}
@@ -42,7 +42,7 @@
42
42
  // background image, so a composer's color transition cannot fade the onset
43
43
  // in. `on` sets the strength to 1 on the first frame. `fading` animates it
44
44
  // from 1 to 0, not to the hover strength, because a finger has no hover. The
45
- // theme's motion tempo scales the release clock (AST-108).
45
+ // release plays the theme's exit motion tokens, which follow its tempo.
46
46
  //
47
47
  // The release is an animation, not a transition. Composers own their
48
48
  // `transition-*` longhands, and StyleX is last-wins per property. A
@@ -55,8 +55,10 @@
55
55
  // `animation-*` on the element that composes them. The touch arms own both.
56
56
 
57
57
  import * as stylex from '@stylexjs/stylex';
58
+ import "../motion/reducedMotion.stylex.js";
59
+ import { reducedMotionFadeConsts } from "../motion/reducedMotion.stylex.js";
58
60
  import "../theme/tokens.stylex.js";
59
- import { colorVars } from "../theme/tokens.stylex.js";
61
+ import { colorVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
60
62
 
61
63
  /**
62
64
  * The touch press's strength on the surface the controller painted, 0 to 1.
@@ -75,25 +77,21 @@ export const pressVars = {
75
77
  };
76
78
 
77
79
  /**
78
- * The touch press's clocks that both the stylesheet and the controller read.
79
- *
80
- * `defineConsts`, so the one number is inlined here at build time and is the
81
- * controller's constant at run time (`PRESS_FADE_MS` in pressGesture.ts):
82
- * the release animation and the controller's clock cannot drift apart. When
83
- * that clock runs out, the controller waits for a release animation that a
84
- * busy main thread started late, then removes the attribute.
80
+ * The touch press's measured release clock, kept as a reference value. Press
81
+ * releases now play the theme's `--duration-exit`.
85
82
  */
86
83
  export const pressConsts = {
87
84
  releaseMs: 200
88
85
  };
89
86
 
90
87
  /**
91
- * The release's clock as CSS, scaled by the theme's `--_astryx-motion-tempo`
92
- * up to 1.5, its maximum. The controller's timer reads the same property.
88
+ * The release's clock: the theme's exit duration. The token already
89
+ * follows the theme's tempo. The controller's timer reads the
90
+ * same property.
93
91
  */
94
- const PRESS_RELEASE_DURATION = `calc(${pressConsts.releaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
95
- /** The same clock under Reduce Motion: a tempo may shorten it, never lengthen it. */
96
- const PRESS_RELEASE_DURATION_REDUCED = `min(${pressConsts.releaseMs}ms, calc(${pressConsts.releaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
92
+ const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
93
+ /** The same clock under Reduce Motion, no longer than the Reduce Motion fade. */
94
+ const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
97
95
  const ENABLED = ':where(:not(:disabled,[aria-disabled="true"]))';
98
96
  const HOVER_HOVER = '@media (hover: hover)';
99
97
  const COARSE = '@media (pointer: coarse)';
@@ -139,17 +137,12 @@ const pressedOverlayImage = 'var(--_press-paint-image)';
139
137
  const pressRelease = "x10jkm1t-B";
140
138
 
141
139
  /**
142
- * The release's curve: a gentle ease-out that spends the whole clock fading
143
- * (strength ≈ 0.2 at the midpoint), which is what a deselect crossfade reads
144
- * as. Not the system's `--ease-standard`: that curve is for things that move,
145
- * and is so front-loaded (strength 0.05 at the midpoint) that the release
146
- * would read as half its clock. It is the constants table's
147
- * `timing.press.highlightOutCurve`, which the list row's layer mirrors too
148
- * (rowPressLayer.stylex.ts); interactionOverlay.cell.test.ts fails if either
149
- * drifts. A copy, not an import: this module reaches nearly every component,
150
- * and the row layer's constants stay with the rows.
140
+ * The release's curve: the theme's exit easing. The list row's layer
141
+ * (privateAttributes/press.stylex.ts) and Switch's press layers use the same
142
+ * token; interactionOverlay.cell.test.ts and Switch.test.tsx fail if they
143
+ * differ.
151
144
  */
152
- const RELEASE_EASE = 'cubic-bezier(0, 0, 0.2, 1)';
145
+ const RELEASE_EASE = easeVars['--ease-exit'];
153
146
 
154
147
  /**
155
148
  * The touch press's strength and its release, on the element the controller
@@ -203,8 +196,8 @@ export const interactionOverlayStyles = {
203
196
  backgroundColor: {
204
197
  "--astryx-press-alpha": "x11z29ks xli5ek3",
205
198
  kKVMdj: "x14e4jsf",
206
- k44tkh: "x1heh2iz x1sgdaq5",
207
- kyAemX: "xwkbtvz",
199
+ k44tkh: "xem8lmn xogcwkh",
200
+ kyAemX: "x1t1ddl7",
208
201
  kWV6AL: "xziyay6",
209
202
  "--_press-paint": "xz2mauf",
210
203
  "--_press-paint-image": "x1l7afqf",
@@ -215,8 +208,8 @@ export const interactionOverlayStyles = {
215
208
  backgroundImage: {
216
209
  "--astryx-press-alpha": "x11z29ks xli5ek3",
217
210
  kKVMdj: "x14e4jsf",
218
- k44tkh: "x1heh2iz x1sgdaq5",
219
- kyAemX: "xwkbtvz",
211
+ k44tkh: "xem8lmn xogcwkh",
212
+ kyAemX: "x1t1ddl7",
220
213
  kWV6AL: "xziyay6",
221
214
  "--_press-paint": "xz2mauf",
222
215
  "--_press-paint-image": "x1l7afqf",
@@ -226,8 +219,8 @@ export const interactionOverlayStyles = {
226
219
  backgroundImageOnNeutral: {
227
220
  "--astryx-press-alpha": "x11z29ks xli5ek3",
228
221
  kKVMdj: "x14e4jsf",
229
- k44tkh: "x1heh2iz x1sgdaq5",
230
- kyAemX: "xwkbtvz",
222
+ k44tkh: "xem8lmn xogcwkh",
223
+ kyAemX: "x1t1ddl7",
231
224
  kWV6AL: "xziyay6",
232
225
  "--_press-paint": "xz2mauf",
233
226
  "--_press-paint-image": "x1l7afqf",
@@ -237,8 +230,8 @@ export const interactionOverlayStyles = {
237
230
  pressedBackgroundColor: {
238
231
  "--astryx-press-alpha": "x11z29ks xli5ek3",
239
232
  kKVMdj: "x14e4jsf",
240
- k44tkh: "x1heh2iz x1sgdaq5",
241
- kyAemX: "xwkbtvz",
233
+ k44tkh: "xem8lmn xogcwkh",
234
+ kyAemX: "x1t1ddl7",
242
235
  kWV6AL: "xziyay6",
243
236
  "--_press-paint": "xz2mauf",
244
237
  "--_press-paint-image": "x1l7afqf",
@@ -249,8 +242,8 @@ export const interactionOverlayStyles = {
249
242
  pressedAlpha: {
250
243
  "--astryx-press-alpha": "x11z29ks xli5ek3",
251
244
  kKVMdj: "x14e4jsf",
252
- k44tkh: "x1heh2iz x1sgdaq5",
253
- kyAemX: "xwkbtvz",
245
+ k44tkh: "xem8lmn xogcwkh",
246
+ kyAemX: "x1t1ddl7",
254
247
  kWV6AL: "xziyay6",
255
248
  "--_press-paint": "xz2mauf",
256
249
  "--_press-paint-image": "x1l7afqf",
@@ -25,8 +25,9 @@ export declare const pressableProps: {
25
25
  export declare const PRESS_GESTURE_MEMORY_MS = 3000;
26
26
  /**
27
27
  * The release fade's clock on `element`, read once, at the release, from the
28
- * property its stylesheet reads: the theme's `--_astryx-motion-tempo`. Under
29
- * Reduce Motion a tempo may shorten the fade, never lengthen it past 200 ms.
28
+ * token its stylesheet reads: the theme's `--duration-exit`. Without a
29
+ * readable value it is the token's default. Under Reduce Motion it is no
30
+ * longer than the Reduce Motion fade, as in the stylesheet.
30
31
  */
31
32
  export declare function pressFadeMs(element: Element): number;
32
33
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pressFeedback.d.ts","sourceRoot":"","sources":["../../src/utils/pressFeedback.ts"],"names":[],"mappings":"AAuDA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE;IAAC,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAA;CAE/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AA0E5C;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAUpD;AA6ND;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOlD;AA4aD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,IAAI,CA0BjD"}
1
+ {"version":3,"file":"pressFeedback.d.ts","sourceRoot":"","sources":["../../src/utils/pressFeedback.ts"],"names":[],"mappings":"AAyDA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAE3D;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AAErD,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE;IAAC,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,CAAA;CAE/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,OAAO,CAAC;AA0E5C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAcpD;AA6ND;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOlD;AA4aD;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,IAAI,CA0BjD"}
@@ -39,6 +39,8 @@
39
39
  import { MENU_PRESS_MARKER } from "../hooks/menuPressMarker.js";
40
40
  import { idlePressGesture, PRESS_FADE_MS, PRESS_FLASH_MS, PRESS_ONSET_MS, PRESS_SCROLL_BRAKE_MS, pressGestureStep } from "./pressGesture.js";
41
41
  import { isCoarsePointer, watchCoarsePointer } from "./coarsePointer.js";
42
+ import { reducedMotionFadeConsts } from "../motion/reducedMotion.stylex.js";
43
+ import { parseMotionRoleValue } from "../motion/roles.js";
42
44
  import { subscribeInput } from "./inputStream.js";
43
45
  import { isInsideScrollView } from "./scrollView.js";
44
46
  import { TOUCH_QUERY } from "./touchPresentation.js";
@@ -131,17 +133,15 @@ const TIMER_MS = {
131
133
 
132
134
  /**
133
135
  * The release fade's clock on `element`, read once, at the release, from the
134
- * property its stylesheet reads: the theme's `--_astryx-motion-tempo`. Under
135
- * Reduce Motion a tempo may shorten the fade, never lengthen it past 200 ms.
136
+ * token its stylesheet reads: the theme's `--duration-exit`. Without a
137
+ * readable value it is the token's default. Under Reduce Motion it is no
138
+ * longer than the Reduce Motion fade, as in the stylesheet.
136
139
  */
137
140
  export function pressFadeMs(element) {
138
- const style = getComputedStyle(element);
139
- const value = style.getPropertyValue('--_astryx-motion-tempo').trim();
140
- const read = value === '' ? Number.NaN : Number(value);
141
- const tempo = Number.isFinite(read) && read > 0 ? read : 1;
142
- const scaled = PRESS_FADE_MS * tempo;
141
+ const exit = parseMotionRoleValue('duration', getComputedStyle(element).getPropertyValue('--duration-exit')) ?? PRESS_FADE_MS;
143
142
  const reduced = typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
144
- return reduced ? Math.min(scaled, PRESS_FADE_MS) : scaled;
143
+ const bound = parseMotionRoleValue('duration', reducedMotionFadeConsts.duration);
144
+ return reduced && bound != null ? Math.min(exit, bound) : exit;
145
145
  }
146
146
 
147
147
  /**
@@ -28,12 +28,12 @@ export declare const PRESS_SLOP_PX = 10;
28
28
  */
29
29
  export declare const PRESS_FLASH_MS = 100;
30
30
  /**
31
- * How long the paint takes to leave after a release: UIKit's deselect
32
- * crossfade. The one number, shared with the stylesheet: the release
33
- * animation in interactionOverlay.stylex.ts runs on the same constant, so the
34
- * controller's release clock and the fade cannot drift apart. When the clock
35
- * runs out, the controller waits for a release animation that still runs,
36
- * then removes the attribute.
31
+ * How long the paint takes to leave after a release when no theme sets
32
+ * `--duration-exit`: that token's default. The release plays the theme's
33
+ * exit motion tokens, so the controller reads the token on
34
+ * the pressed element (`pressFadeMs` in pressFeedback.ts) and falls back to
35
+ * this. When the clock runs out, the controller waits for a release
36
+ * animation that still runs, then removes the attribute.
37
37
  */
38
38
  export declare const PRESS_FADE_MS: number;
39
39
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pressGesture.d.ts","sourceRoot":"","sources":["../../src/utils/pressGesture.ts"],"names":[],"mappings":"AAgCA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,MAA8B,CAAC;AAE3D;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GACpB,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACH;;;;GAIG;GACD;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC;AACtB,0EAA0E;GACxE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,GACpC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC;AACd,4FAA4F;GAC1F;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAC;AAClB,iEAAiE;GAC/D;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC;AACjB,yDAAyD;GACvD;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC;AACpB,wFAAwF;GACtF;IAAC,IAAI,EAAE,SAAS,CAAA;CAAC,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACnD;AAkBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,GAChB,SAAS,CAsHX;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C"}
1
+ {"version":3,"file":"pressGesture.d.ts","sourceRoot":"","sources":["../../src/utils/pressGesture.ts"],"names":[],"mappings":"AAiCA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,MAAM,CAAC;AAElC;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,MAE3B,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC;AAElD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GACpB,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACH;;;;GAIG;GACD;IAAC,IAAI,EAAE,YAAY,CAAA;CAAC;AACtB,0EAA0E;GACxE;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAC,GACpC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAC;AACd,4FAA4F;GAC1F;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAC;AAClB,iEAAiE;GAC/D;IAAC,IAAI,EAAE,OAAO,CAAA;CAAC;AACjB,yDAAyD;GACvD;IAAC,IAAI,EAAE,UAAU,CAAA;CAAC;AACpB,wFAAwF;GACtF;IAAC,IAAI,EAAE,SAAS,CAAA;CAAC,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CACnD;AAkBD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,UAAU,GAChB,SAAS,CAsHX;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAE/C"}
@@ -28,7 +28,8 @@
28
28
  // The constants were measured against native apps. The machine knows nothing
29
29
  // of the DOM, so {@link pressGestureStep}'s cases are the state diagram.
30
30
 
31
- import { pressConsts } from "./interactionOverlay.stylex.js";
31
+ import { resolveTokenReferences } from "../theme/tokenReferences.js";
32
+ import { durationDefaults } from "../theme/tokens.stylex.js";
32
33
 
33
34
  /**
34
35
  * How long a finger must stay put before the surface believes it.
@@ -63,14 +64,14 @@ export const PRESS_SLOP_PX = 10;
63
64
  export const PRESS_FLASH_MS = 100;
64
65
 
65
66
  /**
66
- * How long the paint takes to leave after a release: UIKit's deselect
67
- * crossfade. The one number, shared with the stylesheet: the release
68
- * animation in interactionOverlay.stylex.ts runs on the same constant, so the
69
- * controller's release clock and the fade cannot drift apart. When the clock
70
- * runs out, the controller waits for a release animation that still runs,
71
- * then removes the attribute.
67
+ * How long the paint takes to leave after a release when no theme sets
68
+ * `--duration-exit`: that token's default. The release plays the theme's
69
+ * exit motion tokens, so the controller reads the token on
70
+ * the pressed element (`pressFadeMs` in pressFeedback.ts) and falls back to
71
+ * this. When the clock runs out, the controller waits for a release
72
+ * animation that still runs, then removes the attribute.
72
73
  */
73
- export const PRESS_FADE_MS = pressConsts.releaseMs;
74
+ export const PRESS_FADE_MS = Number.parseFloat(resolveTokenReferences(durationDefaults)['--duration-exit']);
74
75
 
75
76
  /**
76
77
  * How recently a scroller must have moved for a touch on it to be a BRAKE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.7.9-canary.12f63f5",
3
+ "version": "0.7.9-canary.2ea8f68",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -870,9 +870,9 @@
870
870
  "react-dom": ">=19.0.0"
871
871
  },
872
872
  "devDependencies": {
873
- "@astryxdesign/a11y-spec": "0.7.9-canary.12f63f5",
874
- "@astryxdesign/cli": "0.7.9-canary.12f63f5",
875
- "@astryxdesign/interaction-harness": "0.7.9-canary.12f63f5",
873
+ "@astryxdesign/a11y-spec": "0.7.9-canary.2ea8f68",
874
+ "@astryxdesign/cli": "0.7.9-canary.2ea8f68",
875
+ "@astryxdesign/interaction-harness": "0.7.9-canary.2ea8f68",
876
876
  "@babel/cli": "^7.29.7",
877
877
  "@babel/core": "^7.29.7",
878
878
  "@babel/preset-react": "^7.29.7",
@@ -62,9 +62,9 @@ import {
62
62
  import english from '../i18n/generated-english/Switch/Switch.generated';
63
63
 
64
64
  registerEnglishFallback(english);
65
+ import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
65
66
  import {
66
67
  interactionOverlayStyles,
67
- pressConsts,
68
68
  pressVars,
69
69
  } from '../utils/interactionOverlay.stylex';
70
70
  import {pressHoldsDragProps} from '../privateAttributes/pressHoldsDrag.stylex';
@@ -93,14 +93,15 @@ const PRESS_FADING = '[data-astryx-press="fading"]';
93
93
 
94
94
  /**
95
95
  * The shared press release, for the press layers the switch fades on the
96
- * compositor. The clock scales by the theme's tempo, and the curve is the
97
- * controller's own. Switch.test.tsx compares the two.
96
+ * compositor: the theme's exit motion tokens, no longer than the Reduce
97
+ * Motion fade under Reduce Motion. Switch.test.tsx compares them with
98
+ * the overlay's.
98
99
  * SYNC: utils/interactionOverlay.stylex.ts PRESS_RELEASE_DURATION,
99
100
  * PRESS_RELEASE_DURATION_REDUCED and RELEASE_EASE.
100
101
  */
101
- const PRESS_RELEASE_DURATION = `calc(${pressConsts.releaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
102
- const PRESS_RELEASE_DURATION_REDUCED = `min(${pressConsts.releaseMs}ms, calc(${pressConsts.releaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
103
- const PRESS_RELEASE_EASE = 'cubic-bezier(0, 0, 0.2, 1)';
102
+ const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
103
+ const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
104
+ const PRESS_RELEASE_EASE = easeVars['--ease-exit'];
104
105
 
105
106
  // The measured hit insets (utils/hitArea), 0 until measured.
106
107
  const HIT_TOP = 'var(--astryx-hit-inset-top, 0px)';
@@ -2,7 +2,9 @@
2
2
 
3
3
  /**
4
4
  * @file touch.ts
5
- * @input The gesture core: the arena, the recognizers, and their geometry
5
+ * @input The gesture core: the arena, the recognizers, and their geometry;
6
+ * the pan, the motion animator and the motion math that Lab's
7
+ * useRefreshControl reads
6
8
  * @output `@astryxdesign/core/internal/touch`: the gesture core's primitives
7
9
  * for Lab components, re-exported by name
8
10
  * @position An internal entry reserved for Astryx's own packages:
@@ -39,3 +41,34 @@ export {
39
41
  export {LongPressGestureRecognizer} from '../gestures/LongPressGestureRecognizer';
40
42
  export {TapGestureRecognizer} from '../gestures/TapGestureRecognizer';
41
43
  export {DEFAULT_ENVIRONMENT} from '../gestures/types';
44
+
45
+ // Lab's useRefreshControl reads these: its pull's pan and the hook that
46
+ // starts it. It also reads the motion animator and math, and the scroll
47
+ // view's bounce spring, for its pull, settle and end. Its indicator fades
48
+ // along the settle's curve, and the motion-role parsers read the theme's
49
+ // tokens for its end.
50
+ export {PanGestureRecognizer} from '../gestures/PanGestureRecognizer';
51
+ export type {PanGestureRecognizerOptions} from '../gestures/PanGestureRecognizer';
52
+ export type {
53
+ GestureEventContext,
54
+ GestureTouch,
55
+ PointerKind,
56
+ } from '../gestures/types';
57
+ export {useGestureRecognizer} from '../gestures/useGestureRecognizer';
58
+ // The animator's internal factory. The public one, `createAnimator`, plays
59
+ // only the theme's state-change motion.
60
+ export {createMotionAnimator} from '../motion/animator';
61
+ export type {
62
+ Animator as MotionAnimator,
63
+ AnimatorOptions as MotionAnimatorOptions,
64
+ MotionCurve,
65
+ } from '../motion/animator';
66
+ export {cubicBezier} from '../motion/bezier';
67
+ export {mapProgress} from '../motion/progress';
68
+ export {parseCssEasing, parseMotionRoleValue} from '../motion/roles';
69
+ export {
70
+ rubberBand,
71
+ rubberBandInverse,
72
+ rubberBandSlope,
73
+ } from '../motion/rubberBand';
74
+ export {scroll} from '../motion/uikit/scroll';
@@ -50,17 +50,19 @@ export const press = {
50
50
  */
51
51
  flashMs: 100,
52
52
  /**
53
- * Highlight fade after release: UIKit's deselect cross-fade.
53
+ * Highlight fade after release: UIKit's deselect cross-fade. Reference
54
+ * only, not played: a press release plays the theme's exit motion tokens
55
+ * (`--duration-exit`, `--ease-exit`).
54
56
  * @source measured: Settings and Contacts, iOS 26.2, simulator driven
55
- * with real HID touches at 60 fps (PRESS_FADE_MS / pressConsts.releaseMs,
57
+ * with real HID touches at 60 fps (touch press model,
56
58
  * packages/core/src/utils/pressGesture.ts, 2026-10-06)
57
59
  */
58
60
  highlightOutMs: 200,
59
61
  /**
60
62
  * The highlight fade's curve after release: an ease-out that spends the
61
- * whole clock fading (strength about 0.2 at the midpoint).
62
- * @source GUESS — the release curve the touch press model ships with
63
- * (`RELEASE_EASE`, packages/core/src/utils/interactionOverlay.stylex.ts),
63
+ * whole clock fading (strength about 0.2 at the midpoint). Reference only,
64
+ * not played: a press release plays the theme's `--ease-exit`.
65
+ * @source GUESS — the release curve the touch press model shipped with,
64
66
  * chosen to read as UIKit's deselect cross-fade, not read from UIKit
65
67
  * @measure M-PR1
66
68
  */
@@ -19,9 +19,9 @@
19
19
  */
20
20
 
21
21
  import * as stylex from '@stylexjs/stylex';
22
- import {colorVars} from '../theme/tokens.stylex';
22
+ import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
23
+ import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
23
24
  import {pressVars} from '../utils/interactionOverlay.stylex';
24
- import {cellPressConsts} from '../utils/rowPressLayer.stylex';
25
25
 
26
26
  // The overlay's arm selectors (interactionOverlay.stylex.ts), restated here:
27
27
  // StyleX resolves a style's keys within its own file.
@@ -54,13 +54,12 @@ const pressRelease = stylex.keyframes({
54
54
  });
55
55
 
56
56
  /**
57
- * The row layer's clock as CSS. It is the strength release's clock, scaled
58
- * by the theme's `--_astryx-motion-tempo` up to 1.5, so the layer and the
59
- * strength land together.
57
+ * The row layer's clock as CSS: the strength release's clock, the theme's
58
+ * exit duration, so the layer and the strength land together.
60
59
  */
61
- const CELL_RELEASE = `calc(${cellPressConsts.cellReleaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
62
- /** The same clock under Reduce Motion: a tempo may shorten it, never lengthen it. */
63
- const CELL_RELEASE_REDUCED = `min(${cellPressConsts.cellReleaseMs}ms, calc(${cellPressConsts.cellReleaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
60
+ const CELL_RELEASE = durationVars['--duration-exit'];
61
+ /** The same clock under Reduce Motion, no longer than the Reduce Motion fade. */
62
+ const CELL_RELEASE_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
64
63
  const REDUCED_MOTION = '@media (prefers-reduced-motion: reduce)';
65
64
 
66
65
  /** Opacity 1 → 0: the row layer leaves; its fading arm runs it. */
@@ -69,8 +68,8 @@ const cellRelease = stylex.keyframes({
69
68
  to: {opacity: 0},
70
69
  });
71
70
 
72
- /** The release's curve: the table's gentle ease-out. */
73
- const RELEASE_EASE = cellPressConsts.cellReleaseEase;
71
+ /** The release's curve: the theme's exit easing, as the strength's. */
72
+ const RELEASE_EASE = easeVars['--ease-exit'];
74
73
 
75
74
  export const rowPressLayerStyles = stylex.create({
76
75
  /**
@@ -82,8 +82,9 @@ function msOf(value: string): number {
82
82
 
83
83
  /**
84
84
  * The private custom property a theme with a `tempo` writes beside its
85
- * duration tokens: the press release fade (`utils/interactionOverlay.stylex.ts`)
86
- * multiplies its clock by it.
85
+ * duration tokens, for a style that scales a clock of its own by it
86
+ * (ProgressBar's move). A press release needs none: it plays
87
+ * `--duration-exit`, which already follows the tempo.
87
88
  */
88
89
  export const MOTION_TEMPO_PROPERTY = '--_astryx-motion-tempo';
89
90
 
@@ -42,7 +42,7 @@
42
42
  // background image, so a composer's color transition cannot fade the onset
43
43
  // in. `on` sets the strength to 1 on the first frame. `fading` animates it
44
44
  // from 1 to 0, not to the hover strength, because a finger has no hover. The
45
- // theme's motion tempo scales the release clock (AST-108).
45
+ // release plays the theme's exit motion tokens, which follow its tempo.
46
46
  //
47
47
  // The release is an animation, not a transition. Composers own their
48
48
  // `transition-*` longhands, and StyleX is last-wins per property. A
@@ -55,7 +55,8 @@
55
55
  // `animation-*` on the element that composes them. The touch arms own both.
56
56
 
57
57
  import * as stylex from '@stylexjs/stylex';
58
- import {colorVars} from '../theme/tokens.stylex';
58
+ import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
59
+ import {colorVars, durationVars, easeVars} from '../theme/tokens.stylex';
59
60
 
60
61
  /**
61
62
  * The touch press's strength on the surface the controller painted, 0 to 1.
@@ -73,26 +74,22 @@ export const pressVars = stylex.defineVars({
73
74
  });
74
75
 
75
76
  /**
76
- * The touch press's clocks that both the stylesheet and the controller read.
77
- *
78
- * `defineConsts`, so the one number is inlined here at build time and is the
79
- * controller's constant at run time (`PRESS_FADE_MS` in pressGesture.ts):
80
- * the release animation and the controller's clock cannot drift apart. When
81
- * that clock runs out, the controller waits for a release animation that a
82
- * busy main thread started late, then removes the attribute.
77
+ * The touch press's measured release clock, kept as a reference value. Press
78
+ * releases now play the theme's `--duration-exit`.
83
79
  */
84
80
  export const pressConsts = stylex.defineConsts({
85
- /** How long the release takes, in ms. UIKit's deselect clock. */
81
+ /** UIKit's deselect clock, in ms: the measured reference value. */
86
82
  releaseMs: 200,
87
83
  });
88
84
 
89
85
  /**
90
- * The release's clock as CSS, scaled by the theme's `--_astryx-motion-tempo`
91
- * up to 1.5, its maximum. The controller's timer reads the same property.
86
+ * The release's clock: the theme's exit duration. The token already
87
+ * follows the theme's tempo. The controller's timer reads the
88
+ * same property.
92
89
  */
93
- const PRESS_RELEASE_DURATION = `calc(${pressConsts.releaseMs}ms * min(var(--_astryx-motion-tempo, 1), 1.5))`;
94
- /** The same clock under Reduce Motion: a tempo may shorten it, never lengthen it. */
95
- const PRESS_RELEASE_DURATION_REDUCED = `min(${pressConsts.releaseMs}ms, calc(${pressConsts.releaseMs}ms * var(--_astryx-motion-tempo, 1)))`;
90
+ const PRESS_RELEASE_DURATION = durationVars['--duration-exit'];
91
+ /** The same clock under Reduce Motion, no longer than the Reduce Motion fade. */
92
+ const PRESS_RELEASE_DURATION_REDUCED = `min(${durationVars['--duration-exit']}, ${reducedMotionFadeConsts.duration})`;
96
93
 
97
94
  const ENABLED = ':where(:not(:disabled,[aria-disabled="true"]))';
98
95
  const HOVER_HOVER = '@media (hover: hover)';
@@ -145,17 +142,12 @@ const pressRelease = stylex.keyframes({
145
142
  });
146
143
 
147
144
  /**
148
- * The release's curve: a gentle ease-out that spends the whole clock fading
149
- * (strength ≈ 0.2 at the midpoint), which is what a deselect crossfade reads
150
- * as. Not the system's `--ease-standard`: that curve is for things that move,
151
- * and is so front-loaded (strength 0.05 at the midpoint) that the release
152
- * would read as half its clock. It is the constants table's
153
- * `timing.press.highlightOutCurve`, which the list row's layer mirrors too
154
- * (rowPressLayer.stylex.ts); interactionOverlay.cell.test.ts fails if either
155
- * drifts. A copy, not an import: this module reaches nearly every component,
156
- * and the row layer's constants stay with the rows.
145
+ * The release's curve: the theme's exit easing. The list row's layer
146
+ * (privateAttributes/press.stylex.ts) and Switch's press layers use the same
147
+ * token; interactionOverlay.cell.test.ts and Switch.test.tsx fail if they
148
+ * differ.
157
149
  */
158
- const RELEASE_EASE = 'cubic-bezier(0, 0, 0.2, 1)';
150
+ const RELEASE_EASE = easeVars['--ease-exit'];
159
151
 
160
152
  /**
161
153
  * The touch press's strength and its release, on the element the controller
@@ -47,6 +47,8 @@ import {
47
47
  pressGestureStep,
48
48
  } from './pressGesture';
49
49
  import {isCoarsePointer, watchCoarsePointer} from './coarsePointer';
50
+ import {reducedMotionFadeConsts} from '../motion/reducedMotion.stylex';
51
+ import {parseMotionRoleValue} from '../motion/roles';
50
52
  import {subscribeInput} from './inputStream';
51
53
  import {isInsideScrollView} from './scrollView';
52
54
  import {TOUCH_QUERY} from './touchPresentation';
@@ -156,19 +158,24 @@ const TIMER_MS: Record<NonNullable<PressStep['timer']>, number> = {
156
158
 
157
159
  /**
158
160
  * The release fade's clock on `element`, read once, at the release, from the
159
- * property its stylesheet reads: the theme's `--_astryx-motion-tempo`. Under
160
- * Reduce Motion a tempo may shorten the fade, never lengthen it past 200 ms.
161
+ * token its stylesheet reads: the theme's `--duration-exit`. Without a
162
+ * readable value it is the token's default. Under Reduce Motion it is no
163
+ * longer than the Reduce Motion fade, as in the stylesheet.
161
164
  */
162
165
  export function pressFadeMs(element: Element): number {
163
- const style = getComputedStyle(element);
164
- const value = style.getPropertyValue('--_astryx-motion-tempo').trim();
165
- const read = value === '' ? Number.NaN : Number(value);
166
- const tempo = Number.isFinite(read) && read > 0 ? read : 1;
167
- const scaled = PRESS_FADE_MS * tempo;
166
+ const exit =
167
+ parseMotionRoleValue(
168
+ 'duration',
169
+ getComputedStyle(element).getPropertyValue('--duration-exit'),
170
+ ) ?? PRESS_FADE_MS;
168
171
  const reduced =
169
172
  typeof window.matchMedia === 'function' &&
170
173
  window.matchMedia('(prefers-reduced-motion: reduce)').matches;
171
- return reduced ? Math.min(scaled, PRESS_FADE_MS) : scaled;
174
+ const bound = parseMotionRoleValue(
175
+ 'duration',
176
+ reducedMotionFadeConsts.duration,
177
+ );
178
+ return reduced && bound != null ? Math.min(exit, bound) : exit;
172
179
  }
173
180
 
174
181
  /**
@@ -28,7 +28,8 @@
28
28
  // The constants were measured against native apps. The machine knows nothing
29
29
  // of the DOM, so {@link pressGestureStep}'s cases are the state diagram.
30
30
 
31
- import {pressConsts} from './interactionOverlay.stylex';
31
+ import {resolveTokenReferences} from '../theme/tokenReferences';
32
+ import {durationDefaults} from '../theme/tokens.stylex';
32
33
 
33
34
  /**
34
35
  * How long a finger must stay put before the surface believes it.
@@ -63,14 +64,16 @@ export const PRESS_SLOP_PX = 10;
63
64
  export const PRESS_FLASH_MS = 100;
64
65
 
65
66
  /**
66
- * How long the paint takes to leave after a release: UIKit's deselect
67
- * crossfade. The one number, shared with the stylesheet: the release
68
- * animation in interactionOverlay.stylex.ts runs on the same constant, so the
69
- * controller's release clock and the fade cannot drift apart. When the clock
70
- * runs out, the controller waits for a release animation that still runs,
71
- * then removes the attribute.
67
+ * How long the paint takes to leave after a release when no theme sets
68
+ * `--duration-exit`: that token's default. The release plays the theme's
69
+ * exit motion tokens, so the controller reads the token on
70
+ * the pressed element (`pressFadeMs` in pressFeedback.ts) and falls back to
71
+ * this. When the clock runs out, the controller waits for a release
72
+ * animation that still runs, then removes the attribute.
72
73
  */
73
- export const PRESS_FADE_MS: number = pressConsts.releaseMs;
74
+ export const PRESS_FADE_MS: number = Number.parseFloat(
75
+ resolveTokenReferences(durationDefaults)['--duration-exit'],
76
+ );
74
77
 
75
78
  /**
76
79
  * How recently a scroller must have moved for a touch on it to be a BRAKE
@@ -1,14 +0,0 @@
1
- /**
2
- * A list row's release (`rowPressLayerStyles.cell`), mirrored for the
3
- * stylesheet. StyleX evaluates a style at build time and cannot read the
4
- * constants table, so these are the table's press release values
5
- * (`timing.press`, motion/uikit/timing.ts). interactionOverlay.cell.test.ts
6
- * fails if they drift.
7
- */
8
- export declare const cellPressConsts: {
9
- /** `timing.press.highlightOutMs`, in ms. */
10
- cellReleaseMs: number;
11
- /** `timing.press.highlightOutCurve`, as CSS. */
12
- cellReleaseEase: string;
13
- };
14
- //# sourceMappingURL=rowPressLayer.stylex.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rowPressLayer.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/rowPressLayer.stylex.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;IAC1B,4CAA4C;;IAE5C,gDAAgD;;CAEhD,CAAC"}
@@ -1,25 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file rowPressLayer.stylex.ts
5
- * @input StyleX
6
- * @output The list row press layer's clocks (`cellPressConsts`)
7
- * @position Internal to core: no package entry exports it. Only the row
8
- * layer (privateAttributes/press.stylex.ts) reads it, so a component
9
- * without a press row ships none of it; interactionOverlay.exports.test.ts
10
- * keeps it off the published paths.
11
- */
12
-
13
- import * as stylex from '@stylexjs/stylex';
14
-
15
- /**
16
- * A list row's release (`rowPressLayerStyles.cell`), mirrored for the
17
- * stylesheet. StyleX evaluates a style at build time and cannot read the
18
- * constants table, so these are the table's press release values
19
- * (`timing.press`, motion/uikit/timing.ts). interactionOverlay.cell.test.ts
20
- * fails if they drift.
21
- */
22
- export const cellPressConsts = {
23
- cellReleaseMs: 200,
24
- cellReleaseEase: "cubic-bezier(0, 0, 0.2, 1)"
25
- };
@@ -1,27 +0,0 @@
1
- // Copyright (c) Meta Platforms, Inc. and affiliates.
2
-
3
- /**
4
- * @file rowPressLayer.stylex.ts
5
- * @input StyleX
6
- * @output The list row press layer's clocks (`cellPressConsts`)
7
- * @position Internal to core: no package entry exports it. Only the row
8
- * layer (privateAttributes/press.stylex.ts) reads it, so a component
9
- * without a press row ships none of it; interactionOverlay.exports.test.ts
10
- * keeps it off the published paths.
11
- */
12
-
13
- import * as stylex from '@stylexjs/stylex';
14
-
15
- /**
16
- * A list row's release (`rowPressLayerStyles.cell`), mirrored for the
17
- * stylesheet. StyleX evaluates a style at build time and cannot read the
18
- * constants table, so these are the table's press release values
19
- * (`timing.press`, motion/uikit/timing.ts). interactionOverlay.cell.test.ts
20
- * fails if they drift.
21
- */
22
- export const cellPressConsts = stylex.defineConsts({
23
- /** `timing.press.highlightOutMs`, in ms. */
24
- cellReleaseMs: 200,
25
- /** `timing.press.highlightOutCurve`, as CSS. */
26
- cellReleaseEase: 'cubic-bezier(0, 0, 0.2, 1)',
27
- });