@rootnative/inertia-svg 0.0.0-alpha.1 → 0.0.0-alpha.3

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.
package/CHANGELOG.md CHANGED
@@ -6,11 +6,24 @@ This package ships in lockstep with `@rootnative/inertia` — version numbers tr
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.0.0-alpha.2] - 2026-07-20
10
+
11
+ ### Added
12
+
13
+ - **`createMotionSvgComponent(Component, config)` factory** — wraps any `react-native-svg` element with the same `initial` / `animate` / `transition` surface as `MotionPath`. Config declares the animatable surface: `animatableProps` (numeric), `colorProps` (color strings), and `arrayProps` (numeric arrays, element-wise with the array length locked at mount — the same rule `MotionPath` applies to path commands). Per-key engagement is locked at mount; `transition` accepts named transitions from the nearest `<MotionConfig transitions>`, both top-level and per-property.
14
+ - **Prebuilt `MotionCircle` / `MotionRect` / `MotionLine`** shapes built on the factory, also reachable as `MotionSvg.Circle` / `.Rect` / `.Line`. `MotionCircle` animates `cx` / `cy` / `r` / `strokeWidth` / opacities / `strokeDashoffset` plus `fill` / `stroke`, and `strokeDasharray` element-wise — the progress-ring shape (`strokeDasharray` circumference + animated `strokeDashoffset`) works without any direct Reanimated imports.
15
+
16
+ ## [0.0.0-alpha.1] - 2026-07-19
17
+
18
+ Lockstep version bump alongside `@rootnative/inertia@0.0.0-alpha.1` (README / `llms.txt` updates only; no runtime changes).
19
+
9
20
  ## [0.0.0-alpha.0]
10
21
 
11
22
  ### Added
12
23
 
13
24
  - `MotionPath` over `react-native-svg`. Animatable: `d` (element-wise scalar interpolation on structurally-compatible paths), `fill`, `stroke`, `strokeWidth`, opacities, `strokeDashoffset`. Source and target paths must share the same command sequence after implicit-repeat expansion; remount with `key` to switch shape.
14
25
 
15
- [unreleased]: https://github.com/rootnative/inertia/compare/v0.0.0-alpha.0...HEAD
26
+ [unreleased]: https://github.com/rootnative/inertia/compare/core+gestures+gradients+svg@0.0.0-alpha.2...HEAD
27
+ [0.0.0-alpha.2]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.2
28
+ [0.0.0-alpha.1]: https://github.com/rootnative/inertia/releases/tag/core+gestures+gradients+svg@0.0.0-alpha.1
16
29
  [0.0.0-alpha.0]: https://github.com/rootnative/inertia/releases/tag/v0.0.0-alpha.0
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Animatable SVG primitives for [`@rootnative/inertia`](../core), built on [`react-native-svg`](https://github.com/software-mansion/react-native-svg).
7
7
 
8
- `MotionPath` accepts the same `initial` / `animate` / `transition` shape as the core `Motion.*` primitives, with animatable keys for the path data (`d`), color paint (`fill`, `stroke`), and numeric paint (`strokeWidth`, opacities, `strokeDashoffset`).
8
+ `MotionPath` accepts the same `initial` / `animate` / `transition` shape as the core `Motion.*` primitives, with animatable keys for the path data (`d`), color paint (`fill`, `stroke`), and numeric paint (`strokeWidth`, opacities, `strokeDashoffset`). Prebuilt `MotionCircle` / `MotionRect` / `MotionLine` cover the other common shapes, and the `createMotionSvgComponent` factory behind them wraps any `react-native-svg` element. Everything is also reachable through the `MotionSvg` namespace (`MotionSvg.Path` / `.Circle` / `.Rect` / `.Line`).
9
9
 
10
10
  ## Install
11
11
 
@@ -81,13 +81,54 @@ In dev, the component throws on template mismatches at mount, when `animate.d` c
81
81
 
82
82
  Path resampling between structurally different shapes (flubber-style) is out of scope for v0.2. For arbitrary shape swaps, remount with `key={...}`.
83
83
 
84
+ ## Shapes — MotionCircle, MotionRect, MotionLine
85
+
86
+ Prebuilt geometry primitives with the same `initial` / `animate` / `transition` surface. Each animates its numeric geometry props (`cx` / `cy` / `r`, `x` / `y` / `width` / `height` / `rx` / `ry`, `x1` / `y1` / `x2` / `y2`), the `fill` / `stroke` paints (`stroke` only for `MotionLine`), opacities, `strokeDashoffset` — and `strokeDasharray` element-wise, with the array length locked at mount (the same rule `MotionPath` applies to path commands). The canonical consumer is a circular progress ring:
87
+
88
+ ```tsx
89
+ import Svg from 'react-native-svg'
90
+ import { MotionCircle } from '@rootnative/inertia-svg'
91
+
92
+ const CIRCUMFERENCE = 2 * Math.PI * 40
93
+
94
+ <Svg viewBox="0 0 100 100" width={96} height={96}>
95
+ <MotionCircle
96
+ cx={50}
97
+ cy={50}
98
+ r={40}
99
+ fill="none"
100
+ stroke="#4f46e5"
101
+ strokeWidth={8}
102
+ strokeDasharray={[CIRCUMFERENCE]}
103
+ animate={{ strokeDashoffset: CIRCUMFERENCE * (1 - progress) }}
104
+ transition={{ type: 'timing', duration: 250 }}
105
+ />
106
+ </Svg>
107
+ ```
108
+
109
+ ## createMotionSvgComponent
110
+
111
+ The factory behind the prebuilt shapes — wraps any other `react-native-svg` element:
112
+
113
+ ```tsx
114
+ import { Ellipse } from 'react-native-svg'
115
+ import { createMotionSvgComponent } from '@rootnative/inertia-svg'
116
+
117
+ const MotionEllipse = createMotionSvgComponent(Ellipse, {
118
+ animatableProps: ['cx', 'cy', 'rx', 'ry', 'strokeWidth', 'opacity'],
119
+ colorProps: ['fill', 'stroke'],
120
+ arrayProps: ['strokeDasharray'],
121
+ })
122
+ ```
123
+
124
+ `animatableProps` are numeric, `colorProps` are color strings, `arrayProps` are numeric arrays (element-wise, length locked at mount). `transition` accepts named transitions from the nearest `<MotionConfig transitions>`, top-level and per-property.
125
+
84
126
  ## Reduced motion
85
127
 
86
- `MotionPath` participates in `<MotionConfig reducedMotion>` just like the core primitives — when the OS reduce-motion setting is on (or you pass `reducedMotion="always"`), every animated property snaps directly to its target.
128
+ All primitives participate in `<MotionConfig reducedMotion>` just like the core ones — when the OS reduce-motion setting is on (or you pass `reducedMotion="always"`), every animated property snaps directly to its target.
87
129
 
88
130
  ## What this package doesn't do (v0.2)
89
131
 
90
- - Other SVG shapes (`Circle`, `Rect`, `Line`, `Ellipse`) — land in a follow-up once the `MotionPath` API is validated.
91
132
  - Path resampling between arbitrary shapes.
92
133
  - Morphing an `L` into a `C` (or other across-command interpolation). Element-wise scalar interpolation is intentional.
93
134
 
package/dist/index.d.mts CHANGED
@@ -1,6 +1,118 @@
1
1
  import * as react from 'react';
2
+ import { ComponentType } from 'react';
3
+ import { TransitionInput, TransitionConfig } from '@rootnative/inertia';
4
+ import * as react_native_svg from 'react-native-svg';
2
5
  import { PathProps } from 'react-native-svg';
3
- import { TransitionConfig } from '@rootnative/inertia';
6
+
7
+ /** String keys of the wrapped component's props. */
8
+ type SvgKey<P> = Extract<keyof P, string>;
9
+ /**
10
+ * Animatable target snapshot for a factory-built motion SVG component. Every
11
+ * field is optional — include only the dimensions you want to animate; the
12
+ * rest fall back to the static props on the component.
13
+ */
14
+ type SvgAnimate<NK extends string = never, CK extends string = never, AK extends string = never> = Partial<Record<NK, number>> & Partial<Record<CK, string>> & Partial<Record<AK, readonly number[]>>;
15
+ /**
16
+ * Per-property transition map for a factory-built motion SVG component. Each
17
+ * entry accepts a `TransitionConfig` or a `TransitionName` registered on the
18
+ * nearest `<MotionConfig transitions>`.
19
+ */
20
+ type SvgPerPropertyTransition<K extends string> = Partial<Record<K, TransitionInput>>;
21
+ /**
22
+ * Transition shape accepted by factory-built motion SVG components: a single
23
+ * config (or registered name) applied to every animated dimension, or a
24
+ * per-property map. Per-property entries win over the top-level transition.
25
+ */
26
+ type SvgTransition<K extends string> = TransitionInput | SvgPerPropertyTransition<K>;
27
+ /**
28
+ * Configuration for `createMotionSvgComponent`. Declares which of the wrapped
29
+ * component's props are animatable and how each interpolates:
30
+ *
31
+ * - `animatableProps` — numeric props (`cx`, `r`, `strokeDashoffset`, …),
32
+ * spring / timing / decay-driven.
33
+ * - `colorProps` — color-string props (`fill`, `stroke`), interpolated via
34
+ * Reanimated's native color animation.
35
+ * - `arrayProps` — numeric-array props (`strokeDasharray`), interpolated
36
+ * element-wise. **The array length is locked at first render** — the same
37
+ * shape-locked-at-mount rule `MotionPath` applies to path commands. Remount
38
+ * with a new `key` to change the length.
39
+ */
40
+ interface CreateMotionSvgComponentConfig<P, NK extends SvgKey<P>, CK extends SvgKey<P>, AK extends SvgKey<P>> {
41
+ animatableProps: readonly NK[];
42
+ colorProps?: readonly CK[];
43
+ arrayProps?: readonly AK[];
44
+ }
45
+ /**
46
+ * Props of a factory-built motion SVG component: the wrapped component's own
47
+ * props (with the animatable keys narrowed to the animatable value shape)
48
+ * plus `initial` / `animate` / `transition`.
49
+ */
50
+ type MotionSvgComponentProps<P, NK extends string, CK extends string, AK extends string> = Omit<P, NK | CK | AK> & Partial<Record<NK, number>> & Partial<Record<CK, string>> & Partial<Record<AK, readonly number[]>> & {
51
+ /**
52
+ * Initial frame override. When present, the component mounts displaying
53
+ * these values, then animates to `animate` on the next effect. Pass
54
+ * `false` to skip the initial-mount animation entirely.
55
+ */
56
+ initial?: SvgAnimate<NK, CK, AK> | false;
57
+ /** Target animation state. */
58
+ animate?: SvgAnimate<NK, CK, AK>;
59
+ /**
60
+ * Transition config — a single `TransitionConfig` (or `TransitionName`
61
+ * registered on the nearest `<MotionConfig transitions>`) applied to
62
+ * every animated dimension, or a per-property map. Per-property entries
63
+ * win over the top-level transition.
64
+ */
65
+ transition?: SvgTransition<NK | CK | AK>;
66
+ };
67
+ /**
68
+ * Build an animatable wrapper around any `react-native-svg` element, driven
69
+ * by the same `initial` / `animate` / `transition` shape as the core
70
+ * `Motion.*` primitives. This is the mechanism behind the prebuilt
71
+ * `MotionCircle` / `MotionRect` / `MotionLine` — use it directly for any
72
+ * element the package doesn't prebuild (`Ellipse`, `Stop`, …).
73
+ *
74
+ * Semantics shared with the rest of the library:
75
+ *
76
+ * - `transition` accepts a config, a registered `TransitionName`, or a
77
+ * per-property map (entries accept names too); names resolve at the
78
+ * nearest `<MotionConfig transitions>`.
79
+ * - `<MotionConfig reducedMotion>` collapses every transition to
80
+ * `no-animation` so values snap.
81
+ * - `initial` seeds the first frame and is read once on mount;
82
+ * `initial={false}` mounts directly at the `animate` target.
83
+ *
84
+ * Factory-specific rules:
85
+ *
86
+ * - **A key only renders through the animation pipeline when it is present
87
+ * at mount** — in the static props, `initial`, or `animate`. Keys
88
+ * introduced into `animate` after mount warn in dev and are ignored
89
+ * (remount with `key={...}` to pick them up). Keys never engaged pass
90
+ * through as ordinary static props.
91
+ * - **Array props lock their length at first render.** Element-wise
92
+ * interpolation needs a stable slot count — a target with a different
93
+ * length throws in dev and is ignored in production.
94
+ * - Numeric keys engaged only via `animate` seed from `0`; color keys seed
95
+ * from `'transparent'`. Provide a static prop or `initial` value when the
96
+ * mount animation should start elsewhere.
97
+ *
98
+ * @example An animatable `<Ellipse>`
99
+ * ```tsx
100
+ * import { Ellipse } from 'react-native-svg'
101
+ * import { createMotionSvgComponent } from '@rootnative/inertia-svg'
102
+ *
103
+ * const MotionEllipse = createMotionSvgComponent(Ellipse, {
104
+ * animatableProps: ['cx', 'cy', 'rx', 'ry', 'opacity'],
105
+ * colorProps: ['fill', 'stroke'],
106
+ * })
107
+ *
108
+ * <MotionEllipse
109
+ * cx={50} cy={50} rx={10} ry={20}
110
+ * animate={{ rx: 30, fill: '#7c3aed' }}
111
+ * transition={{ type: 'spring', tension: 180, friction: 14 }}
112
+ * />
113
+ * ```
114
+ */
115
+ declare function createMotionSvgComponent<P extends object, NK extends SvgKey<P>, CK extends SvgKey<P> = never, AK extends SvgKey<P> = never>(Component: ComponentType<P>, config: CreateMotionSvgComponentConfig<P, NK, CK, AK>): ComponentType<MotionSvgComponentProps<P, NK, CK, AK>>;
4
116
 
5
117
  /**
6
118
  * Animatable target snapshot for a `MotionSvg.Path`. Every field is optional
@@ -96,6 +208,50 @@ interface MotionPathProps extends Omit<PathProps, 'd' | 'fill' | 'stroke' | 'str
96
208
  */
97
209
  declare function MotionPath(props: MotionPathProps): react.JSX.Element;
98
210
 
211
+ /**
212
+ * Animatable `<Circle>` from `react-native-svg`, built with
213
+ * `createMotionSvgComponent`. Animatable dimensions: `cx`, `cy`, `r`,
214
+ * `strokeWidth`, `strokeOpacity`, `fillOpacity`, `opacity`,
215
+ * `strokeDashoffset` (numeric), `fill` / `stroke` (color), and
216
+ * `strokeDasharray` (numeric array, length locked at mount).
217
+ *
218
+ * The canonical consumer is a circular progress ring — animate
219
+ * `strokeDashoffset` against a static `strokeDasharray` of the circumference:
220
+ *
221
+ * @example
222
+ * ```tsx
223
+ * const CIRCUMFERENCE = 2 * Math.PI * 45
224
+ *
225
+ * <Svg viewBox="0 0 100 100">
226
+ * <MotionCircle
227
+ * cx={50} cy={50} r={45}
228
+ * stroke="#0ea5e9" strokeWidth={8} fill="none"
229
+ * strokeDasharray={[CIRCUMFERENCE]}
230
+ * strokeDashoffset={CIRCUMFERENCE}
231
+ * animate={{ strokeDashoffset: CIRCUMFERENCE * (1 - progress) }}
232
+ * transition={{ type: 'timing', duration: 300 }}
233
+ * />
234
+ * </Svg>
235
+ * ```
236
+ */
237
+ declare const MotionCircle: react.ComponentType<MotionSvgComponentProps<react_native_svg.CircleProps, "cx" | "cy" | "opacity" | "r" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset", "fill" | "stroke", "strokeDasharray">>;
238
+ /**
239
+ * Animatable `<Rect>` from `react-native-svg`, built with
240
+ * `createMotionSvgComponent`. Animatable dimensions: `x`, `y`, `width`,
241
+ * `height`, `rx`, `ry`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
242
+ * `opacity`, `strokeDashoffset` (numeric), `fill` / `stroke` (color), and
243
+ * `strokeDasharray` (numeric array, length locked at mount).
244
+ */
245
+ declare const MotionRect: react.ComponentType<MotionSvgComponentProps<react_native_svg.RectProps, "opacity" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x" | "y" | "width" | "height" | "rx" | "ry", "fill" | "stroke", "strokeDasharray">>;
246
+ /**
247
+ * Animatable `<Line>` from `react-native-svg`, built with
248
+ * `createMotionSvgComponent`. Animatable dimensions: `x1`, `y1`, `x2`, `y2`,
249
+ * `strokeWidth`, `strokeOpacity`, `opacity`, `strokeDashoffset` (numeric),
250
+ * `stroke` (color), and `strokeDasharray` (numeric array, length locked at
251
+ * mount).
252
+ */
253
+ declare const MotionLine: react.ComponentType<MotionSvgComponentProps<react_native_svg.LineProps, "opacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x1" | "x2" | "y1" | "y2", "stroke", "strokeDasharray">>;
254
+
99
255
  /**
100
256
  * SVG path-string utilities used by `MotionSvg.Path`. Everything here runs on
101
257
  * the JS thread — paths are tokenized into a normalized command list at mount
@@ -158,31 +314,15 @@ declare function diffTemplate(source: PathTemplate, target: PathTemplate): strin
158
314
  declare function serializePath(template: PathTemplate, params: ReadonlyArray<number>): string;
159
315
 
160
316
  /**
161
- * `@rootnative/inertia-svg` animatable SVG primitives for
162
- * `@rootnative/inertia`.
163
- *
164
- * v0.2 surface:
165
- * - `MotionPath` / `MotionSvg.Path` — animatable `<Path>` over
166
- * `react-native-svg`. Supports path morphing on the `d` attribute (source
167
- * and target must share the same command sequence) plus animatable
168
- * `fill`, `stroke`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
169
- * `opacity`, and `strokeDashoffset` with the same `initial` /
170
- * `animate` / `transition` shape as the core `Motion.*` primitives.
171
- *
172
- * Additional shape primitives (`Circle`, `Rect`, `Line`, `Ellipse`) land in
173
- * a follow-up once the path morphing API is validated. Path normalization
174
- * (resampling between structurally different paths) is out of scope for
175
- * v0.2 — use structurally-compatible source/target paths and remount with
176
- * `key={...}` to switch shape.
177
- */
178
-
179
- /**
180
- * Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` for
181
- * autocomplete-friendly grouping or import `MotionPath` directly — both
182
- * point at the same component.
317
+ * Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` /
318
+ * `MotionSvg.Circle` for autocomplete-friendly grouping or import
319
+ * `MotionPath` / `MotionCircle` directly — both point at the same component.
183
320
  */
184
321
  declare const MotionSvg: {
185
322
  readonly Path: typeof MotionPath;
323
+ readonly Circle: react.ComponentType<MotionSvgComponentProps<react_native_svg.CircleProps, "cx" | "cy" | "opacity" | "r" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset", "fill" | "stroke", "strokeDasharray">>;
324
+ readonly Rect: react.ComponentType<MotionSvgComponentProps<react_native_svg.RectProps, "opacity" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x" | "y" | "width" | "height" | "rx" | "ry", "fill" | "stroke", "strokeDasharray">>;
325
+ readonly Line: react.ComponentType<MotionSvgComponentProps<react_native_svg.LineProps, "opacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x1" | "x2" | "y1" | "y2", "stroke", "strokeDasharray">>;
186
326
  };
187
327
 
188
- export { MotionPath, type MotionPathProps, MotionSvg, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };
328
+ export { type CreateMotionSvgComponentConfig, MotionCircle, MotionLine, MotionPath, type MotionPathProps, MotionRect, MotionSvg, type MotionSvgComponentProps, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, type SvgAnimate, type SvgPerPropertyTransition, type SvgTransition, createMotionSvgComponent, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,118 @@
1
1
  import * as react from 'react';
2
+ import { ComponentType } from 'react';
3
+ import { TransitionInput, TransitionConfig } from '@rootnative/inertia';
4
+ import * as react_native_svg from 'react-native-svg';
2
5
  import { PathProps } from 'react-native-svg';
3
- import { TransitionConfig } from '@rootnative/inertia';
6
+
7
+ /** String keys of the wrapped component's props. */
8
+ type SvgKey<P> = Extract<keyof P, string>;
9
+ /**
10
+ * Animatable target snapshot for a factory-built motion SVG component. Every
11
+ * field is optional — include only the dimensions you want to animate; the
12
+ * rest fall back to the static props on the component.
13
+ */
14
+ type SvgAnimate<NK extends string = never, CK extends string = never, AK extends string = never> = Partial<Record<NK, number>> & Partial<Record<CK, string>> & Partial<Record<AK, readonly number[]>>;
15
+ /**
16
+ * Per-property transition map for a factory-built motion SVG component. Each
17
+ * entry accepts a `TransitionConfig` or a `TransitionName` registered on the
18
+ * nearest `<MotionConfig transitions>`.
19
+ */
20
+ type SvgPerPropertyTransition<K extends string> = Partial<Record<K, TransitionInput>>;
21
+ /**
22
+ * Transition shape accepted by factory-built motion SVG components: a single
23
+ * config (or registered name) applied to every animated dimension, or a
24
+ * per-property map. Per-property entries win over the top-level transition.
25
+ */
26
+ type SvgTransition<K extends string> = TransitionInput | SvgPerPropertyTransition<K>;
27
+ /**
28
+ * Configuration for `createMotionSvgComponent`. Declares which of the wrapped
29
+ * component's props are animatable and how each interpolates:
30
+ *
31
+ * - `animatableProps` — numeric props (`cx`, `r`, `strokeDashoffset`, …),
32
+ * spring / timing / decay-driven.
33
+ * - `colorProps` — color-string props (`fill`, `stroke`), interpolated via
34
+ * Reanimated's native color animation.
35
+ * - `arrayProps` — numeric-array props (`strokeDasharray`), interpolated
36
+ * element-wise. **The array length is locked at first render** — the same
37
+ * shape-locked-at-mount rule `MotionPath` applies to path commands. Remount
38
+ * with a new `key` to change the length.
39
+ */
40
+ interface CreateMotionSvgComponentConfig<P, NK extends SvgKey<P>, CK extends SvgKey<P>, AK extends SvgKey<P>> {
41
+ animatableProps: readonly NK[];
42
+ colorProps?: readonly CK[];
43
+ arrayProps?: readonly AK[];
44
+ }
45
+ /**
46
+ * Props of a factory-built motion SVG component: the wrapped component's own
47
+ * props (with the animatable keys narrowed to the animatable value shape)
48
+ * plus `initial` / `animate` / `transition`.
49
+ */
50
+ type MotionSvgComponentProps<P, NK extends string, CK extends string, AK extends string> = Omit<P, NK | CK | AK> & Partial<Record<NK, number>> & Partial<Record<CK, string>> & Partial<Record<AK, readonly number[]>> & {
51
+ /**
52
+ * Initial frame override. When present, the component mounts displaying
53
+ * these values, then animates to `animate` on the next effect. Pass
54
+ * `false` to skip the initial-mount animation entirely.
55
+ */
56
+ initial?: SvgAnimate<NK, CK, AK> | false;
57
+ /** Target animation state. */
58
+ animate?: SvgAnimate<NK, CK, AK>;
59
+ /**
60
+ * Transition config — a single `TransitionConfig` (or `TransitionName`
61
+ * registered on the nearest `<MotionConfig transitions>`) applied to
62
+ * every animated dimension, or a per-property map. Per-property entries
63
+ * win over the top-level transition.
64
+ */
65
+ transition?: SvgTransition<NK | CK | AK>;
66
+ };
67
+ /**
68
+ * Build an animatable wrapper around any `react-native-svg` element, driven
69
+ * by the same `initial` / `animate` / `transition` shape as the core
70
+ * `Motion.*` primitives. This is the mechanism behind the prebuilt
71
+ * `MotionCircle` / `MotionRect` / `MotionLine` — use it directly for any
72
+ * element the package doesn't prebuild (`Ellipse`, `Stop`, …).
73
+ *
74
+ * Semantics shared with the rest of the library:
75
+ *
76
+ * - `transition` accepts a config, a registered `TransitionName`, or a
77
+ * per-property map (entries accept names too); names resolve at the
78
+ * nearest `<MotionConfig transitions>`.
79
+ * - `<MotionConfig reducedMotion>` collapses every transition to
80
+ * `no-animation` so values snap.
81
+ * - `initial` seeds the first frame and is read once on mount;
82
+ * `initial={false}` mounts directly at the `animate` target.
83
+ *
84
+ * Factory-specific rules:
85
+ *
86
+ * - **A key only renders through the animation pipeline when it is present
87
+ * at mount** — in the static props, `initial`, or `animate`. Keys
88
+ * introduced into `animate` after mount warn in dev and are ignored
89
+ * (remount with `key={...}` to pick them up). Keys never engaged pass
90
+ * through as ordinary static props.
91
+ * - **Array props lock their length at first render.** Element-wise
92
+ * interpolation needs a stable slot count — a target with a different
93
+ * length throws in dev and is ignored in production.
94
+ * - Numeric keys engaged only via `animate` seed from `0`; color keys seed
95
+ * from `'transparent'`. Provide a static prop or `initial` value when the
96
+ * mount animation should start elsewhere.
97
+ *
98
+ * @example An animatable `<Ellipse>`
99
+ * ```tsx
100
+ * import { Ellipse } from 'react-native-svg'
101
+ * import { createMotionSvgComponent } from '@rootnative/inertia-svg'
102
+ *
103
+ * const MotionEllipse = createMotionSvgComponent(Ellipse, {
104
+ * animatableProps: ['cx', 'cy', 'rx', 'ry', 'opacity'],
105
+ * colorProps: ['fill', 'stroke'],
106
+ * })
107
+ *
108
+ * <MotionEllipse
109
+ * cx={50} cy={50} rx={10} ry={20}
110
+ * animate={{ rx: 30, fill: '#7c3aed' }}
111
+ * transition={{ type: 'spring', tension: 180, friction: 14 }}
112
+ * />
113
+ * ```
114
+ */
115
+ declare function createMotionSvgComponent<P extends object, NK extends SvgKey<P>, CK extends SvgKey<P> = never, AK extends SvgKey<P> = never>(Component: ComponentType<P>, config: CreateMotionSvgComponentConfig<P, NK, CK, AK>): ComponentType<MotionSvgComponentProps<P, NK, CK, AK>>;
4
116
 
5
117
  /**
6
118
  * Animatable target snapshot for a `MotionSvg.Path`. Every field is optional
@@ -96,6 +208,50 @@ interface MotionPathProps extends Omit<PathProps, 'd' | 'fill' | 'stroke' | 'str
96
208
  */
97
209
  declare function MotionPath(props: MotionPathProps): react.JSX.Element;
98
210
 
211
+ /**
212
+ * Animatable `<Circle>` from `react-native-svg`, built with
213
+ * `createMotionSvgComponent`. Animatable dimensions: `cx`, `cy`, `r`,
214
+ * `strokeWidth`, `strokeOpacity`, `fillOpacity`, `opacity`,
215
+ * `strokeDashoffset` (numeric), `fill` / `stroke` (color), and
216
+ * `strokeDasharray` (numeric array, length locked at mount).
217
+ *
218
+ * The canonical consumer is a circular progress ring — animate
219
+ * `strokeDashoffset` against a static `strokeDasharray` of the circumference:
220
+ *
221
+ * @example
222
+ * ```tsx
223
+ * const CIRCUMFERENCE = 2 * Math.PI * 45
224
+ *
225
+ * <Svg viewBox="0 0 100 100">
226
+ * <MotionCircle
227
+ * cx={50} cy={50} r={45}
228
+ * stroke="#0ea5e9" strokeWidth={8} fill="none"
229
+ * strokeDasharray={[CIRCUMFERENCE]}
230
+ * strokeDashoffset={CIRCUMFERENCE}
231
+ * animate={{ strokeDashoffset: CIRCUMFERENCE * (1 - progress) }}
232
+ * transition={{ type: 'timing', duration: 300 }}
233
+ * />
234
+ * </Svg>
235
+ * ```
236
+ */
237
+ declare const MotionCircle: react.ComponentType<MotionSvgComponentProps<react_native_svg.CircleProps, "cx" | "cy" | "opacity" | "r" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset", "fill" | "stroke", "strokeDasharray">>;
238
+ /**
239
+ * Animatable `<Rect>` from `react-native-svg`, built with
240
+ * `createMotionSvgComponent`. Animatable dimensions: `x`, `y`, `width`,
241
+ * `height`, `rx`, `ry`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
242
+ * `opacity`, `strokeDashoffset` (numeric), `fill` / `stroke` (color), and
243
+ * `strokeDasharray` (numeric array, length locked at mount).
244
+ */
245
+ declare const MotionRect: react.ComponentType<MotionSvgComponentProps<react_native_svg.RectProps, "opacity" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x" | "y" | "width" | "height" | "rx" | "ry", "fill" | "stroke", "strokeDasharray">>;
246
+ /**
247
+ * Animatable `<Line>` from `react-native-svg`, built with
248
+ * `createMotionSvgComponent`. Animatable dimensions: `x1`, `y1`, `x2`, `y2`,
249
+ * `strokeWidth`, `strokeOpacity`, `opacity`, `strokeDashoffset` (numeric),
250
+ * `stroke` (color), and `strokeDasharray` (numeric array, length locked at
251
+ * mount).
252
+ */
253
+ declare const MotionLine: react.ComponentType<MotionSvgComponentProps<react_native_svg.LineProps, "opacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x1" | "x2" | "y1" | "y2", "stroke", "strokeDasharray">>;
254
+
99
255
  /**
100
256
  * SVG path-string utilities used by `MotionSvg.Path`. Everything here runs on
101
257
  * the JS thread — paths are tokenized into a normalized command list at mount
@@ -158,31 +314,15 @@ declare function diffTemplate(source: PathTemplate, target: PathTemplate): strin
158
314
  declare function serializePath(template: PathTemplate, params: ReadonlyArray<number>): string;
159
315
 
160
316
  /**
161
- * `@rootnative/inertia-svg` animatable SVG primitives for
162
- * `@rootnative/inertia`.
163
- *
164
- * v0.2 surface:
165
- * - `MotionPath` / `MotionSvg.Path` — animatable `<Path>` over
166
- * `react-native-svg`. Supports path morphing on the `d` attribute (source
167
- * and target must share the same command sequence) plus animatable
168
- * `fill`, `stroke`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
169
- * `opacity`, and `strokeDashoffset` with the same `initial` /
170
- * `animate` / `transition` shape as the core `Motion.*` primitives.
171
- *
172
- * Additional shape primitives (`Circle`, `Rect`, `Line`, `Ellipse`) land in
173
- * a follow-up once the path morphing API is validated. Path normalization
174
- * (resampling between structurally different paths) is out of scope for
175
- * v0.2 — use structurally-compatible source/target paths and remount with
176
- * `key={...}` to switch shape.
177
- */
178
-
179
- /**
180
- * Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` for
181
- * autocomplete-friendly grouping or import `MotionPath` directly — both
182
- * point at the same component.
317
+ * Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` /
318
+ * `MotionSvg.Circle` for autocomplete-friendly grouping or import
319
+ * `MotionPath` / `MotionCircle` directly — both point at the same component.
183
320
  */
184
321
  declare const MotionSvg: {
185
322
  readonly Path: typeof MotionPath;
323
+ readonly Circle: react.ComponentType<MotionSvgComponentProps<react_native_svg.CircleProps, "cx" | "cy" | "opacity" | "r" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset", "fill" | "stroke", "strokeDasharray">>;
324
+ readonly Rect: react.ComponentType<MotionSvgComponentProps<react_native_svg.RectProps, "opacity" | "fillOpacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x" | "y" | "width" | "height" | "rx" | "ry", "fill" | "stroke", "strokeDasharray">>;
325
+ readonly Line: react.ComponentType<MotionSvgComponentProps<react_native_svg.LineProps, "opacity" | "strokeWidth" | "strokeOpacity" | "strokeDashoffset" | "x1" | "x2" | "y1" | "y2", "stroke", "strokeDasharray">>;
186
326
  };
187
327
 
188
- export { MotionPath, type MotionPathProps, MotionSvg, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };
328
+ export { type CreateMotionSvgComponentConfig, MotionCircle, MotionLine, MotionPath, type MotionPathProps, MotionRect, MotionSvg, type MotionSvgComponentProps, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, type SvgAnimate, type SvgPerPropertyTransition, type SvgTransition, createMotionSvgComponent, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };