@pixodesk/svg-animator-rn 1.0.21 → 1.0.24

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { PxAnimatedSvgDocument, FillMode, PlaybackDirection, PxNode } from '@pixodesk/svg-animator-core';
2
- import React, { ReactElement, ComponentType, ReactNode } from 'react';
1
+ import { PxAnimatedSvgDocument, FillMode, PlaybackDirection, OutAction, PxDefs, PxNode } from '@pixodesk/svg-animator-core';
2
+ import React, { ReactElement, ComponentType, ReactNode, Component, ErrorInfo } from 'react';
3
3
 
4
4
  /** Imperative playback API — mirrors ReactAnimatorApi from svg-animator-react. */
5
5
  interface RnAnimatorApi {
@@ -33,6 +33,13 @@ interface PixodeskSvgAnimatorProps {
33
33
  fill?: FillMode;
34
34
  /** Playback direction. */
35
35
  direction?: PlaybackDirection;
36
+ /** Snap back to the start state after a natural finish. */
37
+ resetOnFinish?: boolean;
38
+ /**
39
+ * What a second tap does when `startOn: 'click'` is active.
40
+ * Defaults to the document's `trigger.outAction`, else `'pause'`.
41
+ */
42
+ outAction?: OutAction;
36
43
  /** When true, honours the document trigger (`startOn: 'load'` plays on mount). */
37
44
  autoplay?: boolean;
38
45
  /** Starts playback unconditionally. */
@@ -50,6 +57,17 @@ interface PixodeskSvgAnimatorProps {
50
57
  onPause?: () => void;
51
58
  onCancel?: () => void;
52
59
  onFinish?: () => void;
60
+ /**
61
+ * Called when a document cannot be compiled or rendered. The component
62
+ * renders {@link fallback} instead of throwing, so a single broken
63
+ * animation never takes down the screen around it.
64
+ *
65
+ * Only JavaScript failures reach this — a crash inside react-native-svg's
66
+ * native renderer bypasses JavaScript entirely.
67
+ */
68
+ onError?: (error: Error, componentStack?: string) => void;
69
+ /** Rendered in place of the animation after a failure. Default: nothing. */
70
+ fallback?: (error: Error) => ReactElement | null;
53
71
  }
54
72
  /**
55
73
  * React Native component for rendering and controlling Pixodesk SVG animations.
@@ -61,25 +79,31 @@ interface PixodeskSvgAnimatorProps {
61
79
  * `withTiming`/`withRepeat` on the UI thread, with per-element worklets
62
80
  * indexing the precompiled tracks. No JS-thread frame loop.
63
81
  */
64
- declare function PixodeskSvgAnimator({ doc, duration, delay, iterations, fill, direction, autoplay, play, pause, apiRef, time, timeMs, onPlay, onStop, onPause, onCancel, onFinish, }: PixodeskSvgAnimatorProps): ReactElement | null;
82
+ declare function PixodeskSvgAnimator({ doc, duration, delay, iterations, fill, direction, resetOnFinish, outAction: outActionProp, autoplay, play, pause, apiRef, time, timeMs, onPlay, onStop, onPause, onCancel, onFinish, onError, fallback, }: PixodeskSvgAnimatorProps): ReactElement | null;
65
83
 
66
84
  interface RenderRnNodeOptions {
67
85
  /** Collects non-fatal issues (unsupported tags, dropped attrs). */
68
86
  warnings?: Array<string>;
87
+ /** `definitions` from the document, used to resolve named `style` presets. */
88
+ defs?: PxDefs;
69
89
  /**
70
90
  * Wraps the created element for animated nodes: receives the resolved
71
91
  * component + static props and returns the element to mount (the animator
72
92
  * substitutes an Animated component wired to its tracks). Return undefined
73
93
  * to keep the plain static element.
94
+ *
95
+ * `key` is handed over SEPARATELY and is deliberately absent from `props`:
96
+ * React 19 warns when a props object containing `key` is spread into JSX,
97
+ * and implementations of this hook do exactly that.
74
98
  */
75
- decorate?: (node: PxNode, Component: ComponentType<any>, props: Record<string, any>, children: ReactNode) => ReactElement | undefined;
99
+ decorate?: (node: PxNode, Component: ComponentType<any>, props: Record<string, any>, children: ReactNode, key: string | number | undefined) => ReactElement | undefined;
76
100
  }
77
101
  /**
78
102
  * Converts core-normalised wire props into react-native-svg props: RN prop
79
103
  * naming, sanitisation (same security rules as the web renderer), numeric
80
104
  * coercion where possible.
81
105
  */
82
- declare function toRnProps(props: Record<string, any>, warnings?: Array<string>): Record<string, any>;
106
+ declare function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any>;
83
107
  /**
84
108
  * Renders a (materialised) PxNode tree to react-native-svg elements.
85
109
  * Mirrors the web `renderNode` contract: unsupported/dangerous tags are
@@ -87,6 +111,59 @@ declare function toRnProps(props: Record<string, any>, warnings?: Array<string>)
87
111
  */
88
112
  declare function renderRnNode(node: PxNode, opts?: RenderRnNodeOptions, key?: string | number): ReactElement | null;
89
113
 
114
+ interface PxRnErrorBoundaryProps {
115
+ children: ReactNode;
116
+ /** Rendered instead of the children once something has thrown. */
117
+ fallback?: (error: Error) => ReactNode;
118
+ onError?: (error: Error, info?: string) => void;
119
+ }
120
+ interface State {
121
+ error: Error | null;
122
+ }
123
+ /**
124
+ * Keeps one bad animation from taking down the screen around it.
125
+ *
126
+ * A throw anywhere in the rendered SVG tree — an unsupported prop shape, a
127
+ * react-native-svg internal, a reanimated attachment failure — otherwise
128
+ * unmounts the whole React tree above it. Here it is contained to this one
129
+ * animation, reported through `onError`, and replaced by `fallback`.
130
+ *
131
+ * NOTE the limit: this catches JavaScript errors only. A crash INSIDE the
132
+ * native renderer (see `openClosedTextPathTargets` for a real example) never
133
+ * reaches JavaScript and cannot be caught here — those have to be avoided
134
+ * rather than handled.
135
+ */
136
+ declare class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {
137
+ state: State;
138
+ static getDerivedStateFromError(error: Error): State;
139
+ componentDidCatch(error: Error, info: ErrorInfo): void;
140
+ componentDidUpdate(prev: PxRnErrorBoundaryProps): void;
141
+ render(): ReactNode;
142
+ }
143
+
144
+ /**
145
+ * Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.
146
+ *
147
+ * WHY: react-native-svg's native text-on-path layout crashes the app —
148
+ * an uncatchable `NSRangeException` on iOS — for this combination.
149
+ * `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,
150
+ * but for a closed path it sets those bounds to `startOffset … startOffset +
151
+ * pathLength` instead of `0 … pathLength`. Any glyph past the end of the path
152
+ * therefore survives the bounds check and reaches `getPosAndTan`, whose
153
+ * `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths
154
+ * array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is
155
+ * all it takes, and animating `startOffset` guarantees hitting it.
156
+ *
157
+ * Opening the path restores the `0 … pathLength` bounds, so out-of-range
158
+ * glyphs are skipped as intended. The copy is private to the `<textPath>`, so
159
+ * anything else drawing the same path still gets the closed original. For a
160
+ * shape whose ends already meet (a circle, the usual case) the removed segment
161
+ * has zero length and nothing changes visually at all.
162
+ *
163
+ * Returns the document unchanged — the same object — when nothing matches.
164
+ */
165
+ declare function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode;
166
+
90
167
  /**
91
168
  * Sampled animation tracks for ONE element: prop name → per-sample values.
92
169
  *
@@ -113,6 +190,8 @@ interface PxCompiledTracks {
113
190
  delay: number;
114
191
  /** WAAPI-style fill mode (default 'forwards'). */
115
192
  fill: string;
193
+ /** When true, snap back to the start after a natural finish. */
194
+ resetOnFinish: boolean;
116
195
  /** Sample step, ms. */
117
196
  stepMs: number;
118
197
  /** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */
@@ -125,6 +204,15 @@ interface CompileTracksOptions {
125
204
  sampleRate?: number;
126
205
  /** Hard cap on samples per iteration (memory guard). Default 600. */
127
206
  maxSamples?: number;
207
+ /**
208
+ * Sample values in the form the NATIVE react-native-svg views expect
209
+ * (currently: `transform` as a 6-number matrix rather than an SVG string).
210
+ *
211
+ * Defaults to `false` — the plain SVG form, which is what react-native-web
212
+ * hands straight to the DOM. Only the component knows the platform, so it
213
+ * decides; every consumer that does not opt in keeps DOM-compatible values.
214
+ */
215
+ native?: boolean;
128
216
  }
129
217
  /**
130
218
  * Compiles a MATERIALISED document (run `materialiseAllInTree(doc, 'frames')`
@@ -135,8 +223,13 @@ declare function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksO
135
223
  * Worklet-safe sample lookup: returns the per-prop values at time `tMs`
136
224
  * (already mapped into a single iteration by the caller). Kept deliberately
137
225
  * trivial — runs on the UI thread every frame.
226
+ *
227
+ * `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the
228
+ * reanimated animated-props path of a real device. Props that are applied by
229
+ * re-rendering through React (and therefore still pass through react-native-svg's
230
+ * JS layer), and every value on the web, must keep the wire name.
138
231
  */
139
- declare function sampleProps(tracks: PxElementTracks, tMs: number, stepMs: number, sampleCount: number): Record<string, string | number | Array<number>>;
232
+ declare function sampleProps(tracks: PxElementTracks, tMs: number, stepMs: number, sampleCount: number, native?: boolean): Record<string, string | number | Array<number>>;
140
233
 
141
234
  /**
142
235
  * Converts one normalised wire attribute name (camelCase after core's
@@ -152,7 +245,10 @@ declare function toRnPropName(attrName: string): string | undefined;
152
245
  * SVG tag → react-native-svg component. Tags not in this map are skipped at
153
246
  * render time (with a warning collected by the renderer) — they go on the
154
247
  * feature-gap list rather than crashing the tree.
248
+ *
249
+ * Keys are the wire-format `node.type` values, which follow SVG's own casing
250
+ * (`clipPath`, `feGaussianBlur`, `linearGradient`, …).
155
251
  */
156
252
  declare const RN_SVG_COMPONENTS: Record<string, ComponentType<any>>;
157
253
 
158
- export { type CompileTracksOptions, PixodeskSvgAnimator, type PixodeskSvgAnimatorProps, type PxCompiledTracks, type PxElementTracks, RN_SVG_COMPONENTS, type RenderRnNodeOptions, type RnAnimatorApi, compileTracks, PixodeskSvgAnimator as default, renderRnNode, sampleProps, toRnPropName, toRnProps };
254
+ export { type CompileTracksOptions, PixodeskSvgAnimator, type PixodeskSvgAnimatorProps, type PxCompiledTracks, type PxElementTracks, PxRnErrorBoundary, type PxRnErrorBoundaryProps, RN_SVG_COMPONENTS, type RenderRnNodeOptions, type RnAnimatorApi, compileTracks, PixodeskSvgAnimator as default, openClosedTextPathTargets, renderRnNode, sampleProps, toRnPropName, toRnProps };