UNPKG

4.51 kBTypeScriptView Raw
1import React, { Component } from 'react';
2import {
3 requireNativeComponent,
4 StyleSheet,
5 findNodeHandle,
6 NativeModules,
7 MeasureOnSuccessCallback,
8 MeasureLayoutOnSuccessCallback,
9 MeasureInWindowOnSuccessCallback,
10} from 'react-native';
11import {
12 Color,
13 ClipProps,
14 FillProps,
15 NumberProp,
16 StrokeProps,
17 ResponderProps,
18 TransformProps,
19 ResponderInstanceProps,
20} from '../lib/extract/types';
21import extractResponder from '../lib/extract/extractResponder';
22import extractViewBox from '../lib/extract/extractViewBox';
23import extractColor from '../lib/extract/extractColor';
24import Shape from './Shape';
25import G from './G';
26
27const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
28
29const styles = StyleSheet.create({
30 svg: {
31 backgroundColor: 'transparent',
32 borderWidth: 0,
33 },
34});
35
36export default class Svg extends Shape<
37 {
38 color?: Color;
39 style?: [] | {};
40 viewBox?: string;
41 opacity?: NumberProp;
42 onLayout?: () => void;
43 preserveAspectRatio?: string;
44 } & TransformProps &
45 ResponderProps &
46 StrokeProps &
47 FillProps &
48 ClipProps
49> {
50 static displayName = 'Svg';
51
52 static defaultProps = {
53 preserveAspectRatio: 'xMidYMid meet',
54 };
55
56 measureInWindow = (callback: MeasureInWindowOnSuccessCallback) => {
57 this.root && this.root.measureInWindow(callback);
58 };
59
60 measure = (callback: MeasureOnSuccessCallback) => {
61 this.root && this.root.measure(callback);
62 };
63
64 measureLayout = (
65 relativeToNativeNode: number,
66 onSuccess: MeasureLayoutOnSuccessCallback,
67 onFail: () => void /* currently unused */,
68 ) => {
69 this.root &&
70 this.root.measureLayout(relativeToNativeNode, onSuccess, onFail);
71 };
72
73 setNativeProps = (
74 props: Object & {
75 width?: NumberProp;
76 height?: NumberProp;
77 bbWidth?: NumberProp;
78 bbHeight?: NumberProp;
79 },
80 ) => {
81 const { width, height } = props;
82 if (width) {
83 props.bbWidth = width;
84 }
85 if (height) {
86 props.bbHeight = height;
87 }
88 this.root && this.root.setNativeProps(props);
89 };
90
91 toDataURL = (callback: () => void, options?: Object) => {
92 if (!callback) {
93 return;
94 }
95 const handle = findNodeHandle(this.root as Component);
96 RNSVGSvgViewManager.toDataURL(handle, options, callback);
97 };
98
99 render() {
100 const {
101 opacity = 1,
102 viewBox,
103 preserveAspectRatio,
104 style,
105 children,
106 onLayout,
107 ...props
108 } = this.props;
109 const stylesAndProps = {
110 ...(Array.isArray(style) ? Object.assign({}, ...style) : style),
111 ...props,
112 };
113 const {
114 color,
115 width,
116 height,
117 focusable,
118
119 // Inherited G properties
120 font,
121 transform,
122 fill,
123 fillOpacity,
124 fillRule,
125 stroke,
126 strokeWidth,
127 strokeOpacity,
128 strokeDasharray,
129 strokeDashoffset,
130 strokeLinecap,
131 strokeLinejoin,
132 strokeMiterlimit,
133 } = stylesAndProps;
134
135 const w = parseInt(width, 10);
136 const h = parseInt(height, 10);
137 const doNotParseWidth = isNaN(w) || width[width.length - 1] === '%';
138 const doNotParseHeight = isNaN(h) || height[height.length - 1] === '%';
139 const dimensions =
140 width && height
141 ? {
142 width: doNotParseWidth ? width : w,
143 height: doNotParseHeight ? height : h,
144 flex: 0,
145 }
146 : null;
147
148 const o = +opacity;
149 const opacityStyle = !isNaN(o)
150 ? {
151 opacity: o,
152 }
153 : null;
154
155 const tint = extractColor(color);
156 return (
157 <RNSVGSvg
158 {...props}
159 bbWidth={width}
160 bbHeight={height}
161 color={tint}
162 tintColor={tint}
163 onLayout={onLayout}
164 ref={this.refMethod}
165 style={[styles.svg, style, opacityStyle, dimensions]}
166 focusable={Boolean(focusable) && focusable !== 'false'}
167 {...extractResponder(props, this as ResponderInstanceProps)}
168 {...extractViewBox({ viewBox, preserveAspectRatio })}
169 >
170 <G
171 {...{
172 children,
173 style,
174 font,
175 transform,
176 fill,
177 fillOpacity,
178 fillRule,
179 stroke,
180 strokeWidth,
181 strokeOpacity,
182 strokeDasharray,
183 strokeDashoffset,
184 strokeLinecap,
185 strokeLinejoin,
186 strokeMiterlimit,
187 }}
188 />
189 </RNSVGSvg>
190 );
191 }
192}
193
194export const RNSVGSvg = requireNativeComponent('RNSVGSvgView');