diff --git a/__tests__/__snapshots__/css.test.tsx.snap b/__tests__/__snapshots__/css.test.tsx.snap
index a486d502..dbd433ee 100644
--- a/__tests__/__snapshots__/css.test.tsx.snap
+++ b/__tests__/__snapshots__/css.test.tsx.snap
@@ -98,10 +98,6 @@ exports[`supports CSS in style element 1`] = `
"backgroundColor": "transparent",
"borderWidth": 0,
},
- undefined,
- Object {
- "opacity": 1,
- },
Object {
"flex": 0,
"height": "100%",
diff --git a/src/ReactNativeSVG.ts b/src/ReactNativeSVG.ts
index 0b88ae72..d7009250 100644
--- a/src/ReactNativeSVG.ts
+++ b/src/ReactNativeSVG.ts
@@ -1,28 +1,28 @@
import Shape from './elements/Shape';
-import Rect, { RNSVGRect } from './elements/Rect';
-import Circle, { RNSVGCircle } from './elements/Circle';
-import Ellipse, { RNSVGEllipse } from './elements/Ellipse';
+import Rect from './elements/Rect';
+import Circle from './elements/Circle';
+import Ellipse from './elements/Ellipse';
import Polygon from './elements/Polygon';
import Polyline from './elements/Polyline';
-import Line, { RNSVGLine } from './elements/Line';
-import Svg, { RNSVGSvg } from './elements/Svg';
-import Path, { RNSVGPath } from './elements/Path';
-import G, { RNSVGGroup } from './elements/G';
-import Text, { RNSVGText } from './elements/Text';
-import TSpan, { RNSVGTSpan } from './elements/TSpan';
-import TextPath, { RNSVGTextPath } from './elements/TextPath';
-import Use, { RNSVGUse } from './elements/Use';
-import Image, { RNSVGImage } from './elements/Image';
-import Symbol, { RNSVGSymbol } from './elements/Symbol';
-import Defs, { RNSVGDefs } from './elements/Defs';
-import LinearGradient, { RNSVGLinearGradient } from './elements/LinearGradient';
-import RadialGradient, { RNSVGRadialGradient } from './elements/RadialGradient';
+import Line from './elements/Line';
+import Svg from './elements/Svg';
+import Path from './elements/Path';
+import G from './elements/G';
+import Text from './elements/Text';
+import TSpan from './elements/TSpan';
+import TextPath from './elements/TextPath';
+import Use from './elements/Use';
+import Image from './elements/Image';
+import Symbol from './elements/Symbol';
+import Defs from './elements/Defs';
+import LinearGradient from './elements/LinearGradient';
+import RadialGradient from './elements/RadialGradient';
import Stop from './elements/Stop';
-import ClipPath, { RNSVGClipPath } from './elements/ClipPath';
-import Pattern, { RNSVGPattern } from './elements/Pattern';
-import Mask, { RNSVGMask } from './elements/Mask';
-import Marker, { RNSVGMarker } from './elements/Marker';
-import ForeignObject, { RNSVGForeignObject } from './elements/ForeignObject';
+import ClipPath from './elements/ClipPath';
+import Pattern from './elements/Pattern';
+import Mask from './elements/Mask';
+import Marker from './elements/Marker';
+import ForeignObject from './elements/ForeignObject';
import { parse, SvgAst, SvgFromUri, SvgFromXml, SvgUri, SvgXml } from './xml';
import {
SvgCss,
@@ -31,6 +31,29 @@ import {
SvgWithCssUri,
inlineStyles,
} from './css';
+import {
+ RNSVGCircle,
+ RNSVGClipPath,
+ RNSVGDefs,
+ RNSVGEllipse,
+ RNSVGForeignObject,
+ RNSVGGroup,
+ RNSVGImage,
+ RNSVGLine,
+ RNSVGLinearGradient,
+ RNSVGMarker,
+ RNSVGMask,
+ RNSVGPath,
+ RNSVGPattern,
+ RNSVGRadialGradient,
+ RNSVGRect,
+ RNSVGSvg,
+ RNSVGSymbol,
+ RNSVGText,
+ RNSVGTextPath,
+ RNSVGTSpan,
+ RNSVGUse,
+} from './elements/NativeComponents';
export {
Svg,
diff --git a/src/elements/Circle.tsx b/src/elements/Circle.tsx
index a3c2c503..27abe230 100644
--- a/src/elements/Circle.tsx
+++ b/src/elements/Circle.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import { extract } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGCircle } from './NativeComponents';
export default class Circle extends Shape<{
cx?: NumberProp;
@@ -31,5 +31,3 @@ export default class Circle extends Shape<{
);
}
}
-
-export const RNSVGCircle = requireNativeComponent('RNSVGCircle');
diff --git a/src/elements/ClipPath.tsx b/src/elements/ClipPath.tsx
index 47fe7433..8987cd59 100644
--- a/src/elements/ClipPath.tsx
+++ b/src/elements/ClipPath.tsx
@@ -1,7 +1,7 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import { extract } from '../lib/extract/extractProps';
import Shape from './Shape';
+import { RNSVGClipPath } from './NativeComponents';
export default class ClipPath extends Shape<{}> {
static displayName = 'ClipPath';
@@ -15,5 +15,3 @@ export default class ClipPath extends Shape<{}> {
);
}
}
-
-export const RNSVGClipPath = requireNativeComponent('RNSVGClipPath');
diff --git a/src/elements/Defs.tsx b/src/elements/Defs.tsx
index 43491661..ebd7d579 100644
--- a/src/elements/Defs.tsx
+++ b/src/elements/Defs.tsx
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
-import { requireNativeComponent } from 'react-native';
+import { RNSVGDefs } from './NativeComponents';
export default class Defs extends Component {
static displayName = 'Defs';
@@ -8,5 +8,3 @@ export default class Defs extends Component {
return
extends Shape
{
static displayName = 'G';
@@ -43,5 +43,3 @@ const hasProps = (obj: {}) => {
}
return false;
};
-
-export const RNSVGGroup = requireNativeComponent('RNSVGGroup');
diff --git a/src/elements/Image.tsx b/src/elements/Image.tsx
index 99b09098..3742ce94 100644
--- a/src/elements/Image.tsx
+++ b/src/elements/Image.tsx
@@ -1,13 +1,10 @@
import React from 'react';
-import {
- Image,
- ImageSourcePropType,
- requireNativeComponent,
-} from 'react-native';
-import { meetOrSliceTypes, alignEnum } from '../lib/extract/extractViewBox';
+import { Image, ImageSourcePropType } from 'react-native';
+import { alignEnum, meetOrSliceTypes } from '../lib/extract/extractViewBox';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGImage } from './NativeComponents';
const spacesRegExp = /\s+/;
@@ -68,5 +65,3 @@ export default class SvgImage extends Shape<{
);
}
}
-
-export const RNSVGImage = requireNativeComponent('RNSVGImage');
diff --git a/src/elements/Line.tsx b/src/elements/Line.tsx
index 2ddf1a99..d6d27b4a 100644
--- a/src/elements/Line.tsx
+++ b/src/elements/Line.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import { extract } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGLine } from './NativeComponents';
export default class Line extends Shape<{
x1?: NumberProp;
@@ -34,5 +34,3 @@ export default class Line extends Shape<{
);
}
}
-
-export const RNSVGLine = requireNativeComponent('RNSVGLine');
diff --git a/src/elements/LinearGradient.tsx b/src/elements/LinearGradient.tsx
index e3f85c01..c0cacb6d 100644
--- a/src/elements/LinearGradient.tsx
+++ b/src/elements/LinearGradient.tsx
@@ -1,8 +1,8 @@
import React, { ReactElement } from 'react';
-import { requireNativeComponent } from 'react-native';
import extractGradient from '../lib/extract/extractGradient';
import { NumberProp, TransformProps } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGLinearGradient } from './NativeComponents';
export default class LinearGradient extends Shape<{
id?: string;
@@ -39,7 +39,3 @@ export default class LinearGradient extends Shape<{
);
}
}
-
-export const RNSVGLinearGradient = requireNativeComponent(
- 'RNSVGLinearGradient',
-);
diff --git a/src/elements/Marker.tsx b/src/elements/Marker.tsx
index 470b2807..31f9d874 100644
--- a/src/elements/Marker.tsx
+++ b/src/elements/Marker.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import extractViewBox from '../lib/extract/extractViewBox';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGMarker } from './NativeComponents';
export default class Marker extends Shape<{
id?: string;
@@ -57,5 +57,3 @@ export default class Marker extends Shape<{
);
}
}
-
-export const RNSVGMarker = requireNativeComponent('RNSVGMarker');
diff --git a/src/elements/Mask.tsx b/src/elements/Mask.tsx
index 63515a5e..d513a9d6 100644
--- a/src/elements/Mask.tsx
+++ b/src/elements/Mask.tsx
@@ -1,10 +1,10 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import extractTransform from '../lib/extract/extractTransform';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp, TransformProps } from '../lib/extract/types';
import units from '../lib/units';
import Shape from './Shape';
+import { RNSVGMask } from './NativeComponents';
export default class Mask extends Shape<{
x?: NumberProp;
@@ -57,5 +57,3 @@ export default class Mask extends Shape<{
);
}
}
-
-export const RNSVGMask = requireNativeComponent('RNSVGMask');
diff --git a/src/elements/NativeComponents.tsx b/src/elements/NativeComponents.tsx
new file mode 100644
index 00000000..edf97232
--- /dev/null
+++ b/src/elements/NativeComponents.tsx
@@ -0,0 +1,23 @@
+import { requireNativeComponent as rnc } from 'react-native';
+
+export const RNSVGSvg = rnc('RNSVGSvgView');
+export const RNSVGCircle = rnc('RNSVGCircle');
+export const RNSVGClipPath = rnc('RNSVGClipPath');
+export const RNSVGDefs = rnc('RNSVGDefs');
+export const RNSVGEllipse = rnc('RNSVGEllipse');
+export const RNSVGForeignObject = rnc('RNSVGForeignObject');
+export const RNSVGGroup = rnc('RNSVGGroup');
+export const RNSVGImage = rnc('RNSVGImage');
+export const RNSVGLine = rnc('RNSVGLine');
+export const RNSVGLinearGradient = rnc('RNSVGLinearGradient');
+export const RNSVGMarker = rnc('RNSVGMarker');
+export const RNSVGMask = rnc('RNSVGMask');
+export const RNSVGPath = rnc('RNSVGPath');
+export const RNSVGPattern = rnc('RNSVGPattern');
+export const RNSVGRadialGradient = rnc('RNSVGRadialGradient');
+export const RNSVGRect = rnc('RNSVGRect');
+export const RNSVGSymbol = rnc('RNSVGSymbol');
+export const RNSVGText = rnc('RNSVGText');
+export const RNSVGTextPath = rnc('RNSVGTextPath');
+export const RNSVGTSpan = rnc('RNSVGTSpan');
+export const RNSVGUse = rnc('RNSVGUse');
diff --git a/src/elements/Path.tsx b/src/elements/Path.tsx
index 1f9df65e..5a14463f 100644
--- a/src/elements/Path.tsx
+++ b/src/elements/Path.tsx
@@ -1,7 +1,7 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import { extract } from '../lib/extract/extractProps';
import Shape from './Shape';
+import { RNSVGPath } from './NativeComponents';
export default class Path extends Shape<{
d?: string;
@@ -15,5 +15,3 @@ export default class Path extends Shape<{
);
}
}
-
-export const RNSVGPath = requireNativeComponent('RNSVGPath');
diff --git a/src/elements/Pattern.tsx b/src/elements/Pattern.tsx
index 78b2029e..241a3e45 100644
--- a/src/elements/Pattern.tsx
+++ b/src/elements/Pattern.tsx
@@ -1,10 +1,10 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import extractTransform from '../lib/extract/extractTransform';
import extractViewBox from '../lib/extract/extractViewBox';
import { NumberProp, TransformProps } from '../lib/extract/types';
import units from '../lib/units';
import Shape from './Shape';
+import { RNSVGPattern } from './NativeComponents';
export default class Pattern extends Shape<{
id?: string;
@@ -66,5 +66,3 @@ export default class Pattern extends Shape<{
);
}
}
-
-export const RNSVGPattern = requireNativeComponent('RNSVGPattern');
diff --git a/src/elements/RadialGradient.tsx b/src/elements/RadialGradient.tsx
index 4a7c74f5..afb29f7e 100644
--- a/src/elements/RadialGradient.tsx
+++ b/src/elements/RadialGradient.tsx
@@ -1,8 +1,8 @@
import React, { ReactElement } from 'react';
-import { requireNativeComponent } from 'react-native';
import extractGradient from '../lib/extract/extractGradient';
import { NumberProp, TransformProps } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGRadialGradient } from './NativeComponents';
export default class RadialGradient extends Shape<{
fx?: NumberProp;
@@ -43,7 +43,3 @@ export default class RadialGradient extends Shape<{
);
}
}
-
-export const RNSVGRadialGradient = requireNativeComponent(
- 'RNSVGRadialGradient',
-);
diff --git a/src/elements/Rect.tsx b/src/elements/Rect.tsx
index 07bfe43b..e712ccee 100644
--- a/src/elements/Rect.tsx
+++ b/src/elements/Rect.tsx
@@ -1,8 +1,8 @@
import React from 'react';
-import { requireNativeComponent } from 'react-native';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
+import { RNSVGRect } from './NativeComponents';
export default class Rect extends Shape<{
x?: NumberProp;
@@ -38,5 +38,3 @@ export default class Rect extends Shape<{
);
}
}
-
-export const RNSVGRect = requireNativeComponent('RNSVGRect');
diff --git a/src/elements/Svg.tsx b/src/elements/Svg.tsx
index 732b0aac..74a2b2c5 100644
--- a/src/elements/Svg.tsx
+++ b/src/elements/Svg.tsx
@@ -1,29 +1,30 @@
import React, { Component } from 'react';
import {
- requireNativeComponent,
- StyleSheet,
findNodeHandle,
- NativeModules,
- MeasureOnSuccessCallback,
- MeasureLayoutOnSuccessCallback,
MeasureInWindowOnSuccessCallback,
+ MeasureLayoutOnSuccessCallback,
+ MeasureOnSuccessCallback,
+ NativeModules,
+ StyleSheet,
+ ViewStyle,
} from 'react-native';
import {
- Color,
ClipProps,
+ Color,
+ extractedProps,
FillProps,
NumberProp,
- StrokeProps,
- ResponderProps,
- TransformProps,
ResponderInstanceProps,
- extractedProps,
+ ResponderProps,
+ StrokeProps,
+ TransformProps,
} from '../lib/extract/types';
import extractResponder from '../lib/extract/extractResponder';
import extractViewBox from '../lib/extract/extractViewBox';
import extractColor from '../lib/extract/extractColor';
import Shape from './Shape';
import G from './G';
+import { RNSVGSvg } from './NativeComponents';
const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
@@ -33,15 +34,16 @@ const styles = StyleSheet.create({
borderWidth: 0,
},
});
+const defaultStyle = styles.svg;
export default class Svg extends Shape<
{
color?: Color;
- style?: [] | {};
viewBox?: string;
opacity?: NumberProp;
onLayout?: () => void;
preserveAspectRatio?: string;
+ style?: ViewStyle[] | ViewStyle;
} & TransformProps &
ResponderProps &
StrokeProps &
@@ -55,11 +57,13 @@ export default class Svg extends Shape<
};
measureInWindow = (callback: MeasureInWindowOnSuccessCallback) => {
- this.root && this.root.measureInWindow(callback);
+ const { root } = this;
+ root && root.measureInWindow(callback);
};
measure = (callback: MeasureOnSuccessCallback) => {
- this.root && this.root.measure(callback);
+ const { root } = this;
+ root && root.measure(callback);
};
measureLayout = (
@@ -67,8 +71,8 @@ export default class Svg extends Shape<
onSuccess: MeasureLayoutOnSuccessCallback,
onFail: () => void /* currently unused */,
) => {
- this.root &&
- this.root.measureLayout(relativeToNativeNode, onSuccess, onFail);
+ const { root } = this;
+ root && root.measureLayout(relativeToNativeNode, onSuccess, onFail);
};
setNativeProps = (
@@ -86,7 +90,8 @@ export default class Svg extends Shape<
if (height) {
props.bbHeight = height;
}
- this.root && this.root.setNativeProps(props);
+ const { root } = this;
+ root && root.setNativeProps(props);
};
toDataURL = (callback: () => void, options?: Object) => {
@@ -99,17 +104,17 @@ export default class Svg extends Shape<
render() {
const {
- opacity = 1,
- viewBox,
- preserveAspectRatio,
style,
+ opacity,
+ viewBox,
children,
onLayout,
- ...props
+ preserveAspectRatio,
+ ...extracted
} = this.props;
const stylesAndProps = {
...(Array.isArray(style) ? Object.assign({}, ...style) : style),
- ...props,
+ ...extracted,
};
const {
color,
@@ -133,42 +138,63 @@ export default class Svg extends Shape<
strokeMiterlimit,
} = stylesAndProps;
- const w = parseInt(width, 10);
- const h = parseInt(height, 10);
- const doNotParseWidth = isNaN(w) || width[width.length - 1] === '%';
- const doNotParseHeight = isNaN(h) || height[height.length - 1] === '%';
- const dimensions =
- width && height
- ? {
- width: doNotParseWidth ? width : w,
- height: doNotParseHeight ? height : h,
- flex: 0,
- }
- : null;
+ const props: extractedProps = extracted as extractedProps;
+ props.focusable = Boolean(focusable) && focusable !== 'false';
+ const rootStyles: (ViewStyle | ViewStyle[])[] = [defaultStyle];
- const o = +opacity;
- const opacityStyle = !isNaN(o)
- ? {
- opacity: o,
- }
- : null;
+ if (style) {
+ rootStyles.push(style);
+ }
+
+ let override = false;
+ const overrideStyles: ViewStyle = {};
+ const o = opacity != null ? +opacity : NaN;
+ if (!isNaN(o)) {
+ override = true;
+ overrideStyles.opacity = o;
+ }
+
+ if (width && height) {
+ override = true;
+ const w = parseInt(width, 10);
+ const h = parseInt(height, 10);
+ const doNotParseWidth = isNaN(w) || width[width.length - 1] === '%';
+ const doNotParseHeight = isNaN(h) || height[height.length - 1] === '%';
+ overrideStyles.width = doNotParseWidth ? width : w;
+ overrideStyles.height = doNotParseHeight ? height : h;
+ overrideStyles.flex = 0;
+ }
+
+ if (override) {
+ rootStyles.push(overrideStyles);
+ }
+
+ props.style = rootStyles.length > 1 ? rootStyles : defaultStyle;
+
+ if (width != null) {
+ props.bbWidth = width;
+ }
+ if (height != null) {
+ props.bbHeight = height;
+ }
+
+ extractResponder(props, props, this as ResponderInstanceProps);
const tint = extractColor(color);
- const responder: extractedProps = {};
- extractResponder(responder, props, this as ResponderInstanceProps);
+ if (tint != null) {
+ props.color = tint;
+ props.tintColor = tint;
+ }
+
+ if (onLayout != null) {
+ props.onLayout = onLayout;
+ }
+
return (