Refactor Symbol on iOS

This commit is contained in:
Horcrux
2017-01-22 17:51:47 +08:00
parent f529f93565
commit 1b04e11ca4
21 changed files with 385 additions and 311 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import {ImageAttributes} from '../lib/attributes';
import {numberProp, touchableProps, responderProps} from '../lib/props';
import Shape from './Shape';
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
import {meetOrSliceTypes, alignEnum} from './ViewBox';
import {meetOrSliceTypes, alignEnum} from '../lib/extract/extractViewBox';
const spacesRegExp = /\s+/;
class Image extends Shape {
+21 -28
View File
@@ -11,8 +11,10 @@ import {
NativeModules,
Platform
} from 'react-native';
import ViewBox from './ViewBox';
import extractViewBox from '../lib/extract/extractViewBox';
import {ViewBoxAttributes} from '../lib/attributes';
import _ from 'lodash';
const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
// Svg - Root node of all Svg elements
@@ -36,6 +38,10 @@ class Svg extends Component{
preserveAspectRatio: PropTypes.string
};
static defaultProps = {
preserveAspectRatio: 'xMidYMid meet'
};
constructor() {
super(...arguments);
id++;
@@ -79,52 +85,39 @@ class Svg extends Component{
};
render() {
let {props} = this;
let opacity = +props.opacity;
let width = +props.width;
let height = +props.height;
let viewBox = props.viewBox;
const {opacity, width, height, viewBox, preserveAspectRatio, style, ...props} = this.props;
let dimensions;
if (width && height) {
dimensions = {
width,
height,
width: +width,
height: +height,
flex: 0
};
}
if (props.viewbox) {
viewBox = props.viewbox;
console.warn('Prop `viewbox` is deprecated. please use `viewBox` instead.');
}
let content = viewBox ? <ViewBox
viewBox={viewBox}
preserveAspectRatio={props.preserveAspectRatio}
>{props.children}</ViewBox> : props.children;
const nativeProps = _.omit(props, ['width', 'height', 'viewBox', 'preserveAspectRatio', 'opacity']);
return <NativeSvgView
{...nativeProps}
{...props}
{...extractViewBox({ viewBox, preserveAspectRatio })}
ref={ele => {this.root = ele;}}
style={[
styles.svg,
props.style,
!isNaN(opacity) && {
opacity
style,
!isNaN(+opacity) && {
opacity: +opacity
},
dimensions
]}
onDataURL={this._onDataURL}
>
{content}
</NativeSvgView>;
/>;
}
}
const NativeSvgView = requireNativeComponent('RNSVGSvgView', null);
const NativeSvgView = requireNativeComponent('RNSVGSvgView', null, {
nativeOnly: {
...ViewBoxAttributes
}
});
export default Svg;
+11 -19
View File
@@ -1,7 +1,7 @@
import React, {Component, PropTypes} from 'react';
import ViewBox from './ViewBox';
import G from './G';
import Defs from './Defs';
import extractViewBox from '../lib/extract/extractViewBox';
import createReactNativeComponentClass from 'react-native/Libraries/Renderer/src/renderers/native/createReactNativeComponentClass';
import {SymbolAttributes} from '../lib/attributes';
class SymbolElement extends Component{
static displayName = 'Symbol';
@@ -13,26 +13,18 @@ class SymbolElement extends Component{
render() {
let {props} = this;
let viewBox = props.viewBox;
if (props.viewbox) {
viewBox = props.viewbox;
console.warn('Prop `viewbox` is deprecated. please use `viewBox` instead.');
}
let content = viewBox ? <ViewBox
return <RNSVGSymbol
name={props.id}
viewBox={viewBox}
preserveAspectRatio={props.preserveAspectRatio}
{...extractViewBox(props)}
>
{props.children}
</ViewBox> : <G id={props.id}>
{props.children}
</G>;
return <Defs>
{content}
</Defs>;
</RNSVGSymbol>;
}
}
const RNSVGSymbol = createReactNativeComponentClass({
validAttributes: SymbolAttributes,
uiViewClassName: 'RNSVGSymbol'
});
export default SymbolElement;
-79
View File
@@ -1,79 +0,0 @@
import React, {Component, PropTypes} from 'react';
import createReactNativeComponentClass from 'react-native/Libraries/Renderer/src/renderers/native/createReactNativeComponentClass';
import {ViewBoxAttributes} from '../lib/attributes';
import G from './G';
const meetOrSliceTypes = {
meet: 0,
slice: 1,
none: 2
};
const alignEnum = [
'xMinYMin', 'xMidYMin', 'xMaxYMin',
'xMinYMid', 'xMidYMid', 'xMaxYMid',
'xMinYMax', 'xMidYMax', 'xMaxYMax',
'none'
].reduce((prev, name) => {
prev[name] = name;
return prev;
}, {});
const numberRegExp = /^\d*\.?\d*%?$/;
const spacesRegExp = /\s+/;
class ViewBox extends Component{
static displayName = 'ViewBox';
static propTypes = {
viewBox: PropTypes.string.isRequired,
preserveAspectRatio: PropTypes.string
};
static defaultProps = {
preserveAspectRatio: 'xMidYMid meet'
};
render() {
const {viewBox, preserveAspectRatio, name} = this.props;
let params = viewBox.trim().split(spacesRegExp);
if (params.length !== 4 || !params.some(param => param && numberRegExp.test(param))) {
console.warn('`viewBox` expected a string like `minX minY width height`, but got:' + viewBox);
return <G>
{this.props.children}
</G>;
}
let modes = preserveAspectRatio.trim().split(spacesRegExp);
let meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
let align = alignEnum[modes[0]] || 'xMidYMid';
return <RNSVGViewBox
name={name}
minX={params[0]}
minY={params[1]}
vbWidth={params[2]}
vbHeight={params[3]}
align={align}
meetOrSlice={meetOrSlice}
>
{this.props.children}
</RNSVGViewBox>;
}
}
const RNSVGViewBox = createReactNativeComponentClass({
validAttributes: ViewBoxAttributes,
uiViewClassName: 'RNSVGViewBox'
});
export default ViewBox;
export {
meetOrSliceTypes,
alignEnum
};