@rootnative/inertia 0.0.0-alpha.0 → 0.0.0-alpha.1

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 (69) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +2 -0
  3. package/dist/gestureLayer/index.d.mts +6 -5
  4. package/dist/gestureLayer/index.d.ts +6 -5
  5. package/dist/gestureLayer/index.js +89 -27
  6. package/dist/gestureLayer/index.js.map +1 -1
  7. package/dist/gestureLayer/index.mjs +89 -27
  8. package/dist/gestureLayer/index.mjs.map +1 -1
  9. package/dist/index.d.mts +127 -16
  10. package/dist/index.d.ts +127 -16
  11. package/dist/index.js +177 -60
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +175 -61
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/motion/Image.d.mts +1 -1
  16. package/dist/motion/Image.d.ts +1 -1
  17. package/dist/motion/Image.js +90 -48
  18. package/dist/motion/Image.js.map +1 -1
  19. package/dist/motion/Image.mjs +90 -48
  20. package/dist/motion/Image.mjs.map +1 -1
  21. package/dist/motion/Pressable.d.mts +1 -1
  22. package/dist/motion/Pressable.d.ts +1 -1
  23. package/dist/motion/Pressable.js +90 -48
  24. package/dist/motion/Pressable.js.map +1 -1
  25. package/dist/motion/Pressable.mjs +90 -48
  26. package/dist/motion/Pressable.mjs.map +1 -1
  27. package/dist/motion/ScrollView.d.mts +1 -1
  28. package/dist/motion/ScrollView.d.ts +1 -1
  29. package/dist/motion/ScrollView.js +90 -48
  30. package/dist/motion/ScrollView.js.map +1 -1
  31. package/dist/motion/ScrollView.mjs +90 -48
  32. package/dist/motion/ScrollView.mjs.map +1 -1
  33. package/dist/motion/Text.d.mts +1 -1
  34. package/dist/motion/Text.d.ts +1 -1
  35. package/dist/motion/Text.js +90 -48
  36. package/dist/motion/Text.js.map +1 -1
  37. package/dist/motion/Text.mjs +90 -48
  38. package/dist/motion/Text.mjs.map +1 -1
  39. package/dist/motion/View.d.mts +1 -1
  40. package/dist/motion/View.d.ts +1 -1
  41. package/dist/motion/View.js +90 -48
  42. package/dist/motion/View.js.map +1 -1
  43. package/dist/motion/View.mjs +90 -48
  44. package/dist/motion/View.mjs.map +1 -1
  45. package/dist/touch/index.d.mts +1 -1
  46. package/dist/touch/index.d.ts +1 -1
  47. package/dist/{types-cU43dEmH.d.mts → types-BzEgiUdJ.d.mts} +58 -9
  48. package/dist/{types-cU43dEmH.d.ts → types-BzEgiUdJ.d.ts} +58 -9
  49. package/dist/{useGesture-BnY65PlQ.d.ts → useGesture-BRLgiNOC.d.ts} +6 -4
  50. package/dist/{useGesture-DxtXdz-K.d.mts → useGesture-C0GBS7d2.d.mts} +6 -4
  51. package/llms.txt +8 -4
  52. package/package.json +1 -1
  53. package/src/__type-tests__/motion-value.test-d.ts +39 -0
  54. package/src/config/MotionConfig.tsx +55 -9
  55. package/src/config/MotionConfigContext.ts +21 -1
  56. package/src/config/index.ts +7 -1
  57. package/src/config/namedTransitions.ts +80 -0
  58. package/src/gestureLayer/useGestureLayer.ts +32 -8
  59. package/src/index.ts +20 -2
  60. package/src/motion/createMotionComponent.tsx +36 -6
  61. package/src/transitions/cubicBezier.ts +126 -0
  62. package/src/transitions/index.ts +1 -0
  63. package/src/types.ts +63 -8
  64. package/src/values/useAnimation.ts +12 -6
  65. package/src/values/useBooleanSpring.ts +5 -3
  66. package/src/values/useGesture.ts +25 -7
  67. package/src/values/useMotionValue.ts +11 -0
  68. package/src/values/useScroll.ts +8 -1
  69. package/src/values/useSpring.ts +46 -9
package/CHANGELOG.md CHANGED
@@ -4,6 +4,16 @@ All notable changes to `@rootnative/inertia` are documented here. The format fol
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ### Added
8
+
9
+ - **Named transition registry** — `<MotionConfig transitions={{ name: TransitionConfig }}>` registers named transitions for the subtree; the name is accepted everywhere a `TransitionConfig` is: the `transition` prop (top-level, per-property, per gesture layer), the `layout` prop, and `useAnimation` / `useSpring` / `useBooleanSpring` / `useGesture` / `useGestureLayer`. Names resolve at the nearest provider; nested providers merge with child-overrides-per-name; unknown names warn in dev and fall back to the default spring. No presets ship — names are consumer vocabulary. New exports: `useNamedTransitions()`, `resolveNamedTransition()`, and the `TransitionName` / `TransitionInput` / `NamedTransitions` / `RegisteredTransitions` types (`RegisteredTransitions` is the augmentation point for compile-time-typed names).
10
+
11
+ - **`cubicBezier()` easing helper** — builds a `timing.easing` value from cubic-bezier control points as four numbers, as a W3C CSS `cubic-bezier(x1, y1, x2, y2)` string, or as a CSS keyword (`'linear'` / `'ease'` / `'ease-in'` / `'ease-out'` / `'ease-in-out'`). Makes CSS-format design-token easings directly consumable (pair with the named-transition registry). Invalid input throws: `x1` / `x2` must be finite and within `[0, 1]`; `step-*` keywords and the CSS `linear(...)` function are unsupported. The `EasingFunction` / `EasingFunctionFactory` / `EasingInput` types are now exported from the root barrel.
12
+
13
+ ### Changed
14
+
15
+ - **Nested `<MotionConfig>` now inherits `reducedMotion`** from its ancestor when the prop is omitted (previously an inner provider silently reset the subtree to the `'user'` default). A transitions-only inner provider no longer clobbers an outer `reducedMotion="never"` / `"always"`.
16
+
7
17
  ## [0.0.0-alpha.0]
8
18
 
9
19
  Initial alpha publish. The full v0.1 surface is in place; APIs are still subject to change before `0.1.0`.
package/README.md CHANGED
@@ -126,6 +126,8 @@ Full docs, every primitive's example screen, and an `llms-full.txt` reference li
126
126
  - [llms.txt](https://rootnative.github.io/inertia/llms.txt) — concise overview
127
127
  - [llms-full.txt](https://rootnative.github.io/inertia/llms-full.txt) — full API reference
128
128
 
129
+ AI agents: this package ships its own copy of the reference — read `node_modules/@rootnative/inertia/llms.txt` for the full API, no network needed.
130
+
129
131
  ## License
130
132
 
131
133
  [MIT](./LICENSE) © RootNative
@@ -1,6 +1,6 @@
1
1
  import { AnimatedStyle } from 'react-native-reanimated';
2
- import { U as UseGestureHandlers } from '../useGesture-DxtXdz-K.mjs';
3
- import { T as TransitionConfig, h as GestureLayerTransitions } from '../types-cU43dEmH.mjs';
2
+ import { U as UseGestureHandlers } from '../useGesture-C0GBS7d2.mjs';
3
+ import { T as TransitionInput, n as GestureLayerTransitions } from '../types-BzEgiUdJ.mjs';
4
4
  import 'react';
5
5
  import 'react-native';
6
6
 
@@ -49,10 +49,11 @@ interface UseGestureLayerOptions {
49
49
  /**
50
50
  * Transition forwarded to the underlying `useGesture` hook. Either a single
51
51
  * `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`
52
- * map for per-layer fades. Reduced motion collapses every transition to
53
- * `no-animation`.
52
+ * map for per-layer fades. A `TransitionName` registered on the nearest
53
+ * `<MotionConfig transitions>` is accepted in both positions. Reduced
54
+ * motion collapses every transition to `no-animation`.
54
55
  */
55
- transition?: TransitionConfig | GestureLayerTransitions;
56
+ transition?: TransitionInput | GestureLayerTransitions;
56
57
  }
57
58
  interface UseGestureLayerResult {
58
59
  /**
@@ -1,6 +1,6 @@
1
1
  import { AnimatedStyle } from 'react-native-reanimated';
2
- import { U as UseGestureHandlers } from '../useGesture-BnY65PlQ.js';
3
- import { T as TransitionConfig, h as GestureLayerTransitions } from '../types-cU43dEmH.js';
2
+ import { U as UseGestureHandlers } from '../useGesture-BRLgiNOC.js';
3
+ import { T as TransitionInput, n as GestureLayerTransitions } from '../types-BzEgiUdJ.js';
4
4
  import 'react';
5
5
  import 'react-native';
6
6
 
@@ -49,10 +49,11 @@ interface UseGestureLayerOptions {
49
49
  /**
50
50
  * Transition forwarded to the underlying `useGesture` hook. Either a single
51
51
  * `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`
52
- * map for per-layer fades. Reduced motion collapses every transition to
53
- * `no-animation`.
52
+ * map for per-layer fades. A `TransitionName` registered on the nearest
53
+ * `<MotionConfig transitions>` is accepted in both positions. Reduced
54
+ * motion collapses every transition to `no-animation`.
54
55
  */
55
- transition?: TransitionConfig | GestureLayerTransitions;
56
+ transition?: TransitionInput | GestureLayerTransitions;
56
57
  }
57
58
  interface UseGestureLayerResult {
58
59
  /**
@@ -6,8 +6,31 @@ var reactNativeWorklets = require('react-native-worklets');
6
6
  var reactNative = require('react-native');
7
7
 
8
8
  // src/gestureLayer/useGestureLayer.ts
9
+
10
+ // src/transitions/sig.ts
11
+ function stableSig(value) {
12
+ if (value === void 0) return "";
13
+ try {
14
+ return stableStringify(value);
15
+ } catch {
16
+ return String(value);
17
+ }
18
+ }
19
+ function stableStringify(v) {
20
+ if (v === null || typeof v !== "object") {
21
+ if (typeof v === "function" || v === void 0) return "null";
22
+ return JSON.stringify(v);
23
+ }
24
+ if (Array.isArray(v)) {
25
+ return "[" + v.map(stableStringify).join(",") + "]";
26
+ }
27
+ const obj = v;
28
+ const keys = Object.keys(obj).sort();
29
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
30
+ }
9
31
  var DEFAULT_MOTION_CONFIG = {
10
- reducedMotion: "user"
32
+ reducedMotion: "user",
33
+ transitions: {}
11
34
  };
12
35
  var MotionConfigContext = react.createContext(
13
36
  DEFAULT_MOTION_CONFIG
@@ -15,6 +38,9 @@ var MotionConfigContext = react.createContext(
15
38
  function useMotionConfig() {
16
39
  return react.useContext(MotionConfigContext);
17
40
  }
41
+ function useNamedTransitions() {
42
+ return useMotionConfig().transitions;
43
+ }
18
44
  function useShouldReduceMotion() {
19
45
  const { reducedMotion } = useMotionConfig();
20
46
  const osReduced = reactNativeReanimated.useReducedMotion();
@@ -22,6 +48,59 @@ function useShouldReduceMotion() {
22
48
  if (reducedMotion === "always") return true;
23
49
  return osReduced;
24
50
  }
51
+
52
+ // src/transitions/keys.ts
53
+ var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
54
+ "type",
55
+ "tension",
56
+ "friction",
57
+ "mass",
58
+ "velocity",
59
+ "restSpeedThreshold",
60
+ "restDisplacementThreshold",
61
+ "duration",
62
+ "easing",
63
+ "delay",
64
+ "repeat",
65
+ "deceleration",
66
+ "clamp"
67
+ ]);
68
+ function isTopLevelTransition(t) {
69
+ if (t === null || typeof t !== "object") return false;
70
+ const keys = Object.keys(t);
71
+ if (keys.length === 0) return false;
72
+ return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
73
+ }
74
+
75
+ // src/config/namedTransitions.ts
76
+ var UNKNOWN_NAME_FALLBACK = { type: "spring" };
77
+ function lookupNamedTransition(name, registry) {
78
+ const cfg = registry[name];
79
+ if (cfg) return cfg;
80
+ if (__DEV__) {
81
+ console.warn(
82
+ `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
83
+ );
84
+ }
85
+ return UNKNOWN_NAME_FALLBACK;
86
+ }
87
+ function resolveNamedTransitionProp(transition, registry) {
88
+ if (transition === void 0) return void 0;
89
+ if (typeof transition === "string") {
90
+ return lookupNamedTransition(transition, registry);
91
+ }
92
+ if (isTopLevelTransition(transition)) return transition;
93
+ const map = transition;
94
+ let out = null;
95
+ for (const key in map) {
96
+ const value = map[key];
97
+ if (typeof value === "string") {
98
+ if (out === null) out = { ...map };
99
+ out[key] = lookupNamedTransition(value, registry);
100
+ }
101
+ }
102
+ return out ?? transition;
103
+ }
25
104
  function ensureWorkletEasing(easing) {
26
105
  if (!easing) return void 0;
27
106
  const fn = isEasingFactory(easing) ? easing.factory() : easing;
@@ -117,29 +196,6 @@ function delayOf(cfg) {
117
196
  if (cfg.type === "no-animation") return void 0;
118
197
  return cfg.delay;
119
198
  }
120
-
121
- // src/transitions/keys.ts
122
- var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
123
- "type",
124
- "tension",
125
- "friction",
126
- "mass",
127
- "velocity",
128
- "restSpeedThreshold",
129
- "restDisplacementThreshold",
130
- "duration",
131
- "easing",
132
- "delay",
133
- "repeat",
134
- "deceleration",
135
- "clamp"
136
- ]);
137
- function isTopLevelTransition(t) {
138
- if (t === null || typeof t !== "object") return false;
139
- const keys = Object.keys(t);
140
- if (keys.length === 0) return false;
141
- return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
142
- }
143
199
  var modality = "keyboard";
144
200
  var installed = false;
145
201
  function setKeyboard() {
@@ -171,9 +227,10 @@ function useGesture(transition) {
171
227
  const focusVisible = reactNativeReanimated.useSharedValue(0);
172
228
  const hovered = reactNativeReanimated.useSharedValue(0);
173
229
  const shouldReduceMotion = useShouldReduceMotion();
230
+ const resolved = resolveNamedTransitionProp(transition, useNamedTransitions());
174
231
  const setLayer = react.useCallback(
175
232
  (sv, layer, target) => {
176
- const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, transition) ?? { type: "spring" };
233
+ const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
177
234
  sv.value = resolveTransition(cfg, target);
178
235
  },
179
236
  // The transition is intentionally read on every call rather than cooked
@@ -212,15 +269,20 @@ function layerTransition(layer, transition) {
212
269
 
213
270
  // src/gestureLayer/useGestureLayer.ts
214
271
  function useGestureLayer(states, options = {}) {
215
- const { disabled: isDisabled = false, transition } = options;
272
+ const { disabled: isDisabled = false, transition: transitionInput } = options;
216
273
  const shouldReduceMotion = useShouldReduceMotion();
274
+ const transition = resolveNamedTransitionProp(
275
+ transitionInput,
276
+ useNamedTransitions()
277
+ );
217
278
  const gesture = useGesture(transition);
218
279
  const disabledProgress = reactNativeReanimated.useSharedValue(0);
280
+ const transitionSig = stableSig(transition);
219
281
  react.useEffect(() => {
220
282
  const target = isDisabled ? 1 : 0;
221
283
  const cfg = shouldReduceMotion ? { type: "no-animation" } : disabledTransition(transition) ?? { type: "spring" };
222
284
  disabledProgress.value = resolveTransition(cfg, target);
223
- }, [isDisabled, shouldReduceMotion, transition, disabledProgress]);
285
+ }, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress]);
224
286
  const meta = react.useMemo(() => {
225
287
  const layers = {
226
288
  rest: states.rest,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/MotionConfigContext.ts","../../src/transitions/easing.ts","../../src/transitions/spring.ts","../../src/transitions/resolve.ts","../../src/transitions/keys.ts","../../src/gestures/focusVisibility.ts","../../src/values/useGesture.ts","../../src/gestureLayer/useGestureLayer.ts"],"names":["createContext","useContext","useReducedMotion","isWorkletFunction","withSpring","withTiming","Easing","withDecay","withRepeat","withDelay","Platform","useSharedValue","useCallback","useMemo","useEffect","useAnimatedStyle","interpolateColor"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, useContext } from 'react'\nimport { useReducedMotion } from 'react-native-reanimated'\n\n/**\n * How descendant Motion primitives should treat reduced-motion preferences.\n *\n * - `'user'` (default): defer to the OS accessibility setting via\n * Reanimated's `useReducedMotion()`. This is the only value that respects\n * user choice and is the right default for app-level wrappers.\n * - `'never'`: animate regardless of OS setting. Use sparingly — e.g. for\n * onboarding transitions you've decided are essential.\n * - `'always'`: never animate, regardless of OS setting. Useful for tests\n * and snapshots.\n */\nexport type ReducedMotion = 'user' | 'never' | 'always'\n\nexport interface MotionConfigValue {\n reducedMotion: ReducedMotion\n}\n\n/**\n * Default config used when a Motion primitive is rendered without a\n * `<MotionConfig>` ancestor. `'user'` means respect the OS setting.\n */\nexport const DEFAULT_MOTION_CONFIG: MotionConfigValue = {\n reducedMotion: 'user',\n}\n\nexport const MotionConfigContext = createContext<MotionConfigValue>(\n DEFAULT_MOTION_CONFIG,\n)\n\n/**\n * Read the active `<MotionConfig>` from a descendant. Returns the default\n * (`'user'`) when no provider is present.\n */\nexport function useMotionConfig(): MotionConfigValue {\n return useContext(MotionConfigContext)\n}\n\n/**\n * Resolve the active reduced-motion mode to a boolean. `'user'` consults\n * Reanimated's OS-backed hook; `'always'` / `'never'` shortcut. Motion\n * primitives call this to decide whether to swap transitions for\n * `no-animation`.\n */\nexport function useShouldReduceMotion(): boolean {\n const { reducedMotion } = useMotionConfig()\n const osReduced = useReducedMotion()\n if (reducedMotion === 'never') return false\n if (reducedMotion === 'always') return true\n return osReduced\n}\n","// `isWorkletFunction` lives in `react-native-worklets` (the Reanimated 4 peer\n// dep); Reanimated's own re-export is deprecated.\nimport { isWorkletFunction } from 'react-native-worklets'\nimport { type EasingInput } from '../types'\n\n/**\n * Reanimated 3.9+ validates that easing functions used in nested-transition\n * contexts (variants, sequences, per-property maps) are worklets, and crashes\n * with `[Reanimated] The easing function is not a worklet` otherwise. The\n * library accepts plain functions on the public surface; this helper wraps\n * them so consumers don't have to think about the worklet boundary.\n *\n * If the input is already a worklet (has been processed by the worklets babel\n * plugin), it's returned as-is. Otherwise it's wrapped in a function whose\n * body declares the `'worklet'` directive — when our source is processed by\n * the consumer's worklets babel plugin (the default Expo/RN setup), the\n * wrapper becomes a real worklet that captures the user fn via closure.\n *\n * Reanimated 4 changed `Easing.bezier(...)` to return an\n * `EasingFunctionFactory` (`{ factory: () => EasingFunction }`) rather than\n * the function itself. The helper accepts both shapes — `EasingFunction` and\n * `EasingFunctionFactory` — and unwraps the factory automatically so\n * consumers don't have to call `.factory()` manually.\n *\n * The user fn must be pure: no JS-thread captured refs, no shared mutable\n * state, no calls to non-worklet APIs.\n */\nexport function ensureWorkletEasing(\n easing: EasingInput | undefined,\n): ((t: number) => number) | undefined {\n if (!easing) return undefined\n // Reanimated 4 `EasingFunctionFactory` — unwrap via `.factory()` before\n // checking worklet status, so the wrapped fn (not the factory wrapper)\n // ends up in the transition config.\n const fn = isEasingFactory(easing) ? easing.factory() : easing\n if (isWorkletFunction(fn)) return fn\n const wrapped = (t: number) => {\n 'worklet'\n return fn(t)\n }\n return wrapped\n}\n\nfunction isEasingFactory(\n value: EasingInput,\n): value is { factory: () => (t: number) => number } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'factory' in value &&\n typeof (value as { factory: unknown }).factory === 'function'\n )\n}\n","import { type SpringTransition } from '../types'\n\n/**\n * Default spring physics, expressed in react-spring vocabulary.\n *\n * `tension: 170` / `friction: 26` / `mass: 1` was picked over Reanimated's\n * raw `stiffness: 100` / `damping: 10` default because the raw default\n * overshoots noticeably for the small (~100px) translates that dominate\n * UI work — buttons, sheets, popovers. These numbers settle in ~350ms with\n * a single, almost-imperceptible overshoot, which matches the perceptual\n * target the rest of the library is tuned against.\n */\nexport const DEFAULT_SPRING: Required<\n Pick<SpringTransition, 'tension' | 'friction' | 'mass'>\n> = {\n tension: 170,\n friction: 26,\n mass: 1,\n}\n\n/**\n * Convert public react-spring vocabulary (`tension` / `friction` / `mass`)\n * to Reanimated's raw `stiffness` / `damping` / `mass`. This is the single\n * place the mapping lives; resolvers, value hooks, and any future surface\n * that needs a Reanimated spring config import from here.\n *\n * The mapping is identity (tension ≡ stiffness, friction ≡ damping) — the\n * names differ but the underlying physics constants are the same. We don't\n * surface the raw names publicly because the react-spring vocabulary is\n * what designers and prior-art consumers expect.\n */\nexport function springToReanimated(t: SpringTransition) {\n 'worklet'\n return {\n stiffness: t.tension ?? DEFAULT_SPRING.tension,\n damping: t.friction ?? DEFAULT_SPRING.friction,\n mass: t.mass ?? DEFAULT_SPRING.mass,\n velocity: t.velocity,\n restSpeedThreshold: t.restSpeedThreshold,\n restDisplacementThreshold: t.restDisplacementThreshold,\n }\n}\n","import {\n Easing,\n withDecay,\n withDelay,\n withRepeat,\n withSpring,\n withTiming,\n} from 'react-native-reanimated'\nimport { ensureWorkletEasing } from './easing'\nimport { springToReanimated } from './spring'\nimport {\n type DecayTransition,\n type RepeatConfig,\n type SpringTransition,\n type TimingTransition,\n type TransitionConfig,\n} from '../types'\n\n/**\n * UI-thread callback Reanimated invokes when an animation settles. Must be a\n * worklet — callers either author one with `'worklet'` or build one via\n * `runOnJS(...)` to bridge to JS-thread code.\n */\nexport type AnimationCallback = (\n finished?: boolean,\n current?: number | string,\n) => void\n\n/**\n * Per-step callback factory. Resolvers call this with the step's phase and\n * sequence index (or `undefined` for non-sequence animations) and attach the\n * resulting callback to the underlying `withSpring` / `withTiming` /\n * `withDecay` call.\n */\nexport type CallbackFactory = (\n phase: 'step' | 'animation',\n step: number | undefined,\n) => AnimationCallback | undefined\n\nconst DEFAULT_TIMING_DURATION = 250\n\nfunction buildSpring(\n cfg: SpringTransition,\n toValue: number | string,\n cb?: AnimationCallback,\n) {\n return withSpring(toValue as number, springToReanimated(cfg), cb as never)\n}\n\nfunction buildTiming(\n cfg: TimingTransition,\n toValue: number | string,\n cb?: AnimationCallback,\n) {\n return withTiming(\n toValue as number,\n {\n duration: cfg.duration ?? DEFAULT_TIMING_DURATION,\n easing: ensureWorkletEasing(cfg.easing) ?? Easing.inOut(Easing.ease),\n },\n cb as never,\n )\n}\n\nfunction buildDecay(cfg: DecayTransition, cb?: AnimationCallback) {\n return withDecay(\n {\n velocity: cfg.velocity ?? 0,\n deceleration: cfg.deceleration,\n clamp: cfg.clamp,\n },\n cb as never,\n )\n}\n\n/**\n * Build a single-step animation (no repeat / no delay / no sequence) for a\n * given config + target. Pulled out so sequence steps can compose without\n * recursing into repeat/delay handling per step. The callback is forwarded\n * to Reanimated; for `no-animation` the callback is fired synchronously\n * since there's nothing to wait for.\n */\nfunction buildOne(\n cfg: TransitionConfig,\n toValue: number | string,\n cb?: AnimationCallback,\n): unknown {\n if (cfg.type === 'no-animation') {\n if (cb) cb(true, toValue)\n return toValue\n }\n if (cfg.type === 'decay') return buildDecay(cfg, cb)\n if (cfg.type === 'timing') return buildTiming(cfg, toValue, cb)\n return buildSpring(cfg as SpringTransition, toValue, cb)\n}\n\n/**\n * Wrap an animation in `withRepeat` per the unified `repeat` shape:\n * - `number` → finite count, alternating direction\n * - `'infinite'` → endless, alternating direction\n * - `{ count, alternate }`→ explicit; `alternate` defaults to `true`\n */\nexport function applyRepeat(\n animation: unknown,\n repeat: RepeatConfig | undefined,\n) {\n if (repeat === undefined) return animation\n if (repeat === 'infinite') {\n return withRepeat(animation as never, -1, true)\n }\n if (typeof repeat === 'number') {\n return withRepeat(animation as never, repeat, true)\n }\n const count = repeat.count === 'infinite' ? -1 : repeat.count\n const alternate = repeat.alternate ?? true\n return withRepeat(animation as never, count, alternate)\n}\n\nfunction applyDelay(animation: unknown, delay: number | undefined) {\n if (!delay || delay <= 0) return animation\n return withDelay(delay, animation as never)\n}\n\n/**\n * Build a Reanimated animation for a single property. Runs on the JS thread\n * once per change and produces a baked `withSpring` / `withTiming` /\n * `withDecay` (optionally wrapped in `withDelay` / `withRepeat`) call. The\n * worklet body only consumes the result.\n *\n * `callback`, when provided, fires once when the underlying single-shot\n * animation settles. Repeat-wrapped animations forward the callback to\n * `withRepeat`, so it fires once per iteration as Reanimated does.\n */\nexport function resolveTransition(\n config: TransitionConfig | undefined,\n toValue: number | string,\n callback?: AnimationCallback,\n): unknown {\n const cfg = config ?? ({ type: 'spring' } as SpringTransition)\n const base = buildOne(cfg, toValue, callback)\n const repeated = applyRepeat(base, repeatOf(cfg))\n return applyDelay(repeated, delayOf(cfg))\n}\n\nexport function repeatOf(cfg: TransitionConfig): RepeatConfig | undefined {\n if (cfg.type === 'no-animation' || cfg.type === 'decay') return undefined\n return cfg.repeat\n}\n\n/**\n * Return `cfg` minus its `repeat` field. Used when peeling top-level repeat\n * off a base transition before passing it down to per-sequence-step\n * resolution — the sequence as a whole is what should repeat, not each step.\n */\nexport function stripRepeat(\n cfg: TransitionConfig | undefined,\n): TransitionConfig | undefined {\n if (!cfg) return cfg\n if (cfg.type === 'no-animation' || cfg.type === 'decay') return cfg\n if (cfg.repeat === undefined) return cfg\n const next = { ...cfg }\n delete next.repeat\n return next\n}\n\nfunction delayOf(cfg: TransitionConfig): number | undefined {\n if (cfg.type === 'no-animation') return undefined\n return cfg.delay\n}\n","import { type TransitionConfig } from '../types'\n\n/**\n * Field names that may appear on a `TransitionConfig` (spring / timing /\n * decay / no-animation). Used as a structural discriminator: if every key on\n * an object is in this set, the object is treated as a top-level transition;\n * otherwise it's a per-property / per-layer transition map.\n *\n * Adding a new field to `TransitionConfig` requires adding the name here.\n */\nexport const TRANSITION_CONFIG_KEYS = new Set([\n 'type',\n 'tension',\n 'friction',\n 'mass',\n 'velocity',\n 'restSpeedThreshold',\n 'restDisplacementThreshold',\n 'duration',\n 'easing',\n 'delay',\n 'repeat',\n 'deceleration',\n 'clamp',\n])\n\nexport function isTopLevelTransition(t: unknown): t is TransitionConfig {\n if (t === null || typeof t !== 'object') return false\n const keys = Object.keys(t as object)\n if (keys.length === 0) return false\n return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k))\n}\n","import { Platform } from 'react-native'\n\n/**\n * Input-modality tracker for the `focusVisible` gesture sub-state.\n *\n * Implements the W3C `:focus-visible` heuristic: a focus event counts as\n * \"visible\" only when the most recent user input was keyboard-driven. Mouse,\n * pointer, and touch events flip the modality to `'pointer'`; keyboard events\n * flip it back to `'keyboard'`.\n *\n * On native platforms there is no pointer-vs-keyboard distinction — focus\n * arrives via D-pad, screen reader, or hardware keyboard, all of which are\n * keyboard-equivalent — so `isFocusVisible()` is unconditionally `true`.\n *\n * The web listeners attach lazily on first call (capture phase, so they run\n * before the focus event reaches the focused element) and stay installed for\n * the lifetime of the document. They are passive and idle-cheap; the cost is\n * one boolean read per `onFocus` dispatch.\n */\n\ntype InputModality = 'keyboard' | 'pointer'\n\n// Default to `'keyboard'` so a programmatic / autofocus that happens before\n// any user input still draws a focus ring — matches the W3C polyfill default.\nlet modality: InputModality = 'keyboard'\nlet installed = false\n\nfunction setKeyboard() {\n modality = 'keyboard'\n}\n\nfunction setPointer() {\n modality = 'pointer'\n}\n\nfunction ensureInstalled(): void {\n if (installed) return\n if (Platform.OS !== 'web') return\n if (typeof document === 'undefined') return\n document.addEventListener('keydown', setKeyboard, true)\n document.addEventListener('mousedown', setPointer, true)\n document.addEventListener('pointerdown', setPointer, true)\n document.addEventListener('touchstart', setPointer, true)\n installed = true\n}\n\n/**\n * `true` if the next `onFocus` should be treated as \"focus-visible\" (keyboard\n * focus). On native, always `true`. On web, reflects the most recent user\n * input modality.\n */\nexport function isFocusVisible(): boolean {\n if (Platform.OS !== 'web') return true\n ensureInstalled()\n return modality === 'keyboard'\n}\n\n/** @internal — test-only hook to reset module state between cases. */\nexport function __resetFocusVisibilityForTests(next: InputModality): void {\n modality = next\n}\n","import { useCallback, useMemo } from 'react'\nimport { useSharedValue, type SharedValue } from 'react-native-reanimated'\nimport { useShouldReduceMotion } from '../config'\nimport { isFocusVisible } from '../gestures'\nimport { isTopLevelTransition, resolveTransition } from '../transitions'\nimport { type GestureLayerTransitions, type TransitionConfig } from '../types'\n\ntype LayerName = 'pressed' | 'focused' | 'focusVisible' | 'hovered'\n\n/**\n * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the\n * shared values returned alongside.\n *\n * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web\n * only — no-ops on native). `onFocus` consults `isFocusVisible()` before\n * raising the keyboard-only `focusVisible` layer; `focused` always raises.\n */\nexport interface UseGestureHandlers {\n onPressIn: () => void\n onPressOut: () => void\n onHoverIn: () => void\n onHoverOut: () => void\n onFocus: () => void\n onBlur: () => void\n}\n\nexport interface UseGestureResult {\n /** 0↔1 progress for the pressed layer. */\n pressed: SharedValue<number>\n /** 0↔1 progress for the focused layer (any focus modality). */\n focused: SharedValue<number>\n /** 0↔1 progress for the focusVisible layer (keyboard focus only). */\n focusVisible: SharedValue<number>\n /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */\n hovered: SharedValue<number>\n /** Handlers to spread on the receiving `Pressable`. */\n handlers: UseGestureHandlers\n}\n\n/**\n * Build a gesture-layer controller. The hook-form of the `gesture` prop —\n * reach for it when you need to drive multiple animated views from the same\n * gesture state (a focus ring + state-layer halo + content tint all on one\n * Pressable), which the prop-form's \"animate the receiver's own style\" model\n * can't express.\n *\n * Returns four 0↔1 shared values (one per layer) and a handler bag to spread\n * on a `Pressable`. The shared values are stable across renders — feed them\n * into any number of `useAnimatedStyle` blocks anywhere in the tree.\n *\n * Transitions follow the same shape as the `gesture` prop's accompanying\n * `transition`: pass a single `TransitionConfig` to use for every layer, or a\n * `GestureLayerTransitions` map to give each layer its own. Layers without an\n * explicit transition fall back to the library default spring.\n *\n * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every\n * transition to `no-animation` so state changes snap instead of interpolating\n * — same behaviour the gesture prop applies.\n *\n * @example\n * ```tsx\n * import { useAnimatedStyle } from 'react-native-reanimated'\n * import { useGesture } from '@rootnative/inertia'\n *\n * function Card() {\n * const { pressed, focused, hovered, handlers } = useGesture({\n * pressed: { type: 'timing', duration: 100 },\n * hovered: { type: 'timing', duration: 150 },\n * focused: { type: 'timing', duration: 200 },\n * })\n *\n * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))\n * const haloStyle = useAnimatedStyle(() => ({\n * opacity: Math.max(\n * hovered.value * 0.08,\n * focused.value * 0.10,\n * pressed.value * 0.10,\n * ),\n * }))\n *\n * return (\n * <Pressable {...handlers}>\n * <Animated.View style={ringStyle} />\n * <Animated.View style={haloStyle} />\n * </Pressable>\n * )\n * }\n * ```\n */\nexport function useGesture(\n transition?: TransitionConfig | GestureLayerTransitions,\n): UseGestureResult {\n const pressed = useSharedValue(0)\n const focused = useSharedValue(0)\n const focusVisible = useSharedValue(0)\n const hovered = useSharedValue(0)\n const shouldReduceMotion = useShouldReduceMotion()\n\n const setLayer = useCallback(\n (sv: SharedValue<number>, layer: LayerName, target: 0 | 1) => {\n const cfg = shouldReduceMotion\n ? ({ type: 'no-animation' } as const)\n : (layerTransition(layer, transition) ?? ({ type: 'spring' } as const))\n sv.value = resolveTransition(cfg, target) as never\n },\n // The transition is intentionally read on every call rather than cooked\n // into the dep array — a fresh literal each render would otherwise\n // rebuild the handler bag and break composing consumers that key off\n // handler identity. `transition` is read inside the callback closure;\n // shared values are stable so the only dep that matters is the reduce-\n // motion flag.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [shouldReduceMotion],\n )\n\n const handlers = useMemo<UseGestureHandlers>(\n () => ({\n onPressIn: () => setLayer(pressed, 'pressed', 1),\n onPressOut: () => setLayer(pressed, 'pressed', 0),\n onHoverIn: () => setLayer(hovered, 'hovered', 1),\n onHoverOut: () => setLayer(hovered, 'hovered', 0),\n onFocus: () => {\n setLayer(focused, 'focused', 1)\n if (isFocusVisible()) setLayer(focusVisible, 'focusVisible', 1)\n },\n onBlur: () => {\n setLayer(focused, 'focused', 0)\n setLayer(focusVisible, 'focusVisible', 0)\n },\n }),\n [setLayer, pressed, focused, focusVisible, hovered],\n )\n\n return { pressed, focused, focusVisible, hovered, handlers }\n}\n\nfunction layerTransition(\n layer: LayerName,\n transition: TransitionConfig | GestureLayerTransitions | undefined,\n): TransitionConfig | undefined {\n if (!transition) return undefined\n if (isTopLevelTransition(transition)) return transition\n return (transition as GestureLayerTransitions)[layer]\n}\n","import { useEffect, useMemo } from 'react'\nimport {\n interpolateColor,\n useAnimatedStyle,\n useSharedValue,\n type AnimatedStyle,\n} from 'react-native-reanimated'\nimport { useShouldReduceMotion } from '../config'\nimport { isTopLevelTransition, resolveTransition } from '../transitions'\nimport { useGesture, type UseGestureHandlers } from '../values/useGesture'\nimport { type GestureLayerTransitions, type TransitionConfig } from '../types'\n\n/**\n * A single gesture-layer style — a flat map of style keys to a value. Numeric\n * values participate in clamped-max composition (the \"strongest active layer\n * wins\" model used by MD3 state-layer haloes); string values are treated as\n * colors and composed via priority cascade with `interpolateColor`.\n *\n * The hook does not validate that string values are valid colors — passing\n * something like `borderStyle: 'solid'` will crash inside the worklet. Keep\n * string values to color strings.\n */\nexport type GestureLayerStyle = {\n [key: string]: number | string | undefined\n}\n\n/**\n * Per-state style maps. Every key is optional; missing layers default to\n * `rest` (or `0` / `'transparent'` if `rest` is also absent for that key).\n *\n * - `rest` — base values, applied when no other layer is active.\n * - `hovered` / `focused` / `focusVisible` / `pressed` — gesture-driven\n * states tracked via the underlying `useGesture` hook. Each owns an\n * independent 0↔1 progress that fades the layer in/out per the configured\n * transition.\n * - `disabled` — gated by the JS-side `options.disabled` flag rather than a\n * gesture. Sits at the top of the priority cascade and overrides every\n * gesture layer when active.\n */\nexport interface GestureLayerStates {\n rest?: GestureLayerStyle\n hovered?: GestureLayerStyle\n focused?: GestureLayerStyle\n focusVisible?: GestureLayerStyle\n pressed?: GestureLayerStyle\n disabled?: GestureLayerStyle\n}\n\nexport interface UseGestureLayerOptions {\n /**\n * When `true`, the `disabled` layer becomes active (or `rest` if `disabled`\n * is undefined). Animates via the top-level transition or the library\n * default spring; per-layer transitions (`GestureLayerTransitions`) do not\n * apply to `disabled`.\n */\n disabled?: boolean\n /**\n * Transition forwarded to the underlying `useGesture` hook. Either a single\n * `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`\n * map for per-layer fades. Reduced motion collapses every transition to\n * `no-animation`.\n */\n transition?: TransitionConfig | GestureLayerTransitions\n}\n\nexport interface UseGestureLayerResult {\n /**\n * Animated style produced by `useAnimatedStyle` — spread on an\n * `Animated.View` or pass through `<Motion.View style={...} />`.\n */\n style: AnimatedStyle<Record<string, unknown>>\n /** Handlers to spread on the receiving `Pressable`. */\n handlers: UseGestureHandlers\n}\n\n/**\n * A \"strongest active layer wins\" interactive-feedback primitive. Sits one\n * step above `useGesture()` — the consumer supplies the per-state target\n * values, the hook handles the four gesture progress shared values, the\n * disabled override, the worklet, and the transition.\n *\n * Composition model:\n *\n * - **Numeric keys** (opacity, scale, borderWidth, etc.) compose via\n * clamped-max with `rest` as the floor:\n * `out = max(rest, ...for each active gesture layer: lerp(rest, layer, progress))`.\n * This matches the MD3 state-layer halo pattern — multiple states active\n * simultaneously raise the value to the strongest, not the sum.\n * - **Color keys** (any string value) compose via priority cascade with\n * `interpolateColor`, lowest priority first: `hovered → focused →\n * focusVisible → pressed`. Clamped-max doesn't apply to colors; this\n * matches the cascade used by the declarative `gesture` prop.\n * - **Disabled** sits at the top of the cascade for both numeric and color\n * keys — when active, it lerps the composed value toward the `disabled`\n * target.\n *\n * Reach for this when you want MD3 / iOS-translucent state-layer overlays\n * without rewriting the worklet by hand for every consumer; reach for plain\n * `useGesture()` when you need a composition model this hook doesn't\n * express (additive, multiply, per-key custom blends).\n *\n * @example MD3 state-layer halo\n * ```tsx\n * import { useGestureLayer } from '@rootnative/inertia/gesture-layer'\n * import Animated from 'react-native-reanimated'\n * import { Pressable } from 'react-native'\n *\n * function SwitchHalo({ disabled }: { disabled?: boolean }) {\n * const { style, handlers } = useGestureLayer(\n * {\n * rest: { opacity: 0, backgroundColor: 'transparent' },\n * hovered: { opacity: 0.08, backgroundColor: '#000' },\n * focused: { opacity: 0.10, backgroundColor: '#000' },\n * pressed: { opacity: 0.12, backgroundColor: '#000' },\n * },\n * { disabled, transition: { type: 'timing', duration: 150 } },\n * )\n *\n * return (\n * <Pressable {...handlers}>\n * <Animated.View style={style} />\n * </Pressable>\n * )\n * }\n * ```\n */\nexport function useGestureLayer(\n states: GestureLayerStates,\n options: UseGestureLayerOptions = {},\n): UseGestureLayerResult {\n const { disabled: isDisabled = false, transition } = options\n const shouldReduceMotion = useShouldReduceMotion()\n const gesture = useGesture(transition)\n const disabledProgress = useSharedValue(0)\n\n useEffect(() => {\n const target = isDisabled ? 1 : 0\n const cfg = shouldReduceMotion\n ? ({ type: 'no-animation' } as const)\n : (disabledTransition(transition) ?? ({ type: 'spring' } as const))\n disabledProgress.value = resolveTransition(cfg, target) as never\n }, [isDisabled, shouldReduceMotion, transition, disabledProgress])\n\n // JS-thread precompute: union of keys across all layers, per-key type\n // (number vs color), and a rest-fallback table. The worklet body reads\n // from `meta` instead of probing each layer per frame — the type check\n // only runs when layer identities change.\n const meta = useMemo(() => {\n const layers = {\n rest: states.rest,\n hovered: states.hovered,\n focused: states.focused,\n focusVisible: states.focusVisible,\n pressed: states.pressed,\n disabled: states.disabled,\n }\n const sources = [\n layers.rest,\n layers.hovered,\n layers.focused,\n layers.focusVisible,\n layers.pressed,\n layers.disabled,\n ]\n const keySet = new Set<string>()\n for (const src of sources) {\n if (!src) continue\n for (const k in src) if (src[k] !== undefined) keySet.add(k)\n }\n const keys = Array.from(keySet)\n const types: Record<string, 'number' | 'color'> = {}\n const restValues: Record<string, number | string> = {}\n for (const k of keys) {\n let firstDefined: number | string | undefined\n for (const src of sources) {\n if (src && src[k] !== undefined) {\n firstDefined = src[k]\n break\n }\n }\n const isColor = typeof firstDefined === 'string'\n types[k] = isColor ? 'color' : 'number'\n const restRaw = layers.rest ? layers.rest[k] : undefined\n restValues[k] =\n restRaw !== undefined ? restRaw : isColor ? 'transparent' : 0\n }\n return { layers, keys, types, restValues }\n }, [\n states.rest,\n states.hovered,\n states.focused,\n states.focusVisible,\n states.pressed,\n states.disabled,\n ])\n\n const style = useAnimatedStyle(() => {\n const { layers, keys, types, restValues } = meta\n const ph = gesture.hovered.value\n const pf = gesture.focused.value\n const pfv = gesture.focusVisible.value\n const pp = gesture.pressed.value\n const pd = disabledProgress.value\n\n const hoveredLayer = layers.hovered\n const focusedLayer = layers.focused\n const focusVisibleLayer = layers.focusVisible\n const pressedLayer = layers.pressed\n const disabledLayer = layers.disabled\n\n const out: Record<string, unknown> = {}\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]!\n const isColor = types[k] === 'color'\n const rest = restValues[k]!\n\n if (isColor) {\n let v = rest as string\n if (hoveredLayer && ph > 0 && hoveredLayer[k] !== undefined) {\n v = interpolateColor(ph, [0, 1], [v, hoveredLayer[k] as string])\n }\n if (focusedLayer && pf > 0 && focusedLayer[k] !== undefined) {\n v = interpolateColor(pf, [0, 1], [v, focusedLayer[k] as string])\n }\n if (\n focusVisibleLayer &&\n pfv > 0 &&\n focusVisibleLayer[k] !== undefined\n ) {\n v = interpolateColor(pfv, [0, 1], [v, focusVisibleLayer[k] as string])\n }\n if (pressedLayer && pp > 0 && pressedLayer[k] !== undefined) {\n v = interpolateColor(pp, [0, 1], [v, pressedLayer[k] as string])\n }\n if (disabledLayer && pd > 0 && disabledLayer[k] !== undefined) {\n v = interpolateColor(pd, [0, 1], [v, disabledLayer[k] as string])\n }\n out[k] = v\n } else {\n const base = rest as number\n let m = base\n if (hoveredLayer && ph > 0 && hoveredLayer[k] !== undefined) {\n const c = base + ((hoveredLayer[k] as number) - base) * ph\n if (c > m) m = c\n }\n if (focusedLayer && pf > 0 && focusedLayer[k] !== undefined) {\n const c = base + ((focusedLayer[k] as number) - base) * pf\n if (c > m) m = c\n }\n if (\n focusVisibleLayer &&\n pfv > 0 &&\n focusVisibleLayer[k] !== undefined\n ) {\n const c = base + ((focusVisibleLayer[k] as number) - base) * pfv\n if (c > m) m = c\n }\n if (pressedLayer && pp > 0 && pressedLayer[k] !== undefined) {\n const c = base + ((pressedLayer[k] as number) - base) * pp\n if (c > m) m = c\n }\n if (disabledLayer && pd > 0 && disabledLayer[k] !== undefined) {\n m = m + ((disabledLayer[k] as number) - m) * pd\n }\n out[k] = m\n }\n }\n\n return out\n })\n\n return {\n style: style as AnimatedStyle<Record<string, unknown>>,\n handlers: gesture.handlers,\n }\n}\n\nfunction disabledTransition(\n transition: TransitionConfig | GestureLayerTransitions | undefined,\n): TransitionConfig | undefined {\n if (!transition) return undefined\n if (isTopLevelTransition(transition)) return transition\n return undefined\n}\n"]}
1
+ {"version":3,"sources":["../../src/transitions/sig.ts","../../src/config/MotionConfigContext.ts","../../src/transitions/keys.ts","../../src/config/namedTransitions.ts","../../src/transitions/easing.ts","../../src/transitions/spring.ts","../../src/transitions/resolve.ts","../../src/gestures/focusVisibility.ts","../../src/values/useGesture.ts","../../src/gestureLayer/useGestureLayer.ts"],"names":["createContext","useContext","useReducedMotion","isWorkletFunction","withSpring","withTiming","Easing","withDecay","withRepeat","withDelay","Platform","useSharedValue","useCallback","useMemo","useEffect","useAnimatedStyle","interpolateColor"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Stable string signature for an arbitrary value — used as a dep-array\n * member so a fresh object literal each render doesn't re-fire an effect\n * unless something structurally changed. Functions serialize as `null`\n * (their identity isn't useful in a sig); `undefined` collapses to an empty\n * string so omitted props compare equal across renders.\n */\nexport function stableSig(value: unknown): string {\n if (value === undefined) return ''\n try {\n return stableStringify(value)\n } catch {\n return String(value)\n }\n}\n\n/**\n * JSON.stringify with keys sorted at every level so a sig is invariant under\n * property-declaration order. Functions and `undefined` both serialize as\n * `null` — we accept the latter's information loss (rare in practice) in\n * exchange for not crashing on circular function-bearing graphs.\n */\nfunction stableStringify(v: unknown): string {\n if (v === null || typeof v !== 'object') {\n if (typeof v === 'function' || v === undefined) return 'null'\n return JSON.stringify(v)\n }\n if (Array.isArray(v)) {\n return '[' + v.map(stableStringify).join(',') + ']'\n }\n const obj = v as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return (\n '{' +\n keys\n .map((k) => JSON.stringify(k) + ':' + stableStringify(obj[k]))\n .join(',') +\n '}'\n )\n}\n","import { createContext, useContext } from 'react'\nimport { useReducedMotion } from 'react-native-reanimated'\nimport { type NamedTransitions } from '../types'\n\n/**\n * How descendant Motion primitives should treat reduced-motion preferences.\n *\n * - `'user'` (default): defer to the OS accessibility setting via\n * Reanimated's `useReducedMotion()`. This is the only value that respects\n * user choice and is the right default for app-level wrappers.\n * - `'never'`: animate regardless of OS setting. Use sparingly — e.g. for\n * onboarding transitions you've decided are essential.\n * - `'always'`: never animate, regardless of OS setting. Useful for tests\n * and snapshots.\n */\nexport type ReducedMotion = 'user' | 'never' | 'always'\n\nexport interface MotionConfigValue {\n reducedMotion: ReducedMotion\n /**\n * Named transitions registered by ancestor `<MotionConfig transitions>`\n * providers, already merged (nearest provider wins per name). Empty with no\n * provider — every name then resolves to the unknown-name fallback.\n */\n transitions: NamedTransitions\n}\n\n/**\n * Default config used when a Motion primitive is rendered without a\n * `<MotionConfig>` ancestor. `'user'` means respect the OS setting; no\n * transitions are registered.\n */\nexport const DEFAULT_MOTION_CONFIG: MotionConfigValue = {\n reducedMotion: 'user',\n transitions: {},\n}\n\nexport const MotionConfigContext = createContext<MotionConfigValue>(\n DEFAULT_MOTION_CONFIG,\n)\n\n/**\n * Read the active `<MotionConfig>` from a descendant. Returns the default\n * (`'user'`) when no provider is present.\n */\nexport function useMotionConfig(): MotionConfigValue {\n return useContext(MotionConfigContext)\n}\n\n/**\n * Resolve the active reduced-motion mode to a boolean. `'user'` consults\n * Reanimated's OS-backed hook; `'always'` / `'never'` shortcut. Motion\n * primitives call this to decide whether to swap transitions for\n * `no-animation`.\n */\n/**\n * Read the merged named-transition registry from the nearest `<MotionConfig>`\n * ancestors. This is what the Motion primitives and value-layer hooks consult\n * when a `TransitionName` string is passed where a `TransitionConfig` is\n * accepted; custom animated components (and adapter packages) use it together\n * with `resolveNamedTransition` to support names on their own surface.\n */\nexport function useNamedTransitions(): NamedTransitions {\n return useMotionConfig().transitions\n}\n\nexport function useShouldReduceMotion(): boolean {\n const { reducedMotion } = useMotionConfig()\n const osReduced = useReducedMotion()\n if (reducedMotion === 'never') return false\n if (reducedMotion === 'always') return true\n return osReduced\n}\n","import { type TransitionConfig } from '../types'\n\n/**\n * Field names that may appear on a `TransitionConfig` (spring / timing /\n * decay / no-animation). Used as a structural discriminator: if every key on\n * an object is in this set, the object is treated as a top-level transition;\n * otherwise it's a per-property / per-layer transition map.\n *\n * Adding a new field to `TransitionConfig` requires adding the name here.\n */\nexport const TRANSITION_CONFIG_KEYS = new Set([\n 'type',\n 'tension',\n 'friction',\n 'mass',\n 'velocity',\n 'restSpeedThreshold',\n 'restDisplacementThreshold',\n 'duration',\n 'easing',\n 'delay',\n 'repeat',\n 'deceleration',\n 'clamp',\n])\n\nexport function isTopLevelTransition(t: unknown): t is TransitionConfig {\n if (t === null || typeof t !== 'object') return false\n const keys = Object.keys(t as object)\n if (keys.length === 0) return false\n return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k))\n}\n","import { isTopLevelTransition } from '../transitions/keys'\nimport {\n type NamedTransitions,\n type Transition,\n type TransitionConfig,\n type TransitionInput,\n} from '../types'\n\ndeclare const __DEV__: boolean\n\n/**\n * Fallback used when a name isn't found in the registry: the library default\n * spring, matching what an omitted transition resolves to everywhere else.\n */\nconst UNKNOWN_NAME_FALLBACK: TransitionConfig = { type: 'spring' }\n\n/**\n * Look a registered transition name up in a registry. Unknown names warn in\n * dev and fall back to the library default spring — the animation still runs,\n * it just isn't the one the token intended, which is the same failure\n * softness the web platform gives an unknown CSS keyword.\n */\nexport function lookupNamedTransition(\n name: string,\n registry: NamedTransitions,\n): TransitionConfig {\n const cfg = registry[name]\n if (cfg) return cfg\n if (__DEV__) {\n console.warn(\n `[inertia] Unknown transition name \"${name}\" — falling back to the ` +\n `default spring. Register it on a provider: ` +\n `<MotionConfig transitions={{ '${name}': { ... } }}>.`,\n )\n }\n return UNKNOWN_NAME_FALLBACK\n}\n\n/**\n * Resolve a single transition input — a `TransitionConfig` passes through\n * untouched, a `TransitionName` is looked up in `registry`. This is the\n * building block adapter packages use to accept names wherever they accept a\n * config (pair it with `useNamedTransitions()` for the registry).\n */\nexport function resolveNamedTransition(\n input: TransitionInput | undefined,\n registry: NamedTransitions,\n): TransitionConfig | undefined {\n if (input === undefined) return undefined\n if (typeof input === 'string') return lookupNamedTransition(input, registry)\n return input\n}\n\n/**\n * Resolve every name inside a `transition` prop value — the top-level string\n * form, and string values on the per-property / gesture-layer map form.\n * Identity-preserving: when the input contains no names it is returned\n * unchanged, so signature- and identity-keyed memoization downstream is\n * unaffected for the config-object path.\n */\nexport function resolveNamedTransitionProp<S>(\n transition: Transition<S> | undefined,\n registry: NamedTransitions,\n): Exclude<Transition<S>, string> | undefined {\n if (transition === undefined) return undefined\n if (typeof transition === 'string') {\n return lookupNamedTransition(transition, registry)\n }\n if (isTopLevelTransition(transition)) return transition\n const map = transition as Record<string, unknown>\n let out: Record<string, unknown> | null = null\n for (const key in map) {\n const value = map[key]\n if (typeof value === 'string') {\n if (out === null) out = { ...map }\n out[key] = lookupNamedTransition(value, registry)\n }\n }\n return (out ?? transition) as Exclude<Transition<S>, string>\n}\n","// `isWorkletFunction` lives in `react-native-worklets` (the Reanimated 4 peer\n// dep); Reanimated's own re-export is deprecated.\nimport { isWorkletFunction } from 'react-native-worklets'\nimport { type EasingInput } from '../types'\n\n/**\n * Reanimated 3.9+ validates that easing functions used in nested-transition\n * contexts (variants, sequences, per-property maps) are worklets, and crashes\n * with `[Reanimated] The easing function is not a worklet` otherwise. The\n * library accepts plain functions on the public surface; this helper wraps\n * them so consumers don't have to think about the worklet boundary.\n *\n * If the input is already a worklet (has been processed by the worklets babel\n * plugin), it's returned as-is. Otherwise it's wrapped in a function whose\n * body declares the `'worklet'` directive — when our source is processed by\n * the consumer's worklets babel plugin (the default Expo/RN setup), the\n * wrapper becomes a real worklet that captures the user fn via closure.\n *\n * Reanimated 4 changed `Easing.bezier(...)` to return an\n * `EasingFunctionFactory` (`{ factory: () => EasingFunction }`) rather than\n * the function itself. The helper accepts both shapes — `EasingFunction` and\n * `EasingFunctionFactory` — and unwraps the factory automatically so\n * consumers don't have to call `.factory()` manually.\n *\n * The user fn must be pure: no JS-thread captured refs, no shared mutable\n * state, no calls to non-worklet APIs.\n */\nexport function ensureWorkletEasing(\n easing: EasingInput | undefined,\n): ((t: number) => number) | undefined {\n if (!easing) return undefined\n // Reanimated 4 `EasingFunctionFactory` — unwrap via `.factory()` before\n // checking worklet status, so the wrapped fn (not the factory wrapper)\n // ends up in the transition config.\n const fn = isEasingFactory(easing) ? easing.factory() : easing\n if (isWorkletFunction(fn)) return fn\n const wrapped = (t: number) => {\n 'worklet'\n return fn(t)\n }\n return wrapped\n}\n\nfunction isEasingFactory(\n value: EasingInput,\n): value is { factory: () => (t: number) => number } {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'factory' in value &&\n typeof (value as { factory: unknown }).factory === 'function'\n )\n}\n","import { type SpringTransition } from '../types'\n\n/**\n * Default spring physics, expressed in react-spring vocabulary.\n *\n * `tension: 170` / `friction: 26` / `mass: 1` was picked over Reanimated's\n * raw `stiffness: 100` / `damping: 10` default because the raw default\n * overshoots noticeably for the small (~100px) translates that dominate\n * UI work — buttons, sheets, popovers. These numbers settle in ~350ms with\n * a single, almost-imperceptible overshoot, which matches the perceptual\n * target the rest of the library is tuned against.\n */\nexport const DEFAULT_SPRING: Required<\n Pick<SpringTransition, 'tension' | 'friction' | 'mass'>\n> = {\n tension: 170,\n friction: 26,\n mass: 1,\n}\n\n/**\n * Convert public react-spring vocabulary (`tension` / `friction` / `mass`)\n * to Reanimated's raw `stiffness` / `damping` / `mass`. This is the single\n * place the mapping lives; resolvers, value hooks, and any future surface\n * that needs a Reanimated spring config import from here.\n *\n * The mapping is identity (tension ≡ stiffness, friction ≡ damping) — the\n * names differ but the underlying physics constants are the same. We don't\n * surface the raw names publicly because the react-spring vocabulary is\n * what designers and prior-art consumers expect.\n */\nexport function springToReanimated(t: SpringTransition) {\n 'worklet'\n return {\n stiffness: t.tension ?? DEFAULT_SPRING.tension,\n damping: t.friction ?? DEFAULT_SPRING.friction,\n mass: t.mass ?? DEFAULT_SPRING.mass,\n velocity: t.velocity,\n restSpeedThreshold: t.restSpeedThreshold,\n restDisplacementThreshold: t.restDisplacementThreshold,\n }\n}\n","import {\n Easing,\n withDecay,\n withDelay,\n withRepeat,\n withSpring,\n withTiming,\n} from 'react-native-reanimated'\nimport { ensureWorkletEasing } from './easing'\nimport { springToReanimated } from './spring'\nimport {\n type DecayTransition,\n type RepeatConfig,\n type SpringTransition,\n type TimingTransition,\n type TransitionConfig,\n} from '../types'\n\n/**\n * UI-thread callback Reanimated invokes when an animation settles. Must be a\n * worklet — callers either author one with `'worklet'` or build one via\n * `runOnJS(...)` to bridge to JS-thread code.\n */\nexport type AnimationCallback = (\n finished?: boolean,\n current?: number | string,\n) => void\n\n/**\n * Per-step callback factory. Resolvers call this with the step's phase and\n * sequence index (or `undefined` for non-sequence animations) and attach the\n * resulting callback to the underlying `withSpring` / `withTiming` /\n * `withDecay` call.\n */\nexport type CallbackFactory = (\n phase: 'step' | 'animation',\n step: number | undefined,\n) => AnimationCallback | undefined\n\nconst DEFAULT_TIMING_DURATION = 250\n\nfunction buildSpring(\n cfg: SpringTransition,\n toValue: number | string,\n cb?: AnimationCallback,\n) {\n return withSpring(toValue as number, springToReanimated(cfg), cb as never)\n}\n\nfunction buildTiming(\n cfg: TimingTransition,\n toValue: number | string,\n cb?: AnimationCallback,\n) {\n return withTiming(\n toValue as number,\n {\n duration: cfg.duration ?? DEFAULT_TIMING_DURATION,\n easing: ensureWorkletEasing(cfg.easing) ?? Easing.inOut(Easing.ease),\n },\n cb as never,\n )\n}\n\nfunction buildDecay(cfg: DecayTransition, cb?: AnimationCallback) {\n return withDecay(\n {\n velocity: cfg.velocity ?? 0,\n deceleration: cfg.deceleration,\n clamp: cfg.clamp,\n },\n cb as never,\n )\n}\n\n/**\n * Build a single-step animation (no repeat / no delay / no sequence) for a\n * given config + target. Pulled out so sequence steps can compose without\n * recursing into repeat/delay handling per step. The callback is forwarded\n * to Reanimated; for `no-animation` the callback is fired synchronously\n * since there's nothing to wait for.\n */\nfunction buildOne(\n cfg: TransitionConfig,\n toValue: number | string,\n cb?: AnimationCallback,\n): unknown {\n if (cfg.type === 'no-animation') {\n if (cb) cb(true, toValue)\n return toValue\n }\n if (cfg.type === 'decay') return buildDecay(cfg, cb)\n if (cfg.type === 'timing') return buildTiming(cfg, toValue, cb)\n return buildSpring(cfg as SpringTransition, toValue, cb)\n}\n\n/**\n * Wrap an animation in `withRepeat` per the unified `repeat` shape:\n * - `number` → finite count, alternating direction\n * - `'infinite'` → endless, alternating direction\n * - `{ count, alternate }`→ explicit; `alternate` defaults to `true`\n */\nexport function applyRepeat(\n animation: unknown,\n repeat: RepeatConfig | undefined,\n) {\n if (repeat === undefined) return animation\n if (repeat === 'infinite') {\n return withRepeat(animation as never, -1, true)\n }\n if (typeof repeat === 'number') {\n return withRepeat(animation as never, repeat, true)\n }\n const count = repeat.count === 'infinite' ? -1 : repeat.count\n const alternate = repeat.alternate ?? true\n return withRepeat(animation as never, count, alternate)\n}\n\nfunction applyDelay(animation: unknown, delay: number | undefined) {\n if (!delay || delay <= 0) return animation\n return withDelay(delay, animation as never)\n}\n\n/**\n * Build a Reanimated animation for a single property. Runs on the JS thread\n * once per change and produces a baked `withSpring` / `withTiming` /\n * `withDecay` (optionally wrapped in `withDelay` / `withRepeat`) call. The\n * worklet body only consumes the result.\n *\n * `callback`, when provided, fires once when the underlying single-shot\n * animation settles. Repeat-wrapped animations forward the callback to\n * `withRepeat`, so it fires once per iteration as Reanimated does.\n */\nexport function resolveTransition(\n config: TransitionConfig | undefined,\n toValue: number | string,\n callback?: AnimationCallback,\n): unknown {\n const cfg = config ?? ({ type: 'spring' } as SpringTransition)\n const base = buildOne(cfg, toValue, callback)\n const repeated = applyRepeat(base, repeatOf(cfg))\n return applyDelay(repeated, delayOf(cfg))\n}\n\nexport function repeatOf(cfg: TransitionConfig): RepeatConfig | undefined {\n if (cfg.type === 'no-animation' || cfg.type === 'decay') return undefined\n return cfg.repeat\n}\n\n/**\n * Return `cfg` minus its `repeat` field. Used when peeling top-level repeat\n * off a base transition before passing it down to per-sequence-step\n * resolution — the sequence as a whole is what should repeat, not each step.\n */\nexport function stripRepeat(\n cfg: TransitionConfig | undefined,\n): TransitionConfig | undefined {\n if (!cfg) return cfg\n if (cfg.type === 'no-animation' || cfg.type === 'decay') return cfg\n if (cfg.repeat === undefined) return cfg\n const next = { ...cfg }\n delete next.repeat\n return next\n}\n\nfunction delayOf(cfg: TransitionConfig): number | undefined {\n if (cfg.type === 'no-animation') return undefined\n return cfg.delay\n}\n","import { Platform } from 'react-native'\n\n/**\n * Input-modality tracker for the `focusVisible` gesture sub-state.\n *\n * Implements the W3C `:focus-visible` heuristic: a focus event counts as\n * \"visible\" only when the most recent user input was keyboard-driven. Mouse,\n * pointer, and touch events flip the modality to `'pointer'`; keyboard events\n * flip it back to `'keyboard'`.\n *\n * On native platforms there is no pointer-vs-keyboard distinction — focus\n * arrives via D-pad, screen reader, or hardware keyboard, all of which are\n * keyboard-equivalent — so `isFocusVisible()` is unconditionally `true`.\n *\n * The web listeners attach lazily on first call (capture phase, so they run\n * before the focus event reaches the focused element) and stay installed for\n * the lifetime of the document. They are passive and idle-cheap; the cost is\n * one boolean read per `onFocus` dispatch.\n */\n\ntype InputModality = 'keyboard' | 'pointer'\n\n// Default to `'keyboard'` so a programmatic / autofocus that happens before\n// any user input still draws a focus ring — matches the W3C polyfill default.\nlet modality: InputModality = 'keyboard'\nlet installed = false\n\nfunction setKeyboard() {\n modality = 'keyboard'\n}\n\nfunction setPointer() {\n modality = 'pointer'\n}\n\nfunction ensureInstalled(): void {\n if (installed) return\n if (Platform.OS !== 'web') return\n if (typeof document === 'undefined') return\n document.addEventListener('keydown', setKeyboard, true)\n document.addEventListener('mousedown', setPointer, true)\n document.addEventListener('pointerdown', setPointer, true)\n document.addEventListener('touchstart', setPointer, true)\n installed = true\n}\n\n/**\n * `true` if the next `onFocus` should be treated as \"focus-visible\" (keyboard\n * focus). On native, always `true`. On web, reflects the most recent user\n * input modality.\n */\nexport function isFocusVisible(): boolean {\n if (Platform.OS !== 'web') return true\n ensureInstalled()\n return modality === 'keyboard'\n}\n\n/** @internal — test-only hook to reset module state between cases. */\nexport function __resetFocusVisibilityForTests(next: InputModality): void {\n modality = next\n}\n","import { useCallback, useMemo } from 'react'\nimport { useSharedValue, type SharedValue } from 'react-native-reanimated'\nimport {\n resolveNamedTransitionProp,\n useNamedTransitions,\n useShouldReduceMotion,\n} from '../config'\nimport { isFocusVisible } from '../gestures'\nimport { isTopLevelTransition, resolveTransition } from '../transitions'\nimport {\n type GestureLayerTransitions,\n type TransitionConfig,\n type TransitionInput,\n} from '../types'\n\ntype LayerName = 'pressed' | 'focused' | 'focusVisible' | 'hovered'\n\n/**\n * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the\n * shared values returned alongside.\n *\n * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web\n * only — no-ops on native). `onFocus` consults `isFocusVisible()` before\n * raising the keyboard-only `focusVisible` layer; `focused` always raises.\n */\nexport interface UseGestureHandlers {\n onPressIn: () => void\n onPressOut: () => void\n onHoverIn: () => void\n onHoverOut: () => void\n onFocus: () => void\n onBlur: () => void\n}\n\nexport interface UseGestureResult {\n /** 0↔1 progress for the pressed layer. */\n pressed: SharedValue<number>\n /** 0↔1 progress for the focused layer (any focus modality). */\n focused: SharedValue<number>\n /** 0↔1 progress for the focusVisible layer (keyboard focus only). */\n focusVisible: SharedValue<number>\n /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */\n hovered: SharedValue<number>\n /** Handlers to spread on the receiving `Pressable`. */\n handlers: UseGestureHandlers\n}\n\n/**\n * Build a gesture-layer controller. The hook-form of the `gesture` prop —\n * reach for it when you need to drive multiple animated views from the same\n * gesture state (a focus ring + state-layer halo + content tint all on one\n * Pressable), which the prop-form's \"animate the receiver's own style\" model\n * can't express.\n *\n * Returns four 0↔1 shared values (one per layer) and a handler bag to spread\n * on a `Pressable`. The shared values are stable across renders — feed them\n * into any number of `useAnimatedStyle` blocks anywhere in the tree.\n *\n * Transitions follow the same shape as the `gesture` prop's accompanying\n * `transition`: pass a single `TransitionConfig` to use for every layer, or a\n * `GestureLayerTransitions` map to give each layer its own. A `TransitionName`\n * registered on the nearest `<MotionConfig transitions>` is accepted in both\n * positions (top-level and per-layer). Layers without an explicit transition\n * fall back to the library default spring.\n *\n * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every\n * transition to `no-animation` so state changes snap instead of interpolating\n * — same behaviour the gesture prop applies.\n *\n * @example\n * ```tsx\n * import { useAnimatedStyle } from 'react-native-reanimated'\n * import { useGesture } from '@rootnative/inertia'\n *\n * function Card() {\n * const { pressed, focused, hovered, handlers } = useGesture({\n * pressed: { type: 'timing', duration: 100 },\n * hovered: { type: 'timing', duration: 150 },\n * focused: { type: 'timing', duration: 200 },\n * })\n *\n * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))\n * const haloStyle = useAnimatedStyle(() => ({\n * opacity: Math.max(\n * hovered.value * 0.08,\n * focused.value * 0.10,\n * pressed.value * 0.10,\n * ),\n * }))\n *\n * return (\n * <Pressable {...handlers}>\n * <Animated.View style={ringStyle} />\n * <Animated.View style={haloStyle} />\n * </Pressable>\n * )\n * }\n * ```\n */\nexport function useGesture(\n transition?: TransitionInput | GestureLayerTransitions,\n): UseGestureResult {\n const pressed = useSharedValue(0)\n const focused = useSharedValue(0)\n const focusVisible = useSharedValue(0)\n const hovered = useSharedValue(0)\n const shouldReduceMotion = useShouldReduceMotion()\n // Registered transition names (top-level string or per-layer string values)\n // resolve against the nearest <MotionConfig transitions> at render time, so\n // the callbacks below only ever see concrete configs.\n const resolved = resolveNamedTransitionProp(transition, useNamedTransitions())\n\n const setLayer = useCallback(\n (sv: SharedValue<number>, layer: LayerName, target: 0 | 1) => {\n const cfg = shouldReduceMotion\n ? ({ type: 'no-animation' } as const)\n : (layerTransition(layer, resolved) ?? ({ type: 'spring' } as const))\n sv.value = resolveTransition(cfg, target) as never\n },\n // The transition is intentionally read on every call rather than cooked\n // into the dep array — a fresh literal each render would otherwise\n // rebuild the handler bag and break composing consumers that key off\n // handler identity. `transition` is read inside the callback closure;\n // shared values are stable so the only dep that matters is the reduce-\n // motion flag.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [shouldReduceMotion],\n )\n\n const handlers = useMemo<UseGestureHandlers>(\n () => ({\n onPressIn: () => setLayer(pressed, 'pressed', 1),\n onPressOut: () => setLayer(pressed, 'pressed', 0),\n onHoverIn: () => setLayer(hovered, 'hovered', 1),\n onHoverOut: () => setLayer(hovered, 'hovered', 0),\n onFocus: () => {\n setLayer(focused, 'focused', 1)\n if (isFocusVisible()) setLayer(focusVisible, 'focusVisible', 1)\n },\n onBlur: () => {\n setLayer(focused, 'focused', 0)\n setLayer(focusVisible, 'focusVisible', 0)\n },\n }),\n [setLayer, pressed, focused, focusVisible, hovered],\n )\n\n return { pressed, focused, focusVisible, hovered, handlers }\n}\n\n// Runs after name resolution, so the `TransitionInput` values on the map form\n// are concrete configs by the time they're read — hence the return cast.\nfunction layerTransition(\n layer: LayerName,\n transition: TransitionConfig | GestureLayerTransitions | undefined,\n): TransitionConfig | undefined {\n if (!transition) return undefined\n if (isTopLevelTransition(transition)) return transition\n return (transition as GestureLayerTransitions)[layer] as\n | TransitionConfig\n | undefined\n}\n","import { useEffect, useMemo } from 'react'\nimport {\n interpolateColor,\n useAnimatedStyle,\n useSharedValue,\n type AnimatedStyle,\n} from 'react-native-reanimated'\nimport {\n resolveNamedTransitionProp,\n useNamedTransitions,\n useShouldReduceMotion,\n} from '../config'\nimport {\n isTopLevelTransition,\n resolveTransition,\n stableSig,\n} from '../transitions'\nimport { useGesture, type UseGestureHandlers } from '../values/useGesture'\nimport {\n type GestureLayerTransitions,\n type TransitionConfig,\n type TransitionInput,\n} from '../types'\n\n/**\n * A single gesture-layer style — a flat map of style keys to a value. Numeric\n * values participate in clamped-max composition (the \"strongest active layer\n * wins\" model used by MD3 state-layer haloes); string values are treated as\n * colors and composed via priority cascade with `interpolateColor`.\n *\n * The hook does not validate that string values are valid colors — passing\n * something like `borderStyle: 'solid'` will crash inside the worklet. Keep\n * string values to color strings.\n */\nexport type GestureLayerStyle = {\n [key: string]: number | string | undefined\n}\n\n/**\n * Per-state style maps. Every key is optional; missing layers default to\n * `rest` (or `0` / `'transparent'` if `rest` is also absent for that key).\n *\n * - `rest` — base values, applied when no other layer is active.\n * - `hovered` / `focused` / `focusVisible` / `pressed` — gesture-driven\n * states tracked via the underlying `useGesture` hook. Each owns an\n * independent 0↔1 progress that fades the layer in/out per the configured\n * transition.\n * - `disabled` — gated by the JS-side `options.disabled` flag rather than a\n * gesture. Sits at the top of the priority cascade and overrides every\n * gesture layer when active.\n */\nexport interface GestureLayerStates {\n rest?: GestureLayerStyle\n hovered?: GestureLayerStyle\n focused?: GestureLayerStyle\n focusVisible?: GestureLayerStyle\n pressed?: GestureLayerStyle\n disabled?: GestureLayerStyle\n}\n\nexport interface UseGestureLayerOptions {\n /**\n * When `true`, the `disabled` layer becomes active (or `rest` if `disabled`\n * is undefined). Animates via the top-level transition or the library\n * default spring; per-layer transitions (`GestureLayerTransitions`) do not\n * apply to `disabled`.\n */\n disabled?: boolean\n /**\n * Transition forwarded to the underlying `useGesture` hook. Either a single\n * `TransitionConfig` for every gesture layer, or a `GestureLayerTransitions`\n * map for per-layer fades. A `TransitionName` registered on the nearest\n * `<MotionConfig transitions>` is accepted in both positions. Reduced\n * motion collapses every transition to `no-animation`.\n */\n transition?: TransitionInput | GestureLayerTransitions\n}\n\nexport interface UseGestureLayerResult {\n /**\n * Animated style produced by `useAnimatedStyle` — spread on an\n * `Animated.View` or pass through `<Motion.View style={...} />`.\n */\n style: AnimatedStyle<Record<string, unknown>>\n /** Handlers to spread on the receiving `Pressable`. */\n handlers: UseGestureHandlers\n}\n\n/**\n * A \"strongest active layer wins\" interactive-feedback primitive. Sits one\n * step above `useGesture()` — the consumer supplies the per-state target\n * values, the hook handles the four gesture progress shared values, the\n * disabled override, the worklet, and the transition.\n *\n * Composition model:\n *\n * - **Numeric keys** (opacity, scale, borderWidth, etc.) compose via\n * clamped-max with `rest` as the floor:\n * `out = max(rest, ...for each active gesture layer: lerp(rest, layer, progress))`.\n * This matches the MD3 state-layer halo pattern — multiple states active\n * simultaneously raise the value to the strongest, not the sum.\n * - **Color keys** (any string value) compose via priority cascade with\n * `interpolateColor`, lowest priority first: `hovered → focused →\n * focusVisible → pressed`. Clamped-max doesn't apply to colors; this\n * matches the cascade used by the declarative `gesture` prop.\n * - **Disabled** sits at the top of the cascade for both numeric and color\n * keys — when active, it lerps the composed value toward the `disabled`\n * target.\n *\n * Reach for this when you want MD3 / iOS-translucent state-layer overlays\n * without rewriting the worklet by hand for every consumer; reach for plain\n * `useGesture()` when you need a composition model this hook doesn't\n * express (additive, multiply, per-key custom blends).\n *\n * @example MD3 state-layer halo\n * ```tsx\n * import { useGestureLayer } from '@rootnative/inertia/gesture-layer'\n * import Animated from 'react-native-reanimated'\n * import { Pressable } from 'react-native'\n *\n * function SwitchHalo({ disabled }: { disabled?: boolean }) {\n * const { style, handlers } = useGestureLayer(\n * {\n * rest: { opacity: 0, backgroundColor: 'transparent' },\n * hovered: { opacity: 0.08, backgroundColor: '#000' },\n * focused: { opacity: 0.10, backgroundColor: '#000' },\n * pressed: { opacity: 0.12, backgroundColor: '#000' },\n * },\n * { disabled, transition: { type: 'timing', duration: 150 } },\n * )\n *\n * return (\n * <Pressable {...handlers}>\n * <Animated.View style={style} />\n * </Pressable>\n * )\n * }\n * ```\n */\nexport function useGestureLayer(\n states: GestureLayerStates,\n options: UseGestureLayerOptions = {},\n): UseGestureLayerResult {\n const { disabled: isDisabled = false, transition: transitionInput } = options\n const shouldReduceMotion = useShouldReduceMotion()\n // Resolve registered names here (not just in useGesture) because the\n // `disabled` layer reads the top-level transition locally. Identity is\n // preserved when no names are present; when a name resolves, the effect\n // below keys on the structural signature so a per-render resolve of the\n // map form doesn't re-fire it.\n const transition = resolveNamedTransitionProp(\n transitionInput,\n useNamedTransitions(),\n )\n const gesture = useGesture(transition)\n const disabledProgress = useSharedValue(0)\n\n const transitionSig = stableSig(transition)\n useEffect(() => {\n const target = isDisabled ? 1 : 0\n const cfg = shouldReduceMotion\n ? ({ type: 'no-animation' } as const)\n : (disabledTransition(transition) ?? ({ type: 'spring' } as const))\n disabledProgress.value = resolveTransition(cfg, target) as never\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress])\n\n // JS-thread precompute: union of keys across all layers, per-key type\n // (number vs color), and a rest-fallback table. The worklet body reads\n // from `meta` instead of probing each layer per frame — the type check\n // only runs when layer identities change.\n const meta = useMemo(() => {\n const layers = {\n rest: states.rest,\n hovered: states.hovered,\n focused: states.focused,\n focusVisible: states.focusVisible,\n pressed: states.pressed,\n disabled: states.disabled,\n }\n const sources = [\n layers.rest,\n layers.hovered,\n layers.focused,\n layers.focusVisible,\n layers.pressed,\n layers.disabled,\n ]\n const keySet = new Set<string>()\n for (const src of sources) {\n if (!src) continue\n for (const k in src) if (src[k] !== undefined) keySet.add(k)\n }\n const keys = Array.from(keySet)\n const types: Record<string, 'number' | 'color'> = {}\n const restValues: Record<string, number | string> = {}\n for (const k of keys) {\n let firstDefined: number | string | undefined\n for (const src of sources) {\n if (src && src[k] !== undefined) {\n firstDefined = src[k]\n break\n }\n }\n const isColor = typeof firstDefined === 'string'\n types[k] = isColor ? 'color' : 'number'\n const restRaw = layers.rest ? layers.rest[k] : undefined\n restValues[k] =\n restRaw !== undefined ? restRaw : isColor ? 'transparent' : 0\n }\n return { layers, keys, types, restValues }\n }, [\n states.rest,\n states.hovered,\n states.focused,\n states.focusVisible,\n states.pressed,\n states.disabled,\n ])\n\n const style = useAnimatedStyle(() => {\n const { layers, keys, types, restValues } = meta\n const ph = gesture.hovered.value\n const pf = gesture.focused.value\n const pfv = gesture.focusVisible.value\n const pp = gesture.pressed.value\n const pd = disabledProgress.value\n\n const hoveredLayer = layers.hovered\n const focusedLayer = layers.focused\n const focusVisibleLayer = layers.focusVisible\n const pressedLayer = layers.pressed\n const disabledLayer = layers.disabled\n\n const out: Record<string, unknown> = {}\n\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i]!\n const isColor = types[k] === 'color'\n const rest = restValues[k]!\n\n if (isColor) {\n let v = rest as string\n if (hoveredLayer && ph > 0 && hoveredLayer[k] !== undefined) {\n v = interpolateColor(ph, [0, 1], [v, hoveredLayer[k] as string])\n }\n if (focusedLayer && pf > 0 && focusedLayer[k] !== undefined) {\n v = interpolateColor(pf, [0, 1], [v, focusedLayer[k] as string])\n }\n if (\n focusVisibleLayer &&\n pfv > 0 &&\n focusVisibleLayer[k] !== undefined\n ) {\n v = interpolateColor(pfv, [0, 1], [v, focusVisibleLayer[k] as string])\n }\n if (pressedLayer && pp > 0 && pressedLayer[k] !== undefined) {\n v = interpolateColor(pp, [0, 1], [v, pressedLayer[k] as string])\n }\n if (disabledLayer && pd > 0 && disabledLayer[k] !== undefined) {\n v = interpolateColor(pd, [0, 1], [v, disabledLayer[k] as string])\n }\n out[k] = v\n } else {\n const base = rest as number\n let m = base\n if (hoveredLayer && ph > 0 && hoveredLayer[k] !== undefined) {\n const c = base + ((hoveredLayer[k] as number) - base) * ph\n if (c > m) m = c\n }\n if (focusedLayer && pf > 0 && focusedLayer[k] !== undefined) {\n const c = base + ((focusedLayer[k] as number) - base) * pf\n if (c > m) m = c\n }\n if (\n focusVisibleLayer &&\n pfv > 0 &&\n focusVisibleLayer[k] !== undefined\n ) {\n const c = base + ((focusVisibleLayer[k] as number) - base) * pfv\n if (c > m) m = c\n }\n if (pressedLayer && pp > 0 && pressedLayer[k] !== undefined) {\n const c = base + ((pressedLayer[k] as number) - base) * pp\n if (c > m) m = c\n }\n if (disabledLayer && pd > 0 && disabledLayer[k] !== undefined) {\n m = m + ((disabledLayer[k] as number) - m) * pd\n }\n out[k] = m\n }\n }\n\n return out\n })\n\n return {\n style: style as AnimatedStyle<Record<string, unknown>>,\n handlers: gesture.handlers,\n }\n}\n\nfunction disabledTransition(\n transition: TransitionConfig | GestureLayerTransitions | undefined,\n): TransitionConfig | undefined {\n if (!transition) return undefined\n if (isTopLevelTransition(transition)) return transition\n return undefined\n}\n"]}
@@ -4,8 +4,31 @@ import { isWorkletFunction } from 'react-native-worklets';
4
4
  import { Platform } from 'react-native';
5
5
 
6
6
  // src/gestureLayer/useGestureLayer.ts
7
+
8
+ // src/transitions/sig.ts
9
+ function stableSig(value) {
10
+ if (value === void 0) return "";
11
+ try {
12
+ return stableStringify(value);
13
+ } catch {
14
+ return String(value);
15
+ }
16
+ }
17
+ function stableStringify(v) {
18
+ if (v === null || typeof v !== "object") {
19
+ if (typeof v === "function" || v === void 0) return "null";
20
+ return JSON.stringify(v);
21
+ }
22
+ if (Array.isArray(v)) {
23
+ return "[" + v.map(stableStringify).join(",") + "]";
24
+ }
25
+ const obj = v;
26
+ const keys = Object.keys(obj).sort();
27
+ return "{" + keys.map((k) => JSON.stringify(k) + ":" + stableStringify(obj[k])).join(",") + "}";
28
+ }
7
29
  var DEFAULT_MOTION_CONFIG = {
8
- reducedMotion: "user"
30
+ reducedMotion: "user",
31
+ transitions: {}
9
32
  };
10
33
  var MotionConfigContext = createContext(
11
34
  DEFAULT_MOTION_CONFIG
@@ -13,6 +36,9 @@ var MotionConfigContext = createContext(
13
36
  function useMotionConfig() {
14
37
  return useContext(MotionConfigContext);
15
38
  }
39
+ function useNamedTransitions() {
40
+ return useMotionConfig().transitions;
41
+ }
16
42
  function useShouldReduceMotion() {
17
43
  const { reducedMotion } = useMotionConfig();
18
44
  const osReduced = useReducedMotion();
@@ -20,6 +46,59 @@ function useShouldReduceMotion() {
20
46
  if (reducedMotion === "always") return true;
21
47
  return osReduced;
22
48
  }
49
+
50
+ // src/transitions/keys.ts
51
+ var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
52
+ "type",
53
+ "tension",
54
+ "friction",
55
+ "mass",
56
+ "velocity",
57
+ "restSpeedThreshold",
58
+ "restDisplacementThreshold",
59
+ "duration",
60
+ "easing",
61
+ "delay",
62
+ "repeat",
63
+ "deceleration",
64
+ "clamp"
65
+ ]);
66
+ function isTopLevelTransition(t) {
67
+ if (t === null || typeof t !== "object") return false;
68
+ const keys = Object.keys(t);
69
+ if (keys.length === 0) return false;
70
+ return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
71
+ }
72
+
73
+ // src/config/namedTransitions.ts
74
+ var UNKNOWN_NAME_FALLBACK = { type: "spring" };
75
+ function lookupNamedTransition(name, registry) {
76
+ const cfg = registry[name];
77
+ if (cfg) return cfg;
78
+ if (__DEV__) {
79
+ console.warn(
80
+ `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
81
+ );
82
+ }
83
+ return UNKNOWN_NAME_FALLBACK;
84
+ }
85
+ function resolveNamedTransitionProp(transition, registry) {
86
+ if (transition === void 0) return void 0;
87
+ if (typeof transition === "string") {
88
+ return lookupNamedTransition(transition, registry);
89
+ }
90
+ if (isTopLevelTransition(transition)) return transition;
91
+ const map = transition;
92
+ let out = null;
93
+ for (const key in map) {
94
+ const value = map[key];
95
+ if (typeof value === "string") {
96
+ if (out === null) out = { ...map };
97
+ out[key] = lookupNamedTransition(value, registry);
98
+ }
99
+ }
100
+ return out ?? transition;
101
+ }
23
102
  function ensureWorkletEasing(easing) {
24
103
  if (!easing) return void 0;
25
104
  const fn = isEasingFactory(easing) ? easing.factory() : easing;
@@ -115,29 +194,6 @@ function delayOf(cfg) {
115
194
  if (cfg.type === "no-animation") return void 0;
116
195
  return cfg.delay;
117
196
  }
118
-
119
- // src/transitions/keys.ts
120
- var TRANSITION_CONFIG_KEYS = /* @__PURE__ */ new Set([
121
- "type",
122
- "tension",
123
- "friction",
124
- "mass",
125
- "velocity",
126
- "restSpeedThreshold",
127
- "restDisplacementThreshold",
128
- "duration",
129
- "easing",
130
- "delay",
131
- "repeat",
132
- "deceleration",
133
- "clamp"
134
- ]);
135
- function isTopLevelTransition(t) {
136
- if (t === null || typeof t !== "object") return false;
137
- const keys = Object.keys(t);
138
- if (keys.length === 0) return false;
139
- return keys.every((k) => TRANSITION_CONFIG_KEYS.has(k));
140
- }
141
197
  var modality = "keyboard";
142
198
  var installed = false;
143
199
  function setKeyboard() {
@@ -169,9 +225,10 @@ function useGesture(transition) {
169
225
  const focusVisible = useSharedValue(0);
170
226
  const hovered = useSharedValue(0);
171
227
  const shouldReduceMotion = useShouldReduceMotion();
228
+ const resolved = resolveNamedTransitionProp(transition, useNamedTransitions());
172
229
  const setLayer = useCallback(
173
230
  (sv, layer, target) => {
174
- const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, transition) ?? { type: "spring" };
231
+ const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
175
232
  sv.value = resolveTransition(cfg, target);
176
233
  },
177
234
  // The transition is intentionally read on every call rather than cooked
@@ -210,15 +267,20 @@ function layerTransition(layer, transition) {
210
267
 
211
268
  // src/gestureLayer/useGestureLayer.ts
212
269
  function useGestureLayer(states, options = {}) {
213
- const { disabled: isDisabled = false, transition } = options;
270
+ const { disabled: isDisabled = false, transition: transitionInput } = options;
214
271
  const shouldReduceMotion = useShouldReduceMotion();
272
+ const transition = resolveNamedTransitionProp(
273
+ transitionInput,
274
+ useNamedTransitions()
275
+ );
215
276
  const gesture = useGesture(transition);
216
277
  const disabledProgress = useSharedValue(0);
278
+ const transitionSig = stableSig(transition);
217
279
  useEffect(() => {
218
280
  const target = isDisabled ? 1 : 0;
219
281
  const cfg = shouldReduceMotion ? { type: "no-animation" } : disabledTransition(transition) ?? { type: "spring" };
220
282
  disabledProgress.value = resolveTransition(cfg, target);
221
- }, [isDisabled, shouldReduceMotion, transition, disabledProgress]);
283
+ }, [isDisabled, shouldReduceMotion, transitionSig, disabledProgress]);
222
284
  const meta = useMemo(() => {
223
285
  const layers = {
224
286
  rest: states.rest,