@rootnative/inertia 0.0.2 → 0.0.4

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 (77) hide show
  1. package/CHANGELOG.md +63 -5
  2. package/README.md +5 -3
  3. package/dist/{chunk-ZN3PNGHQ.mjs → chunk-4ASOELLA.mjs} +1 -1
  4. package/dist/{chunk-LYMLQ6WQ.mjs → chunk-55W7BNO2.mjs} +604 -106
  5. package/dist/chunk-5SRD2WCO.js +8 -0
  6. package/dist/{chunk-PTRF47DA.js → chunk-7A6WTXNK.js} +10 -3
  7. package/dist/{chunk-NKA6XR77.js → chunk-CENTULW6.js} +2 -2
  8. package/dist/{chunk-4PEHWDAZ.js → chunk-D5KAHWMC.js} +7 -7
  9. package/dist/{chunk-2DHKV2XY.mjs → chunk-J5Q46OPW.mjs} +1 -1
  10. package/dist/{chunk-RGNX6UZN.mjs → chunk-K3CLP74S.mjs} +2 -2
  11. package/dist/{chunk-IWLU3VDE.js → chunk-MYE5NMXW.js} +623 -123
  12. package/dist/{chunk-HFDZAHWP.mjs → chunk-NAOXQJ7U.mjs} +1 -1
  13. package/dist/{chunk-R63GIUNU.mjs → chunk-QKC3APP4.mjs} +1 -1
  14. package/dist/{chunk-V6BTXHZK.mjs → chunk-RF7J5FRM.mjs} +1 -1
  15. package/dist/{chunk-CY7Y64C3.mjs → chunk-TU2XFPAK.mjs} +10 -4
  16. package/dist/chunk-TVFNJ25Z.js +8 -0
  17. package/dist/chunk-VLDIFL3F.js +8 -0
  18. package/dist/{chunk-7AOERN53.js → chunk-WVRCKOPO.js} +3 -3
  19. package/dist/{chunk-TUYHTHVV.js → chunk-XMEVPEMH.js} +2 -2
  20. package/dist/{chunk-TUMNV4P7.mjs → chunk-YKGY22SB.mjs} +1 -1
  21. package/dist/gestureLayer/index.d.mts +2 -2
  22. package/dist/gestureLayer/index.d.ts +2 -2
  23. package/dist/gestureLayer/index.js +10 -10
  24. package/dist/gestureLayer/index.mjs +3 -3
  25. package/dist/index.d.mts +14 -12
  26. package/dist/index.d.ts +14 -12
  27. package/dist/index.js +68 -176
  28. package/dist/index.mjs +40 -147
  29. package/dist/motion/Image.d.mts +1 -1
  30. package/dist/motion/Image.d.ts +1 -1
  31. package/dist/motion/Image.js +5 -5
  32. package/dist/motion/Image.mjs +4 -4
  33. package/dist/motion/Pressable.d.mts +1 -1
  34. package/dist/motion/Pressable.d.ts +1 -1
  35. package/dist/motion/Pressable.js +5 -5
  36. package/dist/motion/Pressable.mjs +4 -4
  37. package/dist/motion/ScrollView.d.mts +1 -1
  38. package/dist/motion/ScrollView.d.ts +1 -1
  39. package/dist/motion/ScrollView.js +5 -5
  40. package/dist/motion/ScrollView.mjs +4 -4
  41. package/dist/motion/Text.d.mts +1 -1
  42. package/dist/motion/Text.d.ts +1 -1
  43. package/dist/motion/Text.js +5 -5
  44. package/dist/motion/Text.mjs +4 -4
  45. package/dist/motion/View.d.mts +1 -1
  46. package/dist/motion/View.d.ts +1 -1
  47. package/dist/motion/View.js +5 -5
  48. package/dist/motion/View.mjs +4 -4
  49. package/dist/touch/index.d.mts +1 -1
  50. package/dist/touch/index.d.ts +1 -1
  51. package/dist/touch/index.js +3 -3
  52. package/dist/touch/index.mjs +1 -1
  53. package/dist/{types-G1dBU2IQ.d.mts → types-37pN82yh.d.mts} +49 -14
  54. package/dist/{types-G1dBU2IQ.d.ts → types-37pN82yh.d.ts} +49 -14
  55. package/dist/{useGesture-D1e4ixJo.d.ts → useGesture-Cl4uzZIr.d.ts} +1 -1
  56. package/dist/{useGesture-RFY6kTL3.d.mts → useGesture-_IKkS8Dv.d.mts} +1 -1
  57. package/llms.txt +3 -1
  58. package/package.json +1 -1
  59. package/src/index.ts +2 -1
  60. package/src/internal/boxShadow.ts +177 -6
  61. package/src/internal/nonWorkletWarning.ts +4 -6
  62. package/src/internal/warnOnce.ts +28 -0
  63. package/src/layout/index.ts +11 -0
  64. package/src/layout/measureWindow.ts +135 -0
  65. package/src/layout/sharedRegistry.ts +156 -18
  66. package/src/layout/useSharedLayout.ts +256 -91
  67. package/src/motion/createMotionComponent.tsx +550 -55
  68. package/src/motion/installCheck.ts +1 -1
  69. package/src/presence/Presence.tsx +73 -10
  70. package/src/transitions/index.ts +1 -1
  71. package/src/types.ts +52 -12
  72. package/src/values/useAnimator.ts +25 -14
  73. package/src/values/useColorCascade.ts +34 -16
  74. package/src/values/useColorTransition.ts +1 -1
  75. package/dist/chunk-34Q4UM6V.js +0 -8
  76. package/dist/chunk-KYJROYCG.js +0 -8
  77. package/dist/chunk-X5J5M3K3.js +0 -8
package/CHANGELOG.md CHANGED
@@ -1,9 +1,59 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to `@rootnative/inertia` are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Pre-`1.0`, breaking changes may land in minor versions and are called out under their release.
3
+ All notable changes to `@rootnative/inertia` are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Pre-`1.0.0`, breaking changes may land in minor versions and are called out under their release.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.0.4] - 2026-07-29
8
+
9
+ **Feature release.** The three deferred items the `0.0.3` audit left on the roadmap land together: `boxShadow` joins the declarative `animate` surface, and `layoutId` shared-element transitions gain window-coordinate measurement and a style carry. No breaking changes; the three adapters are lockstep-bumped with no runtime changes of their own.
10
+
11
+ ### Added
12
+
13
+ - **`boxShadow` is now an animatable property on the `animate` surface.** The cross-platform CSS shadow form joins the declarative surface alongside the native `shadow*` keys, accepting either a CSS string (`'0px 4px 8px rgba(0,0,0,0.3)'` — the shape design systems store elevation tokens in) or React Native's own `BoxShadowValue[]`, whose lengths may be numbers or px strings. The key was already accepted at compile time and silently ignored at runtime, because `AnimateStyle<C>` maps over every key of the inferred style and RN's `ViewStyle` has carried `boxShadow` since 0.76 — so this makes an accepted key work rather than widening the type surface. Endpoints are normalized on the JS thread once per change and padded to a common layer count, so **layer counts may differ between `initial` and `animate`**: the short side gains transparent zero layers and the surplus layer fades rather than popping, matching CSS transition semantics. Every length and color interpolates per layer. `inset` is carried as a **static** per-layer flag rather than interpolated (there is no meaningful midpoint between an inner and an outer shadow, and a boolean driven down Reanimated's numeric path yields `0` mid-flight — a number where native expects a boolean); both endpoints may use it freely, but a layer that is `inset` on one side only throws, as it already did in `useShadow`. Only px and unitless lengths are accepted; `em` / `%` / `rem` throw rather than animating from a `NaN`. New `BoxShadowInput` type exported from the root barrel. Guarded by `boxShadow.test.tsx` (22 cases) and seven compile-time assertions in `animate.test-d.tsx`.
14
+
15
+ Worth knowing if you go looking at the implementation: the target has to reach Reanimated as the **structured array**, not the CSS string. `withSpring` / `withTiming` dispatch on the runtime shape of the value, and a box-shadow string is not a color, so it lands in the prefix-number-suffix branch built for values like `'100%'` and would pull a single number out of a four-value shadow. The array form instead recurses into each layer and animates every leaf. All string parsing therefore happens on the JS thread, and the worklet only emits what the slot already holds — no frame-time string or structural work.
16
+
17
+ Two deliberate limits, both matching the single-value contract `shadowOffset` has carried since `0.0.1`. **Sequences are unsupported on this key**: `boxShadow: [a, b]` means one two-layer shadow, not a two-step keyframe sequence, because nothing distinguishes the two shapes structurally and the array form is the one RN itself uses. Per-property transitions are unaffected. **`boxShadow` is not accepted inside `gesture` sub-states**: compositing a layer stack through the priority cascade would put per-layer, per-field interpolation on the UI thread for every primitive whether or not it animates a shadow. It dev-warns and is ignored — drive it from `animate` (optionally via a variant keyed off the same state), or interpolate it yourself with `useShadow`. Animating `boxShadow` alongside the native `shadow*` keys on one element also dev-warns: that applies two shadow systems at once and whichever the view resolves last wins.
18
+
19
+ **Bundle cost, measured:** +1.61 kB (+24%) per primitive subpath — 6.63 kB → 8.24 kB brotlied — and +0.82 kB on the root entry, which was already carrying the shadow parser via `useShadow`. The `size-limit` caps were raised deliberately to keep the ~25% band the config has always claimed; the full accounting, including the alternatives that were measured and rejected, is in `.size-limit.cjs`.
20
+
21
+ - **`layoutId` shared-element transitions now carry style across, not just the rect.** A hero card that changes background colour, corner radius, or opacity between screens used to snap on those props while its frame animated — the most visible half of the transition arriving instantly. The source element's values for `opacity`, `borderRadius`, `backgroundColor`, `borderColor`, `color`, and `tintColor` are now snapshotted alongside its rect and crossfaded out over the same transition that drives the FLIP, so the arriving element starts wearing its counterpart's style and ends wearing its own. Nothing to configure: it rides the existing `layoutId` + `transition` props.
22
+
23
+ **Which keys carry, and why not more.** Transform keys are deliberately excluded — they are the FLIP's job, and carrying them too would apply the same displacement twice. So is `shadowColor`, despite being a colour key: crossfading one of the four native shadow props over geometry that snapped looks worse than letting the whole shadow snap together. There is no configuration surface for the list and no `layoutStyles` prop; if you need a key that isn't carried, drive it from `animate` on both sides.
24
+
25
+ **A key only participates when the element already has a value for it** — from `animate` / `initial` / a variant / `gesture`, or from the static `style`, read through `StyleSheet.flatten` the same way undriven resting values are. Values are never invented: activating a key the element says nothing about would rest it at the generic type default, and for `color` on a `Motion.Text` that inherits its colour from a parent, that default is `'transparent'` — invisible text on an element the consumer only asked to move. This is the same failure mode as the `0.0.3` resting-value regression, approached from the other side. A key the source carried but the target has no value for is ignored, and vice versa.
26
+
27
+ **A still-mounted source is read live**, for the same reason its rect is re-measured: values move without a layout pass (an animation settling, a theme swap), so the stored snapshot is a floor rather than the truth. Once the source has unmounted, the snapshot taken at release is all that remains. Reduced motion and `transition={{ type: 'no-animation' }}` snap, matching the rect path — and a source and target in mismatched coordinate spaces skip the style carry along with the FLIP, since half a shared-element transition reads as a glitch rather than as graceful degradation. On the mount that consumes a source, the carry composites _above_ the base value, so it overrides `initial` for the carried keys on that mount.
28
+
29
+ Cheap by construction: one progress shared value drives however many keys are carried, and the blend reuses the worklet's existing lerp / `interpolateColor` branches — the same ones the `gesture` cascade uses — sitting one priority above every gesture layer. At rest the pair is `(null, 0)`, so a primitive that isn't mid-transition pays a single comparison. **Bundle cost: +0.56 kB (+6.8%) per primitive subpath**, 8.24 → 8.80 kB brotlied, +0.59 kB root; the `size-limit` caps did not move. Workspace-internal API changes (none of it is exported from the package root): `consumeLayout` returns `{ rect, remeasure?, styles?, readStyles? }`, `registerLayout` takes an optional style reader, `releaseLayout` takes an optional snapshot, and `useSharedLayout` returns a `carry` binding alongside `flip`. Guarded by 16 new cases in `sharedLayout.test.tsx`.
30
+
31
+ ### Changed
32
+
33
+ - **`layoutId` shared-element rects are now measured in window coordinates.** Rects came from `onLayout`, which reports **parent-relative** coordinates, so a source and target sitting under containers at different screen offsets produced a FLIP short by exactly that offset — the element flew in from the wrong place. Rects are now measured with `measureInWindow` on the host node, which is what makes nested-parent setups line up. Where a synchronous measurement isn't available the parent-relative rect is used instead, so behavior is unchanged rather than broken; each entry records which space it is in, and a source and target that ended up in _different_ spaces skip the animation rather than play a wrong one.
34
+
35
+ **Synchronous or not at all**, and this is a design decision rather than a limitation. `measureInWindow` resolves synchronously on Fabric (a JSI call), asynchronously on the legacy architecture (over the bridge), and **never** on a detached node — `ReactFabricHostComponent.measureInWindow` looks the node up and simply returns when it's missing, and the Jest host mock behaves the same way. Awaiting the callback would put the same element in window space on one platform and parent space on another, and since the two aren't comparable, a source stored in one and a target measured in the other would silently cancel the transition. Reading the result synchronously or treating it as unavailable keeps the space coherent: fixed on Fabric, unchanged on legacy, never intermittent. A late callback is deliberately dropped. A measurement that is zero-sized or non-finite is also rejected — trusting it would fling the element in from the top-left corner, which is worse than not animating.
36
+
37
+ **A still-mounted source is re-measured when the target lays out.** This is the other half of the change, and without it window coordinates would have been a net regression. `onLayout` does not fire when an _ancestor_ scrolls, so a stored window rect drifts as the user scrolls a list while a parent-relative rect would have stayed valid — meaning the most common shared-element case (scroll a list of photos, tap one) would have been offset by the scroll distance. A registry entry now carries a re-measure hook while its owner is mounted, which a stack navigator's outgoing screen still is at the moment the incoming one lays out. `releaseLayout` drops the hook, since a detached node measures to nothing. Remaining caveat: if the navigator has already begun translating the outgoing screen, the re-measurement catches it mid-transition — bounded by how far the transition has progressed, far smaller than an unbounded scroll offset.
38
+
39
+ Also fixed while here: **the four FLIP shared values now cancel on unmount.** The `0.0.2` unmount-cancel pass covered the value-layer hooks and the factory's per-key values but missed these. Workspace-internal API changes (none of it is exported from the package root): `SharedRect` gains a required `space` field, `consumeLayout` returns a source object instead of a bare rect, `registerLayout` takes an optional re-measure hook, and a new `__setSharedLayoutMeasurer` test hook joins `__setSharedLayoutClock`. Guarded by 12 new cases in `sharedLayout.test.tsx` (49 in total for this release, counting the style carry below).
40
+
41
+ ## [0.0.3] - 2026-07-25
42
+
43
+ ### Fixed
44
+
45
+ - **Properties mentioned only by `gesture` / `exit` / a non-current variant no longer stomp the static `style`.** A key touched by any of those joins the animated key set — the worklet has to know about it so the layer or branch can drive it later — but until something actually drove it, it rested at a generic default and the animated style, which merges _after_ `style`, silently overrode the element's own stylesheet. `<Motion.View style={styles.field} gesture={{ focused: { borderColor: '#4f46e5' } }} />` rendered `borderColor: 'transparent'` on the very first frame, before any interaction; `exit={{ width: 0 }}` collapsed the element to zero width while it was still on screen; a `width` present in one variant branch collapsed the element whenever a different branch was active. Affected every property whose default isn't an identity — `width`, `height`, `borderRadius`, `shadowOpacity`, `shadowRadius`, `elevation`, `shadowOffset`, and all five color keys. Transforms and `opacity` were unaffected, which is why this survived so long: their defaults (`0` / `1`) happen to be no-ops. Undriven properties now rest at the value the static `style` sets — read through `StyleSheet.flatten`, so style arrays and registered stylesheet IDs resolve, transform entries are read out of the `transform` array, `shadowOffset` decomposes into both axes, and unit-suffixed rotations (`'45deg'`, `'0.5rad'`) convert to the plain degrees the shared value holds — falling back to the type default only when the style is silent too. Gesture layers now blend from that style-derived base and return to it on release. The base also tracks a `style` that changes after mount (a theme swap no longer gets pinned to the value captured at mount). Non-numeric style values such as `width: '100%'` are deliberately not seeded into numeric slots, since a later `withTiming` can't interpolate them. Values a record has already driven are untouched: switching to a variant branch that omits a key still leaves it where the previous branch put it. Guarded by `style-resting.test.tsx` (18 cases).
46
+
47
+ - **`<Presence>` children now animate out in place instead of jumping to the end of their siblings.** The render list was built as "every present entry, then every exiting entry". React reconciles that array by key, so appending physically moved the node: removing the middle of a three-row list rendered `a, c, b` and the departing row visibly jumped to the bottom before it had finished fading. Absolutely-positioned overlays — popovers, sheets, toasts, the cases `<Presence>` gets used for most and the ones the existing tests covered — never showed it; every list and column did. Exiting entries are now spliced back in at the position they held, anchored immediately after their nearest surviving predecessor (or at the front if there isn't one), so adjacent departures keep their relative order and siblings added or reordered mid-exit are placed around them. `<Presence>` remembers the full previous render order, including entries that were already exiting, since an exiting child is by definition absent from `children`. Note for anyone touching this code: the ordering pass has to read the exiting map that the _current_ render computed, not the `useState` value — on the render that first detects a departure the state update hasn't applied yet, and using the stale map drops the child from the remembered order entirely on the following render, losing the exit animation rather than merely misplacing it. Guarded by `Presence.order.test.tsx` (12 cases; 7 fail against the previous implementation).
48
+
49
+ - **An endless (`repeat: 'infinite'`) animation no longer blocks completion counters.** A callback is only promoted to the terminal `'animation'` phase once `iteration >= totalIterations - 1`, which is unreachable against `Infinity`. Two counters were gated behind that check and both broke in the presence of an endless animation. **(1) The transform group** — a multi-axis transform coalesces its terminal callbacks into one `onAnimationEnd({ key: 'transform' })`, counting the participating axes and firing when the last settles. An endless axis pinned that count above zero forever, so `animate={{ translateX: 100, translateY: 50 }}` with `transition={{ translateX: { repeat: 'infinite' }, translateY: {} }}` settled `translateY`, decremented the counter, and fired **nothing** — the completion was silently swallowed. Endless axes are now excluded from the group, so the finite axes still report; when every transform axis is endless no terminal callback fires at all, which is correct since nothing finishes. **(2) `<Presence>`'s settle counter** — the same unreachable check gated `safeToRemove`, so an endless exit animation left the child **mounted forever**. A top-level `transition={{ repeat: 'infinite' }}` is inherited by `exit`, so a pulsing element inside `<Presence>` would never unmount — a permanent leak, not just a missed callback. Exit keys that can never settle are no longer counted: finite keys still gate the unmount, and if every exiting property is endless the child is released immediately. Scope the repeat to one property (`transition={{ opacity: { repeat: 'infinite' } }}`) when you want a loop _and_ a normal exit. Guarded by `endless-repeat.test.tsx` (8 cases; 4 fail against the previous implementation).
50
+
51
+ - **`useColorCascade` now notices when a layer's `progress` shared value is swapped.** The layer chain is memoized on a structural signature — key, base colour, layer count, layer colours — which can't contain the shared values themselves because they're objects, and they were excluded from change detection entirely. Swapping _which_ value drives a layer while its colour stayed the same therefore did nothing: the worklet went on reading the old shared value, and driving the one no longer referenced by any layer still moved the colour. A conditionally-sourced progress (`{ progress: isError ? errorSpring : hoverSpring, color }`) silently animated off the wrong input. Shared-value references are now compared directly and the array is rebuilt only when one actually differs, so the swap rewires the worklet while a fresh-but-equal `layers` literal still produces no new UI-thread closure.
52
+
53
+ - **`useAnimator()` is now identity-stable by construction, as documented.** Its JSDoc, the hooks reference, and the `0.0.2` changelog all promised an identity-stable setter safe to drop into memoized handlers, and all three explained it as reading the registry "live inside the body" — but the implementation listed `[registry, shouldReduceMotion]` as `useCallback` dependencies, so a provider republishing its `transitions` map or a reduced-motion change handed back a new function and churned every handler built on it. It stayed stable only by accident of `<MotionConfig>` memoizing. Both values now genuinely live in refs read at call time, which also makes writes resolve against the registry current _when the event fires_ rather than the one captured at render.
54
+
55
+ - **The `layoutId` measure registry now evicts expired entries.** Rects only ever left the module-level map through `consumeLayout` / `peekSharedLayout`, so a `layoutId` that unmounted and was never remounted kept its entry for the lifetime of the process. Harmless for a handful of hero images; a slow leak for per-item ids in a long-lived list (`layoutId={`photo-${item.id}`}`), where the release is never consumed. Writes now run an expiry sweep, amortized to at most one full scan per TTL window so a burst of layout events doesn't become a burst of scans. Sweeping a still-mounted element's entry is safe — it re-registers on its next `onLayout`, and unmount re-publishes the rect with a fresh TTL either way.
56
+
7
57
  ## [0.0.2] - 2026-07-24
8
58
 
9
59
  ### Added
@@ -64,9 +114,11 @@ All notable changes to `@rootnative/inertia` are documented here. The format fol
64
114
 
65
115
  - **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"`.
66
116
 
67
- ## [0.0.0-alpha.0]
117
+ ## 0.0.0-alpha.0
118
+
119
+ _No git tag was cut for this release; the published artifact is on npm as [`@rootnative/inertia@0.0.0-alpha.0`](https://www.npmjs.com/package/@rootnative/inertia/v/0.0.0-alpha.0). Unlinked here for that reason — every other heading resolves to a real tag._
68
120
 
69
- Initial alpha publish. The full v0.1 surface is in place; APIs are still subject to change before `0.1.0`.
121
+ Initial alpha publish. The full initial surface is in place; APIs are still subject to change before the stability lock at `1.0.0`.
70
122
 
71
123
  ### Added
72
124
 
@@ -89,7 +141,13 @@ Initial alpha publish. The full v0.1 surface is in place; APIs are still subject
89
141
  - SVG path morphing, gradient interpolation, and shared-element transitions across screens are out of scope until `0.2.x` / `1.x` per the roadmap.
90
142
  - `react-native-gesture-handler` integration (drag, pan, swipe sub-states) lands in `0.2` via the optional `@rootnative/inertia-gestures` adapter.
91
143
 
92
- [unreleased]: https://github.com/rootnative/inertia/compare/core+gestures+gradients+svg@0.0.0-alpha.2...HEAD
144
+ [unreleased]: https://github.com/rootnative/inertia/compare/core+gestures+gradients+svg@0.0.4...HEAD
145
+ [0.0.4]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.4
146
+ [0.0.3]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.3
147
+ [0.0.2]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.2
148
+ [0.0.1]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.1
149
+ [0.0.0-alpha.5]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.5
150
+ [0.0.0-alpha.4]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.4
151
+ [0.0.0-alpha.3]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.3
93
152
  [0.0.0-alpha.2]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.2
94
153
  [0.0.0-alpha.1]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.1
95
- [0.0.0-alpha.0]: https://github.com/rootnative/inertia/releases/tag/v0.0.0-alpha.0
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  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).
8
8
 
9
- > **Status:** `0.0.1` — the first stable release. Pre-`1.0.0` minor versions may break — see the root [README](https://github.com/rootnative/inertia#versioning--release).
9
+ > **Status:** `0.0.4` — stable. Pre-`1.0.0` minor versions may break — see the root [README](https://github.com/rootnative/inertia#versioning--release).
10
10
 
11
11
  ## Install
12
12
 
@@ -86,9 +86,11 @@ Plus, on any transition: `delay`, `repeat`. Per-property transitions take preced
86
86
 
87
87
  ## Animatable properties
88
88
 
89
- Numeric: `opacity`, `translateX`, `translateY`, `scale`, `scaleX`, `scaleY`, `rotate`, `rotateX`, `rotateY`, `width`, `height`, `borderRadius`. Color: `backgroundColor`, `borderColor`, `color`, `tintColor` (Image only — `Motion.View` rejects it at compile time). Layout transforms via `transform: [...]`. Color targets are forwarded straight through `withSpring` / `withTiming`; Reanimated's value setter packs the string to RGBA and interpolates on the UI thread.
89
+ Numeric: `opacity`, `translateX`, `translateY`, `scale`, `scaleX`, `scaleY`, `rotate`, `rotateX`, `rotateY`, `width`, `height`, `borderRadius`, `shadowOpacity`, `shadowRadius`, `elevation`. Color: `backgroundColor`, `borderColor`, `color`, `shadowColor`, `tintColor` (Image only — `Motion.View` rejects it at compile time). Layout transforms via `transform: [...]`. Color targets are forwarded straight through `withSpring` / `withTiming`; Reanimated's value setter packs the string to RGBA and interpolates on the UI thread.
90
90
 
91
- SVG path morphing ships in the [`@rootnative/inertia-svg`](../svg) adapter (`MotionPath`). Shared-element transitions across screens are wired through the `layoutId` prop pair the same id on a source and target `Motion.*` and Inertia FLIPs between them on mount.
91
+ Nested object: `shadowOffset: { width, height }` — single-value form only (no sequences, no array keyframes). Structured: `boxShadow` — the cross-platform CSS shadow, as a string (`'0px 4px 8px rgba(0,0,0,0.3)'`) or RN's `BoxShadowValue[]`. Endpoints are padded to a common layer count, so layer counts may differ between `initial` and `animate`; sequences and `gesture` sub-states are not supported on this key.
92
+
93
+ SVG path morphing ships in the [`@rootnative/inertia-svg`](../svg) adapter (`MotionPath`). Shared-element transitions across screens are wired through the `layoutId` prop — pair the same id on a source and target `Motion.*` and Inertia FLIPs between them on mount, carrying `opacity`, `borderRadius`, and the color keys across alongside the rect.
92
94
 
93
95
  ## When not to use the core package alone
94
96
 
@@ -1,4 +1,4 @@
1
- import { createMotionComponent } from './chunk-LYMLQ6WQ.mjs';
1
+ import { createMotionComponent } from './chunk-55W7BNO2.mjs';
2
2
  import { Text } from 'react-native';
3
3
 
4
4
  var MotionText = createMotionComponent(Text);