Skip to content

Commit f535b9d

Browse files
committed
ref-forwarding + split setNativeProps to multiple refs
1 parent b2e2c35 commit f535b9d

File tree

2 files changed

+67
-14
lines changed

2 files changed

+67
-14
lines changed

src/elements/Svg.tsx

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Component } from 'react';
1+
import React, { Component, createRef } from 'react';
22
import {
33
findNodeHandle,
44
MeasureInWindowOnSuccessCallback,
@@ -56,6 +56,10 @@ export default class Svg extends Shape<
5656
preserveAspectRatio: 'xMidYMid meet',
5757
};
5858

59+
gRef = createRef<
60+
G<TransformProps & ResponderProps & StrokeProps & FillProps & ClipProps>
61+
>();
62+
5963
measureInWindow = (callback: MeasureInWindowOnSuccessCallback) => {
6064
const { root } = this;
6165
root && root.measureInWindow(callback);
@@ -81,17 +85,51 @@ export default class Svg extends Shape<
8185
height?: NumberProp;
8286
bbWidth?: NumberProp;
8387
bbHeight?: NumberProp;
84-
},
88+
} & FillProps &
89+
StrokeProps &
90+
TransformProps,
8591
) => {
86-
const { width, height } = props;
87-
if (width) {
88-
props.bbWidth = width;
92+
const {
93+
fill,
94+
fillOpacity,
95+
fillRule,
96+
stroke,
97+
strokeWidth,
98+
strokeOpacity,
99+
strokeDasharray,
100+
strokeDashoffset,
101+
strokeLinecap,
102+
strokeLinejoin,
103+
strokeMiterlimit,
104+
transform,
105+
...svgProps
106+
} = props;
107+
108+
const gProps = {
109+
fill,
110+
fillOpacity,
111+
fillRule,
112+
stroke,
113+
strokeWidth,
114+
strokeOpacity,
115+
strokeDasharray,
116+
strokeDashoffset,
117+
strokeLinecap,
118+
strokeLinejoin,
119+
strokeMiterlimit,
120+
transform,
121+
};
122+
123+
if (svgProps.width) {
124+
svgProps.bbWidth = svgProps.width;
89125
}
90-
if (height) {
91-
props.bbHeight = height;
126+
if (svgProps.height) {
127+
svgProps.bbHeight = svgProps.height;
92128
}
93-
const { root } = this;
94-
root && root.setNativeProps(props);
129+
130+
const { root, gRef } = this;
131+
root && root.setNativeProps(svgProps);
132+
gRef && gRef.current && gRef.current.setNativeProps(gProps);
95133
};
96134

97135
toDataURL = (callback: () => void, options?: Object) => {
@@ -216,6 +254,7 @@ export default class Svg extends Shape<
216254
strokeLinecap,
217255
strokeLinejoin,
218256
strokeMiterlimit,
257+
ref: this.gRef,
219258
}}
220259
/>
221260
</RNSVGSvg>

src/xml.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import React, {
44
useEffect,
55
useMemo,
66
useState,
7+
forwardRef,
8+
Ref,
79
} from 'react';
810
import Rect from './elements/Rect';
911
import Circle from './elements/Circle';
@@ -94,34 +96,46 @@ export type XmlState = { ast: JsxAST | null };
9496

9597
export type AstProps = { ast: JsxAST | null } & AdditionalProps;
9698

97-
export function SvgAst({ ast, override }: AstProps) {
99+
function SvgAstInternal({
100+
ast,
101+
override,
102+
forwardedRef,
103+
}: AstProps & { forwardedRef?: Ref<Svg> }) {
98104
if (!ast) {
99105
return null;
100106
}
101107
const { props, children } = ast;
102108
return (
103-
<Svg {...props} {...override}>
109+
<Svg {...props} {...override} ref={forwardedRef}>
104110
{children}
105111
</Svg>
106112
);
107113
}
108114

115+
export const SvgAst = forwardRef<Svg, AstProps>((props, ref) => (
116+
<SvgAstInternal {...props} forwardedRef={ref} />
117+
));
118+
109119
export const err = console.error.bind(console);
110120

111-
export function SvgXml(props: XmlProps) {
112-
const { onError = err, xml, override } = props;
121+
function SvgXmlInternal(props: XmlProps & { forwardedRef?: Ref<Svg> }) {
122+
const { onError = err, xml, override, forwardedRef } = props;
113123
const ast = useMemo<JsxAST | null>(() => (xml !== null ? parse(xml) : null), [
114124
xml,
115125
]);
116126

117127
try {
118-
return <SvgAst ast={ast} override={override || props} />;
128+
return <SvgAst ast={ast} override={override || props} ref={forwardedRef} />;
119129
} catch (error) {
120130
onError(error);
121131
return null;
122132
}
123133
}
124134

135+
export const SvgXml = forwardRef<Svg, XmlProps>((props, ref) => (
136+
<SvgXmlInternal {...props} forwardedRef={ref} />
137+
));
138+
125139
export async function fetchText(uri: string) {
126140
const response = await fetch(uri);
127141
return await response.text();

0 commit comments

Comments
 (0)