refactor: typescript
@@ -2,7 +2,7 @@
|
|||||||
Example/examples/
|
Example/examples/
|
||||||
Example/android/
|
Example/android/
|
||||||
Example/ios/
|
Example/ios/
|
||||||
screenShoots/
|
screenshots/
|
||||||
android/
|
android/
|
||||||
ios/
|
ios/
|
||||||
lib/extract/transform.js
|
src/lib/extract/transform.js
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
module.exports = { extends: "@react-native-community", "rules": { "no-bitwise": 0 } };
|
module.exports = {
|
||||||
|
extends: '@react-native-community',
|
||||||
|
rules: { 'no-bitwise': 0, '@typescript-eslint/no-explicit-any': 2 },
|
||||||
|
};
|
||||||
|
|||||||
1
.gitignore
vendored
@@ -45,3 +45,4 @@ cn-doc.md
|
|||||||
# experimental code
|
# experimental code
|
||||||
#
|
#
|
||||||
experimental/
|
experimental/
|
||||||
|
/lib/
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ node_modules/
|
|||||||
Example/
|
Example/
|
||||||
experimental/
|
experimental/
|
||||||
android/build/
|
android/build/
|
||||||
screenShoots/
|
screenshots/
|
||||||
idl/
|
idl/
|
||||||
|
|
||||||
# OSX
|
# OSX
|
||||||
|
|||||||
42
README.md
@@ -171,8 +171,10 @@ and run `pod install` from `ios` folder
|
|||||||
### Troubleshooting
|
### Troubleshooting
|
||||||
|
|
||||||
#### Problems with Proguard
|
#### Problems with Proguard
|
||||||
|
|
||||||
When Proguard is enabled (which it is by default for Android release builds), it causes runtine error
|
When Proguard is enabled (which it is by default for Android release builds), it causes runtine error
|
||||||
To avoid this, add an exception to `android/app/proguard-rules.pro`:
|
To avoid this, add an exception to `android/app/proguard-rules.pro`:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
-keep public class com.horcrux.svg.** {*;}
|
-keep public class com.horcrux.svg.** {*;}
|
||||||
```
|
```
|
||||||
@@ -223,7 +225,7 @@ If you suspect that you've found a spec conformance bug, then you can test using
|
|||||||
|
|
||||||
Here's a simple example. To render output like this:
|
Here's a simple example. To render output like this:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Use the following code:
|
Use the following code:
|
||||||
|
|
||||||
@@ -464,7 +466,7 @@ Colors set in the Svg element are inherited by its children:
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -490,7 +492,7 @@ The <Rect> element is used to create a rectangle and variations of a rectangle s
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -508,7 +510,7 @@ The <Circle> element is used to create a circle:
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -535,7 +537,7 @@ An ellipse is closely related to a circle. The difference is that an ellipse has
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -554,7 +556,7 @@ The <Line> element is an SVG basic shape, used to create a line connecting two p
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -578,7 +580,7 @@ The <Polygon> element is used to create a graphic that contains at least three s
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -599,7 +601,7 @@ The <Polyline> element is used to create any shape that consists of only straigh
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Code explanation:
|
Code explanation:
|
||||||
|
|
||||||
@@ -634,7 +636,7 @@ The following commands are available for path data:
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Text
|
#### Text
|
||||||
|
|
||||||
@@ -656,7 +658,7 @@ The <Text> element is used to define text.
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### TSpan
|
#### TSpan
|
||||||
|
|
||||||
@@ -689,7 +691,7 @@ The <TSpan> element is used to draw multiple lines of text in SVG. Rather than h
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### TextPath
|
#### TextPath
|
||||||
|
|
||||||
@@ -714,7 +716,7 @@ In addition to text drawn in a straight line, SVG also includes the ability to p
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### G
|
#### G
|
||||||
|
|
||||||
@@ -734,7 +736,7 @@ The <G> element is a container used to group other SVG elements. Transformations
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Use
|
#### Use
|
||||||
|
|
||||||
@@ -762,7 +764,7 @@ Before the <G> element can be referenced, it must have an ID set on it via its i
|
|||||||
|
|
||||||
The <Use> element specifies where to show the reused shapes via its x and y props. Notice that the shapes inside the <G> element are located at 0,0. That is done because their position is added to the position specified in the <Use> element.
|
The <Use> element specifies where to show the reused shapes via its x and y props. Notice that the shapes inside the <G> element are located at 0,0. That is done because their position is added to the position specified in the <Use> element.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Symbol
|
#### Symbol
|
||||||
|
|
||||||
@@ -788,7 +790,7 @@ The SVG <Symbol> element is used to define reusable symbols. The shapes nested i
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Defs
|
#### Defs
|
||||||
|
|
||||||
@@ -831,7 +833,7 @@ The <Image> element allows a raster image to be included in an Svg componenet.
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### ClipPath
|
#### ClipPath
|
||||||
|
|
||||||
@@ -883,7 +885,7 @@ The <ClipPath> SVG element defines a clipping path. A clipping path is used/refe
|
|||||||
</Svg>
|
</Svg>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### LinearGradient
|
#### LinearGradient
|
||||||
|
|
||||||
@@ -915,7 +917,7 @@ Code explanation:
|
|||||||
- The color range for a gradient can be composed of two or more colors. Each color is specified with a <Stop> tag. The offset prop is used to define where the gradient color begin and end
|
- The color range for a gradient can be composed of two or more colors. Each color is specified with a <Stop> tag. The offset prop is used to define where the gradient color begin and end
|
||||||
- The fill prop links the ellipse element to the gradient
|
- The fill prop links the ellipse element to the gradient
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
_NOTICE:_
|
_NOTICE:_
|
||||||
LinearGradient also supports percentage as prop:
|
LinearGradient also supports percentage as prop:
|
||||||
@@ -961,7 +963,7 @@ Code explanation:
|
|||||||
- The color range for a gradient can be composed of two or more colors. Each color is specified with a <stop> tag. The offset prop is used to define where the gradient color begin and end
|
- The color range for a gradient can be composed of two or more colors. Each color is specified with a <stop> tag. The offset prop is used to define where the gradient color begin and end
|
||||||
- The fill prop links the ellipse element to the gradient
|
- The fill prop links the ellipse element to the gradient
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Mask
|
#### Mask
|
||||||
|
|
||||||
@@ -1084,7 +1086,7 @@ You can use these events to provide interactivity to your react-native-svg compo
|
|||||||
/>
|
/>
|
||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
For more examples of touch in action, checkout the [TouchEvents.js examples](https://github.com/magicismight/react-native-svg-example/blob/master/examples/TouchEvents.js).
|
For more examples of touch in action, checkout the [TouchEvents.js examples](https://github.com/magicismight/react-native-svg-example/blob/master/examples/TouchEvents.js).
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { Image, requireNativeComponent } from 'react-native';
|
|
||||||
import { meetOrSliceTypes, alignEnum } from '../lib/extract/extractViewBox';
|
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
|
||||||
import Shape from './Shape';
|
|
||||||
|
|
||||||
const spacesRegExp = /\s+/;
|
|
||||||
|
|
||||||
export default class SvgImage extends Shape {
|
|
||||||
static displayName = 'Image';
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: 0,
|
|
||||||
height: 0,
|
|
||||||
preserveAspectRatio: 'xMidYMid meet',
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { props } = this;
|
|
||||||
const {
|
|
||||||
preserveAspectRatio,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
xlinkHref,
|
|
||||||
href = xlinkHref,
|
|
||||||
} = props;
|
|
||||||
const modes = preserveAspectRatio.trim().split(spacesRegExp);
|
|
||||||
return (
|
|
||||||
<RNSVGImage
|
|
||||||
ref={this.refMethod}
|
|
||||||
{...extractProps({ ...propsAndStyles(props), x: null, y: null }, this)}
|
|
||||||
x={x}
|
|
||||||
y={y}
|
|
||||||
width={width}
|
|
||||||
height={height}
|
|
||||||
meetOrSlice={meetOrSliceTypes[modes[1]] || 0}
|
|
||||||
align={alignEnum[modes[0]] || 'xMidYMid'}
|
|
||||||
src={Image.resolveAssetSource(
|
|
||||||
typeof href === 'string' ? { uri: href } : href,
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const RNSVGImage = requireNativeComponent('RNSVGImage');
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
import { Component } from 'react';
|
|
||||||
import SvgTouchableMixin from '../lib/SvgTouchableMixin';
|
|
||||||
|
|
||||||
const touchKeys = Object.keys(SvgTouchableMixin);
|
|
||||||
const touchVals = touchKeys.map(key => SvgTouchableMixin[key]);
|
|
||||||
const numTouchKeys = touchKeys.length;
|
|
||||||
|
|
||||||
export default class Shape extends Component {
|
|
||||||
constructor() {
|
|
||||||
super(...arguments);
|
|
||||||
for (let i = 0; i < numTouchKeys; i++) {
|
|
||||||
const key = touchKeys[i];
|
|
||||||
const val = touchVals[i];
|
|
||||||
if (typeof val === 'function') {
|
|
||||||
this[key] = val.bind(this);
|
|
||||||
} else {
|
|
||||||
this[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.state = this.touchableGetInitialState();
|
|
||||||
}
|
|
||||||
refMethod = ref => {
|
|
||||||
this.root = ref;
|
|
||||||
};
|
|
||||||
setNativeProps = props => {
|
|
||||||
this.root.setNativeProps(props);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import { Touchable } from 'react-native';
|
|
||||||
const PRESS_RETENTION_OFFSET = { top: 20, left: 20, right: 20, bottom: 30 };
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...Touchable.Mixin,
|
|
||||||
|
|
||||||
touchableHandleStartShouldSetResponder: function(e) {
|
|
||||||
if (this.props.onStartShouldSetResponder) {
|
|
||||||
return this.props.onStartShouldSetResponder(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleStartShouldSetResponder.call(
|
|
||||||
this,
|
|
||||||
e,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleResponderTerminationRequest: function(e) {
|
|
||||||
if (this.props.onResponderTerminationRequest) {
|
|
||||||
return this.props.onResponderTerminationRequest(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleResponderTerminationRequest.call(
|
|
||||||
this,
|
|
||||||
e,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleResponderGrant: function(e) {
|
|
||||||
if (this.props.onResponderGrant) {
|
|
||||||
return this.props.onResponderGrant(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleResponderGrant.call(this, e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleResponderMove: function(e) {
|
|
||||||
if (this.props.onResponderMove) {
|
|
||||||
return this.props.onResponderMove(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleResponderMove.call(this, e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleResponderRelease: function(e) {
|
|
||||||
if (this.props.onResponderRelease) {
|
|
||||||
return this.props.onResponderRelease(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleResponderRelease.call(this, e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleResponderTerminate: function(e) {
|
|
||||||
if (this.props.onResponderTerminate) {
|
|
||||||
return this.props.onResponderTerminate(e);
|
|
||||||
} else {
|
|
||||||
return Touchable.Mixin.touchableHandleResponderTerminate.call(this, e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandlePress: function(e) {
|
|
||||||
this.props.onPress && this.props.onPress(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleActivePressIn: function(e) {
|
|
||||||
this.props.onPressIn && this.props.onPressIn(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleActivePressOut: function(e) {
|
|
||||||
this.props.onPressOut && this.props.onPressOut(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableHandleLongPress: function(e) {
|
|
||||||
this.props.onLongPress && this.props.onLongPress(e);
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableGetPressRectOffset: function() {
|
|
||||||
return this.props.pressRetentionOffset || PRESS_RETENTION_OFFSET;
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableGetHitSlop: function() {
|
|
||||||
return this.props.hitSlop;
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableGetHighlightDelayMS: function() {
|
|
||||||
return this.props.delayPressIn || 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableGetLongPressDelayMS: function() {
|
|
||||||
return this.props.delayLongPress === 0
|
|
||||||
? 0
|
|
||||||
: this.props.delayLongPress || 500;
|
|
||||||
},
|
|
||||||
|
|
||||||
touchableGetPressOutDelayMS: function() {
|
|
||||||
return this.props.delayPressOut || 0;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export default function extractOpacity(opacity) {
|
|
||||||
const value = +opacity;
|
|
||||||
return typeof value !== 'number' || isNaN(value) ? 1 : value;
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export default {
|
|
||||||
objectBoundingBox: 0,
|
|
||||||
userSpaceOnUse: 1,
|
|
||||||
};
|
|
||||||
9999
package-lock.json
generated
108
package.json
@@ -1,43 +1,69 @@
|
|||||||
{
|
{
|
||||||
"version": "9.8.5",
|
"version": "9.8.5",
|
||||||
"name": "react-native-svg",
|
"name": "react-native-svg",
|
||||||
"description": "SVG library for react-native",
|
"description": "SVG library for react-native",
|
||||||
"homepage": "https://github.com/react-native-community/react-native-svg",
|
"homepage": "https://github.com/react-native-community/react-native-svg",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/react-native-community/react-native-svg"
|
"url": "https://github.com/react-native-community/react-native-svg"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./index",
|
"main": "lib/commonjs/index.js",
|
||||||
"keywords": [
|
"module": "lib/module/index.js",
|
||||||
"react-component",
|
"react-native": "src/index.js",
|
||||||
"react-native",
|
"types": "lib/typescript/src/index.d.ts",
|
||||||
"ios",
|
"files": [
|
||||||
"android",
|
"lib/",
|
||||||
"SVG",
|
"src/"
|
||||||
"ART",
|
],
|
||||||
"VML",
|
"@react-native-community/bob": {
|
||||||
"gradient"
|
"source": "src",
|
||||||
],
|
"output": "lib",
|
||||||
"scripts": {
|
"targets": [
|
||||||
"lint": "eslint ./",
|
"commonjs",
|
||||||
"format": "prettier index.js index.web.js xml.js README.md './{elements,lib}/*.js' './lib/extract/e*.js' --write",
|
"module",
|
||||||
"peg": "pegjs -o ./lib/extract/transform.js ./lib/extract/transform.peg"
|
"typescript"
|
||||||
},
|
]
|
||||||
"peerDependencies": {
|
},
|
||||||
"react": "*",
|
"keywords": [
|
||||||
"react-native": ">=0.50.0"
|
"react-component",
|
||||||
},
|
"react-native",
|
||||||
"dependencies": {},
|
"ios",
|
||||||
"devDependencies": {
|
"android",
|
||||||
"@react-native-community/eslint-config": "^0.0.5",
|
"SVG",
|
||||||
"babel-eslint": "^10.0.3",
|
"ART",
|
||||||
"eslint": "^6.2.2",
|
"VML",
|
||||||
"eslint-plugin-prettier": "^3.1.0",
|
"gradient"
|
||||||
"eslint-plugin-react": "^7.14.3",
|
],
|
||||||
"pegjs": "^0.10.0",
|
"scripts": {
|
||||||
"prettier": "^1.18.2",
|
"lint": "eslint --ext .ts,.tsx src",
|
||||||
"react": "^16.9.0"
|
"format": "prettier README.md './src/**/*.{ts,tsx}' src/index.d.ts --write",
|
||||||
},
|
"peg": "pegjs -o src/lib/extract/transform.js ./src/lib/extract/transform.peg",
|
||||||
"nativePackage": true
|
"tsc": "tsc --noEmit",
|
||||||
|
"test": "yarn lint && yarn tsc",
|
||||||
|
"prepare": "bob build",
|
||||||
|
"semantic-release": "semantic-release"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-native": ">=0.50.0"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"@react-native-community/bob": "^0.7.0",
|
||||||
|
"@react-native-community/eslint-config": "^0.0.5",
|
||||||
|
"@types/react": "^16.9.2",
|
||||||
|
"@types/react-native": "^0.60.12",
|
||||||
|
"babel-eslint": "^10.0.3",
|
||||||
|
"eslint": "^6.2.2",
|
||||||
|
"eslint-plugin-prettier": "^3.1.0",
|
||||||
|
"eslint-plugin-react": "^7.14.3",
|
||||||
|
"pegjs": "^0.10.0",
|
||||||
|
"prettier": "^1.18.2",
|
||||||
|
"react": "^16.9.0",
|
||||||
|
"semantic-release": "^15.13.24",
|
||||||
|
"semantic-release-cli": "^5.2.1",
|
||||||
|
"typescript": "^3.6.2"
|
||||||
|
},
|
||||||
|
"nativePackage": true
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 851 KiB After Width: | Height: | Size: 851 KiB |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
@@ -1,9 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Circle extends Shape {
|
export default class Circle extends Shape<{
|
||||||
|
cx?: NumberProp;
|
||||||
|
cy?: NumberProp;
|
||||||
|
r?: NumberProp;
|
||||||
|
}> {
|
||||||
static displayName = 'Circle';
|
static displayName = 'Circle';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -3,7 +3,11 @@ import { requireNativeComponent } from 'react-native';
|
|||||||
import extractClipPath from '../lib/extract/extractClipPath';
|
import extractClipPath from '../lib/extract/extractClipPath';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class ClipPath extends Shape {
|
export default class ClipPath extends Shape<{
|
||||||
|
id?: string;
|
||||||
|
clipPath?: string;
|
||||||
|
clipRule?: 'evenodd' | 'nonzero';
|
||||||
|
}> {
|
||||||
static displayName = 'ClipPath';
|
static displayName = 'ClipPath';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Ellipse extends Shape {
|
export default class Ellipse extends Shape<{
|
||||||
|
cx?: NumberProp;
|
||||||
|
cy?: NumberProp;
|
||||||
|
rx?: NumberProp;
|
||||||
|
ry?: NumberProp;
|
||||||
|
}> {
|
||||||
static displayName = 'Ellipse';
|
static displayName = 'Ellipse';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -3,17 +3,22 @@ import { requireNativeComponent } from 'react-native';
|
|||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
import { extractFont } from '../lib/extract/extractText';
|
import { extractFont } from '../lib/extract/extractText';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
|
import { TransformProps } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class G extends Shape {
|
export default class G extends Shape<{}> {
|
||||||
static displayName = 'G';
|
static displayName = 'G';
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
matrix?: number[];
|
||||||
|
} & TransformProps,
|
||||||
|
) => {
|
||||||
const matrix = !props.matrix && extractTransform(props);
|
const matrix = !props.matrix && extractTransform(props);
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
props.matrix = matrix;
|
props.matrix = matrix;
|
||||||
}
|
}
|
||||||
this.root.setNativeProps(props);
|
this.root && this.root.setNativeProps(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
72
src/elements/Image.tsx
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
Image,
|
||||||
|
ImageSourcePropType,
|
||||||
|
requireNativeComponent,
|
||||||
|
} from 'react-native';
|
||||||
|
import { meetOrSliceTypes, alignEnum } from '../lib/extract/extractViewBox';
|
||||||
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
|
import Shape from './Shape';
|
||||||
|
|
||||||
|
const spacesRegExp = /\s+/;
|
||||||
|
|
||||||
|
export default class SvgImage extends Shape<{
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
xlinkHref?: string | number | ImageSourcePropType;
|
||||||
|
href?: string | number | ImageSourcePropType;
|
||||||
|
}> {
|
||||||
|
static displayName = 'Image';
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
preserveAspectRatio: 'xMidYMid meet',
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { props } = this;
|
||||||
|
const {
|
||||||
|
preserveAspectRatio,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
xlinkHref,
|
||||||
|
href = xlinkHref,
|
||||||
|
} = props;
|
||||||
|
const modes = preserveAspectRatio
|
||||||
|
? preserveAspectRatio.trim().split(spacesRegExp)
|
||||||
|
: [];
|
||||||
|
const align = modes[0];
|
||||||
|
const meetOrSlice: 'meet' | 'slice' | 'none' | string | undefined =
|
||||||
|
modes[1];
|
||||||
|
return (
|
||||||
|
<RNSVGImage
|
||||||
|
ref={this.refMethod}
|
||||||
|
{...extractProps({ ...propsAndStyles(props), x: null, y: null }, this)}
|
||||||
|
x={x}
|
||||||
|
y={y}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
meetOrSlice={meetOrSliceTypes[meetOrSlice] || 0}
|
||||||
|
align={alignEnum[align] || 'xMidYMid'}
|
||||||
|
src={
|
||||||
|
!href
|
||||||
|
? null
|
||||||
|
: Image.resolveAssetSource(
|
||||||
|
typeof href === 'string' ? { uri: href } : href,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RNSVGImage = requireNativeComponent('RNSVGImage');
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Line extends Shape {
|
export default class Line extends Shape<{
|
||||||
|
x1?: NumberProp;
|
||||||
|
y1?: NumberProp;
|
||||||
|
x2?: NumberProp;
|
||||||
|
y2?: NumberProp;
|
||||||
|
}> {
|
||||||
static displayName = 'Line';
|
static displayName = 'Line';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -1,9 +1,20 @@
|
|||||||
import React from 'react';
|
import React, { ReactElement } from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractGradient from '../lib/extract/extractGradient';
|
import extractGradient from '../lib/extract/extractGradient';
|
||||||
|
import { NumberProp, TransformProps } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class LinearGradient extends Shape {
|
export default class LinearGradient extends Shape<{
|
||||||
|
id?: string;
|
||||||
|
x1?: NumberProp;
|
||||||
|
y1?: NumberProp;
|
||||||
|
x2?: NumberProp;
|
||||||
|
y2?: NumberProp;
|
||||||
|
children?: ReactElement[];
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
gradientTransform?: number[] | string | TransformProps;
|
||||||
|
gradientUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
}> {
|
||||||
static displayName = 'LinearGradient';
|
static displayName = 'LinearGradient';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -2,10 +2,20 @@ import React from 'react';
|
|||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp, TransformProps } from '../lib/extract/types';
|
||||||
import units from '../lib/units';
|
import units from '../lib/units';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Mask extends Shape {
|
export default class Mask extends Shape<{
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
maskTransform?: number[] | string | TransformProps;
|
||||||
|
maskUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
maskContentUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
}> {
|
||||||
static displayName = 'Mask';
|
static displayName = 'Mask';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -3,7 +3,9 @@ import { requireNativeComponent } from 'react-native';
|
|||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Path extends Shape {
|
export default class Path extends Shape<{
|
||||||
|
d?: string;
|
||||||
|
}> {
|
||||||
static displayName = 'Path';
|
static displayName = 'Path';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -2,10 +2,23 @@ import React from 'react';
|
|||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
import extractViewBox from '../lib/extract/extractViewBox';
|
import extractViewBox from '../lib/extract/extractViewBox';
|
||||||
|
import { NumberProp, TransformProps } from '../lib/extract/types';
|
||||||
import units from '../lib/units';
|
import units from '../lib/units';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Pattern extends Shape {
|
export default class Pattern extends Shape<{
|
||||||
|
id?: string;
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
viewBox?: string;
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
patternTransform?: number[] | string | TransformProps;
|
||||||
|
patternUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
patternContentUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
}> {
|
||||||
static displayName = 'Pattern';
|
static displayName = 'Pattern';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -42,7 +55,7 @@ export default class Pattern extends Shape {
|
|||||||
height={height}
|
height={height}
|
||||||
matrix={matrix}
|
matrix={matrix}
|
||||||
patternTransform={matrix}
|
patternTransform={matrix}
|
||||||
patternUnits={units[patternUnits] || 0}
|
patternUnits={(patternUnits && units[patternUnits]) || 0}
|
||||||
patternContentUnits={
|
patternContentUnits={
|
||||||
patternContentUnits ? units[patternContentUnits] : 1
|
patternContentUnits ? units[patternContentUnits] : 1
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import extractPolyPoints from '../lib/extract/extractPolyPoints';
|
import extractPolyPoints from '../lib/extract/extractPolyPoints';
|
||||||
|
|
||||||
export default class Polygon extends Shape {
|
export default class Polygon extends Shape<{ points?: number[] }> {
|
||||||
static displayName = 'Polygon';
|
static displayName = 'Polygon';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
points: '',
|
points: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
points?: string | (NumberProp)[];
|
||||||
|
d?: string;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
const { points } = props;
|
const { points } = props;
|
||||||
if (points) {
|
if (points) {
|
||||||
props.d = `M${extractPolyPoints(points)}z`;
|
props.d = `M${extractPolyPoints(points)}z`;
|
||||||
}
|
}
|
||||||
this.root.setNativeProps(props);
|
this.root && this.root.setNativeProps(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -23,8 +29,8 @@ export default class Polygon extends Shape {
|
|||||||
const { points } = props;
|
const { points } = props;
|
||||||
return (
|
return (
|
||||||
<Path
|
<Path
|
||||||
ref={this.refMethod}
|
ref={this.refMethod as ((instance: Path | null) => void)}
|
||||||
d={`M${extractPolyPoints(points)}z`}
|
d={points && `M${extractPolyPoints(points)}z`}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -1,21 +1,27 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Path from './Path';
|
import Path from './Path';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import extractPolyPoints from '../lib/extract/extractPolyPoints';
|
import extractPolyPoints from '../lib/extract/extractPolyPoints';
|
||||||
|
|
||||||
export default class Polyline extends Shape {
|
export default class Polyline extends Shape<{ points?: number[] }> {
|
||||||
static displayName = 'Polyline';
|
static displayName = 'Polyline';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
points: '',
|
points: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
points?: string | (NumberProp)[];
|
||||||
|
d?: string;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
const { points } = props;
|
const { points } = props;
|
||||||
if (points) {
|
if (points) {
|
||||||
props.d = `M${extractPolyPoints(points)}`;
|
props.d = `M${extractPolyPoints(points)}`;
|
||||||
}
|
}
|
||||||
this.root.setNativeProps(props);
|
this.root && this.root.setNativeProps(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -23,8 +29,8 @@ export default class Polyline extends Shape {
|
|||||||
const { points } = props;
|
const { points } = props;
|
||||||
return (
|
return (
|
||||||
<Path
|
<Path
|
||||||
ref={this.refMethod}
|
ref={this.refMethod as ((instance: Path | null) => void)}
|
||||||
d={`M${extractPolyPoints(points)}`}
|
d={points && `M${extractPolyPoints(points)}`}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -1,9 +1,23 @@
|
|||||||
import React from 'react';
|
import React, { ReactElement } from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractGradient from '../lib/extract/extractGradient';
|
import extractGradient from '../lib/extract/extractGradient';
|
||||||
|
import { NumberProp, TransformProps } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class RadialGradient extends Shape {
|
export default class RadialGradient extends Shape<{
|
||||||
|
fx?: NumberProp;
|
||||||
|
fy?: NumberProp;
|
||||||
|
rx?: NumberProp;
|
||||||
|
ry?: NumberProp;
|
||||||
|
r?: NumberProp;
|
||||||
|
cx?: NumberProp;
|
||||||
|
cy?: NumberProp;
|
||||||
|
id?: string;
|
||||||
|
children?: ReactElement[];
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
gradientTransform?: number[] | string | TransformProps;
|
||||||
|
gradientUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
}> {
|
||||||
static displayName = 'RadialGradient';
|
static displayName = 'RadialGradient';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Rect extends Shape {
|
export default class Rect extends Shape<{
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
rx?: NumberProp;
|
||||||
|
ry?: NumberProp;
|
||||||
|
}> {
|
||||||
static displayName = 'Rect';
|
static displayName = 'Rect';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
39
src/elements/Shape.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Component } from 'react';
|
||||||
|
import SvgTouchableMixin from '../lib/SvgTouchableMixin';
|
||||||
|
import { NativeMethodsMixinStatic } from 'react-native';
|
||||||
|
import { TransformProps } from '../lib/extract/types';
|
||||||
|
|
||||||
|
const { touchableGetInitialState } = SvgTouchableMixin;
|
||||||
|
const touchKeys = Object.keys(SvgTouchableMixin);
|
||||||
|
const touchVals = touchKeys.map(key => SvgTouchableMixin[key]);
|
||||||
|
const numTouchKeys = touchKeys.length;
|
||||||
|
|
||||||
|
export default class Shape<P> extends Component<P> {
|
||||||
|
[x: string]: unknown;
|
||||||
|
root: (Shape<P> & NativeMethodsMixinStatic) | null = null;
|
||||||
|
constructor(props: P, context: {}) {
|
||||||
|
super(props, context);
|
||||||
|
for (let i = 0; i < numTouchKeys; i++) {
|
||||||
|
const key = touchKeys[i];
|
||||||
|
const val = touchVals[i];
|
||||||
|
if (typeof val === 'function') {
|
||||||
|
this[key] = val.bind(this);
|
||||||
|
} else {
|
||||||
|
this[key] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.state = touchableGetInitialState();
|
||||||
|
}
|
||||||
|
refMethod: (
|
||||||
|
instance: (Shape<P> & NativeMethodsMixinStatic) | null,
|
||||||
|
) => void = (instance: (Shape<P> & NativeMethodsMixinStatic) | null) => {
|
||||||
|
this.root = instance;
|
||||||
|
};
|
||||||
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
matrix?: [number, number, number, number, number, number];
|
||||||
|
} & TransformProps,
|
||||||
|
) => {
|
||||||
|
this.root && this.root.setNativeProps(props);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,11 @@
|
|||||||
import { Component } from 'react';
|
import { Component } from 'react';
|
||||||
|
|
||||||
export default class Stop extends Component {
|
type StopProps = {
|
||||||
|
parent?: Component;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class Stop extends Component<StopProps, {}> {
|
||||||
|
props!: StopProps;
|
||||||
static displayName = 'Stop';
|
static displayName = 'Stop';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -1,10 +1,22 @@
|
|||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import {
|
import {
|
||||||
requireNativeComponent,
|
requireNativeComponent,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
findNodeHandle,
|
findNodeHandle,
|
||||||
NativeModules,
|
NativeModules,
|
||||||
|
MeasureOnSuccessCallback,
|
||||||
|
MeasureLayoutOnSuccessCallback,
|
||||||
|
MeasureInWindowOnSuccessCallback,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
|
import {
|
||||||
|
ClipProps,
|
||||||
|
FillProps,
|
||||||
|
NumberProp,
|
||||||
|
StrokeProps,
|
||||||
|
ResponderProps,
|
||||||
|
TransformProps,
|
||||||
|
ResponderInstanceProps,
|
||||||
|
} from '../lib/extract/types';
|
||||||
import extractResponder from '../lib/extract/extractResponder';
|
import extractResponder from '../lib/extract/extractResponder';
|
||||||
import extractViewBox from '../lib/extract/extractViewBox';
|
import extractViewBox from '../lib/extract/extractViewBox';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
@@ -19,26 +31,50 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default class Svg extends Shape {
|
export default class Svg extends Shape<
|
||||||
|
{
|
||||||
|
style?: [] | {};
|
||||||
|
viewBox?: string;
|
||||||
|
opacity?: NumberProp;
|
||||||
|
onLayout?: () => void;
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
} & TransformProps &
|
||||||
|
ResponderProps &
|
||||||
|
StrokeProps &
|
||||||
|
FillProps &
|
||||||
|
ClipProps
|
||||||
|
> {
|
||||||
static displayName = 'Svg';
|
static displayName = 'Svg';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
preserveAspectRatio: 'xMidYMid meet',
|
preserveAspectRatio: 'xMidYMid meet',
|
||||||
};
|
};
|
||||||
|
|
||||||
measureInWindow = (...args) => {
|
measureInWindow = (callback: MeasureInWindowOnSuccessCallback) => {
|
||||||
this.root.measureInWindow(...args);
|
this.root && this.root.measureInWindow(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
measure = (...args) => {
|
measure = (callback: MeasureOnSuccessCallback) => {
|
||||||
this.root.measure(...args);
|
this.root && this.root.measure(callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
measureLayout = (...args) => {
|
measureLayout = (
|
||||||
this.root.measureLayout(...args);
|
relativeToNativeNode: number,
|
||||||
|
onSuccess: MeasureLayoutOnSuccessCallback,
|
||||||
|
onFail: () => void /* currently unused */,
|
||||||
|
) => {
|
||||||
|
this.root &&
|
||||||
|
this.root.measureLayout(relativeToNativeNode, onSuccess, onFail);
|
||||||
};
|
};
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
bbWidth?: NumberProp;
|
||||||
|
bbHeight?: NumberProp;
|
||||||
|
},
|
||||||
|
) => {
|
||||||
const { width, height } = props;
|
const { width, height } = props;
|
||||||
if (width) {
|
if (width) {
|
||||||
props.bbWidth = width;
|
props.bbWidth = width;
|
||||||
@@ -46,20 +82,20 @@ export default class Svg extends Shape {
|
|||||||
if (height) {
|
if (height) {
|
||||||
props.bbHeight = height;
|
props.bbHeight = height;
|
||||||
}
|
}
|
||||||
this.root.setNativeProps(props);
|
this.root && this.root.setNativeProps(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
toDataURL = (callback, options) => {
|
toDataURL = (callback: () => void, options: Object) => {
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const handle = findNodeHandle(this.root);
|
const handle = findNodeHandle(this.root as Component);
|
||||||
RNSVGSvgViewManager.toDataURL(handle, options, callback);
|
RNSVGSvgViewManager.toDataURL(handle, options, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
opacity,
|
opacity = 1,
|
||||||
viewBox,
|
viewBox,
|
||||||
preserveAspectRatio,
|
preserveAspectRatio,
|
||||||
style,
|
style,
|
||||||
@@ -68,7 +104,7 @@ export default class Svg extends Shape {
|
|||||||
...props
|
...props
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const stylesAndProps = {
|
const stylesAndProps = {
|
||||||
...(style && style.length ? Object.assign({}, ...style) : style),
|
...(Array.isArray(style) ? Object.assign({}, ...style) : style),
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
const {
|
const {
|
||||||
@@ -121,7 +157,7 @@ export default class Svg extends Shape {
|
|||||||
onLayout={onLayout}
|
onLayout={onLayout}
|
||||||
ref={this.refMethod}
|
ref={this.refMethod}
|
||||||
style={[styles.svg, style, opacityStyle, dimensions]}
|
style={[styles.svg, style, opacityStyle, dimensions]}
|
||||||
{...extractResponder(props, this)}
|
{...extractResponder(props, this as ResponderInstanceProps)}
|
||||||
{...extractViewBox({ viewBox, preserveAspectRatio })}
|
{...extractViewBox({ viewBox, preserveAspectRatio })}
|
||||||
>
|
>
|
||||||
<G
|
<G
|
||||||
@@ -3,7 +3,11 @@ import { requireNativeComponent } from 'react-native';
|
|||||||
import extractViewBox from '../lib/extract/extractViewBox';
|
import extractViewBox from '../lib/extract/extractViewBox';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Symbol extends Shape {
|
export default class Symbol extends Shape<{
|
||||||
|
id?: string;
|
||||||
|
viewBox?: string;
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
}> {
|
||||||
static displayName = 'Symbol';
|
static displayName = 'Symbol';
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -1,22 +1,28 @@
|
|||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
import extractText, { setTSpan } from '../lib/extract/extractText';
|
import extractText, { setTSpan } from '../lib/extract/extractText';
|
||||||
import { pickNotNil } from '../lib/util';
|
import { pickNotNil } from '../lib/util';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
import { TransformProps } from '../lib/extract/types';
|
||||||
|
|
||||||
export default class TSpan extends Shape {
|
export default class TSpan extends Shape<{}> {
|
||||||
static displayName = 'TSpan';
|
static displayName = 'TSpan';
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
matrix?: number[];
|
||||||
|
style?: [] | {};
|
||||||
|
} & TransformProps,
|
||||||
|
) => {
|
||||||
const matrix = !props.matrix && extractTransform(props);
|
const matrix = !props.matrix && extractTransform(props);
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
props.matrix = matrix;
|
props.matrix = matrix;
|
||||||
}
|
}
|
||||||
const prop = propsAndStyles(props);
|
const prop = propsAndStyles(props);
|
||||||
Object.assign(prop, pickNotNil(extractText(prop, false)));
|
Object.assign(prop, pickNotNil(extractText(prop, false)));
|
||||||
this.root.setNativeProps(prop);
|
this.root && this.root.setNativeProps(prop);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -30,7 +36,7 @@ export default class TSpan extends Shape {
|
|||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
Object.assign(props, extractText(prop, false));
|
Object.assign(props, extractText(prop, false));
|
||||||
props.ref = this.refMethod;
|
props.ref = this.refMethod as (instance: Component | null) => void;
|
||||||
return <RNSVGTSpan {...props} />;
|
return <RNSVGTSpan {...props} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,29 @@
|
|||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractText from '../lib/extract/extractText';
|
import extractText from '../lib/extract/extractText';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
|
import { TransformProps } from '../lib/extract/types';
|
||||||
import { pickNotNil } from '../lib/util';
|
import { pickNotNil } from '../lib/util';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
import './TSpan';
|
import './TSpan';
|
||||||
|
|
||||||
export default class Text extends Shape {
|
export default class Text extends Shape<{}> {
|
||||||
static displayName = 'Text';
|
static displayName = 'Text';
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
const matrix = !props.matrix && extractTransform(props);
|
props: Object & {
|
||||||
|
matrix?: number[];
|
||||||
|
style?: [] | {};
|
||||||
|
} & TransformProps,
|
||||||
|
) => {
|
||||||
|
const matrix = props && !props.matrix && extractTransform(props);
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
props.matrix = matrix;
|
props.matrix = matrix;
|
||||||
}
|
}
|
||||||
const prop = propsAndStyles(props);
|
const prop = propsAndStyles(props);
|
||||||
Object.assign(prop, pickNotNil(extractText(prop, true)));
|
Object.assign(prop, pickNotNil(extractText(prop, true)));
|
||||||
this.root.setNativeProps(prop);
|
this.root && this.root.setNativeProps(prop);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -31,7 +37,7 @@ export default class Text extends Shape {
|
|||||||
this,
|
this,
|
||||||
);
|
);
|
||||||
Object.assign(props, extractText(prop, true));
|
Object.assign(props, extractText(prop, true));
|
||||||
props.ref = this.refMethod;
|
props.ref = this.refMethod as (instance: Component | null) => void;
|
||||||
return <RNSVGText {...props} />;
|
return <RNSVGText {...props} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,38 @@
|
|||||||
import React from 'react';
|
import React, { Component } from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractTransform from '../lib/extract/extractTransform';
|
import extractTransform from '../lib/extract/extractTransform';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp, TransformProps } from '../lib/extract/types';
|
||||||
import extractText from '../lib/extract/extractText';
|
import extractText from '../lib/extract/extractText';
|
||||||
import { idPattern, pickNotNil } from '../lib/util';
|
import { idPattern, pickNotNil } from '../lib/util';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
import TSpan from './TSpan';
|
import TSpan from './TSpan';
|
||||||
|
|
||||||
export default class TextPath extends Shape {
|
export default class TextPath extends Shape<{
|
||||||
|
children?: NumberProp | [NumberProp | React.ComponentType];
|
||||||
|
alignmentBaseline?: string;
|
||||||
|
startOffset?: NumberProp;
|
||||||
|
xlinkHref?: string;
|
||||||
|
midLine?: string;
|
||||||
|
spacing?: string;
|
||||||
|
method?: string;
|
||||||
|
href?: string;
|
||||||
|
side?: string;
|
||||||
|
}> {
|
||||||
static displayName = 'TextPath';
|
static displayName = 'TextPath';
|
||||||
|
|
||||||
setNativeProps = props => {
|
setNativeProps = (
|
||||||
|
props: Object & {
|
||||||
|
matrix?: number[];
|
||||||
|
style?: [] | {};
|
||||||
|
} & TransformProps,
|
||||||
|
) => {
|
||||||
const matrix = !props.matrix && extractTransform(props);
|
const matrix = !props.matrix && extractTransform(props);
|
||||||
if (matrix) {
|
if (matrix) {
|
||||||
props.matrix = matrix;
|
props.matrix = matrix;
|
||||||
}
|
}
|
||||||
Object.assign(props, pickNotNil(extractText(props, true)));
|
Object.assign(props, pickNotNil(extractText(props, true)));
|
||||||
this.root.setNativeProps(props);
|
this.root && this.root.setNativeProps(props);
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -61,7 +77,7 @@ export default class TextPath extends Shape {
|
|||||||
midLine,
|
midLine,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
props.ref = this.refMethod;
|
props.ref = this.refMethod as (instance: Component | null) => void;
|
||||||
return <RNSVGTextPath {...props} />;
|
return <RNSVGTextPath {...props} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +86,11 @@ export default class TextPath extends Shape {
|
|||||||
href +
|
href +
|
||||||
'"',
|
'"',
|
||||||
);
|
);
|
||||||
return <TSpan ref={this.refMethod}>{children}</TSpan>;
|
return (
|
||||||
|
<TSpan ref={this.refMethod as (instance: Component | null) => void}>
|
||||||
|
{children}
|
||||||
|
</TSpan>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { requireNativeComponent } from 'react-native';
|
import { requireNativeComponent } from 'react-native';
|
||||||
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
|
||||||
|
import { NumberProp } from '../lib/extract/types';
|
||||||
import { idPattern } from '../lib/util';
|
import { idPattern } from '../lib/util';
|
||||||
import Shape from './Shape';
|
import Shape from './Shape';
|
||||||
|
|
||||||
export default class Use extends Shape {
|
export default class Use extends Shape<{
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
width?: NumberProp;
|
||||||
|
height?: NumberProp;
|
||||||
|
xlinkHref?: string;
|
||||||
|
href?: string;
|
||||||
|
}> {
|
||||||
static displayName = 'Use';
|
static displayName = 'Use';
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
@@ -26,7 +34,7 @@ export default class Use extends Shape {
|
|||||||
href = xlinkHref,
|
href = xlinkHref,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const matched = href.match(idPattern);
|
const matched = href && href.match(idPattern);
|
||||||
const match = matched && matched[1];
|
const match = matched && matched[1];
|
||||||
|
|
||||||
if (!match) {
|
if (!match) {
|
||||||
380
index.d.ts → src/index.d.ts
vendored
@@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import * as ReactNative from 'react-native';
|
import * as ReactNative from 'react-native';
|
||||||
|
import { GestureResponderEvent } from 'react-native';
|
||||||
|
|
||||||
// Common props
|
// Common props
|
||||||
type NumberProp = string | number;
|
type NumberProp = string | number;
|
||||||
@@ -23,8 +24,7 @@ export type FontWeight =
|
|||||||
| '600'
|
| '600'
|
||||||
| '700'
|
| '700'
|
||||||
| '800'
|
| '800'
|
||||||
| '900'
|
| '900';
|
||||||
;
|
|
||||||
export type FontStretch =
|
export type FontStretch =
|
||||||
| 'normal'
|
| 'normal'
|
||||||
| 'wider'
|
| 'wider'
|
||||||
@@ -36,9 +36,13 @@ export type FontStretch =
|
|||||||
| 'semi-expanded'
|
| 'semi-expanded'
|
||||||
| 'expanded'
|
| 'expanded'
|
||||||
| 'extra-expanded'
|
| 'extra-expanded'
|
||||||
| 'ultra-expanded'
|
| 'ultra-expanded';
|
||||||
;
|
export type TextDecoration =
|
||||||
export type TextDecoration = 'none' | 'underline' | 'overline' | 'line-through' | 'blink';
|
| 'none'
|
||||||
|
| 'underline'
|
||||||
|
| 'overline'
|
||||||
|
| 'line-through'
|
||||||
|
| 'blink';
|
||||||
export type FontVariantLigatures = 'normal' | 'none';
|
export type FontVariantLigatures = 'normal' | 'none';
|
||||||
export type AlignmentBaseline =
|
export type AlignmentBaseline =
|
||||||
| 'baseline'
|
| 'baseline'
|
||||||
@@ -56,9 +60,13 @@ export type AlignmentBaseline =
|
|||||||
| 'text-after-edge'
|
| 'text-after-edge'
|
||||||
| 'before-edge'
|
| 'before-edge'
|
||||||
| 'after-edge'
|
| 'after-edge'
|
||||||
| 'hanging'
|
| 'hanging';
|
||||||
;
|
export type BaselineShift =
|
||||||
export type BaselineShift = 'sub' | 'super' | 'baseline' | ReadonlyArray<NumberProp> | NumberProp;
|
| 'sub'
|
||||||
|
| 'super'
|
||||||
|
| 'baseline'
|
||||||
|
| ReadonlyArray<NumberProp>
|
||||||
|
| NumberProp;
|
||||||
export type LengthAdjust = 'spacing' | 'spacingAndGlyphs';
|
export type LengthAdjust = 'spacing' | 'spacingAndGlyphs';
|
||||||
|
|
||||||
export type TextPathMethod = 'align' | 'stretch';
|
export type TextPathMethod = 'align' | 'stretch';
|
||||||
@@ -69,94 +77,100 @@ export type Linecap = 'butt' | 'square' | 'round';
|
|||||||
export type Linejoin = 'miter' | 'bevel' | 'round';
|
export type Linejoin = 'miter' | 'bevel' | 'round';
|
||||||
|
|
||||||
export interface TouchableProps {
|
export interface TouchableProps {
|
||||||
disabled?: boolean,
|
disabled?: boolean;
|
||||||
onPress?: (event: any) => any,
|
onPress?: (event: GestureResponderEvent) => void;
|
||||||
onPressIn?: (event: any) => any,
|
onPressIn?: (event: GestureResponderEvent) => void;
|
||||||
onPressOut?: (event: any) => any,
|
onPressOut?: (event: GestureResponderEvent) => void;
|
||||||
onLongPress?: (event: any) => any,
|
onLongPress?: (event: GestureResponderEvent) => void;
|
||||||
delayPressIn?: number,
|
delayPressIn?: number;
|
||||||
delayPressOut?: number,
|
delayPressOut?: number;
|
||||||
delayLongPress?: number
|
delayLongPress?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ResponderProps extends ReactNative.GestureResponderHandlers {
|
export interface ResponderProps extends ReactNative.GestureResponderHandlers {
|
||||||
pointerEvents?: "box-none" | "none" | "box-only" | "auto",
|
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto';
|
||||||
}
|
}
|
||||||
|
|
||||||
// rgba values inside range 0 to 1 inclusive
|
// rgba values inside range 0 to 1 inclusive
|
||||||
// rgbaArray = [r, g, b, a]
|
// rgbaArray = [r, g, b, a]
|
||||||
type rgbaArray = ReadonlyArray<number>
|
type rgbaArray = ReadonlyArray<number>;
|
||||||
|
|
||||||
// argb values inside range 0x00 to 0xff inclusive
|
// argb values inside range 0x00 to 0xff inclusive
|
||||||
// int32ARGBColor = 0xaarrggbb
|
// int32ARGBColor = 0xaarrggbb
|
||||||
type int32ARGBColor = number
|
type int32ARGBColor = number;
|
||||||
|
|
||||||
export interface FillProps {
|
export interface FillProps {
|
||||||
fill?: int32ARGBColor | rgbaArray | string,
|
fill?: int32ARGBColor | rgbaArray | string;
|
||||||
fillOpacity?: NumberProp,
|
fillOpacity?: NumberProp;
|
||||||
fillRule?: FillRule,
|
fillRule?: FillRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ClipProps {
|
export interface ClipProps {
|
||||||
clipRule?: FillRule,
|
clipRule?: FillRule;
|
||||||
clipPath?: string
|
clipPath?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VectorEffectProps {
|
interface VectorEffectProps {
|
||||||
vectorEffect?: "none" | "non-scaling-stroke" | "nonScalingStroke" | "default" | "inherit" | "uri";
|
vectorEffect?:
|
||||||
|
| 'none'
|
||||||
|
| 'non-scaling-stroke'
|
||||||
|
| 'nonScalingStroke'
|
||||||
|
| 'default'
|
||||||
|
| 'inherit'
|
||||||
|
| 'uri';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DefinitionProps {
|
export interface DefinitionProps {
|
||||||
id?: string,
|
id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StrokeProps {
|
export interface StrokeProps {
|
||||||
stroke?: int32ARGBColor | rgbaArray | string,
|
stroke?: int32ARGBColor | rgbaArray | string;
|
||||||
strokeWidth?: NumberProp,
|
strokeWidth?: NumberProp;
|
||||||
strokeOpacity?: NumberProp,
|
strokeOpacity?: NumberProp;
|
||||||
strokeDasharray?: ReadonlyArray<NumberProp> | NumberProp,
|
strokeDasharray?: ReadonlyArray<NumberProp> | NumberProp;
|
||||||
strokeDashoffset?: NumberProp,
|
strokeDashoffset?: NumberProp;
|
||||||
strokeLinecap?: Linecap,
|
strokeLinecap?: Linecap;
|
||||||
strokeLinejoin?: Linejoin,
|
strokeLinejoin?: Linejoin;
|
||||||
strokeMiterlimit?: NumberProp,
|
strokeMiterlimit?: NumberProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FontObject {
|
export interface FontObject {
|
||||||
fontStyle?: FontStyle,
|
fontStyle?: FontStyle;
|
||||||
fontVariant?: FontVariant,
|
fontVariant?: FontVariant;
|
||||||
fontWeight?: FontWeight,
|
fontWeight?: FontWeight;
|
||||||
fontStretch?: FontStretch,
|
fontStretch?: FontStretch;
|
||||||
fontSize?: NumberProp,
|
fontSize?: NumberProp;
|
||||||
fontFamily?: string,
|
fontFamily?: string;
|
||||||
textAnchor?: TextAnchor,
|
textAnchor?: TextAnchor;
|
||||||
textDecoration?: TextDecoration,
|
textDecoration?: TextDecoration;
|
||||||
letterSpacing?: NumberProp,
|
letterSpacing?: NumberProp;
|
||||||
wordSpacing?: NumberProp,
|
wordSpacing?: NumberProp;
|
||||||
kerning?: NumberProp,
|
kerning?: NumberProp;
|
||||||
fontVariantLigatures?: FontVariantLigatures,
|
fontVariantLigatures?: FontVariantLigatures;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FontProps extends FontObject {
|
export interface FontProps extends FontObject {
|
||||||
font?: FontObject,
|
font?: FontObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransformObject {
|
export interface TransformObject {
|
||||||
scale?: NumberProp,
|
scale?: NumberProp;
|
||||||
scaleX?: NumberProp,
|
scaleX?: NumberProp;
|
||||||
scaleY?: NumberProp,
|
scaleY?: NumberProp;
|
||||||
rotate?: NumberProp,
|
rotate?: NumberProp;
|
||||||
rotation?: NumberProp,
|
rotation?: NumberProp;
|
||||||
translate?: NumberProp,
|
translate?: NumberProp;
|
||||||
translateX?: NumberProp,
|
translateX?: NumberProp;
|
||||||
translateY?: NumberProp,
|
translateY?: NumberProp;
|
||||||
x?: NumberProp,
|
x?: NumberProp;
|
||||||
y?: NumberProp,
|
y?: NumberProp;
|
||||||
origin?: NumberProp,
|
origin?: NumberProp;
|
||||||
originX?: NumberProp,
|
originX?: NumberProp;
|
||||||
originY?: NumberProp,
|
originY?: NumberProp;
|
||||||
skew?: NumberProp,
|
skew?: NumberProp;
|
||||||
skewX?: NumberProp,
|
skewX?: NumberProp;
|
||||||
skewY?: NumberProp,
|
skewY?: NumberProp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -177,147 +191,160 @@ export interface TransformObject {
|
|||||||
type ColumnMajorTransformMatrix = ReadonlyArray<number>;
|
type ColumnMajorTransformMatrix = ReadonlyArray<number>;
|
||||||
|
|
||||||
export interface TransformProps extends TransformObject {
|
export interface TransformProps extends TransformObject {
|
||||||
transform?: ColumnMajorTransformMatrix | string | TransformObject,
|
transform?: ColumnMajorTransformMatrix | string | TransformObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommonMaskProps {
|
export interface CommonMaskProps {
|
||||||
mask?: string;
|
mask?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CommonPathProps extends FillProps, StrokeProps, ClipProps, TransformProps, VectorEffectProps, ResponderProps, TouchableProps, DefinitionProps, CommonMaskProps {}
|
export interface CommonPathProps
|
||||||
|
extends FillProps,
|
||||||
|
StrokeProps,
|
||||||
|
ClipProps,
|
||||||
|
TransformProps,
|
||||||
|
VectorEffectProps,
|
||||||
|
ResponderProps,
|
||||||
|
TouchableProps,
|
||||||
|
DefinitionProps,
|
||||||
|
CommonMaskProps {}
|
||||||
|
|
||||||
// Element props
|
// Element props
|
||||||
export interface CircleProps extends CommonPathProps {
|
export interface CircleProps extends CommonPathProps {
|
||||||
cx?: NumberProp,
|
cx?: NumberProp;
|
||||||
cy?: NumberProp,
|
cy?: NumberProp;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
r?: NumberProp,
|
r?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Circle: React.ComponentClass<CircleProps>;
|
export const Circle: React.ComponentClass<CircleProps>;
|
||||||
|
|
||||||
export interface ClipPathProps {
|
export interface ClipPathProps {
|
||||||
id: string,
|
id: string;
|
||||||
}
|
}
|
||||||
export const ClipPath: React.ComponentClass<ClipPathProps>;
|
export const ClipPath: React.ComponentClass<ClipPathProps>;
|
||||||
|
|
||||||
export const Defs: React.ComponentClass<{}>;
|
export const Defs: React.ComponentClass<{}>;
|
||||||
|
|
||||||
export interface EllipseProps extends CommonPathProps {
|
export interface EllipseProps extends CommonPathProps {
|
||||||
cx?: NumberProp,
|
cx?: NumberProp;
|
||||||
cy?: NumberProp,
|
cy?: NumberProp;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
rx?: NumberProp,
|
rx?: NumberProp;
|
||||||
ry?: NumberProp,
|
ry?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Ellipse: React.ComponentClass<EllipseProps>;
|
export const Ellipse: React.ComponentClass<EllipseProps>;
|
||||||
|
|
||||||
export interface GProps extends CommonPathProps {
|
export interface GProps extends CommonPathProps {
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const G: React.ComponentClass<GProps>;
|
export const G: React.ComponentClass<GProps>;
|
||||||
|
|
||||||
export interface ImageProps extends ResponderProps, CommonMaskProps, ClipProps, TouchableProps {
|
export interface ImageProps
|
||||||
x?: NumberProp,
|
extends ResponderProps,
|
||||||
y?: NumberProp,
|
CommonMaskProps,
|
||||||
width?: NumberProp,
|
ClipProps,
|
||||||
height?: NumberProp,
|
TouchableProps {
|
||||||
xlinkHref?: ReactNative.ImageProperties['source'],
|
x?: NumberProp;
|
||||||
href: ReactNative.ImageProperties['source'],
|
y?: NumberProp;
|
||||||
preserveAspectRatio?: string,
|
width?: NumberProp;
|
||||||
opacity?: NumberProp,
|
height?: NumberProp;
|
||||||
clipPath?: string
|
xlinkHref?: ReactNative.ImageProps['source'];
|
||||||
|
href: ReactNative.ImageProps['source'];
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
opacity?: NumberProp;
|
||||||
|
clipPath?: string;
|
||||||
}
|
}
|
||||||
export const Image: React.ComponentClass<ImageProps>;
|
export const Image: React.ComponentClass<ImageProps>;
|
||||||
|
|
||||||
export interface LineProps extends CommonPathProps {
|
export interface LineProps extends CommonPathProps {
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
x1?: NumberProp,
|
x1?: NumberProp;
|
||||||
x2?: NumberProp,
|
x2?: NumberProp;
|
||||||
y1?: NumberProp,
|
y1?: NumberProp;
|
||||||
y2?: NumberProp,
|
y2?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Line: React.ComponentClass<LineProps>;
|
export const Line: React.ComponentClass<LineProps>;
|
||||||
|
|
||||||
export interface LinearGradientProps {
|
export interface LinearGradientProps {
|
||||||
x1?: NumberProp,
|
x1?: NumberProp;
|
||||||
x2?: NumberProp,
|
x2?: NumberProp;
|
||||||
y1?: NumberProp,
|
y1?: NumberProp;
|
||||||
y2?: NumberProp,
|
y2?: NumberProp;
|
||||||
gradientUnits?: Units,
|
gradientUnits?: Units;
|
||||||
id: string,
|
id: string;
|
||||||
}
|
}
|
||||||
export const LinearGradient: React.ComponentClass<LinearGradientProps>;
|
export const LinearGradient: React.ComponentClass<LinearGradientProps>;
|
||||||
|
|
||||||
export interface PathProps extends CommonPathProps {
|
export interface PathProps extends CommonPathProps {
|
||||||
d: string,
|
d: string;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Path: React.ComponentClass<PathProps>;
|
export const Path: React.ComponentClass<PathProps>;
|
||||||
|
|
||||||
export interface PatternProps {
|
export interface PatternProps {
|
||||||
id: string,
|
id: string;
|
||||||
x?: NumberProp,
|
x?: NumberProp;
|
||||||
y?: NumberProp,
|
y?: NumberProp;
|
||||||
width?: NumberProp,
|
width?: NumberProp;
|
||||||
height?: NumberProp,
|
height?: NumberProp;
|
||||||
patternTransform?: ColumnMajorTransformMatrix | string,
|
patternTransform?: ColumnMajorTransformMatrix | string;
|
||||||
patternUnits?: Units,
|
patternUnits?: Units;
|
||||||
patternContentUnits?: Units,
|
patternContentUnits?: Units;
|
||||||
viewBox?: string,
|
viewBox?: string;
|
||||||
preserveAspectRatio?: string
|
preserveAspectRatio?: string;
|
||||||
}
|
}
|
||||||
export const Pattern: React.ComponentClass<PatternProps>;
|
export const Pattern: React.ComponentClass<PatternProps>;
|
||||||
|
|
||||||
export interface PolygonProps extends CommonPathProps {
|
export interface PolygonProps extends CommonPathProps {
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
points: string | ReadonlyArray<NumberProp>,
|
points: string | ReadonlyArray<NumberProp>;
|
||||||
}
|
}
|
||||||
export const Polygon: React.ComponentClass<PolygonProps>;
|
export const Polygon: React.ComponentClass<PolygonProps>;
|
||||||
|
|
||||||
export interface PolylineProps extends CommonPathProps {
|
export interface PolylineProps extends CommonPathProps {
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
points: string | ReadonlyArray<NumberProp>,
|
points: string | ReadonlyArray<NumberProp>;
|
||||||
}
|
}
|
||||||
export const Polyline: React.ComponentClass<PolylineProps>;
|
export const Polyline: React.ComponentClass<PolylineProps>;
|
||||||
|
|
||||||
export interface RadialGradientProps {
|
export interface RadialGradientProps {
|
||||||
fx?: NumberProp,
|
fx?: NumberProp;
|
||||||
fy?: NumberProp,
|
fy?: NumberProp;
|
||||||
rx?: NumberProp,
|
rx?: NumberProp;
|
||||||
ry?: NumberProp,
|
ry?: NumberProp;
|
||||||
cx?: NumberProp,
|
cx?: NumberProp;
|
||||||
cy?: NumberProp,
|
cy?: NumberProp;
|
||||||
r?: NumberProp,
|
r?: NumberProp;
|
||||||
gradientUnits?: Units,
|
gradientUnits?: Units;
|
||||||
id: string,
|
id: string;
|
||||||
}
|
}
|
||||||
export const RadialGradient: React.ComponentClass<RadialGradientProps>;
|
export const RadialGradient: React.ComponentClass<RadialGradientProps>;
|
||||||
|
|
||||||
export interface RectProps extends CommonPathProps {
|
export interface RectProps extends CommonPathProps {
|
||||||
x?: NumberProp,
|
x?: NumberProp;
|
||||||
y?: NumberProp,
|
y?: NumberProp;
|
||||||
width?: NumberProp,
|
width?: NumberProp;
|
||||||
height?: NumberProp,
|
height?: NumberProp;
|
||||||
rx?: NumberProp,
|
rx?: NumberProp;
|
||||||
ry?: NumberProp,
|
ry?: NumberProp;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Rect: React.ComponentClass<RectProps>;
|
export const Rect: React.ComponentClass<RectProps>;
|
||||||
|
|
||||||
export interface StopProps {
|
export interface StopProps {
|
||||||
stopColor?: int32ARGBColor | rgbaArray | string,
|
stopColor?: int32ARGBColor | rgbaArray | string;
|
||||||
stopOpacity?: NumberProp,
|
stopOpacity?: NumberProp;
|
||||||
offset?: NumberProp,
|
offset?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Stop: React.ComponentClass<StopProps>;
|
export const Stop: React.ComponentClass<StopProps>;
|
||||||
|
|
||||||
export interface SvgProps extends GProps, ReactNative.ViewProperties {
|
export interface SvgProps extends GProps, ReactNative.ViewProperties {
|
||||||
width?: NumberProp,
|
width?: NumberProp;
|
||||||
height?: NumberProp,
|
height?: NumberProp;
|
||||||
viewBox?: string,
|
viewBox?: string;
|
||||||
preserveAspectRatio?: string,
|
preserveAspectRatio?: string;
|
||||||
color?: int32ARGBColor | rgbaArray | string,
|
color?: int32ARGBColor | rgbaArray | string;
|
||||||
title?: string,
|
title?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Svg is both regular and default exported
|
// Svg is both regular and default exported
|
||||||
@@ -325,58 +352,57 @@ export const Svg: React.ComponentClass<SvgProps>;
|
|||||||
export default Svg;
|
export default Svg;
|
||||||
|
|
||||||
export interface SymbolProps {
|
export interface SymbolProps {
|
||||||
id: string,
|
id: string;
|
||||||
viewBox?: string,
|
viewBox?: string;
|
||||||
preserveAspectRatio?: string,
|
preserveAspectRatio?: string;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Symbol: React.ComponentClass<SymbolProps>;
|
export const Symbol: React.ComponentClass<SymbolProps>;
|
||||||
|
|
||||||
export interface TSpanProps extends CommonPathProps, FontProps {
|
export interface TSpanProps extends CommonPathProps, FontProps {
|
||||||
dx?: NumberProp,
|
dx?: NumberProp;
|
||||||
dy?: NumberProp,
|
dy?: NumberProp;
|
||||||
}
|
}
|
||||||
export const TSpan: React.ComponentClass<TSpanProps>;
|
export const TSpan: React.ComponentClass<TSpanProps>;
|
||||||
|
|
||||||
export interface TextSpecificProps extends CommonPathProps, FontProps {
|
export interface TextSpecificProps extends CommonPathProps, FontProps {
|
||||||
alignmentBaseline?: AlignmentBaseline,
|
alignmentBaseline?: AlignmentBaseline;
|
||||||
baselineShift?: BaselineShift,
|
baselineShift?: BaselineShift;
|
||||||
verticalAlign?: NumberProp,
|
verticalAlign?: NumberProp;
|
||||||
lengthAdjust?: LengthAdjust,
|
lengthAdjust?: LengthAdjust;
|
||||||
textLength?: NumberProp,
|
textLength?: NumberProp;
|
||||||
fontData?: null | { [name: string]: any },
|
fontData?: null | { [name: string]: unknown };
|
||||||
fontFeatureSettings?: string,
|
fontFeatureSettings?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TextProps extends TextSpecificProps {
|
export interface TextProps extends TextSpecificProps {
|
||||||
dx?: NumberProp,
|
dx?: NumberProp;
|
||||||
dy?: NumberProp,
|
dy?: NumberProp;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Text: React.ComponentClass<TextProps>;
|
export const Text: React.ComponentClass<TextProps>;
|
||||||
|
|
||||||
export interface TextPathProps extends TextSpecificProps {
|
export interface TextPathProps extends TextSpecificProps {
|
||||||
xlinkHref?: string,
|
xlinkHref?: string;
|
||||||
href: string,
|
href: string;
|
||||||
startOffset?: NumberProp,
|
startOffset?: NumberProp;
|
||||||
method?: TextPathMethod,
|
method?: TextPathMethod;
|
||||||
spacing?: TextPathSpacing,
|
spacing?: TextPathSpacing;
|
||||||
midLine: TextPathMidLine,
|
midLine: TextPathMidLine;
|
||||||
}
|
}
|
||||||
export const TextPath: React.ComponentClass<TextPathProps>;
|
export const TextPath: React.ComponentClass<TextPathProps>;
|
||||||
|
|
||||||
export interface UseProps extends CommonPathProps {
|
export interface UseProps extends CommonPathProps {
|
||||||
xlinkHref?: string,
|
xlinkHref?: string;
|
||||||
href: string,
|
href: string;
|
||||||
width?: NumberProp,
|
width?: NumberProp;
|
||||||
height?: NumberProp,
|
height?: NumberProp;
|
||||||
x?: NumberProp,
|
x?: NumberProp;
|
||||||
y?: NumberProp,
|
y?: NumberProp;
|
||||||
opacity?: NumberProp,
|
opacity?: NumberProp;
|
||||||
}
|
}
|
||||||
export const Use: React.ComponentClass<UseProps>;
|
export const Use: React.ComponentClass<UseProps>;
|
||||||
|
|
||||||
|
|
||||||
export enum EMaskUnits {
|
export enum EMaskUnits {
|
||||||
USER_SPACE_ON_USE = 'userSpaceOnUse',
|
USER_SPACE_ON_USE = 'userSpaceOnUse',
|
||||||
OBJECT_BOUNDING_BOX = 'objectBoundingBox',
|
OBJECT_BOUNDING_BOX = 'objectBoundingBox',
|
||||||
@@ -387,13 +413,13 @@ export type TMaskUnits =
|
|||||||
| EMaskUnits.OBJECT_BOUNDING_BOX;
|
| EMaskUnits.OBJECT_BOUNDING_BOX;
|
||||||
|
|
||||||
export interface MaskProps extends CommonPathProps {
|
export interface MaskProps extends CommonPathProps {
|
||||||
id: string,
|
id: string;
|
||||||
x?: NumberProp,
|
x?: NumberProp;
|
||||||
y?: NumberProp,
|
y?: NumberProp;
|
||||||
width?: NumberProp,
|
width?: NumberProp;
|
||||||
height?: NumberProp,
|
height?: NumberProp;
|
||||||
maskTransform?: ColumnMajorTransformMatrix | string,
|
maskTransform?: ColumnMajorTransformMatrix | string;
|
||||||
maskUnits?: TMaskUnits,
|
maskUnits?: TMaskUnits;
|
||||||
maskContentUnits?: TMaskUnits,
|
maskContentUnits?: TMaskUnits;
|
||||||
}
|
}
|
||||||
export const Mask: React.ComponentClass<MaskProps>;
|
export const Mask: React.ComponentClass<MaskProps>;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createElement } from 'react-native-web';
|
import { createElement } from 'react-native-web';
|
||||||
import { resolve } from './lib/resolve';
|
import { resolve } from './lib/resolve';
|
||||||
import { Component } from 'react';
|
import { Component } from 'react';
|
||||||
|
import { NumberProp } from './lib/extract/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `react-native-svg` supports additional props that aren't defined in the spec.
|
* `react-native-svg` supports additional props that aren't defined in the spec.
|
||||||
@@ -56,7 +57,12 @@ function prepare(props) {
|
|||||||
clean.transform = transform.join(' ');
|
clean.transform = transform.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = {};
|
const styles: {
|
||||||
|
fontStyle?: string;
|
||||||
|
fontFamily?: string;
|
||||||
|
fontSize?: NumberProp;
|
||||||
|
fontWeight?: NumberProp;
|
||||||
|
} = {};
|
||||||
|
|
||||||
if (fontFamily != null) {
|
if (fontFamily != null) {
|
||||||
styles.fontFamily = fontFamily;
|
styles.fontFamily = fontFamily;
|
||||||
@@ -100,7 +106,11 @@ export class Ellipse extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class G extends Component {
|
export class G extends Component<{
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
translate?: string;
|
||||||
|
}> {
|
||||||
render() {
|
render() {
|
||||||
const { x, y, ...rest } = this.props;
|
const { x, y, ...rest } = this.props;
|
||||||
|
|
||||||
@@ -62,7 +62,14 @@ export function toArray() {
|
|||||||
* @param {Number} tx2
|
* @param {Number} tx2
|
||||||
* @param {Number} ty2
|
* @param {Number} ty2
|
||||||
**/
|
**/
|
||||||
export function append(a2, b2, c2, d2, tx2, ty2) {
|
export function append(
|
||||||
|
a2: number,
|
||||||
|
b2: number,
|
||||||
|
c2: number,
|
||||||
|
d2: number,
|
||||||
|
tx2: number,
|
||||||
|
ty2: number,
|
||||||
|
) {
|
||||||
const change = a2 !== 1 || b2 !== 0 || c2 !== 0 || d2 !== 1;
|
const change = a2 !== 1 || b2 !== 0 || c2 !== 0 || d2 !== 1;
|
||||||
const translate = tx2 !== 0 || ty2 !== 0;
|
const translate = tx2 !== 0 || ty2 !== 0;
|
||||||
if (!change && !translate) {
|
if (!change && !translate) {
|
||||||
@@ -114,15 +121,15 @@ export function append(a2, b2, c2, d2, tx2, ty2) {
|
|||||||
* @param {Number} regY Optional.
|
* @param {Number} regY Optional.
|
||||||
**/
|
**/
|
||||||
export function appendTransform(
|
export function appendTransform(
|
||||||
x,
|
x: number,
|
||||||
y,
|
y: number,
|
||||||
scaleX,
|
scaleX: number,
|
||||||
scaleY,
|
scaleY: number,
|
||||||
rotation,
|
rotation: number,
|
||||||
skewX,
|
skewX: number,
|
||||||
skewY,
|
skewY: number,
|
||||||
regX,
|
regX: number,
|
||||||
regY,
|
regY: number,
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
x === 0 &&
|
x === 0 &&
|
||||||
118
src/lib/SvgTouchableMixin.ts
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
// @ts-ignore
|
||||||
|
import { Touchable, GestureResponderEvent } from 'react-native';
|
||||||
|
const PRESS_RETENTION_OFFSET = { top: 20, left: 20, right: 20, bottom: 30 };
|
||||||
|
// @ts-ignore
|
||||||
|
const { Mixin } = Touchable;
|
||||||
|
const {
|
||||||
|
touchableHandleStartShouldSetResponder,
|
||||||
|
touchableHandleResponderTerminationRequest,
|
||||||
|
touchableHandleResponderGrant,
|
||||||
|
touchableHandleResponderMove,
|
||||||
|
touchableHandleResponderRelease,
|
||||||
|
touchableHandleResponderTerminate,
|
||||||
|
} = Mixin;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
...Mixin,
|
||||||
|
|
||||||
|
touchableHandleStartShouldSetResponder: function(e: GestureResponderEvent) {
|
||||||
|
const { onStartShouldSetResponder } = this.props;
|
||||||
|
if (onStartShouldSetResponder) {
|
||||||
|
return onStartShouldSetResponder(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleStartShouldSetResponder.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderTerminationRequest: function(
|
||||||
|
e: GestureResponderEvent,
|
||||||
|
) {
|
||||||
|
const { onResponderTerminationRequest } = this.props;
|
||||||
|
if (onResponderTerminationRequest) {
|
||||||
|
return onResponderTerminationRequest(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleResponderTerminationRequest.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderGrant: function(e: GestureResponderEvent) {
|
||||||
|
const { onResponderGrant } = this.props;
|
||||||
|
if (onResponderGrant) {
|
||||||
|
return onResponderGrant(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleResponderGrant.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderMove: function(e: GestureResponderEvent) {
|
||||||
|
const { onResponderMove } = this.props;
|
||||||
|
if (onResponderMove) {
|
||||||
|
return onResponderMove(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleResponderMove.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderRelease: function(e: GestureResponderEvent) {
|
||||||
|
const { onResponderRelease } = this.props;
|
||||||
|
if (onResponderRelease) {
|
||||||
|
return onResponderRelease(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleResponderRelease.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleResponderTerminate: function(e: GestureResponderEvent) {
|
||||||
|
const { onResponderTerminate } = this.props;
|
||||||
|
if (onResponderTerminate) {
|
||||||
|
return onResponderTerminate(e);
|
||||||
|
} else {
|
||||||
|
return touchableHandleResponderTerminate.call(this, e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandlePress: function(e: GestureResponderEvent) {
|
||||||
|
const { onPress } = this.props;
|
||||||
|
onPress && onPress(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleActivePressIn: function(e: GestureResponderEvent) {
|
||||||
|
const { onPressIn } = this.props;
|
||||||
|
onPressIn && onPressIn(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleActivePressOut: function(e: GestureResponderEvent) {
|
||||||
|
const { onPressOut } = this.props;
|
||||||
|
onPressOut && onPressOut(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableHandleLongPress: function(e: GestureResponderEvent) {
|
||||||
|
const { onLongPress } = this.props;
|
||||||
|
onLongPress && onLongPress(e);
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetPressRectOffset: function() {
|
||||||
|
const { pressRetentionOffset } = this.props;
|
||||||
|
return pressRetentionOffset || PRESS_RETENTION_OFFSET;
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetHitSlop: function() {
|
||||||
|
const { hitSlop } = this.props;
|
||||||
|
return hitSlop;
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetHighlightDelayMS: function() {
|
||||||
|
const { delayPressIn } = this.props;
|
||||||
|
return delayPressIn || 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetLongPressDelayMS: function() {
|
||||||
|
const { delayLongPress } = this.props;
|
||||||
|
return delayLongPress === 0 ? 0 : delayLongPress || 500;
|
||||||
|
},
|
||||||
|
|
||||||
|
touchableGetPressOutDelayMS: function() {
|
||||||
|
const { delayPressOut } = this.props;
|
||||||
|
return delayPressOut || 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import extractColor, { integerColor } from './extractColor';
|
import extractColor, { integerColor } from './extractColor';
|
||||||
|
import { Color } from './types';
|
||||||
|
|
||||||
const urlIdPattern = /^url\(#(.+)\)$/;
|
const urlIdPattern = /^url\(#(.+)\)$/;
|
||||||
|
|
||||||
const currentColorBrush = [2];
|
const currentColorBrush = [2];
|
||||||
|
|
||||||
export default function extractBrush(color) {
|
export default function extractBrush(color?: Color) {
|
||||||
if (typeof color === 'number') {
|
if (typeof color === 'number') {
|
||||||
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
|
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
|
||||||
return [0, integerColor(color)];
|
return [0, integerColor(color)];
|
||||||
@@ -1,13 +1,17 @@
|
|||||||
import { idPattern } from '../util';
|
import { idPattern } from '../util';
|
||||||
|
import { ClipProps } from './types';
|
||||||
|
|
||||||
const clipRules = {
|
const clipRules: { evenodd: number; nonzero: number } = {
|
||||||
evenodd: 0,
|
evenodd: 0,
|
||||||
nonzero: 1,
|
nonzero: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function extractClipPath(props) {
|
export default function extractClipPath(props: ClipProps) {
|
||||||
const { clipPath, clipRule } = props;
|
const { clipPath, clipRule } = props;
|
||||||
const extracted = {};
|
const extracted: {
|
||||||
|
clipPath?: string;
|
||||||
|
clipRule?: number;
|
||||||
|
} = {};
|
||||||
|
|
||||||
if (clipRule) {
|
if (clipRule) {
|
||||||
extracted.clipRule = clipRules[clipRule] === 0 ? 0 : 1;
|
extracted.clipRule = clipRules[clipRule] === 0 ? 0 : 1;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Platform } from 'react-native';
|
import { Platform } from 'react-native';
|
||||||
|
import { Color } from './types';
|
||||||
|
|
||||||
export const colorNames = {
|
export const colors: { [colorname: string]: number[] } = {
|
||||||
aliceblue: [240, 248, 255],
|
aliceblue: [240, 248, 255],
|
||||||
antiquewhite: [250, 235, 215],
|
antiquewhite: [250, 235, 215],
|
||||||
aqua: [0, 255, 255],
|
aqua: [0, 255, 255],
|
||||||
@@ -150,9 +151,10 @@ export const colorNames = {
|
|||||||
yellow: [255, 255, 0],
|
yellow: [255, 255, 0],
|
||||||
yellowgreen: [154, 205, 50],
|
yellowgreen: [154, 205, 50],
|
||||||
};
|
};
|
||||||
for (const name in colorNames) {
|
export const colorNames: { [colorname: string]: number | void } = {};
|
||||||
if (colorNames.hasOwnProperty(name)) {
|
for (const name in colors) {
|
||||||
const color = colorNames[name];
|
if (colors.hasOwnProperty(name)) {
|
||||||
|
const color: number[] = colors[name];
|
||||||
const r = color[0];
|
const r = color[0];
|
||||||
const g = color[1];
|
const g = color[1];
|
||||||
const b = color[2];
|
const b = color[2];
|
||||||
@@ -161,7 +163,7 @@ for (const name in colorNames) {
|
|||||||
}
|
}
|
||||||
Object.freeze(colorNames);
|
Object.freeze(colorNames);
|
||||||
|
|
||||||
function hslToRgb(_h, _s, _l, a) {
|
function hslToRgb(_h: number, _s: number, _l: number, a: number) {
|
||||||
const h = _h / 360;
|
const h = _h / 360;
|
||||||
const s = _s / 100;
|
const s = _s / 100;
|
||||||
const l = _l / 100;
|
const l = _l / 100;
|
||||||
@@ -210,7 +212,7 @@ function hslToRgb(_h, _s, _l, a) {
|
|||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hwbToRgb(_h, _w, _b, a) {
|
function hwbToRgb(_h: number, _w: number, _b: number, a: number) {
|
||||||
const h = _h / 360;
|
const h = _h / 360;
|
||||||
let wh = _w / 100;
|
let wh = _w / 100;
|
||||||
let bl = _b / 100;
|
let bl = _b / 100;
|
||||||
@@ -277,7 +279,7 @@ function hwbToRgb(_h, _w, _b, a) {
|
|||||||
return [r, g, b, a];
|
return [r, g, b, a];
|
||||||
}
|
}
|
||||||
|
|
||||||
function clamp(num, min, max) {
|
function clamp(num: number, min: number, max: number) {
|
||||||
return Math.min(Math.max(min, num), max);
|
return Math.min(Math.max(min, num), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +289,7 @@ const rgba = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*(
|
|||||||
const per = /^rgba?\(\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
const per = /^rgba?\(\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
||||||
const keyword = /(\D+)/;
|
const keyword = /(\D+)/;
|
||||||
|
|
||||||
function rgbFromString(string) {
|
function rgbFromString(string: string) {
|
||||||
let rgb = [0, 0, 0, 1];
|
let rgb = [0, 0, 0, 1];
|
||||||
let match;
|
let match;
|
||||||
let i;
|
let i;
|
||||||
@@ -339,13 +341,13 @@ function rgbFromString(string) {
|
|||||||
return [0, 0, 0, 0];
|
return [0, 0, 0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
rgb = colorNames[match[1]];
|
let color = colorNames[match[1]];
|
||||||
|
|
||||||
if (!(typeof rgb === 'number')) {
|
if (!(typeof color === 'number')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return integerColor(rgb);
|
return integerColor(color);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -359,7 +361,7 @@ function rgbFromString(string) {
|
|||||||
|
|
||||||
const hslRegEx = /^hsla?\(\s*([+-]?(?:\d*\.)?\d+)(?:deg)?\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
const hslRegEx = /^hsla?\(\s*([+-]?(?:\d*\.)?\d+)(?:deg)?\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
||||||
|
|
||||||
function rgbFromHslString(string) {
|
function rgbFromHslString(string: string) {
|
||||||
const match = string.match(hslRegEx);
|
const match = string.match(hslRegEx);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return null;
|
return null;
|
||||||
@@ -375,7 +377,7 @@ function rgbFromHslString(string) {
|
|||||||
|
|
||||||
const hwbRegEx = /^hwb\(\s*([+-]?\d*[.]?\d+)(?:deg)?\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
const hwbRegEx = /^hwb\(\s*([+-]?\d*[.]?\d+)(?:deg)?\s*,\s*([+-]?[\d.]+)%\s*,\s*([+-]?[\d.]+)%\s*(?:,\s*([+-]?[\d.]+)\s*)?\)$/;
|
||||||
|
|
||||||
function rgbFromHwbString(string) {
|
function rgbFromHwbString(string: string) {
|
||||||
const match = string.match(hwbRegEx);
|
const match = string.match(hwbRegEx);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
return null;
|
return null;
|
||||||
@@ -389,7 +391,7 @@ function rgbFromHwbString(string) {
|
|||||||
return hwbToRgb(h, w, b, a);
|
return hwbToRgb(h, w, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
function colorFromString(string) {
|
function colorFromString(string: string) {
|
||||||
const prefix = string.substring(0, 3).toLowerCase();
|
const prefix = string.substring(0, 3).toLowerCase();
|
||||||
|
|
||||||
switch (prefix) {
|
switch (prefix) {
|
||||||
@@ -402,9 +404,9 @@ function colorFromString(string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const identity = x => x;
|
const identity = (x: number) => x;
|
||||||
|
|
||||||
const toSignedInt32 = x => x | 0x0;
|
const toSignedInt32 = (x: number) => x | 0x0;
|
||||||
|
|
||||||
// Android use 32 bit *signed* integer to represent the color
|
// Android use 32 bit *signed* integer to represent the color
|
||||||
// We utilize the fact that bitwise operations in JS also operates on
|
// We utilize the fact that bitwise operations in JS also operates on
|
||||||
@@ -414,7 +416,7 @@ export const integerColor =
|
|||||||
Platform.OS === 'android' ? toSignedInt32 : identity;
|
Platform.OS === 'android' ? toSignedInt32 : identity;
|
||||||
|
|
||||||
// Returns 0xaarrggbb or null
|
// Returns 0xaarrggbb or null
|
||||||
export default function extractColor(color) {
|
export default function extractColor(color: Color | void) {
|
||||||
if (typeof color === 'number') {
|
if (typeof color === 'number') {
|
||||||
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
|
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
|
||||||
return integerColor(color);
|
return integerColor(color);
|
||||||
@@ -1,17 +1,21 @@
|
|||||||
import extractBrush from './extractBrush';
|
import extractBrush from './extractBrush';
|
||||||
import extractOpacity from './extractOpacity';
|
import extractOpacity from './extractOpacity';
|
||||||
import { colorNames, integerColor } from './extractColor';
|
import { colorNames, integerColor } from './extractColor';
|
||||||
|
import { FillProps } from './types';
|
||||||
|
|
||||||
const fillRules = {
|
const fillRules: { evenodd: number; nonzero: number } = {
|
||||||
evenodd: 0,
|
evenodd: 0,
|
||||||
nonzero: 1,
|
nonzero: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
// default fill is black
|
// default fill is black
|
||||||
const black = colorNames.black;
|
const black = colorNames.black;
|
||||||
const defaultFill = [0, integerColor(black)];
|
const defaultFill = [0, integerColor(black as number)];
|
||||||
|
|
||||||
export default function extractFill(props, styleProperties) {
|
export default function extractFill(
|
||||||
|
props: FillProps,
|
||||||
|
styleProperties: string[],
|
||||||
|
) {
|
||||||
const { fill, fillRule, fillOpacity } = props;
|
const { fill, fillRule, fillOpacity } = props;
|
||||||
|
|
||||||
if (fill != null) {
|
if (fill != null) {
|
||||||
@@ -26,7 +30,7 @@ export default function extractFill(props, styleProperties) {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
fill: !fill && typeof fill !== 'number' ? defaultFill : extractBrush(fill),
|
fill: !fill && typeof fill !== 'number' ? defaultFill : extractBrush(fill),
|
||||||
fillRule: fillRules[fillRule] === 0 ? 0 : 1,
|
fillRule: fillRule && fillRules[fillRule] === 0 ? 0 : 1,
|
||||||
fillOpacity: extractOpacity(fillOpacity),
|
fillOpacity: extractOpacity(fillOpacity),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,21 @@
|
|||||||
import React, { Children } from 'react';
|
import React, { Children, ReactElement } from 'react';
|
||||||
|
|
||||||
import extractColor from './extractColor';
|
import extractColor from './extractColor';
|
||||||
import extractOpacity from './extractOpacity';
|
import extractOpacity from './extractOpacity';
|
||||||
import extractTransform from './extractTransform';
|
import extractTransform from './extractTransform';
|
||||||
|
import { TransformProps } from './types';
|
||||||
import units from '../units';
|
import units from '../units';
|
||||||
|
|
||||||
const percentReg = /^([+\-]?\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?)(%?)$/;
|
const percentReg = /^([+\-]?\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?)(%?)$/;
|
||||||
|
|
||||||
function percentToFloat(percent) {
|
function percentToFloat(
|
||||||
|
percent:
|
||||||
|
| number
|
||||||
|
| string
|
||||||
|
| {
|
||||||
|
__getAnimatedValue: () => number;
|
||||||
|
},
|
||||||
|
): number {
|
||||||
if (typeof percent === 'number') {
|
if (typeof percent === 'number') {
|
||||||
return percent;
|
return percent;
|
||||||
}
|
}
|
||||||
@@ -23,23 +31,35 @@ function percentToFloat(percent) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return matched[2] ? matched[1] / 100 : +matched[1];
|
return matched[2] ? +matched[1] / 100 : +matched[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
const offsetComparator = (object, other) => object[0] - other[0];
|
const offsetComparator = (object: number[], other: number[]) =>
|
||||||
|
object[0] - other[0];
|
||||||
|
|
||||||
export default function extractGradient(props, parent) {
|
export default function extractGradient(
|
||||||
|
props: {
|
||||||
|
id?: string;
|
||||||
|
children?: ReactElement[];
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
gradientTransform?: number[] | string | TransformProps;
|
||||||
|
gradientUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
|
||||||
|
} & TransformProps,
|
||||||
|
parent: {},
|
||||||
|
) {
|
||||||
const { id, children, gradientTransform, transform, gradientUnits } = props;
|
const { id, children, gradientTransform, transform, gradientUnits } = props;
|
||||||
if (!id) {
|
if (!id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stops = [];
|
const stops = [];
|
||||||
const childArray = Children.map(children, child =>
|
const childArray = children
|
||||||
React.cloneElement(child, {
|
? Children.map(children, child =>
|
||||||
parent,
|
React.cloneElement(child, {
|
||||||
}),
|
parent,
|
||||||
);
|
}),
|
||||||
|
)
|
||||||
|
: [];
|
||||||
const l = childArray.length;
|
const l = childArray.length;
|
||||||
for (let i = 0; i < l; i++) {
|
for (let i = 0; i < l; i++) {
|
||||||
const {
|
const {
|
||||||
@@ -69,7 +89,7 @@ export default function extractGradient(props, parent) {
|
|||||||
name: id,
|
name: id,
|
||||||
gradient,
|
gradient,
|
||||||
children: childArray,
|
children: childArray,
|
||||||
gradientUnits: units[gradientUnits] || 0,
|
gradientUnits: (gradientUnits && units[gradientUnits]) || 0,
|
||||||
gradientTransform: extractTransform(
|
gradientTransform: extractTransform(
|
||||||
gradientTransform || transform || props,
|
gradientTransform || transform || props,
|
||||||
),
|
),
|
||||||
@@ -1,7 +1,11 @@
|
|||||||
|
import { NumberProp } from './types';
|
||||||
|
|
||||||
const spaceReg = /\s+/;
|
const spaceReg = /\s+/;
|
||||||
const commaReg = /,/g;
|
const commaReg = /,/g;
|
||||||
|
|
||||||
export default function extractLengthList(lengthList) {
|
export default function extractLengthList(
|
||||||
|
lengthList?: (NumberProp)[] | NumberProp,
|
||||||
|
): (NumberProp)[] {
|
||||||
if (Array.isArray(lengthList)) {
|
if (Array.isArray(lengthList)) {
|
||||||
return lengthList;
|
return lengthList;
|
||||||
} else if (typeof lengthList === 'number') {
|
} else if (typeof lengthList === 'number') {
|
||||||
6
src/lib/extract/extractOpacity.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { NumberProp } from './types';
|
||||||
|
|
||||||
|
export default function extractOpacity(opacity: NumberProp | void) {
|
||||||
|
const value = +opacity;
|
||||||
|
return isNaN(value) ? 1 : value;
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
export default function extractPolyPoints(points) {
|
import { NumberProp } from './types';
|
||||||
|
|
||||||
|
export default function extractPolyPoints(points: string | (NumberProp)[]) {
|
||||||
const polyPoints = Array.isArray(points) ? points.join(',') : points;
|
const polyPoints = Array.isArray(points) ? points.join(',') : points;
|
||||||
return polyPoints
|
return polyPoints
|
||||||
.replace(/[^e]-/, ' -')
|
.replace(/[^e]-/, ' -')
|
||||||
@@ -5,21 +5,52 @@ import extractClipPath from './extractClipPath';
|
|||||||
import extractResponder from './extractResponder';
|
import extractResponder from './extractResponder';
|
||||||
import extractOpacity from './extractOpacity';
|
import extractOpacity from './extractOpacity';
|
||||||
import { idPattern } from '../util';
|
import { idPattern } from '../util';
|
||||||
|
import {
|
||||||
|
ClipProps,
|
||||||
|
FillProps,
|
||||||
|
NumberProp,
|
||||||
|
ResponderProps,
|
||||||
|
StrokeProps,
|
||||||
|
TransformProps,
|
||||||
|
} from './types';
|
||||||
|
import { Component } from 'react';
|
||||||
|
|
||||||
export function propsAndStyles(props) {
|
export function propsAndStyles(props: Object & { style?: [] | {} }) {
|
||||||
const { style } = props;
|
const { style } = props;
|
||||||
return {
|
return {
|
||||||
...(style && style.length ? Object.assign({}, ...style) : style),
|
...(Array.isArray(style) ? Object.assign({}, ...style) : style),
|
||||||
...props,
|
...props,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function extractProps(props, ref) {
|
export default function extractProps(
|
||||||
|
props: {
|
||||||
|
id?: string;
|
||||||
|
mask?: string;
|
||||||
|
clipPath?: string;
|
||||||
|
opacity?: NumberProp;
|
||||||
|
onLayout?: () => void;
|
||||||
|
transform?: number[] | string | TransformProps;
|
||||||
|
} & TransformProps &
|
||||||
|
ResponderProps &
|
||||||
|
StrokeProps &
|
||||||
|
FillProps &
|
||||||
|
ClipProps,
|
||||||
|
ref: Object,
|
||||||
|
) {
|
||||||
const { opacity, onLayout, id, clipPath, mask, transform } = props;
|
const { opacity, onLayout, id, clipPath, mask, transform } = props;
|
||||||
const styleProperties = [];
|
const styleProperties: string[] = [];
|
||||||
const transformProps = props2transform(props);
|
const transformProps = props2transform(props);
|
||||||
const matrix = transformToMatrix(transformProps, transform);
|
const matrix = transformToMatrix(transformProps, transform);
|
||||||
const extracted = {
|
const extracted: {
|
||||||
|
name?: string;
|
||||||
|
mask?: string;
|
||||||
|
opacity: number;
|
||||||
|
matrix: number[];
|
||||||
|
propList: string[];
|
||||||
|
onLayout?: () => void;
|
||||||
|
ref?: (instance: Component | null) => void;
|
||||||
|
} = {
|
||||||
matrix,
|
matrix,
|
||||||
onLayout,
|
onLayout,
|
||||||
...transformProps,
|
...transformProps,
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
import { PanResponder } from 'react-native';
|
import { PanResponder } from 'react-native';
|
||||||
|
import { ResponderInstanceProps, ResponderProps } from './types';
|
||||||
|
|
||||||
const responderKeys = Object.keys(PanResponder.create({}).panHandlers);
|
const responderKeys = Object.keys(PanResponder.create({}).panHandlers);
|
||||||
const numResponderKeys = responderKeys.length;
|
const numResponderKeys = responderKeys.length;
|
||||||
|
|
||||||
export default function extractResponder(props, ref) {
|
export default function extractResponder(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
props: { [x: string]: any } & ResponderProps,
|
||||||
|
ref: ResponderInstanceProps,
|
||||||
|
) {
|
||||||
const {
|
const {
|
||||||
onPress,
|
onPress,
|
||||||
disabled,
|
disabled,
|
||||||
@@ -15,7 +20,9 @@ export default function extractResponder(props, ref) {
|
|||||||
delayLongPress,
|
delayLongPress,
|
||||||
pointerEvents,
|
pointerEvents,
|
||||||
} = props;
|
} = props;
|
||||||
const o = {};
|
const o: {
|
||||||
|
[touchableProperty: string]: unknown;
|
||||||
|
} = {};
|
||||||
|
|
||||||
let responsible = false;
|
let responsible = false;
|
||||||
for (let i = 0; i < numResponderKeys; i++) {
|
for (let i = 0; i < numResponderKeys; i++) {
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import extractBrush from './extractBrush';
|
import extractBrush from './extractBrush';
|
||||||
import extractOpacity from './extractOpacity';
|
import extractOpacity from './extractOpacity';
|
||||||
import extractLengthList from './extractLengthList';
|
import extractLengthList from './extractLengthList';
|
||||||
|
import { StrokeProps } from './types';
|
||||||
|
|
||||||
const caps = {
|
const caps = {
|
||||||
butt: 0,
|
butt: 0,
|
||||||
@@ -23,7 +24,10 @@ const vectorEffects = {
|
|||||||
uri: 3,
|
uri: 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function extractStroke(props, styleProperties) {
|
export default function extractStroke(
|
||||||
|
props: StrokeProps,
|
||||||
|
styleProperties: string[],
|
||||||
|
) {
|
||||||
const {
|
const {
|
||||||
stroke,
|
stroke,
|
||||||
strokeOpacity,
|
strokeOpacity,
|
||||||
@@ -69,15 +73,19 @@ export default function extractStroke(props, styleProperties) {
|
|||||||
return {
|
return {
|
||||||
stroke: extractBrush(stroke),
|
stroke: extractBrush(stroke),
|
||||||
strokeOpacity: extractOpacity(strokeOpacity),
|
strokeOpacity: extractOpacity(strokeOpacity),
|
||||||
strokeLinecap: caps[strokeLinecap] || 0,
|
strokeLinecap: (strokeLinecap && caps[strokeLinecap]) || 0,
|
||||||
strokeLinejoin: joins[strokeLinejoin] || 0,
|
strokeLinejoin: (strokeLinejoin && joins[strokeLinejoin]) || 0,
|
||||||
strokeDasharray:
|
strokeDasharray:
|
||||||
strokeDash && strokeDash.length % 2 === 1
|
strokeDash && strokeDash.length % 2 === 1
|
||||||
? strokeDash.concat(strokeDash)
|
? strokeDash.concat(strokeDash)
|
||||||
: strokeDash,
|
: strokeDash,
|
||||||
strokeWidth: strokeWidth != null ? strokeWidth : 1,
|
strokeWidth: strokeWidth != null ? strokeWidth : 1,
|
||||||
strokeDashoffset: strokeDasharray ? +strokeDashoffset || 0 : null,
|
strokeDashoffset:
|
||||||
strokeMiterlimit: parseFloat(strokeMiterlimit) || 4,
|
strokeDasharray && strokeDashoffset ? +strokeDashoffset || 0 : null,
|
||||||
vectorEffect: vectorEffects[vectorEffect] || 0,
|
strokeMiterlimit:
|
||||||
|
(strokeMiterlimit && typeof strokeMiterlimit !== 'number'
|
||||||
|
? parseFloat(strokeMiterlimit)
|
||||||
|
: strokeMiterlimit) || 4,
|
||||||
|
vectorEffect: (vectorEffect && vectorEffects[vectorEffect]) || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,23 @@
|
|||||||
import React, { Children } from 'react';
|
import React, { Children, ComponentType } from 'react';
|
||||||
import extractLengthList from './extractLengthList';
|
import extractLengthList from './extractLengthList';
|
||||||
import { pickNotNil } from '../util';
|
import { pickNotNil } from '../util';
|
||||||
|
import { NumberProp } from './types';
|
||||||
|
|
||||||
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?(?:%|px|em|pt|pc|mm|cm|in]))*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
|
const fontRegExp = /^\s*((?:(?:normal|bold|italic)\s+)*)(?:(\d+(?:\.\d+)?(?:%|px|em|pt|pc|mm|cm|in]))*(?:\s*\/.*?)?\s+)?\s*"?([^"]*)/i;
|
||||||
const fontFamilyPrefix = /^[\s"']*/;
|
const fontFamilyPrefix = /^[\s"']*/;
|
||||||
const fontFamilySuffix = /[\s"']*$/;
|
const fontFamilySuffix = /[\s"']*$/;
|
||||||
const commaReg = /\s*,\s*/g;
|
const commaReg = /\s*,\s*/g;
|
||||||
|
|
||||||
const cachedFontObjectsFromString = {};
|
const cachedFontObjectsFromString: {
|
||||||
|
[font: string]: {
|
||||||
|
fontStyle: string;
|
||||||
|
fontSize: NumberProp;
|
||||||
|
fontWeight: NumberProp;
|
||||||
|
fontFamily: string | null;
|
||||||
|
} | null;
|
||||||
|
} = {};
|
||||||
|
|
||||||
function extractSingleFontFamily(fontFamilyString) {
|
function extractSingleFontFamily(fontFamilyString?: string) {
|
||||||
// SVG on the web allows for multiple font-families to be specified.
|
// SVG on the web allows for multiple font-families to be specified.
|
||||||
// For compatibility, we extract the first font-family, hoping
|
// For compatibility, we extract the first font-family, hoping
|
||||||
// we'll get a match.
|
// we'll get a match.
|
||||||
@@ -21,7 +29,7 @@ function extractSingleFontFamily(fontFamilyString) {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseFontString(font) {
|
function parseFontString(font: string) {
|
||||||
if (cachedFontObjectsFromString.hasOwnProperty(font)) {
|
if (cachedFontObjectsFromString.hasOwnProperty(font)) {
|
||||||
return cachedFontObjectsFromString[font];
|
return cachedFontObjectsFromString[font];
|
||||||
}
|
}
|
||||||
@@ -41,7 +49,26 @@ function parseFontString(font) {
|
|||||||
return cachedFontObjectsFromString[font];
|
return cachedFontObjectsFromString[font];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function extractFont(props) {
|
interface fontProps {
|
||||||
|
fontData?: unknown;
|
||||||
|
fontStyle?: string;
|
||||||
|
fontVariant?: string;
|
||||||
|
fontWeight?: NumberProp;
|
||||||
|
fontStretch?: string;
|
||||||
|
fontSize?: NumberProp;
|
||||||
|
fontFamily?: string;
|
||||||
|
textAnchor?: string;
|
||||||
|
textDecoration?: string;
|
||||||
|
letterSpacing?: NumberProp;
|
||||||
|
wordSpacing?: NumberProp;
|
||||||
|
kerning?: NumberProp;
|
||||||
|
fontFeatureSettings?: string;
|
||||||
|
fontVariantLigatures?: string;
|
||||||
|
fontVariationSettings?: string;
|
||||||
|
font?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractFont(props: fontProps) {
|
||||||
const {
|
const {
|
||||||
fontData,
|
fontData,
|
||||||
fontStyle,
|
fontStyle,
|
||||||
@@ -84,13 +111,13 @@ export function extractFont(props) {
|
|||||||
return { ...baseFont, ...ownedFont };
|
return { ...baseFont, ...ownedFont };
|
||||||
}
|
}
|
||||||
|
|
||||||
let TSpan;
|
let TSpan: ComponentType;
|
||||||
|
|
||||||
export function setTSpan(TSpanImplementation) {
|
export function setTSpan(TSpanImplementation: ComponentType) {
|
||||||
TSpan = TSpanImplementation;
|
TSpan = TSpanImplementation;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChild(child) {
|
function getChild(child: undefined | string | number | ComponentType) {
|
||||||
if (typeof child === 'string' || typeof child === 'number') {
|
if (typeof child === 'string' || typeof child === 'number') {
|
||||||
return <TSpan>{String(child)}</TSpan>;
|
return <TSpan>{String(child)}</TSpan>;
|
||||||
} else {
|
} else {
|
||||||
@@ -98,7 +125,20 @@ function getChild(child) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function extractText(props, container) {
|
export type TextProps = {
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
dx?: NumberProp;
|
||||||
|
dy?: NumberProp;
|
||||||
|
rotate?: NumberProp;
|
||||||
|
children?: string | number | (string | number | ComponentType)[];
|
||||||
|
inlineSize?: NumberProp;
|
||||||
|
baselineShift?: NumberProp;
|
||||||
|
verticalAlign?: string;
|
||||||
|
alignmentBaseline?: string;
|
||||||
|
} & fontProps;
|
||||||
|
|
||||||
|
export default function extractText(props: TextProps, container: boolean) {
|
||||||
const {
|
const {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { identity, reset, toArray, append, appendTransform } from '../Matrix2D';
|
import { append, appendTransform, identity, reset, toArray } from '../Matrix2D';
|
||||||
|
// @ts-ignore
|
||||||
import { parse } from './transform';
|
import { parse } from './transform';
|
||||||
|
import { NumberProp, TransformedProps, TransformProps } from './types';
|
||||||
|
|
||||||
function appendTransformProps(props) {
|
function appendTransformProps(props: TransformedProps) {
|
||||||
const {
|
const {
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
@@ -26,7 +28,12 @@ function appendTransformProps(props) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function universal2axis(universal, axisX, axisY, defaultValue) {
|
function universal2axis(
|
||||||
|
universal: NumberProp | (NumberProp)[] | undefined,
|
||||||
|
axisX: NumberProp | void,
|
||||||
|
axisY: NumberProp | void,
|
||||||
|
defaultValue?: number,
|
||||||
|
) {
|
||||||
let x;
|
let x;
|
||||||
let y;
|
let y;
|
||||||
if (typeof universal === 'number') {
|
if (typeof universal === 'number') {
|
||||||
@@ -61,8 +68,9 @@ function universal2axis(universal, axisX, axisY, defaultValue) {
|
|||||||
return [x || defaultValue || 0, y || defaultValue || 0];
|
return [x || defaultValue || 0, y || defaultValue || 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function props2transform(props) {
|
export function props2transform(props: TransformProps): TransformedProps {
|
||||||
const {
|
const {
|
||||||
|
rotation = 0,
|
||||||
translate,
|
translate,
|
||||||
translateX,
|
translateX,
|
||||||
translateY,
|
translateY,
|
||||||
@@ -75,7 +83,6 @@ export function props2transform(props) {
|
|||||||
skew,
|
skew,
|
||||||
skewX,
|
skewX,
|
||||||
skewY,
|
skewY,
|
||||||
rotation,
|
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
} = props;
|
} = props;
|
||||||
@@ -98,7 +105,10 @@ export function props2transform(props) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transformToMatrix(props, transform) {
|
export function transformToMatrix(
|
||||||
|
props: TransformedProps,
|
||||||
|
transform: number[] | string | TransformProps | void | undefined,
|
||||||
|
) {
|
||||||
reset();
|
reset();
|
||||||
appendTransformProps(props);
|
appendTransformProps(props);
|
||||||
|
|
||||||
@@ -130,7 +140,9 @@ export function transformToMatrix(props, transform) {
|
|||||||
return toArray();
|
return toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function extractTransform(props) {
|
export default function extractTransform(
|
||||||
|
props: number[] | string | TransformProps,
|
||||||
|
) {
|
||||||
if (Array.isArray(props)) {
|
if (Array.isArray(props)) {
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
export const meetOrSliceTypes = {
|
import { NumberProp } from './types';
|
||||||
|
|
||||||
|
export const meetOrSliceTypes: {
|
||||||
|
[meetOrSlice: string]: number;
|
||||||
|
} = {
|
||||||
meet: 0,
|
meet: 0,
|
||||||
slice: 1,
|
slice: 1,
|
||||||
none: 2,
|
none: 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const alignEnum = [
|
export const alignEnum: { [align: string]: string } = [
|
||||||
'xMinYMin',
|
'xMinYMin',
|
||||||
'xMidYMin',
|
'xMidYMin',
|
||||||
'xMaxYMin',
|
'xMaxYMin',
|
||||||
@@ -15,14 +19,17 @@ export const alignEnum = [
|
|||||||
'xMidYMax',
|
'xMidYMax',
|
||||||
'xMaxYMax',
|
'xMaxYMax',
|
||||||
'none',
|
'none',
|
||||||
].reduce((prev, name) => {
|
].reduce((prev: { [align: string]: string }, name) => {
|
||||||
prev[name] = name;
|
prev[name] = name;
|
||||||
return prev;
|
return prev;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
const spacesRegExp = /\s+/;
|
const spacesRegExp = /\s+/;
|
||||||
|
|
||||||
export default function extractViewBox(props) {
|
export default function extractViewBox(props: {
|
||||||
|
viewBox?: string | (NumberProp)[];
|
||||||
|
preserveAspectRatio?: string;
|
||||||
|
}) {
|
||||||
const { viewBox, preserveAspectRatio } = props;
|
const { viewBox, preserveAspectRatio } = props;
|
||||||
|
|
||||||
if (!viewBox) {
|
if (!viewBox) {
|
||||||
@@ -42,13 +49,15 @@ export default function extractViewBox(props) {
|
|||||||
const modes = preserveAspectRatio
|
const modes = preserveAspectRatio
|
||||||
? preserveAspectRatio.trim().split(spacesRegExp)
|
? preserveAspectRatio.trim().split(spacesRegExp)
|
||||||
: [];
|
: [];
|
||||||
|
const align = modes[0];
|
||||||
|
const meetOrSlice = modes[1];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
minX: params[0],
|
minX: params[0],
|
||||||
minY: params[1],
|
minY: params[1],
|
||||||
vbWidth: params[2],
|
vbWidth: params[2],
|
||||||
vbHeight: params[3],
|
vbHeight: params[3],
|
||||||
align: alignEnum[modes[0]] || 'xMidYMid',
|
align: alignEnum[align] || 'xMidYMid',
|
||||||
meetOrSlice: meetOrSliceTypes[modes[1]] || 0,
|
meetOrSlice: meetOrSliceTypes[meetOrSlice] || 0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
95
src/lib/extract/types.ts
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
import { GestureResponderEvent } from 'react-native';
|
||||||
|
|
||||||
|
export type NumberProp = string | number;
|
||||||
|
export type NumberArray = (NumberProp)[] | NumberProp;
|
||||||
|
|
||||||
|
// rgbaArray = [r, g, b, a]
|
||||||
|
export type rgbaArray = number[];
|
||||||
|
// int32ARGBColor = 0xaarrggbb
|
||||||
|
export type Int32ARGBColor = number;
|
||||||
|
export type Color = Int32ARGBColor | rgbaArray | string;
|
||||||
|
|
||||||
|
export type Linecap = 'butt' | 'square' | 'round';
|
||||||
|
export type Linejoin = 'miter' | 'bevel' | 'round';
|
||||||
|
export type VectorEffect =
|
||||||
|
| 'none'
|
||||||
|
| 'non-scaling-stroke'
|
||||||
|
| 'nonScalingStroke'
|
||||||
|
| 'default'
|
||||||
|
| 'inherit'
|
||||||
|
| 'uri';
|
||||||
|
|
||||||
|
export interface TransformProps {
|
||||||
|
translate?: NumberProp;
|
||||||
|
translateX?: NumberProp;
|
||||||
|
translateY?: NumberProp;
|
||||||
|
origin?: NumberProp;
|
||||||
|
originX?: NumberProp;
|
||||||
|
originY?: NumberProp;
|
||||||
|
scale?: NumberProp;
|
||||||
|
scaleX?: NumberProp;
|
||||||
|
scaleY?: NumberProp;
|
||||||
|
skew?: NumberProp;
|
||||||
|
skewX?: NumberProp;
|
||||||
|
skewY?: NumberProp;
|
||||||
|
rotation?: NumberProp;
|
||||||
|
x?: NumberProp;
|
||||||
|
y?: NumberProp;
|
||||||
|
transform?: number[] | string | TransformProps | void | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TransformedProps {
|
||||||
|
rotation: number;
|
||||||
|
originX: number;
|
||||||
|
originY: number;
|
||||||
|
scaleX: number;
|
||||||
|
scaleY: number;
|
||||||
|
skewX: number;
|
||||||
|
skewY: number;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ResponderProps = {
|
||||||
|
onPress?: () => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
onPressIn?: () => void;
|
||||||
|
onPressOut?: () => void;
|
||||||
|
onLongPress?: () => void;
|
||||||
|
delayPressIn?: number;
|
||||||
|
delayPressOut?: number;
|
||||||
|
delayLongPress?: number;
|
||||||
|
pointerEvents?: string;
|
||||||
|
};
|
||||||
|
export type ResponderInstanceProps = {
|
||||||
|
touchableHandleResponderMove?: (e: GestureResponderEvent) => void;
|
||||||
|
touchableHandleResponderGrant?: (e: GestureResponderEvent) => void;
|
||||||
|
touchableHandleResponderRelease?: (e: GestureResponderEvent) => void;
|
||||||
|
touchableHandleResponderTerminate?: (e: GestureResponderEvent) => void;
|
||||||
|
touchableHandleStartShouldSetResponder?: (
|
||||||
|
e: GestureResponderEvent,
|
||||||
|
) => boolean;
|
||||||
|
touchableHandleResponderTerminationRequest?: (
|
||||||
|
e: GestureResponderEvent,
|
||||||
|
) => boolean;
|
||||||
|
};
|
||||||
|
export type FillProps = {
|
||||||
|
fill?: Color;
|
||||||
|
fillRule?: 'evenodd' | 'nonzero';
|
||||||
|
fillOpacity?: NumberProp;
|
||||||
|
};
|
||||||
|
export type StrokeProps = {
|
||||||
|
stroke?: Color;
|
||||||
|
strokeWidth?: NumberProp;
|
||||||
|
strokeOpacity?: NumberProp;
|
||||||
|
strokeDasharray?: NumberArray;
|
||||||
|
strokeDashoffset?: NumberProp;
|
||||||
|
strokeLinecap?: Linecap;
|
||||||
|
strokeLinejoin?: Linejoin;
|
||||||
|
strokeMiterlimit?: NumberProp;
|
||||||
|
vectorEffect?: VectorEffect;
|
||||||
|
};
|
||||||
|
export type ClipProps = {
|
||||||
|
clipPath?: string;
|
||||||
|
clipRule?: 'evenodd' | 'nonzero';
|
||||||
|
};
|
||||||
5
src/lib/units.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export const units: { objectBoundingBox: number; userSpaceOnUse: number } = {
|
||||||
|
objectBoundingBox: 0,
|
||||||
|
userSpaceOnUse: 1,
|
||||||
|
};
|
||||||
|
export default units;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
export function pickNotNil(object) {
|
export function pickNotNil(object: { [prop: string]: unknown }) {
|
||||||
const result = {};
|
const result: { [prop: string]: unknown } = {};
|
||||||
for (const key in object) {
|
for (const key in object) {
|
||||||
if (object.hasOwnProperty(key)) {
|
if (object.hasOwnProperty(key)) {
|
||||||
const value = object[key];
|
const value = object[key];
|
||||||
@@ -1,4 +1,11 @@
|
|||||||
import React, { Component, useState, useEffect, useMemo } from 'react';
|
import React, {
|
||||||
|
Component,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
ReactElement,
|
||||||
|
ComponentType,
|
||||||
|
} from 'react';
|
||||||
import Rect from './elements/Rect';
|
import Rect from './elements/Rect';
|
||||||
import Circle from './elements/Circle';
|
import Circle from './elements/Circle';
|
||||||
import Ellipse from './elements/Ellipse';
|
import Ellipse from './elements/Ellipse';
|
||||||
@@ -22,7 +29,7 @@ import ClipPath from './elements/ClipPath';
|
|||||||
import Pattern from './elements/Pattern';
|
import Pattern from './elements/Pattern';
|
||||||
import Mask from './elements/Mask';
|
import Mask from './elements/Mask';
|
||||||
|
|
||||||
export const tags = {
|
export const tags: { [tag: string]: ComponentType } = {
|
||||||
svg: Svg,
|
svg: Svg,
|
||||||
circle: Circle,
|
circle: Circle,
|
||||||
ellipse: Ellipse,
|
ellipse: Ellipse,
|
||||||
@@ -51,7 +58,14 @@ function missingTag() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SvgAst({ ast, override }) {
|
interface AST {
|
||||||
|
tag: string;
|
||||||
|
children: (AST | string)[] | (ReactElement | string)[];
|
||||||
|
props: {};
|
||||||
|
Tag: ComponentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SvgAst({ ast, override }: { ast: AST; override?: Object }) {
|
||||||
const { props, children } = ast;
|
const { props, children } = ast;
|
||||||
return (
|
return (
|
||||||
<Svg {...props} {...override}>
|
<Svg {...props} {...override}>
|
||||||
@@ -60,20 +74,20 @@ export function SvgAst({ ast, override }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SvgXml(props) {
|
export function SvgXml(props: { xml: string; override?: Object }) {
|
||||||
const { xml, override } = props;
|
const { xml, override } = props;
|
||||||
const ast = useMemo(() => xml && parse(xml), [xml]);
|
const ast = useMemo(() => xml && parse(xml), [xml]);
|
||||||
return (ast && <SvgAst ast={ast} override={override || props} />) || null;
|
return (ast && <SvgAst ast={ast} override={override || props} />) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchText(uri) {
|
async function fetchText(uri: string) {
|
||||||
const response = await fetch(uri);
|
const response = await fetch(uri);
|
||||||
return await response.text();
|
return await response.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
const err = console.error.bind(console);
|
const err = console.error.bind(console);
|
||||||
|
|
||||||
export function SvgUri(props) {
|
export function SvgUri(props: { uri: string; override?: Object }) {
|
||||||
const { uri } = props;
|
const { uri } = props;
|
||||||
const [xml, setXml] = useState();
|
const [xml, setXml] = useState();
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -86,18 +100,18 @@ export function SvgUri(props) {
|
|||||||
|
|
||||||
// Extending Component is required for Animated support.
|
// Extending Component is required for Animated support.
|
||||||
|
|
||||||
export class SvgFromXml extends Component {
|
export class SvgFromXml extends Component<{ xml: string; override?: Object }> {
|
||||||
state = {};
|
state: { ast?: AST } = {};
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.parse(this.props.xml);
|
this.parse(this.props.xml);
|
||||||
}
|
}
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: { xml: string }) {
|
||||||
const { xml } = this.props;
|
const { xml } = this.props;
|
||||||
if (xml !== prevProps.xml) {
|
if (xml !== prevProps.xml) {
|
||||||
this.parse(xml);
|
this.parse(xml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parse(xml) {
|
parse(xml: string) {
|
||||||
try {
|
try {
|
||||||
this.setState({ ast: parse(xml) });
|
this.setState({ ast: parse(xml) });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -113,18 +127,18 @@ export class SvgFromXml extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SvgFromUri extends Component {
|
export class SvgFromUri extends Component<{ uri: string; override?: Object }> {
|
||||||
state = {};
|
state: { xml?: string } = {};
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.fetch(this.props.uri);
|
this.fetch(this.props.uri);
|
||||||
}
|
}
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps: { uri: string }) {
|
||||||
const { uri } = this.props;
|
const { uri } = this.props;
|
||||||
if (uri !== prevProps.uri) {
|
if (uri !== prevProps.uri) {
|
||||||
this.fetch(uri);
|
this.fetch(uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async fetch(uri) {
|
async fetch(uri: string) {
|
||||||
try {
|
try {
|
||||||
this.setState({ xml: await fetchText(uri) });
|
this.setState({ xml: await fetchText(uri) });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -140,12 +154,15 @@ export class SvgFromUri extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const upperCase = (match, letter) => letter.toUpperCase();
|
const upperCase = (_match: string, letter: string) => letter.toUpperCase();
|
||||||
|
|
||||||
const camelCase = phrase => phrase.replace(/[:\-]([a-z])/g, upperCase);
|
const camelCase = (phrase: string) =>
|
||||||
|
phrase.replace(/[:\-]([a-z])/g, upperCase);
|
||||||
|
|
||||||
export function getStyle(string) {
|
type Styles = { [property: string]: string };
|
||||||
const style = {};
|
|
||||||
|
export function getStyle(string: string): Styles {
|
||||||
|
const style: Styles = {};
|
||||||
const declarations = string.split(';');
|
const declarations = string.split(';');
|
||||||
const { length } = declarations;
|
const { length } = declarations;
|
||||||
for (let i = 0; i < length; i++) {
|
for (let i = 0; i < length; i++) {
|
||||||
@@ -160,21 +177,24 @@ export function getStyle(string) {
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function astToReact(child, i) {
|
export function astToReact(
|
||||||
if (typeof child === 'object') {
|
value: AST | string,
|
||||||
const { Tag, props, children } = child;
|
index: number,
|
||||||
|
): ReactElement | string {
|
||||||
|
if (typeof value === 'object') {
|
||||||
|
const { Tag, props, children } = value;
|
||||||
return (
|
return (
|
||||||
<Tag key={i} {...props}>
|
<Tag key={index} {...props}>
|
||||||
{children.map(astToReact)}
|
{(children as (AST | string)[]).map(astToReact)}
|
||||||
</Tag>
|
</Tag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return child;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// slimmed down parser based on https://github.com/Rich-Harris/svg-parser
|
// slimmed down parser based on https://github.com/Rich-Harris/svg-parser
|
||||||
|
|
||||||
function repeat(str, i) {
|
function repeat(str: string, i: number) {
|
||||||
let result = '';
|
let result = '';
|
||||||
while (i--) {
|
while (i--) {
|
||||||
result += str;
|
result += str;
|
||||||
@@ -182,9 +202,9 @@ function repeat(str, i) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toSpaces = tabs => repeat(' ', tabs.length);
|
const toSpaces = (tabs: string) => repeat(' ', tabs.length);
|
||||||
|
|
||||||
function locate(source, i) {
|
function locate(source: string, i: number) {
|
||||||
const lines = source.split('\n');
|
const lines = source.split('\n');
|
||||||
const nLines = lines.length;
|
const nLines = lines.length;
|
||||||
let column = i;
|
let column = i;
|
||||||
@@ -198,9 +218,11 @@ function locate(source, i) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const before = source.slice(0, i).replace(/^\t+/, toSpaces);
|
const before = source.slice(0, i).replace(/^\t+/, toSpaces);
|
||||||
const beforeLine = /(^|\n).*$/.exec(before)[0];
|
const beforeExec = /(^|\n).*$/.exec(before);
|
||||||
|
const beforeLine = (beforeExec && beforeExec[0]) || '';
|
||||||
const after = source.slice(i);
|
const after = source.slice(i);
|
||||||
const afterLine = /.*(\n|$)/.exec(after)[0];
|
const afterExec = /.*(\n|$)/.exec(after);
|
||||||
|
const afterLine = afterExec && afterExec[0];
|
||||||
const pad = repeat(' ', beforeLine.length);
|
const pad = repeat(' ', beforeLine.length);
|
||||||
const snippet = `${beforeLine}${afterLine}\n${pad}^`;
|
const snippet = `${beforeLine}${afterLine}\n${pad}^`;
|
||||||
return { line, column, snippet };
|
return { line, column, snippet };
|
||||||
@@ -210,15 +232,15 @@ const validNameCharacters = /[a-zA-Z0-9:_-]/;
|
|||||||
const whitespace = /[\s\t\r\n]/;
|
const whitespace = /[\s\t\r\n]/;
|
||||||
const quotemarks = /['"]/;
|
const quotemarks = /['"]/;
|
||||||
|
|
||||||
export function parse(source) {
|
export function parse(source: string) {
|
||||||
const length = source.length;
|
const length = source.length;
|
||||||
let currentElement = null;
|
let currentElement: AST | null = null;
|
||||||
let state = metadata;
|
let state = metadata;
|
||||||
let children = null;
|
let children = null;
|
||||||
let root = null;
|
let root: AST | null = null;
|
||||||
let stack = [];
|
let stack: AST[] = [];
|
||||||
|
|
||||||
function error(message) {
|
function error(message: string) {
|
||||||
const { line, column, snippet } = locate(source, i);
|
const { line, column, snippet } = locate(source, i);
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${message} (${line}:${column}). If this is valid SVG, it's probably a bug. Please raise an issue\n\n${snippet}`,
|
`${message} (${line}:${column}). If this is valid SVG, it's probably a bug. Please raise an issue\n\n${snippet}`,
|
||||||
@@ -281,8 +303,8 @@ export function parse(source) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tag = getName();
|
const tag = getName();
|
||||||
const props = {};
|
const props: { style?: Styles | string } = {};
|
||||||
const element = {
|
const element: AST = {
|
||||||
tag,
|
tag,
|
||||||
props,
|
props,
|
||||||
children: [],
|
children: [],
|
||||||
@@ -298,7 +320,7 @@ export function parse(source) {
|
|||||||
getAttributes(props);
|
getAttributes(props);
|
||||||
|
|
||||||
const { style } = props;
|
const { style } = props;
|
||||||
if (style) {
|
if (typeof style === 'string') {
|
||||||
props.style = getStyle(style);
|
props.style = getStyle(style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +371,7 @@ export function parse(source) {
|
|||||||
error('Expected tag name');
|
error('Expected tag name');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tag !== currentElement.tag) {
|
if (currentElement && tag !== currentElement.tag) {
|
||||||
error(
|
error(
|
||||||
`Expected closing tag </${tag}> to match opening tag <${currentElement.tag}>`,
|
`Expected closing tag </${tag}> to match opening tag <${currentElement.tag}>`,
|
||||||
);
|
);
|
||||||
@@ -379,7 +401,10 @@ export function parse(source) {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAttributes(props) {
|
function getAttributes(props: {
|
||||||
|
[x: string]: Styles | string | number | boolean | undefined;
|
||||||
|
style?: string | Styles | undefined;
|
||||||
|
}) {
|
||||||
while (i < length) {
|
while (i < length) {
|
||||||
if (!whitespace.test(source[i])) {
|
if (!whitespace.test(source[i])) {
|
||||||
return;
|
return;
|
||||||
@@ -391,7 +416,7 @@ export function parse(source) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = true;
|
let value: boolean | number | string = true;
|
||||||
|
|
||||||
allowSpaces();
|
allowSpaces();
|
||||||
if (source[i] === '=') {
|
if (source[i] === '=') {
|
||||||
@@ -399,7 +424,7 @@ export function parse(source) {
|
|||||||
allowSpaces();
|
allowSpaces();
|
||||||
|
|
||||||
value = getAttributeValue();
|
value = getAttributeValue();
|
||||||
if (!isNaN(value) && value.trim() !== '') {
|
if (!isNaN(+value) && value.trim() !== '') {
|
||||||
value = +value;
|
value = +value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -408,7 +433,7 @@ export function parse(source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAttributeValue() {
|
function getAttributeValue(): string {
|
||||||
return quotemarks.test(source[i])
|
return quotemarks.test(source[i])
|
||||||
? getQuotedAttributeValue()
|
? getQuotedAttributeValue()
|
||||||
: getUnquotedAttributeValue();
|
: getUnquotedAttributeValue();
|
||||||
@@ -448,6 +473,8 @@ export function parse(source) {
|
|||||||
value += escaped ? `\\${char}` : char;
|
value += escaped ? `\\${char}` : char;
|
||||||
escaped = false;
|
escaped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function allowSpaces() {
|
function allowSpaces() {
|
||||||
@@ -469,8 +496,10 @@ export function parse(source) {
|
|||||||
error('Unexpected end of input');
|
error('Unexpected end of input');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root) {
|
if (root && typeof root === 'object') {
|
||||||
root.children = root.children.map(astToReact);
|
const r: AST = root;
|
||||||
|
const ast: (AST | string)[] = r.children as (AST | string)[];
|
||||||
|
r.children = ast.map(astToReact);
|
||||||
}
|
}
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
26
tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2017",
|
||||||
|
"lib": ["es6"],
|
||||||
|
"jsx": "react-native",
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"strictFunctionTypes": true,
|
||||||
|
"strictPropertyInitialization": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"alwaysStrict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"types": ["react", "react-native"]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/index.d.ts"
|
||||||
|
],
|
||||||
|
"include": ["src/index.ts"]
|
||||||
|
}
|
||||||