@pixodesk/svg-animator-rn 1.0.40 → 1.0.43
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.cjs +15 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +21 -21
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/PixodeskSvgAnimator.tsx +15 -15
- package/src/PxRnErrorBoundary.tsx +3 -3
- package/src/PxRnPropNames.ts +1 -1
- package/src/PxRnRender.tsx +6 -6
- package/src/PxRnTracks.ts +4 -4
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs,
|
|
6
|
+
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PxDiagnosticCode, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';
|
|
7
7
|
import { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
8
8
|
import React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
9
9
|
import { Dimensions, Platform, Pressable, View } from 'react-native';
|
|
@@ -37,13 +37,13 @@ export type RnAnimatorApi = PxAnimatorHandle;
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* The component's props. The playback override, the control props and the callbacks are core's
|
|
40
|
-
* shared shapes (review §9) — `
|
|
40
|
+
* shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and
|
|
41
41
|
* `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs
|
|
42
42
|
* on this platform is declared here: `fallback`, which has no web counterpart.
|
|
43
43
|
* @public
|
|
44
44
|
*/
|
|
45
45
|
export interface PixodeskSvgAnimatorProps
|
|
46
|
-
extends
|
|
46
|
+
extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {
|
|
47
47
|
|
|
48
48
|
// -- Source ---------------------------------------------------------------
|
|
49
49
|
|
|
@@ -51,7 +51,7 @@ export interface PixodeskSvgAnimatorProps
|
|
|
51
51
|
doc: PxAnimatedSvgDocument;
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
|
-
* Per-instance override of the document's `timeline` — see `
|
|
54
|
+
* Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.
|
|
55
55
|
*
|
|
56
56
|
* `engine` is accepted but ignored here: React Native always uses the `native` (fully
|
|
57
57
|
* flattened) materialization, because react-native-svg has no `<use>` shadow-tree
|
|
@@ -70,7 +70,7 @@ export interface PixodeskSvgAnimatorProps
|
|
|
70
70
|
// -- Failure handling -----------------------------------------------------
|
|
71
71
|
// A document that cannot be compiled or rendered is reported through `onError` — the same
|
|
72
72
|
// `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the
|
|
73
|
-
// thrown Error and, when the error boundary caught it, `diagnostic.
|
|
73
|
+
// thrown Error and, when the error boundary caught it, the component stack in `diagnostic.data`.
|
|
74
74
|
// The component renders `fallback` instead of throwing, so one broken animation never
|
|
75
75
|
// takes down the screen around it. Only JavaScript failures reach this — a crash inside
|
|
76
76
|
// react-native-svg's native renderer bypasses JavaScript entirely.
|
|
@@ -217,7 +217,7 @@ function SampledSubtree({
|
|
|
217
217
|
|
|
218
218
|
/** Overrides that shadow the document's own `animator` config. */
|
|
219
219
|
/** The override subset of the props — core's shared shape, not a local copy (review §9). */
|
|
220
|
-
type ConfigOverrides =
|
|
220
|
+
type ConfigOverrides = PxPlaybackOverride;
|
|
221
221
|
|
|
222
222
|
interface Compiled {
|
|
223
223
|
/** Materialized document, or null when compilation failed. */
|
|
@@ -240,7 +240,7 @@ const EMPTY_TRACKS: PxCompiledTracks = {
|
|
|
240
240
|
function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides, diag: PxDiagnostics): Compiled {
|
|
241
241
|
const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
|
|
242
242
|
const warnings = validateNodeEffects(doc as PxNode);
|
|
243
|
-
for (const w of warnings) diag.warn(PxDiagnosticKind.document,
|
|
243
|
+
for (const w of warnings) diag.warn(PxDiagnosticKind.document, PxDiagnosticCode.effectsShape, w);
|
|
244
244
|
// The whole-document boundary diagnostic — see the note in the web player's entry.
|
|
245
245
|
reportDocumentDiagnostics(doc, '[PixodeskSvgAnimator]');
|
|
246
246
|
|
|
@@ -249,8 +249,8 @@ function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides,
|
|
|
249
249
|
// patch would be read by none of the pipeline. Same call, same rules, on every surface.
|
|
250
250
|
const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
|
|
251
251
|
if (patch !== undefined || resetTimeline) {
|
|
252
|
-
const applied = applyAnimatorConfig(doc, patch ?? {}, {
|
|
253
|
-
for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage,
|
|
252
|
+
const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });
|
|
253
|
+
for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.timelineOverrideIgnored, w);
|
|
254
254
|
doc = applied.doc;
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -325,7 +325,7 @@ export function PixodeskSvgAnimator({
|
|
|
325
325
|
// A malformed document must not take the host screen down with it. This instance
|
|
326
326
|
// will not play — an ERROR, reported once, here (review §25.1).
|
|
327
327
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
328
|
-
makeDiag().error(PxDiagnosticKind.internal,
|
|
328
|
+
makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnCompileFailed, error);
|
|
329
329
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
330
330
|
}
|
|
331
331
|
// `timeline` is an object prop, so a fresh literal each render would recompile the whole
|
|
@@ -450,7 +450,7 @@ export function PixodeskSvgAnimator({
|
|
|
450
450
|
},
|
|
451
451
|
setPlaybackRate: (rate: number) => {
|
|
452
452
|
if (!isValidPlaybackRate(rate)) {
|
|
453
|
-
makeDiag().warn(PxDiagnosticKind.usage,
|
|
453
|
+
makeDiag().warn(PxDiagnosticKind.usage, PxDiagnosticCode.rateRejected);
|
|
454
454
|
return;
|
|
455
455
|
}
|
|
456
456
|
rateRef.current = rate;
|
|
@@ -510,7 +510,7 @@ export function PixodeskSvgAnimator({
|
|
|
510
510
|
|
|
511
511
|
useEffect(() => {
|
|
512
512
|
const diag = makeDiag();
|
|
513
|
-
for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, w);
|
|
513
|
+
for (const w of modeWarnings) diag.warn(PxDiagnosticKind.usage, PxDiagnosticCode.controlPropsConflict, w);
|
|
514
514
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
515
515
|
}, [modeWarnings.join('|')]);
|
|
516
516
|
|
|
@@ -602,7 +602,7 @@ export function PixodeskSvgAnimator({
|
|
|
602
602
|
|
|
603
603
|
const renderOpts: RenderRnNodeOptions = {
|
|
604
604
|
warnings: warningsRef.current,
|
|
605
|
-
defs:
|
|
605
|
+
defs: getDefinitions(compiled.doc),
|
|
606
606
|
};
|
|
607
607
|
try {
|
|
608
608
|
return renderRnNode(compiled.doc as PxNode, {
|
|
@@ -648,7 +648,7 @@ export function PixodeskSvgAnimator({
|
|
|
648
648
|
// (an ERROR, review §25.1) and render nothing rather than unmount the host screen.
|
|
649
649
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
650
650
|
renderErrorRef.current = error;
|
|
651
|
-
makeDiag().error(PxDiagnosticKind.internal,
|
|
651
|
+
makeDiag().error(PxDiagnosticKind.internal, PxDiagnosticCode.rnRenderFailed, error);
|
|
652
652
|
return null;
|
|
653
653
|
}
|
|
654
654
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -658,7 +658,7 @@ export function PixodeskSvgAnimator({
|
|
|
658
658
|
const diag = makeDiag();
|
|
659
659
|
// `platform`: these come from the react-native-svg prop mapper — shapes this renderer
|
|
660
660
|
// cannot express, rather than anything wrong with the file.
|
|
661
|
-
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, w);
|
|
661
|
+
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind.platform, PxDiagnosticCode.rnUnsupported, w);
|
|
662
662
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
663
663
|
}, [root]);
|
|
664
664
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
6
|
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
7
|
-
import { PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { PxDiagnosticCode, PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';
|
|
8
8
|
import { createDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
9
9
|
|
|
10
10
|
/** @public @advanced */
|
|
@@ -14,7 +14,7 @@ export interface PxRnErrorBoundaryProps {
|
|
|
14
14
|
fallback?: (error: Error) => ReactNode;
|
|
15
15
|
/**
|
|
16
16
|
* Where the failure is reported (API review §5, §25.1): `error(internal, …)` with
|
|
17
|
-
*
|
|
17
|
+
* the component stack passed as data — so it reaches `onError` like every other failure.
|
|
18
18
|
* Defaults to the console.
|
|
19
19
|
*/
|
|
20
20
|
diag?: PxDiagnostics;
|
|
@@ -47,7 +47,7 @@ export class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State>
|
|
|
47
47
|
|
|
48
48
|
override componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
49
49
|
(this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))
|
|
50
|
-
.error(PxDiagnosticKind.internal, error,
|
|
50
|
+
.error(PxDiagnosticKind.internal, PxDiagnosticCode.rnBoundaryCaught, error, info?.componentStack ?? undefined);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {
|
package/src/PxRnPropNames.ts
CHANGED
|
@@ -17,7 +17,7 @@ const DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xl
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Converts one normalized wire attribute name (camelCase after core's
|
|
20
|
-
* `
|
|
20
|
+
* `toDomProps`, or kebab-case raw) to a react-native-svg prop name.
|
|
21
21
|
* Returns undefined for props that must be dropped.
|
|
22
22
|
*
|
|
23
23
|
* Pure (no react-native-svg import) so the track compiler and its tests
|
package/src/PxRnRender.tsx
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
import { sanitizeAttributeValue,
|
|
6
|
+
import { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';
|
|
8
8
|
import { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
9
9
|
import { RN_SVG_COMPONENTS } from './PxRnTypeMap';
|
|
10
10
|
import { toRnPropName, toRnPropValue } from './PxRnPropNames';
|
|
@@ -14,7 +14,7 @@ export interface RenderRnNodeOptions {
|
|
|
14
14
|
/** Collects non-fatal issues (unsupported tags, dropped attrs). */
|
|
15
15
|
warnings?: Array<string>;
|
|
16
16
|
/** `definitions` from the document, used to resolve named `style` presets. */
|
|
17
|
-
defs?:
|
|
17
|
+
defs?: PxDefinitions;
|
|
18
18
|
/**
|
|
19
19
|
* Wraps the created element for animated nodes: receives the resolved
|
|
20
20
|
* component + static props and returns the element to mount (the animator
|
|
@@ -41,7 +41,7 @@ export interface RenderRnNodeOptions {
|
|
|
41
41
|
* @internal
|
|
42
42
|
*/
|
|
43
43
|
export function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {
|
|
44
|
-
const normalized =
|
|
44
|
+
const normalized = toDomProps(props);
|
|
45
45
|
const out: Record<string, any> = {};
|
|
46
46
|
for (const key of Object.keys(normalized)) {
|
|
47
47
|
const sanitized = sanitizeAttributeValue(key, normalized[key]);
|
|
@@ -72,7 +72,7 @@ export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?:
|
|
|
72
72
|
const domType: string | undefined = props.domType;
|
|
73
73
|
if (domType !== undefined) delete props.domType;
|
|
74
74
|
|
|
75
|
-
if (
|
|
75
|
+
if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {
|
|
76
76
|
opts.warnings?.push('tag blocked (dangerous): ' + tag);
|
|
77
77
|
return null;
|
|
78
78
|
}
|
|
@@ -102,7 +102,7 @@ export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?:
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// Text content: wire nodes carry it in `textContent` — the one key.
|
|
105
|
-
const textContent: string | undefined = props[
|
|
105
|
+
const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];
|
|
106
106
|
|
|
107
107
|
let childElements: ReactNode = undefined;
|
|
108
108
|
if (Array.isArray(children) && children.length > 0) {
|
package/src/PxRnTracks.ts
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import { calcAnimationValues, getAnimatorConfig,
|
|
7
|
-
import {
|
|
6
|
+
import { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';
|
|
8
8
|
import { toRnPropName, toRnPropValue } from './PxRnPropNames';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -73,7 +73,7 @@ export interface CompileTracksOptions {
|
|
|
73
73
|
export function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {
|
|
74
74
|
const config = getAnimatorConfig(doc) || {};
|
|
75
75
|
|
|
76
|
-
const duration = +(config.duration ||
|
|
76
|
+
const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
|
|
77
77
|
const _iterations = config.iterations;
|
|
78
78
|
let iterations = 1;
|
|
79
79
|
if (typeof _iterations === 'number') iterations = _iterations || 1;
|
|
@@ -96,7 +96,7 @@ export function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOp
|
|
|
96
96
|
};
|
|
97
97
|
indexTags(doc);
|
|
98
98
|
|
|
99
|
-
const bindings =
|
|
99
|
+
const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];
|
|
100
100
|
|
|
101
101
|
const elements: Array<PxElementTracks> = [];
|
|
102
102
|
for (const binding of bindings) {
|