@rootnative/inertia 0.0.10 → 0.0.11

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 (83) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/README.md +2 -2
  3. package/dist/{chunk-6FCATUMY.mjs → chunk-2Q6JMDYZ.mjs} +1 -1
  4. package/dist/chunk-2UREDR4Z.js +8 -0
  5. package/dist/{chunk-3ZNHPT5Z.js → chunk-3PB27UIE.js} +2 -2
  6. package/dist/{chunk-JENYDTXH.mjs → chunk-5EYIZG72.mjs} +10 -3
  7. package/dist/{chunk-Z23AMUSW.mjs → chunk-7RMSLKQQ.mjs} +1 -1
  8. package/dist/{chunk-7BH3CAO5.mjs → chunk-DT2KVAAO.mjs} +1 -1
  9. package/dist/{chunk-F4HMCXAX.mjs → chunk-FKJLPYGY.mjs} +2 -2
  10. package/dist/{chunk-2UGWAB6N.js → chunk-HBURWGCZ.js} +43 -36
  11. package/dist/chunk-JAJHKJC5.js +8 -0
  12. package/dist/chunk-JBMTTICC.js +8 -0
  13. package/dist/{chunk-QXKPIENP.mjs → chunk-JGQ6YRDN.mjs} +1 -1
  14. package/dist/{chunk-DRA2K53O.mjs → chunk-LHW4VNWD.mjs} +1 -1
  15. package/dist/{chunk-4EZ5DBL3.js → chunk-NTG6PSGZ.js} +8 -8
  16. package/dist/{chunk-KXU6VH2Y.js → chunk-QDMSFRQR.js} +4 -4
  17. package/dist/{chunk-HEAWMZEM.mjs → chunk-QIRKPDXA.mjs} +13 -2
  18. package/dist/{chunk-N33GSDNQ.js → chunk-QX5JHRZ2.js} +12 -1
  19. package/dist/{chunk-VKXSL3ZL.js → chunk-R7YD6L3D.js} +2 -2
  20. package/dist/{chunk-CUHOCONB.mjs → chunk-RO4XFTQ6.mjs} +1 -1
  21. package/dist/{chunk-OLOSU2BD.mjs → chunk-UGYBFAVY.mjs} +1 -1
  22. package/dist/{chunk-46766TBM.js → chunk-XLKI2MSD.js} +2 -2
  23. package/dist/gestureLayer/index.d.mts +2 -2
  24. package/dist/gestureLayer/index.d.ts +2 -2
  25. package/dist/gestureLayer/index.js +11 -11
  26. package/dist/gestureLayer/index.mjs +3 -3
  27. package/dist/index.d.mts +49 -32
  28. package/dist/index.d.ts +49 -32
  29. package/dist/index.js +62 -62
  30. package/dist/index.mjs +19 -19
  31. package/dist/motion/FlatList.d.mts +2 -1
  32. package/dist/motion/FlatList.d.ts +2 -1
  33. package/dist/motion/FlatList.js +5 -5
  34. package/dist/motion/FlatList.mjs +4 -4
  35. package/dist/motion/Image.d.mts +2 -1
  36. package/dist/motion/Image.d.ts +2 -1
  37. package/dist/motion/Image.js +5 -5
  38. package/dist/motion/Image.mjs +4 -4
  39. package/dist/motion/Pressable.d.mts +2 -1
  40. package/dist/motion/Pressable.d.ts +2 -1
  41. package/dist/motion/Pressable.js +5 -5
  42. package/dist/motion/Pressable.mjs +4 -4
  43. package/dist/motion/ScrollView.d.mts +2 -1
  44. package/dist/motion/ScrollView.d.ts +2 -1
  45. package/dist/motion/ScrollView.js +5 -5
  46. package/dist/motion/ScrollView.mjs +4 -4
  47. package/dist/motion/Text.d.mts +2 -1
  48. package/dist/motion/Text.d.ts +2 -1
  49. package/dist/motion/Text.js +5 -5
  50. package/dist/motion/Text.mjs +4 -4
  51. package/dist/motion/View.d.mts +2 -1
  52. package/dist/motion/View.d.ts +2 -1
  53. package/dist/motion/View.js +5 -5
  54. package/dist/motion/View.mjs +4 -4
  55. package/dist/touch/index.d.mts +5 -4
  56. package/dist/touch/index.d.ts +5 -4
  57. package/dist/touch/index.js +3 -3
  58. package/dist/touch/index.mjs +1 -1
  59. package/dist/{types-08mG8fNk.d.mts → types-C5Zbs9MC.d.mts} +12 -1
  60. package/dist/{types-08mG8fNk.d.ts → types-C5Zbs9MC.d.ts} +12 -1
  61. package/dist/{useGesture-D1lHeQQ6.d.ts → useGesture-Be0ZhCWj.d.ts} +1 -1
  62. package/dist/{useGesture-DjszaHWz.d.mts → useGesture-Ve8EGjTr.d.mts} +1 -1
  63. package/dist/useTranslateStyle-BDrOD97O.d.mts +58 -0
  64. package/dist/useTranslateStyle-BDrOD97O.d.ts +58 -0
  65. package/jest-preset.js +31 -2
  66. package/llms.txt +2 -1
  67. package/package.json +13 -12
  68. package/src/index.ts +3 -0
  69. package/src/internal/boxShadow.ts +24 -2
  70. package/src/touch/useTouchDrag.ts +5 -3
  71. package/src/transitions/resolveSequence.ts +42 -2
  72. package/src/types.ts +14 -1
  73. package/src/values/index.ts +3 -1
  74. package/src/values/useColorCascade.ts +3 -3
  75. package/src/values/useColorTransition.ts +17 -2
  76. package/src/values/useInterpolatedStyle.ts +8 -1
  77. package/src/values/useShadow.ts +18 -2
  78. package/src/values/useTranslateStyle.ts +18 -2
  79. package/dist/applyBounds-BYGiHrYO.d.mts +0 -18
  80. package/dist/applyBounds-BYGiHrYO.d.ts +0 -18
  81. package/dist/chunk-PLKXCJIB.js +0 -8
  82. package/dist/chunk-UBHQJFUW.js +0 -8
  83. package/dist/chunk-XKNEQDAT.js +0 -8
package/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@ All notable changes to `@rootnative/inertia` are documented here. The format fol
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.0.11] - 2026-09-09
8
+
9
+ ### Changed
10
+
11
+ - **Breaking: the peer ranges are narrowed to the Expo SDK 57 band.** `react` is now `>=19.2.3 <20.0.0`, `react-native` is `>=0.83.0 <0.87.0`, `react-native-reanimated` is `>=4.5.0 <4.6.0`, and `react-native-worklets` is `>=0.10.0 <0.11.0`. The old ranges advertised a floor that npm rejects. `0.0.10` declares `react-native >=0.81.0` and `react-native-reanimated >=4.0.0`, and the newest Reanimated that range admits requires `react-native 0.83 - 0.87`, so a fresh install can fail with `ERESOLVE`. Nothing in this repository changed when that became true — Reanimated narrowed its own range after the release, which is why a range needs a gate that re-checks it and not only a review at the time it is written.
12
+
13
+ The band cannot be wider. Each peer range resolves on its own, so any set that admits both SDK 54 (`react-native 0.81` with Reanimated `4.1`) and SDK 57 (`react-native 0.86` with Reanimated `4.5`) also admits `react-native 0.81` with Reanimated `4.6`, which cannot install. A range promises every combination it permits, not only the combinations that were tested.
14
+
15
+ A new `compat.yml` workflow now packs the release candidate and installs it into every Expo SDK fixture in `rootnative/sdk-compat` before the publish, with `enforce-range: true`. The test suite in this repository says nothing about what a consumer can install, and that gap is what let the `0.0.10` range ship.
16
+
17
+ Migration: move the app to Expo SDK 57 (React `19.2.3`, React Native `0.86.3`, Reanimated `4.5.1`, Worklets `0.10.1`). A project on SDK 54 stays on `0.0.10`. The dev pins and the example app moved to the same band, so the package now develops against the runtime it declares. `sdk-compat` records SDK 54 as a documented boundary, not as a failure.
18
+
19
+ - **`@rootnative/inertia/jest-preset` needs `@react-native/jest-preset` in the consuming project.** React Native `0.86` moved its Jest preset into that package and left `react-native/jest-preset` as a shim that re-exports it. The shim declares the new package as an **optional** peer, and no package manager installs an optional peer, so the shim throws a migration error for every consumer who did not add the package by hand. The preset now resolves `@react-native/jest-preset` directly and throws a named error that says what to install, so the failure states this package's requirement instead of surfacing as a React Native migration message. Add it as a devDependency at the version that matches your `react-native`. The docs testing page carries the install step and the new `preset` spelling.
20
+
21
+ The package is deliberately **not** a peer dependency here. React Native pins it to an exact version — `0.86.3` requires exactly `@react-native/jest-preset@0.86.3` — so any range declared in this package would advertise versions that cannot install, and the `sdk-compat` range audit fails on it. An exact pin would break on every React Native patch. The version relationship belongs to `react-native`, which already declares it.
22
+
23
+ ### Added
24
+
25
+ - **Three style types are exported: `ColorStyle`, `TranslateStyle` and `ShadowStyle`.** They are what `useColorTransition`, `useColorCascade`, `useTranslateStyle` and `useShadow` return. Each hook was public while the type of the style object it hands back was not, so a consumer could not name the value in a typed variable, a prop, or a wrapper hook's signature without rebuilding the type by hand.
26
+
27
+ ### Fixed
28
+
29
+ - **A keyframe array no longer crashes the whole render under reduced motion.** `withSequence` writes a `finished` flag onto every argument it is handed. Reduced motion collapses each step to `no-animation`, and `no-animation` resolves to the bare target rather than an animation object, so `animate={{ translateY: [0, -8, 0] }}` reached `withSequence(0, -8, 0)` and threw `TypeError: Cannot create property 'finished' on number` from inside render. React unmounted the tree, so any consumer using the documented keyframe form — the shape in this package's own `llms.txt` — served a blank page to every visitor with reduce-motion switched on at the OS level. The resolver now settles the property on the last keyframe instead of building a sequence, which is where the sequence would have ended; `repeat` and `delay` were already dropped for `no-animation`, so nothing is left pending. A per-step `{ type: 'no-animation' }` inside a sequence that otherwise animates hit the same throw and now becomes a zero-length timing, keeping its slot in the order.
30
+
31
+ Found from a consumer, not from CI, and the reason is worth keeping: **the Jest mock cannot observe this class of bug.** Its `withSequence` is `(...args) => args[args.length - 1]` and its `withTiming` / `withSpring` return their target, so every step looks like a bare value whether the gate is on or off — the existing reduced-motion sequence tests passed against the crashing code. The regression tests therefore assert the one thing that stays observable under the mock: a sequence under the gate never reaches `withSequence` at all. For the same reason the gate is now detected from the resolved config (`no-animation` base), never by inspecting the shape of a resolved step.
32
+
7
33
  ## [0.0.10] - 2026-09-06
8
34
 
9
35
  ### Changed
@@ -351,7 +377,8 @@ Initial alpha publish. The full initial surface is in place; APIs are still subj
351
377
  - SVG path morphing, gradient interpolation, and shared-element transitions across screens are out of scope until `0.2.x` / `1.x` per the roadmap.
352
378
  - `react-native-gesture-handler` integration (drag, pan, swipe sub-states) lands in `0.2` via the optional `@rootnative/inertia-gestures` adapter.
353
379
 
354
- [unreleased]: https://github.com/rootnative/inertia/compare/core+gestures+gradients+svg@0.0.10...HEAD
380
+ [unreleased]: https://github.com/rootnative/inertia/compare/core+gestures+gradients+svg@0.0.11...HEAD
381
+ [0.0.11]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.11
355
382
  [0.0.10]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.10
356
383
  [0.0.9]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.9
357
384
  [0.0.8]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.8
package/README.md CHANGED
@@ -12,7 +12,7 @@
12
12
 
13
13
  Declarative animation primitives for React Native, built as a thin wrapper around [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/). Inspired by Framer Motion (web) and react-spring (cross-platform).
14
14
 
15
- > **Status:** `0.0.10` — stable. Pre-`1.0.0` minor versions may break — see the [CHANGELOG](https://github.com/rootnative/inertia/blob/main/packages/core/CHANGELOG.md).
15
+ > **Status:** `0.0.11` — stable. Pre-`1.0.0` minor versions may break — see the [CHANGELOG](https://github.com/rootnative/inertia/blob/main/packages/core/CHANGELOG.md).
16
16
 
17
17
  ## Install
18
18
 
@@ -22,7 +22,7 @@ pnpm add @rootnative/inertia react-native-reanimated
22
22
 
23
23
  Then enable the [Reanimated Babel plugin](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation).
24
24
 
25
- **Peer dependencies:** `react >=19.0.0`, `react-native >=0.81.0`, `react-native-reanimated >=4.0.0`.
25
+ **Peer dependencies:** `react >=19.2.3`, `react-native >=0.83.0 <0.87.0`, `react-native-reanimated >=4.5.0 <4.6.0`, `react-native-worklets >=0.10.0 <0.11.0`.
26
26
 
27
27
  ## Quick start
28
28
 
@@ -1,4 +1,4 @@
1
- import { stableSig, warnOnce, isTopLevelTransition } from './chunk-HEAWMZEM.mjs';
1
+ import { stableSig, warnOnce, isTopLevelTransition } from './chunk-QIRKPDXA.mjs';
2
2
  import { createContext, useContext, useMemo } from 'react';
3
3
  import { useReducedMotion } from 'react-native-reanimated';
4
4
  import { jsx } from 'react/jsx-runtime';
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionView = chunkHBURWGCZ_js.createMotionComponent(reactNative.View);
7
+
8
+ exports.MotionView = MotionView;
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunk2UGWAB6N_js = require('./chunk-2UGWAB6N.js');
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
4
  var reactNative = require('react-native');
5
5
 
6
- var MotionScrollView = chunk2UGWAB6N_js.createMotionComponent(reactNative.ScrollView);
6
+ var MotionScrollView = chunkHBURWGCZ_js.createMotionComponent(reactNative.ScrollView);
7
7
 
8
8
  exports.MotionScrollView = MotionScrollView;
@@ -1,5 +1,5 @@
1
- import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, installFocusVisibility, isFocusVisible } from './chunk-6FCATUMY.mjs';
2
- import { warnOnce, stableSig, applyDelay, resolveAnimatableValue, isTopLevelTransition, resolveTransition, repeatIterationsOf, DEFAULT_LAYOUT_DURATION, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-HEAWMZEM.mjs';
1
+ import { useNamedTransitions, resolveNamedTransitionProp, lookupNamedTransition, useShouldReduceMotion, installFocusVisibility, isFocusVisible } from './chunk-2Q6JMDYZ.mjs';
2
+ import { warnOnce, stableSig, applyDelay, resolveAnimatableValue, isTopLevelTransition, resolveTransition, repeatIterationsOf, DEFAULT_LAYOUT_DURATION, ensureWorkletEasing, springToReanimated, DEFAULT_SPRING } from './chunk-QIRKPDXA.mjs';
3
3
  import { createContext, useContext, useMemo, Children, isValidElement, useState, useRef, useCallback, forwardRef, useEffect } from 'react';
4
4
  import { jsx, Fragment } from 'react/jsx-runtime';
5
5
  import Animated, { useSharedValue, cancelAnimation, useAnimatedStyle, interpolateColor, reanimatedVersion, runOnJS, LinearTransition, withSequence, withTiming, withSpring } from 'react-native-reanimated';
@@ -260,7 +260,7 @@ function resolveBoxShadowInput(input) {
260
260
  offsetY: coerceLength(layer.offsetY, "offsetY"),
261
261
  blurRadius: coerceLength(layer.blurRadius, "blurRadius"),
262
262
  spreadDistance: coerceLength(layer.spreadDistance, "spreadDistance"),
263
- color: layer.color ?? "black",
263
+ color: coerceColor(layer.color),
264
264
  inset: layer.inset ?? false
265
265
  }));
266
266
  }
@@ -291,6 +291,13 @@ function invisibleLayer(inset) {
291
291
  inset
292
292
  };
293
293
  }
294
+ function coerceColor(value) {
295
+ if (value === void 0) return "black";
296
+ if (typeof value === "string") return value;
297
+ throw new Error(
298
+ `[inertia] boxShadow: color must be a colour string, got ${typeof value}. PlatformColor and DynamicColorIOS values cannot be interpolated \u2014 pass a string colour on an animated shadow.`
299
+ );
300
+ }
294
301
  function coerceLength(value, field) {
295
302
  if (value === void 0) return 0;
296
303
  if (typeof value === "number") return value;
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import Animated from 'react-native-reanimated';
3
3
 
4
4
  var MotionFlatList = createMotionComponent(
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import { Image } from 'react-native';
3
3
 
4
4
  var MotionImage = createMotionComponent(Image);
@@ -1,5 +1,5 @@
1
- import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, installFocusVisibility, isFocusVisible } from './chunk-6FCATUMY.mjs';
2
- import { resolveTransition, isTopLevelTransition } from './chunk-HEAWMZEM.mjs';
1
+ import { useShouldReduceMotion, resolveNamedTransitionProp, useNamedTransitions, installFocusVisibility, isFocusVisible } from './chunk-2Q6JMDYZ.mjs';
2
+ import { resolveTransition, isTopLevelTransition } from './chunk-QIRKPDXA.mjs';
3
3
  import { useEffect, useCallback, useMemo } from 'react';
4
4
  import { useSharedValue } from 'react-native-reanimated';
5
5
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkKXU6VH2Y_js = require('./chunk-KXU6VH2Y.js');
4
- var chunkN33GSDNQ_js = require('./chunk-N33GSDNQ.js');
3
+ var chunkQDMSFRQR_js = require('./chunk-QDMSFRQR.js');
4
+ var chunkQX5JHRZ2_js = require('./chunk-QX5JHRZ2.js');
5
5
  var react = require('react');
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
7
  var Animated = require('react-native-reanimated');
@@ -45,7 +45,7 @@ function Presence({ children }) {
45
45
  react.Children.forEach(children, (child) => {
46
46
  if (!react.isValidElement(child)) return;
47
47
  if (child.key === null) {
48
- chunkN33GSDNQ_js.warnOnce(
48
+ chunkQX5JHRZ2_js.warnOnce(
49
49
  "presence-keyless-child",
50
50
  "[inertia] <Presence> children must have a `key`. Skipping a keyless child."
51
51
  );
@@ -266,7 +266,7 @@ function resolveBoxShadowInput(input) {
266
266
  offsetY: coerceLength(layer.offsetY, "offsetY"),
267
267
  blurRadius: coerceLength(layer.blurRadius, "blurRadius"),
268
268
  spreadDistance: coerceLength(layer.spreadDistance, "spreadDistance"),
269
- color: layer.color ?? "black",
269
+ color: coerceColor(layer.color),
270
270
  inset: layer.inset ?? false
271
271
  }));
272
272
  }
@@ -297,6 +297,13 @@ function invisibleLayer(inset) {
297
297
  inset
298
298
  };
299
299
  }
300
+ function coerceColor(value) {
301
+ if (value === void 0) return "black";
302
+ if (typeof value === "string") return value;
303
+ throw new Error(
304
+ `[inertia] boxShadow: color must be a colour string, got ${typeof value}. PlatformColor and DynamicColorIOS values cannot be interpolated \u2014 pass a string colour on an animated shadow.`
305
+ );
306
+ }
300
307
  function coerceLength(value, field) {
301
308
  if (value === void 0) return 0;
302
309
  if (typeof value === "number") return value;
@@ -364,16 +371,16 @@ function resolveLayoutTransition(layout) {
364
371
  if (cfg.type === "no-animation") return void 0;
365
372
  if (cfg.type === "timing") {
366
373
  let builder2 = Animated.LinearTransition.duration(
367
- cfg.duration ?? chunkN33GSDNQ_js.DEFAULT_LAYOUT_DURATION
374
+ cfg.duration ?? chunkQX5JHRZ2_js.DEFAULT_LAYOUT_DURATION
368
375
  );
369
- const easing = chunkN33GSDNQ_js.ensureWorkletEasing(cfg.easing);
376
+ const easing = chunkQX5JHRZ2_js.ensureWorkletEasing(cfg.easing);
370
377
  if (easing) builder2 = builder2.easing(easing);
371
378
  if (cfg.delay) builder2 = builder2.delay(cfg.delay);
372
379
  return builder2;
373
380
  }
374
381
  const spring = cfg.type === "decay" ? { type: "spring" } : cfg;
375
- const { stiffness, damping, mass } = chunkN33GSDNQ_js.springToReanimated({
376
- ...chunkN33GSDNQ_js.DEFAULT_SPRING,
382
+ const { stiffness, damping, mass } = chunkQX5JHRZ2_js.springToReanimated({
383
+ ...chunkQX5JHRZ2_js.DEFAULT_SPRING,
377
384
  ...spring
378
385
  });
379
386
  let builder = Animated.LinearTransition.springify().stiffness(stiffness).damping(damping).mass(mass);
@@ -561,14 +568,14 @@ function useSharedLayout(options) {
561
568
  }
562
569
  function legBuilder(transition) {
563
570
  if (transition?.type === "timing") {
564
- const duration = transition.duration ?? chunkN33GSDNQ_js.DEFAULT_LAYOUT_DURATION;
571
+ const duration = transition.duration ?? chunkQX5JHRZ2_js.DEFAULT_LAYOUT_DURATION;
565
572
  return (from, to) => Animated.withSequence(
566
573
  Animated.withTiming(from, { duration: 0 }),
567
574
  Animated.withTiming(to, { duration })
568
575
  );
569
576
  }
570
- const springCfg = transition?.type === "spring" ? { ...chunkN33GSDNQ_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkN33GSDNQ_js.DEFAULT_SPRING };
571
- const springParams = chunkN33GSDNQ_js.springToReanimated(springCfg);
577
+ const springCfg = transition?.type === "spring" ? { ...chunkQX5JHRZ2_js.DEFAULT_SPRING, ...transition } : { type: "spring", ...chunkQX5JHRZ2_js.DEFAULT_SPRING };
578
+ const springParams = chunkQX5JHRZ2_js.springToReanimated(springCfg);
572
579
  return (from, to) => Animated.withSequence(
573
580
  Animated.withTiming(from, { duration: 0 }),
574
581
  Animated.withSpring(to, springParams)
@@ -854,14 +861,14 @@ var DEFAULT_RESTING = {
854
861
  function transitionFor(prop, transition) {
855
862
  if (!transition) return void 0;
856
863
  if (typeof transition === "string") return void 0;
857
- if (chunkN33GSDNQ_js.isTopLevelTransition(transition)) return transition;
864
+ if (chunkQX5JHRZ2_js.isTopLevelTransition(transition)) return transition;
858
865
  if (GESTURE_LAYER_NAME_SET.has(prop)) return void 0;
859
866
  return transition[prop];
860
867
  }
861
868
  function gestureLayerTransitionFor(layer, transition) {
862
869
  if (!transition) return void 0;
863
870
  if (typeof transition === "string") return void 0;
864
- if (chunkN33GSDNQ_js.isTopLevelTransition(transition)) return transition;
871
+ if (chunkQX5JHRZ2_js.isTopLevelTransition(transition)) return transition;
865
872
  return transition[layer];
866
873
  }
867
874
  function createMotionComponent(Component) {
@@ -911,12 +918,12 @@ function createMotionComponent(Component) {
911
918
  onLayout: userOnLayout,
912
919
  ...rest
913
920
  } = props;
914
- const namedTransitions = chunkKXU6VH2Y_js.useNamedTransitions();
915
- const transition = chunkKXU6VH2Y_js.resolveNamedTransitionProp(
921
+ const namedTransitions = chunkQDMSFRQR_js.useNamedTransitions();
922
+ const transition = chunkQDMSFRQR_js.resolveNamedTransitionProp(
916
923
  transitionProp,
917
924
  namedTransitions
918
925
  );
919
- const layout = typeof layoutProp === "string" ? chunkKXU6VH2Y_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
926
+ const layout = typeof layoutProp === "string" ? chunkQDMSFRQR_js.lookupNamedTransition(layoutProp, namedTransitions) : layoutProp;
920
927
  if (__DEV__ && typeof style === "function") {
921
928
  throw new Error(
922
929
  "[inertia] `style` must be a style object or array of style objects, not a function. The function-form `style={(state) => ...}` Pressable API is not supported \u2014 use `gesture.pressed` (or `gesture.focused`, etc.) to drive state-dependent styling instead."
@@ -924,7 +931,7 @@ function createMotionComponent(Component) {
924
931
  }
925
932
  const presence = usePresence();
926
933
  const isExiting = presence !== null && presence.isPresent === false;
927
- const shouldReduceMotion = chunkKXU6VH2Y_js.useShouldReduceMotion();
934
+ const shouldReduceMotion = chunkQDMSFRQR_js.useShouldReduceMotion();
928
935
  const staggerDelay = useStaggerDelay();
929
936
  const onAnimationEndRef = react.useRef(onAnimationEnd);
930
937
  onAnimationEndRef.current = onAnimationEnd;
@@ -1003,7 +1010,7 @@ function createMotionComponent(Component) {
1003
1010
  hasBoxShadow: keys.includes("boxShadow")
1004
1011
  };
1005
1012
  if (__DEV__ && activeSetRef.current.hasBoxShadow && keys.some((k) => k !== "boxShadow" && k.startsWith("shadow"))) {
1006
- chunkN33GSDNQ_js.warnOnce(
1013
+ chunkQX5JHRZ2_js.warnOnce(
1007
1014
  "boxShadow-with-native-shadow",
1008
1015
  "[inertia] `boxShadow` is animated alongside the native `shadow*` keys on the same element, which applies two shadow systems at once. Pick one: `boxShadow` for the cross-platform CSS form, or the native `shadow*` keys."
1009
1016
  );
@@ -1076,7 +1083,7 @@ function createMotionComponent(Component) {
1076
1083
  const boxShadowInsets = Animated.useSharedValue(
1077
1084
  boxShadowSeedRef.current.insets
1078
1085
  );
1079
- const styleRestingSig = chunkN33GSDNQ_js.stableSig(styleResting);
1086
+ const styleRestingSig = chunkQX5JHRZ2_js.stableSig(styleResting);
1080
1087
  react.useEffect(() => {
1081
1088
  for (const key of activeKeys) {
1082
1089
  if (everDrivenRef.current.has(key)) continue;
@@ -1104,13 +1111,13 @@ function createMotionComponent(Component) {
1104
1111
  const gestureSV = Animated.useSharedValue(
1105
1112
  resolveGestureLayers(gesture)
1106
1113
  );
1107
- const gestureTargetsSig = chunkN33GSDNQ_js.stableSig(gesture);
1114
+ const gestureTargetsSig = chunkQX5JHRZ2_js.stableSig(gesture);
1108
1115
  react.useEffect(() => {
1109
1116
  gestureSV.value = resolveGestureLayers(gesture);
1110
1117
  }, [gestureTargetsSig]);
1111
1118
  const baseRecord = isExiting && exitRecord ? { ...animateRecord, ...exitRecord } : animateRecord;
1112
- const baseSig = chunkN33GSDNQ_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
1113
- const transitionSig = chunkN33GSDNQ_js.stableSig(transition);
1119
+ const baseSig = chunkQX5JHRZ2_js.stableSig(baseRecord) + (isExiting ? "|exit" : "") + (shouldReduceMotion ? "|rm" : "");
1120
+ const transitionSig = chunkQX5JHRZ2_js.stableSig(transition);
1114
1121
  const hasAnimationEnd = onAnimationEnd !== void 0;
1115
1122
  const safeToRemoveRef = react.useRef(void 0);
1116
1123
  safeToRemoveRef.current = presence?.safeToRemove;
@@ -1186,8 +1193,8 @@ function createMotionComponent(Component) {
1186
1193
  isExiting ? onSettle : void 0,
1187
1194
  TRANSFORM_KEY_SET.has(key) ? transformGroup : void 0
1188
1195
  );
1189
- sharedValues[key].value = chunkN33GSDNQ_js.applyDelay(
1190
- chunkN33GSDNQ_js.resolveAnimatableValue(
1196
+ sharedValues[key].value = chunkQX5JHRZ2_js.applyDelay(
1197
+ chunkQX5JHRZ2_js.resolveAnimatableValue(
1191
1198
  COLOR_KEY_SET.has(key) ? normalizeAnimatableColorTarget(target) : target,
1192
1199
  cfg,
1193
1200
  factory
@@ -1254,7 +1261,7 @@ function createMotionComponent(Component) {
1254
1261
  const sharedLayout = useSharedLayout({
1255
1262
  layoutId,
1256
1263
  userRef: ref,
1257
- transition: chunkN33GSDNQ_js.isTopLevelTransition(transition) ? transition : void 0,
1264
+ transition: chunkQX5JHRZ2_js.isTopLevelTransition(transition) ? transition : void 0,
1258
1265
  shouldReduceMotion,
1259
1266
  userOnLayout,
1260
1267
  readStyles: readSharedStyles
@@ -1357,7 +1364,7 @@ function createMotionComponent(Component) {
1357
1364
  setFocusVisible,
1358
1365
  setHovered
1359
1366
  );
1360
- const layoutSig = chunkN33GSDNQ_js.stableSig(layout);
1367
+ const layoutSig = chunkQX5JHRZ2_js.stableSig(layout);
1361
1368
  const layoutTransition = react.useMemo(
1362
1369
  () => shouldReduceMotion ? void 0 : resolveLayoutTransition(layout),
1363
1370
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -1506,8 +1513,8 @@ function driveBoxShadow(slot, insetSlot, target, cfg, staggerDelay, factory) {
1506
1513
  );
1507
1514
  insetSlot.value = insets;
1508
1515
  if (from.length !== currentLayers.length) slot.value = layersToPayload(from);
1509
- slot.value = chunkN33GSDNQ_js.applyDelay(
1510
- chunkN33GSDNQ_js.resolveTransition(
1516
+ slot.value = chunkQX5JHRZ2_js.applyDelay(
1517
+ chunkQX5JHRZ2_js.resolveTransition(
1511
1518
  cfg,
1512
1519
  layersToPayload(to),
1513
1520
  factory?.("animation", void 0)
@@ -1565,7 +1572,7 @@ function stepCountOf(v) {
1565
1572
  }
1566
1573
  function totalIterationsOf(cfg) {
1567
1574
  if (!cfg || cfg.type === "no-animation" || cfg.type === "decay") return 1;
1568
- return chunkN33GSDNQ_js.repeatIterationsOf(cfg.repeat);
1575
+ return chunkQX5JHRZ2_js.repeatIterationsOf(cfg.repeat);
1569
1576
  }
1570
1577
  function reachesTerminalPhase(cfg) {
1571
1578
  return Number.isFinite(totalIterationsOf(cfg));
@@ -1593,7 +1600,7 @@ function useControllerKey(controller) {
1593
1600
  }
1594
1601
  function resolveAnimateInput(animate, variants, controllerKey) {
1595
1602
  if (controllerKey !== void 0 && animate !== void 0) {
1596
- chunkN33GSDNQ_js.warnOnce(
1603
+ chunkQX5JHRZ2_js.warnOnce(
1597
1604
  "controller-and-animate",
1598
1605
  "[inertia] Both `controller` and `animate` are set on the same primitive. The controller drives the animation and `animate` is ignored \u2014 remove one of the two."
1599
1606
  );
@@ -1603,7 +1610,7 @@ function resolveAnimateInput(animate, variants, controllerKey) {
1603
1610
  }
1604
1611
  if (typeof animate === "string") {
1605
1612
  if (variants && animate in variants) return variants[animate];
1606
- chunkN33GSDNQ_js.warnOnce(
1613
+ chunkQX5JHRZ2_js.warnOnce(
1607
1614
  `missing-variant:${animate}`,
1608
1615
  `[inertia] animate="${animate}" but no matching variant. Did you forget to pass \`variants\`?`
1609
1616
  );
@@ -1633,7 +1640,7 @@ function resolveGestureLayers(gesture) {
1633
1640
  for (const key of ALL_KEYS) {
1634
1641
  if (STRUCTURED_KEY_SET.has(key)) {
1635
1642
  if (__DEV__ && subState[key] !== void 0) {
1636
- chunkN33GSDNQ_js.warnOnce(
1643
+ chunkQX5JHRZ2_js.warnOnce(
1637
1644
  `gesture-structured-${layer}-${key}`,
1638
1645
  `[inertia] \`${key}\` is not supported inside \`gesture.${layer}\` and will be ignored. Drive it from \`animate\` (optionally via a variant keyed off the same state), or interpolate it yourself with \`useShadow\`.`
1639
1646
  );
@@ -1657,7 +1664,7 @@ function resolveGestureLayers(gesture) {
1657
1664
  return out;
1658
1665
  }
1659
1666
  function useGestureLayerProgress(progress, active, declared, layer, transition, isExiting, shouldReduceMotion) {
1660
- const layerCfgSig = chunkN33GSDNQ_js.stableSig(gestureLayerTransitionFor(layer, transition));
1667
+ const layerCfgSig = chunkQX5JHRZ2_js.stableSig(gestureLayerTransitionFor(layer, transition));
1661
1668
  react.useEffect(() => {
1662
1669
  if (!declared) return;
1663
1670
  if (isExiting) {
@@ -1666,7 +1673,7 @@ function useGestureLayerProgress(progress, active, declared, layer, transition,
1666
1673
  }
1667
1674
  const target = active ? 1 : 0;
1668
1675
  const cfg = shouldReduceMotion ? { type: "no-animation" } : gestureLayerTransitionFor(layer, transition) ?? { type: "spring" };
1669
- progress.value = chunkN33GSDNQ_js.resolveTransition(cfg, target);
1676
+ progress.value = chunkQX5JHRZ2_js.resolveTransition(cfg, target);
1670
1677
  }, [active, declared, isExiting, shouldReduceMotion, layerCfgSig]);
1671
1678
  }
1672
1679
  function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisible, setHovered) {
@@ -1675,7 +1682,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
1675
1682
  const hasFocusVisible = gesture?.focusVisible ? 1 : 0;
1676
1683
  const hasHovered = gesture?.hovered ? 1 : 0;
1677
1684
  react.useEffect(() => {
1678
- if (hasFocusVisible) chunkKXU6VH2Y_js.installFocusVisibility();
1685
+ if (hasFocusVisible) chunkQDMSFRQR_js.installFocusVisibility();
1679
1686
  }, [hasFocusVisible]);
1680
1687
  return react.useMemo(() => {
1681
1688
  if (!gesture) return {};
@@ -1702,7 +1709,7 @@ function useGestureHandlers(gesture, rest, setPressed, setFocused, setFocusVisib
1702
1709
  if (gesture.focused || gesture.focusVisible) {
1703
1710
  handlers.onFocus = compose(rest.onFocus, () => {
1704
1711
  if (gesture.focused) setFocused(true);
1705
- if (gesture.focusVisible && chunkKXU6VH2Y_js.isFocusVisible()) setFocusVisible(true);
1712
+ if (gesture.focusVisible && chunkQDMSFRQR_js.isFocusVisible()) setFocusVisible(true);
1706
1713
  });
1707
1714
  handlers.onBlur = compose(rest.onBlur, () => {
1708
1715
  if (gesture.focused) setFocused(false);
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionImage = chunkHBURWGCZ_js.createMotionComponent(reactNative.Image);
7
+
8
+ exports.MotionImage = MotionImage;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
+ var reactNative = require('react-native');
5
+
6
+ var MotionText = chunkHBURWGCZ_js.createMotionComponent(reactNative.Text);
7
+
8
+ exports.MotionText = MotionText;
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import { View } from 'react-native';
3
3
 
4
4
  var MotionView = createMotionComponent(View);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import { ScrollView } from 'react-native';
3
3
 
4
4
  var MotionScrollView = createMotionComponent(ScrollView);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunkKXU6VH2Y_js = require('./chunk-KXU6VH2Y.js');
4
- var chunkN33GSDNQ_js = require('./chunk-N33GSDNQ.js');
3
+ var chunkQDMSFRQR_js = require('./chunk-QDMSFRQR.js');
4
+ var chunkQX5JHRZ2_js = require('./chunk-QX5JHRZ2.js');
5
5
  var react = require('react');
6
6
  var reactNativeReanimated = require('react-native-reanimated');
7
7
 
@@ -10,15 +10,15 @@ function useGesture(transition) {
10
10
  const focused = reactNativeReanimated.useSharedValue(0);
11
11
  const focusVisible = reactNativeReanimated.useSharedValue(0);
12
12
  const hovered = reactNativeReanimated.useSharedValue(0);
13
- const shouldReduceMotion = chunkKXU6VH2Y_js.useShouldReduceMotion();
14
- const resolved = chunkKXU6VH2Y_js.resolveNamedTransitionProp(transition, chunkKXU6VH2Y_js.useNamedTransitions());
13
+ const shouldReduceMotion = chunkQDMSFRQR_js.useShouldReduceMotion();
14
+ const resolved = chunkQDMSFRQR_js.resolveNamedTransitionProp(transition, chunkQDMSFRQR_js.useNamedTransitions());
15
15
  react.useEffect(() => {
16
- chunkKXU6VH2Y_js.installFocusVisibility();
16
+ chunkQDMSFRQR_js.installFocusVisibility();
17
17
  }, []);
18
18
  const setLayer = react.useCallback(
19
19
  (sv, layer, target) => {
20
20
  const cfg = shouldReduceMotion ? { type: "no-animation" } : layerTransition(layer, resolved) ?? { type: "spring" };
21
- sv.value = chunkN33GSDNQ_js.resolveTransition(cfg, target);
21
+ sv.value = chunkQX5JHRZ2_js.resolveTransition(cfg, target);
22
22
  },
23
23
  // The transition is intentionally read on every call rather than cooked
24
24
  // into the dep array — a fresh literal each render would otherwise
@@ -37,7 +37,7 @@ function useGesture(transition) {
37
37
  onHoverOut: () => setLayer(hovered, "hovered", 0),
38
38
  onFocus: () => {
39
39
  setLayer(focused, "focused", 1);
40
- if (chunkKXU6VH2Y_js.isFocusVisible()) setLayer(focusVisible, "focusVisible", 1);
40
+ if (chunkQDMSFRQR_js.isFocusVisible()) setLayer(focusVisible, "focusVisible", 1);
41
41
  },
42
42
  onBlur: () => {
43
43
  setLayer(focused, "focused", 0);
@@ -50,7 +50,7 @@ function useGesture(transition) {
50
50
  }
51
51
  function layerTransition(layer, transition) {
52
52
  if (!transition) return void 0;
53
- if (chunkN33GSDNQ_js.isTopLevelTransition(transition)) return transition;
53
+ if (chunkQX5JHRZ2_js.isTopLevelTransition(transition)) return transition;
54
54
  return transition[layer];
55
55
  }
56
56
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkN33GSDNQ_js = require('./chunk-N33GSDNQ.js');
3
+ var chunkQX5JHRZ2_js = require('./chunk-QX5JHRZ2.js');
4
4
  var react = require('react');
5
5
  var reactNativeReanimated = require('react-native-reanimated');
6
6
  var jsxRuntime = require('react/jsx-runtime');
@@ -32,7 +32,7 @@ function MotionConfig({
32
32
  children
33
33
  }) {
34
34
  const parent = useMotionConfig();
35
- const transitionsSig = chunkN33GSDNQ_js.stableSig(transitions);
35
+ const transitionsSig = chunkQX5JHRZ2_js.stableSig(transitions);
36
36
  const value = react.useMemo(
37
37
  () => ({
38
38
  reducedMotion: reducedMotion ?? parent.reducedMotion,
@@ -49,7 +49,7 @@ var UNKNOWN_NAME_FALLBACK = { type: "spring" };
49
49
  function lookupNamedTransition(name, registry) {
50
50
  const cfg = registry[name];
51
51
  if (cfg) return cfg;
52
- chunkN33GSDNQ_js.warnOnce(
52
+ chunkQX5JHRZ2_js.warnOnce(
53
53
  `unknown-transition:${name}`,
54
54
  `[inertia] Unknown transition name "${name}" \u2014 falling back to the default spring. Register it on a provider: <MotionConfig transitions={{ '${name}': { ... } }}>.`
55
55
  );
@@ -65,7 +65,7 @@ function resolveNamedTransitionProp(transition, registry) {
65
65
  if (typeof transition === "string") {
66
66
  return lookupNamedTransition(transition, registry);
67
67
  }
68
- if (chunkN33GSDNQ_js.isTopLevelTransition(transition)) return transition;
68
+ if (chunkQX5JHRZ2_js.isTopLevelTransition(transition)) return transition;
69
69
  const map = transition;
70
70
  let out = null;
71
71
  for (const key in map) {
@@ -1,5 +1,5 @@
1
1
  import { isWorkletFunction } from 'react-native-worklets';
2
- import { withDelay, withSequence, Easing, withDecay, withTiming, withSpring, withRepeat } from 'react-native-reanimated';
2
+ import { withDelay, withSequence, withTiming, Easing, withDecay, withSpring, withRepeat } from 'react-native-reanimated';
3
3
 
4
4
  // src/transitions/sig.ts
5
5
  function stableSig(value) {
@@ -211,6 +211,10 @@ function delayOf(cfg) {
211
211
  if (cfg.type === "no-animation") return void 0;
212
212
  return cfg.delay;
213
213
  }
214
+ var INSTANT = { duration: 0 };
215
+ function isSnapped(step) {
216
+ return typeof step === "number" || typeof step === "string";
217
+ }
214
218
  function isStepObject(v) {
215
219
  return typeof v === "object" && v !== null && !Array.isArray(v) && "to" in v;
216
220
  }
@@ -221,7 +225,14 @@ function resolveAnimatableValue(value, base, factory) {
221
225
  const animations = steps.map(
222
226
  (step2, i) => resolveStep(step2, stepBase, factory?.("step", i))
223
227
  );
224
- const seq = withSequence(...animations);
228
+ if (stepBase?.type === "no-animation" && animations.length > 0) {
229
+ return animations[animations.length - 1];
230
+ }
231
+ const seq = withSequence(
232
+ ...animations.map(
233
+ (a) => isSnapped(a) ? withTiming(a, INSTANT) : a
234
+ )
235
+ );
225
236
  return applyRepeat(seq, base ? repeatOf(base) : void 0, {
226
237
  sequence: true
227
238
  });
@@ -213,6 +213,10 @@ function delayOf(cfg) {
213
213
  if (cfg.type === "no-animation") return void 0;
214
214
  return cfg.delay;
215
215
  }
216
+ var INSTANT = { duration: 0 };
217
+ function isSnapped(step) {
218
+ return typeof step === "number" || typeof step === "string";
219
+ }
216
220
  function isStepObject(v) {
217
221
  return typeof v === "object" && v !== null && !Array.isArray(v) && "to" in v;
218
222
  }
@@ -223,7 +227,14 @@ function resolveAnimatableValue(value, base, factory) {
223
227
  const animations = steps.map(
224
228
  (step2, i) => resolveStep(step2, stepBase, factory?.("step", i))
225
229
  );
226
- const seq = reactNativeReanimated.withSequence(...animations);
230
+ if (stepBase?.type === "no-animation" && animations.length > 0) {
231
+ return animations[animations.length - 1];
232
+ }
233
+ const seq = reactNativeReanimated.withSequence(
234
+ ...animations.map(
235
+ (a) => isSnapped(a) ? reactNativeReanimated.withTiming(a, INSTANT) : a
236
+ )
237
+ );
227
238
  return applyRepeat(seq, base ? repeatOf(base) : void 0, {
228
239
  sequence: true
229
240
  });
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
- var chunk2UGWAB6N_js = require('./chunk-2UGWAB6N.js');
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
4
  var reactNative = require('react-native');
5
5
 
6
- var MotionPressable = chunk2UGWAB6N_js.createMotionComponent(reactNative.Pressable);
6
+ var MotionPressable = chunkHBURWGCZ_js.createMotionComponent(reactNative.Pressable);
7
7
 
8
8
  exports.MotionPressable = MotionPressable;
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import { Pressable } from 'react-native';
3
3
 
4
4
  var MotionPressable = createMotionComponent(Pressable);
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-JENYDTXH.mjs';
1
+ import { createMotionComponent } from './chunk-5EYIZG72.mjs';
2
2
  import { Text } from 'react-native';
3
3
 
4
4
  var MotionText = createMotionComponent(Text);
@@ -1,13 +1,13 @@
1
1
  'use strict';
2
2
 
3
- var chunk2UGWAB6N_js = require('./chunk-2UGWAB6N.js');
3
+ var chunkHBURWGCZ_js = require('./chunk-HBURWGCZ.js');
4
4
  var Animated = require('react-native-reanimated');
5
5
 
6
6
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
7
 
8
8
  var Animated__default = /*#__PURE__*/_interopDefault(Animated);
9
9
 
10
- var MotionFlatList = chunk2UGWAB6N_js.createMotionComponent(
10
+ var MotionFlatList = chunkHBURWGCZ_js.createMotionComponent(
11
11
  Animated__default.default.FlatList
12
12
  // `createMotionComponent<C>` returns a non-generic `MotionComponent<C>`, so
13
13
  // `data` / `renderItem` would collapse to `any` and lose `ItemT` inference.