@rootnative/inertia 0.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +131 -0
  4. package/dist/gestureLayer/index.d.mts +119 -0
  5. package/dist/gestureLayer/index.d.ts +119 -0
  6. package/dist/gestureLayer/index.js +346 -0
  7. package/dist/gestureLayer/index.js.map +1 -0
  8. package/dist/gestureLayer/index.mjs +344 -0
  9. package/dist/gestureLayer/index.mjs.map +1 -0
  10. package/dist/index.d.mts +507 -0
  11. package/dist/index.d.ts +507 -0
  12. package/dist/index.js +1546 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/index.mjs +1515 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/dist/motion/Image.d.mts +12 -0
  17. package/dist/motion/Image.d.ts +12 -0
  18. package/dist/motion/Image.js +1138 -0
  19. package/dist/motion/Image.js.map +1 -0
  20. package/dist/motion/Image.mjs +1132 -0
  21. package/dist/motion/Image.mjs.map +1 -0
  22. package/dist/motion/Pressable.d.mts +15 -0
  23. package/dist/motion/Pressable.d.ts +15 -0
  24. package/dist/motion/Pressable.js +1138 -0
  25. package/dist/motion/Pressable.js.map +1 -0
  26. package/dist/motion/Pressable.mjs +1132 -0
  27. package/dist/motion/Pressable.mjs.map +1 -0
  28. package/dist/motion/ScrollView.d.mts +12 -0
  29. package/dist/motion/ScrollView.d.ts +12 -0
  30. package/dist/motion/ScrollView.js +1138 -0
  31. package/dist/motion/ScrollView.js.map +1 -0
  32. package/dist/motion/ScrollView.mjs +1132 -0
  33. package/dist/motion/ScrollView.mjs.map +1 -0
  34. package/dist/motion/Text.d.mts +11 -0
  35. package/dist/motion/Text.d.ts +11 -0
  36. package/dist/motion/Text.js +1138 -0
  37. package/dist/motion/Text.js.map +1 -0
  38. package/dist/motion/Text.mjs +1132 -0
  39. package/dist/motion/Text.mjs.map +1 -0
  40. package/dist/motion/View.d.mts +11 -0
  41. package/dist/motion/View.d.ts +11 -0
  42. package/dist/motion/View.js +1138 -0
  43. package/dist/motion/View.js.map +1 -0
  44. package/dist/motion/View.mjs +1132 -0
  45. package/dist/motion/View.mjs.map +1 -0
  46. package/dist/testing/index.d.mts +57 -0
  47. package/dist/testing/index.d.ts +57 -0
  48. package/dist/testing/index.js +19 -0
  49. package/dist/testing/index.js.map +1 -0
  50. package/dist/testing/index.mjs +16 -0
  51. package/dist/testing/index.mjs.map +1 -0
  52. package/dist/touch/index.d.mts +146 -0
  53. package/dist/touch/index.d.ts +146 -0
  54. package/dist/touch/index.js +166 -0
  55. package/dist/touch/index.js.map +1 -0
  56. package/dist/touch/index.mjs +164 -0
  57. package/dist/touch/index.mjs.map +1 -0
  58. package/dist/types-cU43dEmH.d.mts +339 -0
  59. package/dist/types-cU43dEmH.d.ts +339 -0
  60. package/dist/useGesture-BnY65PlQ.d.ts +84 -0
  61. package/dist/useGesture-DxtXdz-K.d.mts +84 -0
  62. package/jest-preset.js +33 -0
  63. package/jest-setup.js +213 -0
  64. package/llms.txt +142 -0
  65. package/package.json +151 -0
  66. package/src/__type-tests__/animate.test-d.tsx +88 -0
  67. package/src/__type-tests__/variants.test-d.tsx +67 -0
  68. package/src/config/MotionConfig.tsx +30 -0
  69. package/src/config/MotionConfigContext.ts +53 -0
  70. package/src/config/index.ts +9 -0
  71. package/src/gestureLayer/index.ts +21 -0
  72. package/src/gestureLayer/useGestureLayer.ts +285 -0
  73. package/src/gestures/focusVisibility.ts +61 -0
  74. package/src/gestures/index.ts +1 -0
  75. package/src/index.ts +72 -0
  76. package/src/layout/index.ts +16 -0
  77. package/src/layout/resolveLayout.ts +54 -0
  78. package/src/layout/sharedRegistry.ts +111 -0
  79. package/src/layout/useSharedLayout.ts +289 -0
  80. package/src/motion/Image.tsx +9 -0
  81. package/src/motion/Pressable.tsx +12 -0
  82. package/src/motion/ScrollView.tsx +9 -0
  83. package/src/motion/Text.tsx +8 -0
  84. package/src/motion/View.tsx +8 -0
  85. package/src/motion/createMotionComponent.tsx +1306 -0
  86. package/src/motion/index.ts +26 -0
  87. package/src/motion/installCheck.ts +65 -0
  88. package/src/presence/Presence.tsx +165 -0
  89. package/src/presence/PresenceContext.ts +28 -0
  90. package/src/presence/index.ts +6 -0
  91. package/src/testing/index.ts +78 -0
  92. package/src/touch/index.ts +18 -0
  93. package/src/touch/useTouchDrag.ts +289 -0
  94. package/src/transitions/easing.ts +53 -0
  95. package/src/transitions/index.ts +7 -0
  96. package/src/transitions/keys.ts +32 -0
  97. package/src/transitions/resolve.ts +169 -0
  98. package/src/transitions/resolveSequence.ts +87 -0
  99. package/src/transitions/runtime.ts +63 -0
  100. package/src/transitions/sig.ts +40 -0
  101. package/src/transitions/spring.ts +42 -0
  102. package/src/types.ts +383 -0
  103. package/src/values/index.ts +26 -0
  104. package/src/values/useAnimation.ts +69 -0
  105. package/src/values/useBooleanSpring.ts +33 -0
  106. package/src/values/useColorTransition.ts +72 -0
  107. package/src/values/useGesture.ts +144 -0
  108. package/src/values/useMotionValue.ts +33 -0
  109. package/src/values/useScroll.ts +72 -0
  110. package/src/values/useShadow.ts +116 -0
  111. package/src/values/useSpring.ts +98 -0
  112. package/src/values/useTransform.ts +132 -0
  113. package/src/values/useVariants.ts +60 -0
@@ -0,0 +1,339 @@
1
+ import { ComponentType, ComponentProps, Ref, ReactElement } from 'react';
2
+ import { StyleProp } from 'react-native';
3
+
4
+ /**
5
+ * A single animation step's destination, optionally overriding the transition
6
+ * for that step.
7
+ */
8
+ type SequenceStep<V> = V | ({
9
+ to: V;
10
+ delay?: number;
11
+ } & TransitionConfig);
12
+ /**
13
+ * A target value for an animatable property: a single value, a sequence of
14
+ * steps (keyframes), or a single step object.
15
+ */
16
+ type AnimatableValue<V> = V | SequenceStep<V> | ReadonlyArray<SequenceStep<V>>;
17
+ /**
18
+ * Spring transition — public surface uses react-spring vocabulary
19
+ * (`tension` / `friction` / `mass`), not Reanimated's raw stiffness/damping.
20
+ */
21
+ interface SpringTransition {
22
+ type?: 'spring';
23
+ tension?: number;
24
+ friction?: number;
25
+ mass?: number;
26
+ velocity?: number;
27
+ restSpeedThreshold?: number;
28
+ restDisplacementThreshold?: number;
29
+ delay?: number;
30
+ repeat?: RepeatConfig;
31
+ }
32
+ /**
33
+ * Easing input accepted by `TimingTransition`. Either a plain easing function
34
+ * `(t: number) => number` (the pre-Reanimated-4 shape and the shape consumers
35
+ * author by hand) or an `EasingFunctionFactory` (the Reanimated 4 shape
36
+ * returned by `Easing.bezier(...)` and similar builders). The resolver
37
+ * unwraps the factory automatically — consumers don't have to call
38
+ * `.factory()` themselves.
39
+ */
40
+ type EasingFunction = (t: number) => number;
41
+ interface EasingFunctionFactory {
42
+ factory: () => EasingFunction;
43
+ }
44
+ type EasingInput = EasingFunction | EasingFunctionFactory;
45
+ interface TimingTransition {
46
+ type: 'timing';
47
+ duration?: number;
48
+ easing?: EasingInput;
49
+ delay?: number;
50
+ repeat?: RepeatConfig;
51
+ }
52
+ interface DecayTransition {
53
+ type: 'decay';
54
+ velocity?: number;
55
+ deceleration?: number;
56
+ clamp?: [number, number];
57
+ delay?: number;
58
+ }
59
+ interface NoAnimationTransition {
60
+ type: 'no-animation';
61
+ }
62
+ type TransitionConfig = SpringTransition | TimingTransition | DecayTransition | NoAnimationTransition;
63
+ /**
64
+ * Repeat config — one shape, not three flags. Default `alternate: true`.
65
+ */
66
+ type RepeatConfig = number | 'infinite' | {
67
+ count: number | 'infinite';
68
+ alternate?: boolean;
69
+ };
70
+ /**
71
+ * Per-property transition map. Keys must match keys present on `animate`.
72
+ * Top-level entries on `transition` apply to all properties unless overridden
73
+ * here.
74
+ */
75
+ type PerPropertyTransition<S> = {
76
+ [K in keyof S]?: TransitionConfig;
77
+ };
78
+ /**
79
+ * Per-gesture-layer transition map. Each `gesture` sub-state animates a
80
+ * progress value 0↔1 with its own transition; the worklet composites the
81
+ * layers in priority order (`hovered → focused → focusVisible → pressed`).
82
+ *
83
+ * Keys live on the same `transition` object as `PerPropertyTransition` because
84
+ * the only other place they could go (nested inside `gesture` itself) would
85
+ * collide with the primitive's inferred style keys.
86
+ */
87
+ interface GestureLayerTransitions {
88
+ pressed?: TransitionConfig;
89
+ focused?: TransitionConfig;
90
+ focusVisible?: TransitionConfig;
91
+ hovered?: TransitionConfig;
92
+ }
93
+ type Transition<S> = TransitionConfig | (PerPropertyTransition<S> & GestureLayerTransitions);
94
+ /**
95
+ * Transform shorthands that Inertia exposes on `animate` but that don't
96
+ * appear on RN's typed ViewStyle as top-level keys. RN keeps `scale`,
97
+ * `rotate`, `rotateX`, and `rotateY` inside the `transform` array; only
98
+ * `scaleX`/`scaleY` and `translateX`/`translateY` are surfaced as
99
+ * (deprecated) top-level shortcuts. Inertia's runtime treats these as
100
+ * transform-group keys (see `TRANSFORM_KEYS` in `createMotionComponent`),
101
+ * so they're documented as first-class animatables in `CLAUDE.md` and must
102
+ * be reachable from `animate` without dropping into the `transform: [...]`
103
+ * array form. Rotation values are degrees as numbers — the runtime appends
104
+ * `'deg'` before handing the transform to Reanimated.
105
+ */
106
+ type AnimatableTransformExtras = {
107
+ scale?: AnimatableValue<number>;
108
+ rotate?: AnimatableValue<number>;
109
+ rotateX?: AnimatableValue<number>;
110
+ rotateY?: AnimatableValue<number>;
111
+ };
112
+ /**
113
+ * The animation state shape inferred from the underlying component's style
114
+ * prop. We narrow to the value side of `style` so consumers see ViewStyle on
115
+ * `Motion.View`, TextStyle on `Motion.Text`, etc. — no shared union.
116
+ *
117
+ * Some components (notably `Pressable`) type `style` as a union of
118
+ * `StyleProp<T>` and a callback `(state) => StyleProp<T>`. If we infer `S`
119
+ * directly from `StyleProp<infer S>`, the callback branch widens `S` to
120
+ * `unknown`, which collapses the animate map to `| {}` and silently
121
+ * accepts any key. Excluding functions first keeps inference tight.
122
+ */
123
+ type _StyleValue<T> = Exclude<T, (...args: any[]) => any>;
124
+ type AnimateStyle<C> = C extends {
125
+ style?: infer Raw;
126
+ } ? _StyleValue<Raw> extends StyleProp<infer S> ? {
127
+ [K in keyof S]?: AnimatableValue<S[K]>;
128
+ } & AnimatableTransformExtras : never : never;
129
+ interface AnimationCallbackInfo<S> {
130
+ /**
131
+ * The animatable key that just settled — typically a `keyof S` (e.g.
132
+ * `'opacity'`, `'translateX'`). The sentinel `'transform'` is emitted in
133
+ * lieu of any specific transform axis (`translateX`/`Y`, `scale`/`X`/`Y`,
134
+ * `rotate`) when the terminal `'animation'` phase fires for a transform
135
+ * group, so a multi-axis translate produces one callback rather than two.
136
+ */
137
+ key: keyof S | 'transform';
138
+ finished: boolean;
139
+ value: unknown;
140
+ target: unknown;
141
+ phase: 'step' | 'sequence' | 'repeat' | 'animation';
142
+ step: number | undefined;
143
+ iteration: number;
144
+ }
145
+ /**
146
+ * A variants map: string state names → animate target objects.
147
+ */
148
+ type VariantsMap<C> = Record<string, AnimateStyle<C>>;
149
+ /**
150
+ * Gesture sub-states accepted by the `gesture` prop on every Motion primitive.
151
+ *
152
+ * - `pressed` — active while the user is touching the component (touch start
153
+ * to touch end / cancel).
154
+ * - `focused` — active while a focusable component owns focus, regardless of
155
+ * how focus arrived (mouse, touch, or keyboard). No-op for non-focusable
156
+ * underlying components.
157
+ * - `focusVisible` — active only when focus arrived from the keyboard
158
+ * (W3C `:focus-visible` semantics). Use this for focus rings to avoid
159
+ * flashing them on click-focus on web. On native — where focus always
160
+ * arrives via D-pad, screen reader, or hardware keyboard — this behaves
161
+ * identically to `focused`.
162
+ * - `hovered` — web-only. Typed for cross-platform call sites; the runtime is
163
+ * a no-op on native.
164
+ *
165
+ * Sub-states layer additively. Each declared sub-state owns an independent
166
+ * progress value (0↔1) that animates in/out with its own transition; the
167
+ * worklet composites layers in priority order (lowest-to-highest):
168
+ * `hovered → focused → focusVisible → pressed`. Per-property the chain is
169
+ *
170
+ * v = base
171
+ * v = lerp(v, hovered.value, progressHovered) // if declared
172
+ * v = lerp(v, focused.value, progressFocused) // if declared
173
+ * v = lerp(v, focusVisible.value, progressFocusVisible) // if declared
174
+ * v = lerp(v, pressed.value, progressPressed) // if declared
175
+ *
176
+ * (Color-valued keys use `interpolateColor` instead of `lerp`.) When a single
177
+ * sub-state is active, this collapses to "the highest-priority declared layer
178
+ * wins". When multiple are mid-transition (e.g. release-while-still-hovered)
179
+ * each layer fades independently — a press layer fading out at 50ms while a
180
+ * hover layer holds at full opacity matches MD3 state-layer semantics.
181
+ *
182
+ * Configure per-layer fade timing via `transition.<stateName>` on the parent
183
+ * primitive (see `GestureLayerTransitions`); without it, layers default to
184
+ * the parent transition or the library default spring.
185
+ *
186
+ * **Priority cascade is the only composition mode on this prop.** Non-priority
187
+ * blends — clamped-max (`Math.max(hover*α, focus*β, press*γ)`, as used by MD3
188
+ * state-layer haloes), additive accumulation, or any per-key custom blend —
189
+ * are not expressible declaratively. Drop to `useGesture()` for those: it
190
+ * returns the four progress shared values and a handler bag, and you write
191
+ * a `useAnimatedStyle` block with whatever composition you need. The hook's
192
+ * JSDoc shows the clamped-max halo pattern in full.
193
+ */
194
+ interface GestureSubStates<C> {
195
+ pressed?: AnimateStyle<C>;
196
+ focused?: AnimateStyle<C>;
197
+ focusVisible?: AnimateStyle<C>;
198
+ hovered?: AnimateStyle<C>;
199
+ }
200
+ /**
201
+ * Controller returned by `useVariants`. The `current` shared state is read
202
+ * via `controller` prop on a Motion primitive; `transitionTo` drives the
203
+ * controller from JS code (event handlers, async chains, etc.).
204
+ */
205
+ interface VariantController<K extends string = string> {
206
+ current: K;
207
+ transitionTo(next: K): void;
208
+ /** @internal — subscription used by Motion primitives to re-render. */
209
+ subscribe(listener: (next: K) => void): () => void;
210
+ }
211
+ /**
212
+ * Props injected onto every Motion primitive.
213
+ *
214
+ * The second type parameter `V` is the concrete `variants` map. It is inferred
215
+ * from the `variants` prop at each JSX use (see `MotionComponent`), which is
216
+ * what lets `animate` narrow to the variant key union and reject typos. When
217
+ * no `variants` prop is passed, `V` falls back to `VariantsMap<C>` — whose key
218
+ * type is the open `string`, so `animate` still accepts any string and nothing
219
+ * regresses for the variant-less case.
220
+ */
221
+ interface MotionProps<C, V extends VariantsMap<C> = VariantsMap<C>> {
222
+ /**
223
+ * Initial values applied on mount. Read once on mount and intentionally
224
+ * non-reactive — to reset after a state change, change the component `key`,
225
+ * remount via `<Presence>`, or drive the value through a controller.
226
+ *
227
+ * Pass `false` to skip the initial-mount animation entirely.
228
+ */
229
+ initial?: AnimateStyle<C> | false;
230
+ /**
231
+ * The animation target. A style object, a variant key (when `variants` is
232
+ * supplied), or an array of sequence steps. When `variants` is set, the
233
+ * string form is narrowed to the map's keys, so a key typo is a compile
234
+ * error and the keys autocomplete — no `as const` required.
235
+ */
236
+ animate?: AnimateStyle<C> | (keyof V & string);
237
+ /**
238
+ * Values applied while the component exits via `<Presence>`.
239
+ */
240
+ exit?: AnimateStyle<C>;
241
+ /**
242
+ * Named animation states. With `variants` set, `animate` accepts a key from
243
+ * this map.
244
+ */
245
+ variants?: V;
246
+ /**
247
+ * Imperative controller from `useVariants(...)`. When supplied, `animate`
248
+ * is read from `controller.current` and re-applied whenever the controller
249
+ * transitions. `animate` and `controller` should not both be set.
250
+ */
251
+ controller?: VariantController<keyof V & string>;
252
+ /**
253
+ * Gesture-driven sub-states (`pressed`, `focused`, `focusVisible`,
254
+ * `hovered`). When omitted, no handlers are mounted on the underlying
255
+ * component. Each declared sub-state animates as an independent layer
256
+ * fading in/out over the base `animate` target — see `GestureSubStates`
257
+ * for the composition model and per-layer transition wiring.
258
+ */
259
+ gesture?: GestureSubStates<C>;
260
+ /**
261
+ * Per-property or top-level transition config. Per-property entries take
262
+ * precedence over the top-level transition.
263
+ */
264
+ transition?: Transition<AnimateStyle<C>>;
265
+ /**
266
+ * Auto-layout animation. When the component's position or size changes
267
+ * because of a parent layout change (a flex sibling growing, a list
268
+ * reordering, a column toggling its width), interpolate between the old
269
+ * and new layout instead of snapping.
270
+ *
271
+ * - `true` — animate with the library's default spring.
272
+ * - `TransitionConfig` — spring (react-spring vocab) or timing config; the
273
+ * resolver bridges to Reanimated's `LinearTransition` builder.
274
+ * - omitted / `false` — no layout animation (default).
275
+ *
276
+ * Only `'spring'` / `'timing'` / `'no-animation'` map to layout transitions
277
+ * — decay is downgraded to spring (no clear target). Reduced motion gates
278
+ * the prop the same way it gates `animate`.
279
+ *
280
+ * `layoutId` (below) is a related but distinct mechanism for shared
281
+ * element transitions across screens — `layout` animates this element's
282
+ * own layout changes, `layoutId` animates from a different element's
283
+ * last measured rect to this element's current rect.
284
+ */
285
+ layout?: boolean | TransitionConfig;
286
+ /**
287
+ * Shared-element transition id. When a Motion primitive with `layoutId`
288
+ * unmounts, its last on-screen rect is recorded under that id; the next
289
+ * mount of any Motion primitive with the same id animates from the
290
+ * recorded rect to its natural position via a FLIP transform stack.
291
+ *
292
+ * Reanimated 4 removed the `sharedTransitionTag` API — `layoutId` is the
293
+ * Inertia-side measure-based replacement. Rects are recorded in
294
+ * parent-relative coordinates (from `onLayout`), which composes when the
295
+ * source and target screens share an outer content container (the common
296
+ * stack-navigator case); nested-parent layouts need the v2
297
+ * window-coordinate path.
298
+ *
299
+ * The same `transition` prop drives the FLIP animation (spring by
300
+ * default; `'timing'` honored; `'decay'` downgrades to spring; reduced
301
+ * motion skips the transition). Out of scope for the first iteration:
302
+ * style-prop interpolation (border radius, colors, etc.) — only the
303
+ * rect-to-rect transform is animated. Two simultaneously-mounted
304
+ * primitives sharing the same `layoutId` are undefined behavior; pick a
305
+ * primitive per id at a time.
306
+ */
307
+ layoutId?: string;
308
+ /**
309
+ * Fired once per logical animation completion. See `AnimationCallbackInfo`
310
+ * for the payload shape — transform parents fire once, not per axis.
311
+ */
312
+ onAnimationEnd?: (info: AnimationCallbackInfo<AnimateStyle<C>>) => void;
313
+ }
314
+ /**
315
+ * Props of a Motion primitive for a given underlying component `C` and a
316
+ * concrete variants map `V`: the component's own props (minus `style`, which
317
+ * we replace with an animated style) intersected with the Motion props.
318
+ */
319
+ type MotionComponentProps<C extends ComponentType<any>, V extends VariantsMap<ComponentProps<C>> = VariantsMap<ComponentProps<C>>> = Omit<ComponentProps<C>, 'style'> & MotionProps<ComponentProps<C>, V> & {
320
+ style?: ComponentProps<C>['style'];
321
+ ref?: Ref<unknown>;
322
+ };
323
+ /**
324
+ * The component type produced by `createMotionComponent`.
325
+ *
326
+ * It is a **generic call signature**, not a plain `ComponentType`: the variant
327
+ * map `V` is inferred from the `variants` prop at each JSX use. That inference
328
+ * is what narrows `animate`'s string form to the variant keys, so
329
+ * `<Motion.View variants={{ open, closed }} animate="opne" />` is a compile
330
+ * error and `open` / `closed` autocomplete. With no `variants` prop, `V` falls
331
+ * back to the open `VariantsMap`, so `animate` still accepts any string and the
332
+ * variant-less call site is unchanged.
333
+ */
334
+ interface MotionComponent<C extends ComponentType<any>> {
335
+ <V extends VariantsMap<ComponentProps<C>> = VariantsMap<ComponentProps<C>>>(props: MotionComponentProps<C, V>): ReactElement | null;
336
+ displayName?: string;
337
+ }
338
+
339
+ export type { AnimatableValue as A, DecayTransition as D, EasingInput as E, GestureSubStates as G, MotionComponent as M, NoAnimationTransition as N, PerPropertyTransition as P, RepeatConfig as R, SpringTransition as S, TransitionConfig as T, VariantController as V, AnimateStyle as a, AnimationCallbackInfo as b, MotionProps as c, SequenceStep as d, TimingTransition as e, Transition as f, VariantsMap as g, GestureLayerTransitions as h };
@@ -0,0 +1,84 @@
1
+ import { SharedValue } from 'react-native-reanimated';
2
+ import { T as TransitionConfig, h as GestureLayerTransitions } from './types-cU43dEmH.js';
3
+
4
+ /**
5
+ * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
6
+ * shared values returned alongside.
7
+ *
8
+ * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web
9
+ * only — no-ops on native). `onFocus` consults `isFocusVisible()` before
10
+ * raising the keyboard-only `focusVisible` layer; `focused` always raises.
11
+ */
12
+ interface UseGestureHandlers {
13
+ onPressIn: () => void;
14
+ onPressOut: () => void;
15
+ onHoverIn: () => void;
16
+ onHoverOut: () => void;
17
+ onFocus: () => void;
18
+ onBlur: () => void;
19
+ }
20
+ interface UseGestureResult {
21
+ /** 0↔1 progress for the pressed layer. */
22
+ pressed: SharedValue<number>;
23
+ /** 0↔1 progress for the focused layer (any focus modality). */
24
+ focused: SharedValue<number>;
25
+ /** 0↔1 progress for the focusVisible layer (keyboard focus only). */
26
+ focusVisible: SharedValue<number>;
27
+ /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
28
+ hovered: SharedValue<number>;
29
+ /** Handlers to spread on the receiving `Pressable`. */
30
+ handlers: UseGestureHandlers;
31
+ }
32
+ /**
33
+ * Build a gesture-layer controller. The hook-form of the `gesture` prop —
34
+ * reach for it when you need to drive multiple animated views from the same
35
+ * gesture state (a focus ring + state-layer halo + content tint all on one
36
+ * Pressable), which the prop-form's "animate the receiver's own style" model
37
+ * can't express.
38
+ *
39
+ * Returns four 0↔1 shared values (one per layer) and a handler bag to spread
40
+ * on a `Pressable`. The shared values are stable across renders — feed them
41
+ * into any number of `useAnimatedStyle` blocks anywhere in the tree.
42
+ *
43
+ * Transitions follow the same shape as the `gesture` prop's accompanying
44
+ * `transition`: pass a single `TransitionConfig` to use for every layer, or a
45
+ * `GestureLayerTransitions` map to give each layer its own. Layers without an
46
+ * explicit transition fall back to the library default spring.
47
+ *
48
+ * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every
49
+ * transition to `no-animation` so state changes snap instead of interpolating
50
+ * — same behaviour the gesture prop applies.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * import { useAnimatedStyle } from 'react-native-reanimated'
55
+ * import { useGesture } from '@rootnative/inertia'
56
+ *
57
+ * function Card() {
58
+ * const { pressed, focused, hovered, handlers } = useGesture({
59
+ * pressed: { type: 'timing', duration: 100 },
60
+ * hovered: { type: 'timing', duration: 150 },
61
+ * focused: { type: 'timing', duration: 200 },
62
+ * })
63
+ *
64
+ * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))
65
+ * const haloStyle = useAnimatedStyle(() => ({
66
+ * opacity: Math.max(
67
+ * hovered.value * 0.08,
68
+ * focused.value * 0.10,
69
+ * pressed.value * 0.10,
70
+ * ),
71
+ * }))
72
+ *
73
+ * return (
74
+ * <Pressable {...handlers}>
75
+ * <Animated.View style={ringStyle} />
76
+ * <Animated.View style={haloStyle} />
77
+ * </Pressable>
78
+ * )
79
+ * }
80
+ * ```
81
+ */
82
+ declare function useGesture(transition?: TransitionConfig | GestureLayerTransitions): UseGestureResult;
83
+
84
+ export { type UseGestureHandlers as U, type UseGestureResult as a, useGesture as u };
@@ -0,0 +1,84 @@
1
+ import { SharedValue } from 'react-native-reanimated';
2
+ import { T as TransitionConfig, h as GestureLayerTransitions } from './types-cU43dEmH.mjs';
3
+
4
+ /**
5
+ * Handler bag returned by `useGesture`. Spread on a `Pressable` to drive the
6
+ * shared values returned alongside.
7
+ *
8
+ * Hover handlers use `Pressable`'s own `onHoverIn` / `onHoverOut` names (web
9
+ * only — no-ops on native). `onFocus` consults `isFocusVisible()` before
10
+ * raising the keyboard-only `focusVisible` layer; `focused` always raises.
11
+ */
12
+ interface UseGestureHandlers {
13
+ onPressIn: () => void;
14
+ onPressOut: () => void;
15
+ onHoverIn: () => void;
16
+ onHoverOut: () => void;
17
+ onFocus: () => void;
18
+ onBlur: () => void;
19
+ }
20
+ interface UseGestureResult {
21
+ /** 0↔1 progress for the pressed layer. */
22
+ pressed: SharedValue<number>;
23
+ /** 0↔1 progress for the focused layer (any focus modality). */
24
+ focused: SharedValue<number>;
25
+ /** 0↔1 progress for the focusVisible layer (keyboard focus only). */
26
+ focusVisible: SharedValue<number>;
27
+ /** 0↔1 progress for the hovered layer (web only — stays at 0 on native). */
28
+ hovered: SharedValue<number>;
29
+ /** Handlers to spread on the receiving `Pressable`. */
30
+ handlers: UseGestureHandlers;
31
+ }
32
+ /**
33
+ * Build a gesture-layer controller. The hook-form of the `gesture` prop —
34
+ * reach for it when you need to drive multiple animated views from the same
35
+ * gesture state (a focus ring + state-layer halo + content tint all on one
36
+ * Pressable), which the prop-form's "animate the receiver's own style" model
37
+ * can't express.
38
+ *
39
+ * Returns four 0↔1 shared values (one per layer) and a handler bag to spread
40
+ * on a `Pressable`. The shared values are stable across renders — feed them
41
+ * into any number of `useAnimatedStyle` blocks anywhere in the tree.
42
+ *
43
+ * Transitions follow the same shape as the `gesture` prop's accompanying
44
+ * `transition`: pass a single `TransitionConfig` to use for every layer, or a
45
+ * `GestureLayerTransitions` map to give each layer its own. Layers without an
46
+ * explicit transition fall back to the library default spring.
47
+ *
48
+ * Reduced motion (via `<MotionConfig reducedMotion>`) collapses every
49
+ * transition to `no-animation` so state changes snap instead of interpolating
50
+ * — same behaviour the gesture prop applies.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * import { useAnimatedStyle } from 'react-native-reanimated'
55
+ * import { useGesture } from '@rootnative/inertia'
56
+ *
57
+ * function Card() {
58
+ * const { pressed, focused, hovered, handlers } = useGesture({
59
+ * pressed: { type: 'timing', duration: 100 },
60
+ * hovered: { type: 'timing', duration: 150 },
61
+ * focused: { type: 'timing', duration: 200 },
62
+ * })
63
+ *
64
+ * const ringStyle = useAnimatedStyle(() => ({ opacity: focused.value }))
65
+ * const haloStyle = useAnimatedStyle(() => ({
66
+ * opacity: Math.max(
67
+ * hovered.value * 0.08,
68
+ * focused.value * 0.10,
69
+ * pressed.value * 0.10,
70
+ * ),
71
+ * }))
72
+ *
73
+ * return (
74
+ * <Pressable {...handlers}>
75
+ * <Animated.View style={ringStyle} />
76
+ * <Animated.View style={haloStyle} />
77
+ * </Pressable>
78
+ * )
79
+ * }
80
+ * ```
81
+ */
82
+ declare function useGesture(transition?: TransitionConfig | GestureLayerTransitions): UseGestureResult;
83
+
84
+ export { type UseGestureHandlers as U, type UseGestureResult as a, useGesture as u };
package/jest-preset.js ADDED
@@ -0,0 +1,33 @@
1
+ // Jest preset for projects consuming `@rootnative/inertia` and its sibling
2
+ // adapter packages (`@rootnative/inertia-gestures`, `-gradients`, `-svg`).
3
+ //
4
+ // Layered on top of `react-native`'s own preset. Adds:
5
+ // - the `react-native-worklets` + Reanimated mock surface Inertia exercises
6
+ // (worklet stubs, animation primitives, color/layout utilities)
7
+ // - `transformIgnorePatterns` widened so Jest transforms the published
8
+ // ESM/CJS bundles of `@rootnative/inertia*` and `react-native-worklets`
9
+ // (their `dist/` files are ESM-only and won't run through the default
10
+ // `react-native` transformIgnorePatterns)
11
+ //
12
+ // Usage:
13
+ //
14
+ // // jest.config.js
15
+ // module.exports = {
16
+ // preset: require.resolve('@rootnative/inertia/jest-preset'),
17
+ // }
18
+ //
19
+ // If you need to allowlist additional packages for transformation, extend
20
+ // `transformIgnorePatterns` in your own config — Jest merges over the preset.
21
+
22
+ const rnPreset = require('react-native/jest-preset')
23
+
24
+ module.exports = {
25
+ ...rnPreset,
26
+ setupFiles: [
27
+ ...(rnPreset.setupFiles ?? []),
28
+ require.resolve('./jest-setup.js'),
29
+ ],
30
+ transformIgnorePatterns: [
31
+ 'node_modules/(?!(react-native|@react-native|@react-native-community|@rootnative/inertia|@rootnative/inertia-gestures|@rootnative/inertia-gradients|@rootnative/inertia-svg|react-native-worklets)/)',
32
+ ],
33
+ }