Skip to content

Commit

Permalink
ref-forwarding + split setNativeProps to multiple refs
Browse files Browse the repository at this point in the history
  • Loading branch information
adkenyon committed Aug 29, 2020
1 parent ffa2e69 commit 18eba33
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 14 deletions.
57 changes: 48 additions & 9 deletions src/elements/Svg.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { Component, createRef } from 'react';
import {
findNodeHandle,
MeasureInWindowOnSuccessCallback,
Expand Down Expand Up @@ -56,6 +56,10 @@ export default class Svg extends Shape<
preserveAspectRatio: 'xMidYMid meet',
};

gRef = createRef<
G<TransformProps & ResponderProps & StrokeProps & FillProps & ClipProps>
>();

measureInWindow = (callback: MeasureInWindowOnSuccessCallback) => {
const { root } = this;
root && root.measureInWindow(callback);
Expand All @@ -81,17 +85,51 @@ export default class Svg extends Shape<
height?: NumberProp;
bbWidth?: NumberProp;
bbHeight?: NumberProp;
},
} & FillProps &
StrokeProps &
TransformProps,
) => {
const { width, height } = props;
if (width) {
props.bbWidth = width;
const {
fill,
fillOpacity,
fillRule,
stroke,
strokeWidth,
strokeOpacity,
strokeDasharray,
strokeDashoffset,
strokeLinecap,
strokeLinejoin,
strokeMiterlimit,
transform,
...svgProps
} = props;

const gProps = {
fill,
fillOpacity,
fillRule,
stroke,
strokeWidth,
strokeOpacity,
strokeDasharray,
strokeDashoffset,
strokeLinecap,
strokeLinejoin,
strokeMiterlimit,
transform,
};

if (svgProps.width) {
svgProps.bbWidth = svgProps.width;
}
if (height) {
props.bbHeight = height;
if (svgProps.height) {
svgProps.bbHeight = svgProps.height;
}
const { root } = this;
root && root.setNativeProps(props);

const { root, gRef } = this;
root && root.setNativeProps(svgProps);
gRef && gRef.current && gRef.current.setNativeProps(gProps);
};

toDataURL = (callback: () => void, options?: Object) => {
Expand Down Expand Up @@ -216,6 +254,7 @@ export default class Svg extends Shape<
strokeLinecap,
strokeLinejoin,
strokeMiterlimit,
ref: this.gRef,
}}
/>
</RNSVGSvg>
Expand Down
24 changes: 19 additions & 5 deletions src/xml.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import React, {
useEffect,
useMemo,
useState,
forwardRef,
Ref,
} from 'react';
import Rect from './elements/Rect';
import Circle from './elements/Circle';
Expand Down Expand Up @@ -94,34 +96,46 @@ export type XmlState = { ast: JsxAST | null };

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

export function SvgAst({ ast, override }: AstProps) {
function SvgAstInternal({
ast,
override,
forwardedRef,
}: AstProps & { forwardedRef?: Ref<Svg> }) {
if (!ast) {
return null;
}
const { props, children } = ast;
return (
<Svg {...props} {...override}>
<Svg {...props} {...override} ref={forwardedRef}>
{children}
</Svg>
);
}

export const SvgAst = forwardRef<Svg, AstProps>((props, ref) => (
<SvgAstInternal {...props} forwardedRef={ref} />
));

export const err = console.error.bind(console);

export function SvgXml(props: XmlProps) {
const { onError = err, xml, override } = props;
function SvgXmlInternal(props: XmlProps & { forwardedRef?: Ref<Svg> }) {
const { onError = err, xml, override, forwardedRef } = props;
const ast = useMemo<JsxAST | null>(() => (xml !== null ? parse(xml) : null), [
xml,
]);

try {
return <SvgAst ast={ast} override={override || props} />;
return <SvgAst ast={ast} override={override || props} ref={forwardedRef} />;
} catch (error) {
onError(error);
return null;
}
}

export const SvgXml = forwardRef<Svg, XmlProps>((props, ref) => (
<SvgXmlInternal {...props} forwardedRef={ref} />
));

export async function fetchText(uri: string) {
const response = await fetch(uri);
return await response.text();
Expand Down

0 comments on commit 18eba33

Please sign in to comment.