Refactor typescript code (#1806)

Co-authored-by: Eric Butler <eric@codebutler.com>
This commit is contained in:
Wojciech Lewicki
2022-07-22 17:41:30 +02:00
committed by GitHub
parent a7a31ca806
commit 286c02fac4
44 changed files with 3511 additions and 3721 deletions

35
.github/workflows/js-build-test.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
name: Test JS build
on:
pull_request:
branches:
- main
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
concurrency:
group: js-${{ github.ref }}
cancel-in-progress: true
steps:
- name: checkout
uses: actions/checkout@v2
- name: Use Node.js 14
uses: actions/setup-node@v2
with:
node-version: 14
cache: 'yarn'
cache-dependency-path: 'yarn.lock'
- name: Install node dependencies
run: yarn
- name: Build
run: yarn bob
- name: Lint
run: yarn lint
- name: Tests
run: yarn jest
- name: Build Example App
working-directory: Example/
run: yarn && yarn tsc

View File

@@ -347,7 +347,7 @@ PODS:
- React-jsi (= 0.68.0-rc.1)
- React-logger (= 0.68.0-rc.1)
- React-perflogger (= 0.68.0-rc.1)
- RNSVG (12.3.0):
- RNSVG (12.4.0):
- React-Core
- SocketRocket (0.6.0)
- Yoga (1.14.0)
@@ -501,7 +501,7 @@ SPEC CHECKSUMS:
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: bcdeff523be9f87a135b7c6fde8736db94904716
FBReactNativeSpec: c01fba40ea819e68030d0d9b9094a173b2a3d127
FBReactNativeSpec: 226f8b0f1a2e736a49301883ee34bca88cdc24f6
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c
@@ -540,11 +540,11 @@ SPEC CHECKSUMS:
React-RCTVibration: 5cab6419b68d5750482b0fc34dbb27af550469cc
React-runtimeexecutor: 10cda3a396b14a764a5f86088e7e3810b9c66cec
ReactCommon: 73a01eb83f22c84a6b09dfb60f3463888ebd4975
RNSVG: 302bfc9905bd8122f08966dc2ce2d07b7b52b9f8
RNSVG: 3dd44d99d1c18e1342aee4bfa53ab3f6a8c4865f
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Yoga: d29dba374c1a582b40cfb736647b5e1b5ed35dba
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: e30a289393eb06dc243ea6a44784bc9e84b1129f
COCOAPODS: 1.11.2
COCOAPODS: 1.11.3

View File

@@ -9,7 +9,8 @@
"start": "react-native start",
"start-webpack": "webpack serve",
"test": "jest",
"lint": "eslint ."
"lint": "eslint .",
"tsc": "tsc --noEmit"
},
"dependencies": {
"react": "17.0.2",
@@ -31,6 +32,7 @@
"metro-react-native-babel-preset": "^0.67.0",
"react-native-gradle-plugin": "^0.0.4",
"react-test-renderer": "17.0.2",
"typescript": "^4.6.4",
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"

View File

@@ -94,7 +94,7 @@ const styles = StyleSheet.create({
},
});
const names = [
const names: (keyof typeof examples)[] = [
'Svg',
'Stroking',
'Path',
@@ -126,7 +126,7 @@ export default class SvgExample extends Component {
scroll?: boolean;
} = initialState;
show = name => {
show = (name: keyof typeof examples) => {
if (this.state.modal) {
return;
}
@@ -145,7 +145,7 @@ export default class SvgExample extends Component {
))}
</View>
),
scroll: example.scroll !== false,
scroll: (example as {scroll?: boolean}).scroll !== false,
});
}
};

View File

@@ -1,5 +1,5 @@
import React, {Component} from 'react';
import {Platform} from 'react-native';
import {Alert, Platform} from 'react-native';
import {Svg, Circle, Text, Rect, Defs, ClipPath, Image} from 'react-native-svg';
class ImageExample extends Component {
@@ -49,7 +49,7 @@ class ClipImage extends Component {
</ClipPath>
</Defs>
<Image
onPress={() => alert('press on Image')}
onPress={() => Alert.alert('press on Image')}
x="5%"
y="5%"
width="90%"

View File

@@ -1,11 +1,11 @@
import React, {PureComponent} from 'react';
import {
PanResponder,
View,
Animated,
PanResponder,
TouchableWithoutFeedback,
View,
} from 'react-native';
import {Svg, G, Text, Path, Polyline, Line} from 'react-native-svg';
import {G, Line, Path, Polyline, Svg, Text} from 'react-native-svg';
const AnimatedSvg = Animated.createAnimatedComponent(Svg);
@@ -14,7 +14,7 @@ const zeroDelta = {x: 0, y: 0};
class PanExample extends PureComponent {
static title = 'Bind PanResponder on the SVG Shape';
panXY: any;
constructor(props, context) {
constructor(props: {}, context: {}) {
super(props, context);
const xy = new Animated.ValueXY();
const {x: dx, y: dy} = xy;

View File

@@ -132,13 +132,13 @@ class SvgNativeMethods extends Component {
base64: null,
};
alert = () => {
this.root.toDataURL(base64 => {
this.root?.toDataURL((base64: string) => {
this.setState({
base64,
});
});
};
root: any;
root?: Svg | null;
render() {
return (
<View>

View File

@@ -10,6 +10,7 @@ import {
Defs,
ClipPath,
} from 'react-native-svg';
import {Alert} from 'react-native';
class PressExample extends Component {
static title =
@@ -22,7 +23,7 @@ class PressExample extends Component {
cy="50%"
r="38%"
fill="red"
onPress={() => alert('Press on Circle')}
onPress={() => Alert.alert('Press on Circle')}
/>
<Rect
x="20%"
@@ -30,7 +31,7 @@ class PressExample extends Component {
width="60%"
height="60%"
fill="blue"
onLongPress={() => alert('Long press on Rect')}
onLongPress={() => Alert.alert('Long press on Rect')}
/>
<Path d="M50,5L20,99L95,39L5,39L80,99z" fill="pink" />
</Svg>
@@ -75,14 +76,14 @@ class GroupExample extends Component {
render() {
return (
<Svg height="120" width="120" viewBox="0 0 240 240">
<G onPress={() => alert('Pressed on G')} scale="1.4">
<G onPress={() => Alert.alert('Pressed on G')} scale="1.4">
<Circle cx="80" cy="80" r="30" fill="green" x="20" scale="1.2" />
<Text
fontWeight="bold"
fontSize="40"
x="100"
y="40"
onPress={() => alert('Pressed on Text')}>
onPress={() => Alert.alert('Pressed on Text')}>
H
</Text>
<Rect x="20" y="20" width="40" height="40" fill="yellow" />

4
Example/tsconfig.json Normal file
View File

@@ -0,0 +1,4 @@
{
"extends": "../tsconfig.json",
"include": ["src/**/*"]
}

View File

@@ -2925,18 +2925,18 @@ css-in-js-utils@^2.0.0:
hyphenate-style-name "^1.0.2"
isobject "^3.0.1"
css-select@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd"
integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==
css-select@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
dependencies:
boolbase "^1.0.0"
css-what "^5.1.0"
domhandler "^4.3.0"
domutils "^2.8.0"
css-what "^6.1.0"
domhandler "^5.0.2"
domutils "^3.0.1"
nth-check "^2.0.1"
css-tree@^1.0.0-alpha.39:
css-tree@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
@@ -2944,10 +2944,10 @@ css-tree@^1.0.0-alpha.39:
mdn-data "2.0.14"
source-map "^0.6.1"
css-what@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
css-what@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
cssom@^0.4.4:
version "0.4.4"
@@ -3190,19 +3190,19 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
dom-serializer@^1.0.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.2.0"
entities "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.0.1, domelementtype@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domexception@^2.0.1:
version "2.0.1"
@@ -3211,21 +3211,21 @@ domexception@^2.0.1:
dependencies:
webidl-conversions "^5.0.0"
domhandler@^4.2.0, domhandler@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
domhandler@^5.0.1, domhandler@^5.0.2:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.2.0"
domelementtype "^2.3.0"
domutils@^2.8.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
domutils@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
domhandler "^4.2.0"
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.1"
ee-first@1.1.1:
version "1.1.1"
@@ -3279,10 +3279,10 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"
entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
entities@^4.2.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4"
integrity sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==
envinfo@^7.7.2, envinfo@^7.7.3:
version "7.8.1"
@@ -7075,10 +7075,8 @@ react-native-macos@^0.66.0-0:
ws "^6.1.4"
"react-native-svg@link:..":
version "12.3.0"
dependencies:
css-select "^4.2.1"
css-tree "^1.0.0-alpha.39"
version "0.0.0"
uid ""
react-native-web@^0.17.7:
version "0.17.7"
@@ -8311,6 +8309,11 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typescript@^4.6.4:
version "4.6.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9"
integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==
ua-parser-js@^0.7.30:
version "0.7.31"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"

View File

@@ -10,8 +10,8 @@
"license": "MIT",
"main": "lib/commonjs/index.js",
"module": "lib/module/index.js",
"types": "lib/typescript/index.d.ts",
"react-native": "src/index.ts",
"types": "src/index.d.ts",
"files": [
"__tests__",
"android",
@@ -46,13 +46,12 @@
"scripts": {
"bob": "bob build",
"flow": "flow src",
"flowgen": "flowgen src/index.d.ts -o src/index.js.flow",
"flowtyped": "flow-typed install",
"format": "prettier README.md CONTRIBUTING.md CODE_OF_CONDUCT.md './src/**/*.{ts,tsx}' src/index.d.ts --write",
"format": "prettier README.md CONTRIBUTING.md CODE_OF_CONDUCT.md './src/**/*.{ts,tsx}'",
"jest": "jest",
"lint": "eslint --ext .ts,.tsx src",
"peg": "pegjs -o src/lib/extract/transform.js ./src/lib/extract/transform.peg",
"prepare": "npm run flowgen && npm run bob",
"prepare": "npm run bob",
"release": "npm login && release-it",
"test": "npm run lint && npm run tsc && npm run flow && npm run jest",
"tsc": "tsc --noEmit"
@@ -75,8 +74,8 @@
"@types/css-tree": "^1.0.3",
"@types/jest": "^27.5.2",
"@types/node": "*",
"@types/react": "^17.0.16",
"@types/react-native": "^0.63.40",
"@types/react": "~18.0.15",
"@types/react-native": "^0.69.3",
"babel-eslint": "^10.1.0",
"babel-jest": "^28.1.0",
"eslint": "^8.16.0",

View File

@@ -1,14 +1,17 @@
import React from 'react';
import { extract } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGCircle } from './NativeComponents';
export default class Circle extends Shape<{
export interface CircleProps extends CommonPathProps {
cx?: NumberProp;
cy?: NumberProp;
opacity?: NumberProp;
r?: NumberProp;
}> {
}
export default class Circle extends Shape<CircleProps> {
static displayName = 'Circle';
static defaultProps = {

View File

@@ -1,9 +1,14 @@
import React from 'react';
import React, { ReactNode } from 'react';
import { extract } from '../lib/extract/extractProps';
import Shape from './Shape';
import { RNSVGClipPath } from './NativeComponents';
export default class ClipPath extends Shape<{}> {
export interface ClipPathProps {
children?: ReactNode;
id?: string;
}
export default class ClipPath extends Shape<ClipPathProps> {
static displayName = 'ClipPath';
render() {

View File

@@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { RNSVGDefs } from './NativeComponents';
export default class Defs extends Component {
export default class Defs extends Component<React.PropsWithChildren<{}>> {
static displayName = 'Defs';
render() {

View File

@@ -1,15 +1,18 @@
import React from 'react';
import { extract } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGEllipse } from './NativeComponents';
export default class Ellipse extends Shape<{
export interface EllipseProps extends CommonPathProps {
cx?: NumberProp;
cy?: NumberProp;
opacity?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
}> {
}
export default class Ellipse extends Shape<EllipseProps> {
static displayName = 'Ellipse';
static defaultProps = {

View File

@@ -1,15 +1,18 @@
import React from 'react';
import React, { ReactNode } from 'react';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import G from './G';
import { RNSVGForeignObject } from './NativeComponents';
export default class ForeignObject extends G<{
export interface ForeignObjectProps {
children?: ReactNode;
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
}> {
}
export default class ForeignObject extends G<ForeignObjectProps> {
static displayName = 'ForeignObject';
static defaultProps = {

View File

@@ -1,12 +1,22 @@
import React from 'react';
import React, { ReactNode } from 'react';
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
import { extractFont } from '../lib/extract/extractText';
import extractTransform from '../lib/extract/extractTransform';
import { TransformProps } from '../lib/extract/types';
import {
CommonPathProps,
FontProps,
NumberProp,
TransformProps,
} from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGGroup } from './NativeComponents';
export default class G<P> extends Shape<P> {
export interface GProps extends CommonPathProps, FontProps {
children?: ReactNode;
opacity?: NumberProp;
}
export default class G<P> extends Shape<GProps & P> {
static displayName = 'G';
setNativeProps = (

View File

@@ -1,22 +1,37 @@
import React from 'react';
import { Image, ImageSourcePropType } from 'react-native';
import { Image, ImageProps as RNImageProps } from 'react-native';
import { alignEnum, meetOrSliceTypes } from '../lib/extract/extractViewBox';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import {
ClipProps,
CommonMaskProps,
NumberProp,
ResponderProps,
TouchableProps,
} from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGImage } from './NativeComponents';
const spacesRegExp = /\s+/;
export default class SvgImage extends Shape<{
preserveAspectRatio?: string;
export interface ImageProps
extends ResponderProps,
CommonMaskProps,
ClipProps,
TouchableProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
xlinkHref?: string | number | ImageSourcePropType;
href?: string | number | ImageSourcePropType;
}> {
xlinkHref?: RNImageProps['source'];
href?: RNImageProps['source'];
preserveAspectRatio?: string;
opacity?: NumberProp;
clipPath?: string;
id?: string;
}
export default class SvgImage extends Shape<ImageProps> {
static displayName = 'Image';
static defaultProps = {

View File

@@ -1,15 +1,18 @@
import React from 'react';
import { extract } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGLine } from './NativeComponents';
export default class Line extends Shape<{
export interface LineProps extends CommonPathProps {
opacity?: NumberProp;
x1?: NumberProp;
y1?: NumberProp;
x2?: NumberProp;
y1?: NumberProp;
y2?: NumberProp;
}> {
}
export default class Line extends Shape<LineProps> {
static displayName = 'Line';
static defaultProps = {

View File

@@ -1,20 +1,25 @@
import React, { ReactElement } from 'react';
import extractGradient from '../lib/extract/extractGradient';
import { NumberProp, TransformProps } from '../lib/extract/types';
import {
ColumnMajorTransformMatrix,
NumberProp,
Units,
} from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGLinearGradient } from './NativeComponents';
export default class LinearGradient extends Shape<{
id?: string;
x1?: NumberProp;
y1?: NumberProp;
x2?: NumberProp;
y2?: NumberProp;
export interface LinearGradientProps {
children?: ReactElement[];
transform?: number[] | string | TransformProps;
gradientTransform?: number[] | string | TransformProps;
gradientUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
}> {
x1?: NumberProp;
x2?: NumberProp;
y1?: NumberProp;
y2?: NumberProp;
gradientUnits?: Units;
gradientTransform?: ColumnMajorTransformMatrix | string;
id?: string;
}
export default class LinearGradient extends Shape<LinearGradientProps> {
static displayName = 'LinearGradient';
static defaultProps = {

View File

@@ -1,10 +1,21 @@
import React from 'react';
import React, { ReactNode } from 'react';
import extractViewBox from '../lib/extract/extractViewBox';
import { NumberProp } from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGMarker } from './NativeComponents';
export default class Marker extends Shape<{
export enum MarkerUnits {
STROKE_WIDTH = 'strokeWidth',
USER_SPACE_ON_USE = 'userSpaceOnUse',
}
export enum Orient {
AUTO = 'auto',
AUTO_START_REVERSE = 'auto-start-reverse',
}
export interface MarkerProps {
children?: ReactNode;
id?: string;
viewBox?: string;
preserveAspectRatio?: string;
@@ -12,9 +23,11 @@ export default class Marker extends Shape<{
refY?: NumberProp;
markerWidth?: NumberProp;
markerHeight?: NumberProp;
markerUnits?: 'strokeWidth' | 'userSpaceOnUse';
orient?: 'auto' | 'auto-start-reverse' | NumberProp;
}> {
markerUnits?: MarkerUnits;
orient?: Orient | NumberProp;
}
export default class Marker extends Shape<MarkerProps> {
static displayName = 'Marker';
static defaultProps = {

View File

@@ -1,21 +1,37 @@
import React from 'react';
import React, { ReactNode } from 'react';
import extractTransform from '../lib/extract/extractTransform';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp, TransformProps } from '../lib/extract/types';
import {
ColumnMajorTransformMatrix,
CommonPathProps,
NumberProp,
} from '../lib/extract/types';
import units from '../lib/units';
import Shape from './Shape';
import { RNSVGMask } from './NativeComponents';
export default class Mask extends Shape<{
export enum EMaskUnits {
USER_SPACE_ON_USE = 'userSpaceOnUse',
OBJECT_BOUNDING_BOX = 'objectBoundingBox',
}
export type TMaskUnits =
| EMaskUnits.USER_SPACE_ON_USE
| EMaskUnits.OBJECT_BOUNDING_BOX;
export interface MaskProps extends CommonPathProps {
children?: ReactNode;
id?: string;
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
transform?: number[] | string | TransformProps;
maskTransform?: number[] | string | TransformProps;
maskUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
maskContentUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
}> {
maskTransform?: ColumnMajorTransformMatrix | string;
maskUnits?: TMaskUnits;
maskContentUnits?: TMaskUnits;
}
export default class Mask extends Shape<MaskProps> {
static displayName = 'Mask';
static defaultProps = {

View File

@@ -1,4 +1,12 @@
import { requireNativeComponent as rnc } from 'react-native';
import React from 'react';
declare module 'react-native' {
function requireNativeComponent(
viewName: string,
): // eslint-disable-next-line @typescript-eslint/no-explicit-any
React.ComponentType<React.PropsWithChildren<any>>;
}
export const RNSVGSvg = rnc('RNSVGSvgView');
export const RNSVGCircle = rnc('RNSVGCircle');

View File

@@ -2,10 +2,14 @@ import React from 'react';
import { extract } from '../lib/extract/extractProps';
import Shape from './Shape';
import { RNSVGPath } from './NativeComponents';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
export default class Path extends Shape<{
export interface PathProps extends CommonPathProps {
d?: string;
}> {
opacity?: NumberProp;
}
export default class Path extends Shape<PathProps> {
static displayName = 'Path';
render() {

View File

@@ -1,24 +1,32 @@
import React from 'react';
import React, { ReactNode } from 'react';
import extractTransform from '../lib/extract/extractTransform';
import extractViewBox from '../lib/extract/extractViewBox';
import { NumberProp, TransformProps } from '../lib/extract/types';
import {
ColumnMajorTransformMatrix,
NumberProp,
TransformProps,
Units,
} from '../lib/extract/types';
import units from '../lib/units';
import Shape from './Shape';
import { RNSVGPattern } from './NativeComponents';
export default class Pattern extends Shape<{
export interface PatternProps {
children?: ReactNode;
id?: string;
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
patternTransform?: ColumnMajorTransformMatrix | string;
patternUnits?: Units;
patternContentUnits?: Units;
viewBox?: string;
preserveAspectRatio?: string;
transform?: number[] | string | TransformProps;
patternTransform?: number[] | string | TransformProps;
patternUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
patternContentUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
}> {
transform?: ColumnMajorTransformMatrix | string | TransformProps;
}
export default class Pattern extends Shape<PatternProps> {
static displayName = 'Pattern';
static defaultProps = {

View File

@@ -1,10 +1,15 @@
import React from 'react';
import Path from './Path';
import Shape from './Shape';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import extractPolyPoints from '../lib/extract/extractPolyPoints';
export default class Polygon extends Shape<{ points?: number[] }> {
export interface PolygonProps extends CommonPathProps {
opacity?: NumberProp;
points?: string | ReadonlyArray<NumberProp>;
}
export default class Polygon extends Shape<PolygonProps> {
static displayName = 'Polygon';
static defaultProps = {

View File

@@ -1,10 +1,15 @@
import React from 'react';
import Path from './Path';
import Shape from './Shape';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import extractPolyPoints from '../lib/extract/extractPolyPoints';
export default class Polyline extends Shape<{ points?: number[] }> {
export interface PolylineProps extends CommonPathProps {
opacity?: NumberProp;
points?: string | ReadonlyArray<NumberProp>;
}
export default class Polyline extends Shape<PolylineProps> {
static displayName = 'Polyline';
static defaultProps = {

View File

@@ -1,23 +1,28 @@
import React, { ReactElement } from 'react';
import extractGradient from '../lib/extract/extractGradient';
import { NumberProp, TransformProps } from '../lib/extract/types';
import {
ColumnMajorTransformMatrix,
NumberProp,
Units,
} from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGRadialGradient } from './NativeComponents';
export default class RadialGradient extends Shape<{
export interface RadialGradientProps {
children?: ReactElement[];
fx?: NumberProp;
fy?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
r?: NumberProp;
cx?: NumberProp;
cy?: NumberProp;
r?: NumberProp;
gradientUnits?: Units;
gradientTransform?: ColumnMajorTransformMatrix | string;
id?: string;
children?: ReactElement[];
transform?: number[] | string | TransformProps;
gradientTransform?: number[] | string | TransformProps;
gradientUnits?: 'objectBoundingBox' | 'userSpaceOnUse';
}> {
}
export default class RadialGradient extends Shape<RadialGradientProps> {
static displayName = 'RadialGradient';
static defaultProps = {

View File

@@ -1,17 +1,20 @@
import React from 'react';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import Shape from './Shape';
import { RNSVGRect } from './NativeComponents';
export default class Rect extends Shape<{
export interface RectProps extends CommonPathProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
}> {
opacity?: NumberProp;
}
export default class Rect extends Shape<RectProps> {
static displayName = 'Rect';
static defaultProps = {

View File

@@ -1,8 +1,12 @@
import { Component } from 'react';
import { Color, NumberProp } from '../lib/extract/types';
type StopProps = {
export interface StopProps {
stopColor?: Color;
stopOpacity?: NumberProp;
offset?: NumberProp;
parent?: Component;
};
}
export default class Stop extends Component<StopProps, {}> {
props!: StopProps;

View File

@@ -1,29 +1,26 @@
import React, { Component } from 'react';
import {
ColorValue,
findNodeHandle,
MeasureInWindowOnSuccessCallback,
MeasureLayoutOnSuccessCallback,
MeasureOnSuccessCallback,
NativeModules,
processColor,
StyleProp,
StyleSheet,
ViewProps,
ViewStyle,
} from 'react-native';
import {
ClipProps,
Color,
extractedProps,
FillProps,
NumberProp,
ResponderInstanceProps,
ResponderProps,
StrokeProps,
TransformProps,
} from '../lib/extract/types';
import extractResponder from '../lib/extract/extractResponder';
import extractViewBox from '../lib/extract/extractViewBox';
import Shape from './Shape';
import G from './G';
import G, { GProps } from './G';
import { RNSVGSvg } from './NativeComponents';
const RNSVGSvgViewManager = NativeModules.RNSVGSvgViewManager;
@@ -36,20 +33,16 @@ const styles = StyleSheet.create({
});
const defaultStyle = styles.svg;
export default class Svg extends Shape<
{
color?: ColorValue;
viewBox?: string;
opacity?: NumberProp;
onLayout?: () => void;
preserveAspectRatio?: string;
style?: ViewStyle[] | ViewStyle;
} & TransformProps &
ResponderProps &
StrokeProps &
FillProps &
ClipProps
> {
export interface SvgProps extends GProps, ViewProps {
width?: NumberProp;
height?: NumberProp;
viewBox?: string;
preserveAspectRatio?: string;
color?: Color;
title?: string;
}
export default class Svg extends Shape<SvgProps> {
static displayName = 'Svg';
static defaultProps = {
@@ -94,7 +87,7 @@ export default class Svg extends Shape<
root && root.setNativeProps(props);
};
toDataURL = (callback: () => void, options?: Object) => {
toDataURL = (callback: (base64: string) => void, options?: Object) => {
if (!callback) {
return;
}
@@ -143,7 +136,7 @@ export default class Svg extends Shape<
const props: extractedProps = extracted as extractedProps;
props.focusable = Boolean(focusable) && focusable !== 'false';
const rootStyles: (ViewStyle | ViewStyle[])[] = [defaultStyle];
const rootStyles: StyleProp<ViewStyle>[] = [defaultStyle];
if (style) {
rootStyles.push(style);

View File

@@ -1,13 +1,18 @@
import React from 'react';
import React, { ReactNode } from 'react';
import extractViewBox from '../lib/extract/extractViewBox';
import Shape from './Shape';
import { RNSVGSymbol } from './NativeComponents';
import { NumberProp } from '../lib/extract/types';
export default class Symbol extends Shape<{
export interface SymbolProps {
children?: ReactNode;
id?: string;
viewBox?: string;
preserveAspectRatio?: string;
}> {
opacity?: NumberProp;
}
export default class Symbol extends Shape<SymbolProps> {
static displayName = 'Symbol';
render() {

View File

@@ -1,13 +1,29 @@
import React, { Component } from 'react';
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
import extractTransform from '../lib/extract/extractTransform';
import extractText, { setTSpan } from '../lib/extract/extractText';
import extractText, { setTSpan, TextChild } from '../lib/extract/extractText';
import { pickNotNil } from '../lib/util';
import Shape from './Shape';
import { TransformProps } from '../lib/extract/types';
import {
CommonPathProps,
FontProps,
NumberArray,
NumberProp,
TransformProps,
} from '../lib/extract/types';
import { RNSVGTSpan } from './NativeComponents';
export default class TSpan extends Shape<{}> {
export interface TSpanProps extends CommonPathProps, FontProps {
children?: TextChild;
x?: NumberArray;
y?: NumberArray;
dx?: NumberArray;
dy?: NumberArray;
rotate?: NumberArray;
inlineSize?: NumberProp;
}
export default class TSpan extends Shape<TSpanProps> {
static displayName = 'TSpan';
setNativeProps = (

View File

@@ -1,14 +1,30 @@
import React, { Component } from 'react';
import React, { Component, ReactNode } from 'react';
import extractText from '../lib/extract/extractText';
import extractProps, { propsAndStyles } from '../lib/extract/extractProps';
import extractTransform from '../lib/extract/extractTransform';
import { TransformProps } from '../lib/extract/types';
import {
NumberArray,
NumberProp,
TextSpecificProps,
TransformProps,
} from '../lib/extract/types';
import { pickNotNil } from '../lib/util';
import Shape from './Shape';
import './TSpan';
import { RNSVGText } from './NativeComponents';
export default class Text extends Shape<{}> {
export interface TextProps extends TextSpecificProps {
children?: ReactNode;
x?: NumberArray;
y?: NumberArray;
dx?: NumberArray;
dy?: NumberArray;
rotate?: NumberArray;
opacity?: NumberProp;
inlineSize?: NumberProp;
}
export default class Text extends Shape<TextProps> {
static displayName = 'Text';
setNativeProps = (

View File

@@ -1,24 +1,32 @@
import React, { Component } from 'react';
import extractTransform from '../lib/extract/extractTransform';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp, TransformProps } from '../lib/extract/types';
import extractText from '../lib/extract/extractText';
import {
NumberProp,
TextPathMethod,
TextPathMidLine,
TextPathSpacing,
TextSpecificProps,
TransformProps,
} from '../lib/extract/types';
import extractText, { TextChild } from '../lib/extract/extractText';
import { idPattern, pickNotNil } from '../lib/util';
import Shape from './Shape';
import TSpan from './TSpan';
import { RNSVGTextPath } from './NativeComponents';
export default class TextPath extends Shape<{
children?: NumberProp | [NumberProp | React.ComponentType];
alignmentBaseline?: string;
startOffset?: NumberProp;
export interface TextPathProps extends TextSpecificProps {
children?: TextChild;
xlinkHref?: string;
midLine?: string;
spacing?: string;
method?: string;
href?: string;
startOffset?: NumberProp;
method?: TextPathMethod;
spacing?: TextPathSpacing;
midLine?: TextPathMidLine;
side?: string;
}> {
}
export default class TextPath extends Shape<TextPathProps> {
static displayName = 'TextPath';
setNativeProps = (

View File

@@ -1,18 +1,22 @@
import React from 'react';
import React, { ReactNode } from 'react';
import { withoutXY } from '../lib/extract/extractProps';
import { NumberProp } from '../lib/extract/types';
import { CommonPathProps, NumberProp } from '../lib/extract/types';
import { idPattern } from '../lib/util';
import Shape from './Shape';
import { RNSVGUse } from './NativeComponents';
export default class Use extends Shape<{
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
export interface UseProps extends CommonPathProps {
children?: ReactNode;
xlinkHref?: string;
href?: string;
}> {
width?: NumberProp;
height?: NumberProp;
x?: NumberProp;
y?: NumberProp;
opacity?: NumberProp;
}
export default class Use extends Shape<UseProps> {
static displayName = 'Use';
static defaultProps = {

557
src/index.d.ts vendored
View File

@@ -1,557 +0,0 @@
import * as React from 'react';
import * as ReactNative from 'react-native';
import {
ColorValue,
GestureResponderEvent,
TransformsStyle,
} from 'react-native';
// Common props
export type NumberProp = string | number;
export type NumberArray = NumberProp[] | NumberProp;
export type FillRule = 'evenodd' | 'nonzero';
export type Units = 'userSpaceOnUse' | 'objectBoundingBox';
export type MarkerUnits = 'strokeWidth' | 'userSpaceOnUse';
export type Orient = 'auto' | 'auto-start-reverse';
export type TextAnchor = 'start' | 'middle' | 'end';
export type FontStyle = 'normal' | 'italic' | 'oblique';
export type FontVariant = 'normal' | 'small-caps';
export type FontWeight =
| NumberProp
| 'normal'
| 'bold'
| 'bolder'
| 'lighter'
| '100'
| '200'
| '300'
| '400'
| '500'
| '600'
| '700'
| '800'
| '900';
export type FontStretch =
| 'normal'
| 'wider'
| 'narrower'
| 'ultra-condensed'
| 'extra-condensed'
| 'condensed'
| 'semi-condensed'
| 'semi-expanded'
| 'expanded'
| 'extra-expanded'
| 'ultra-expanded';
export type TextDecoration =
| 'none'
| 'underline'
| 'overline'
| 'line-through'
| 'blink';
export type FontVariantLigatures = 'normal' | 'none';
export type AlignmentBaseline =
| 'baseline'
| 'text-bottom'
| 'alphabetic'
| 'ideographic'
| 'middle'
| 'central'
| 'mathematical'
| 'text-top'
| 'bottom'
| 'center'
| 'top'
| 'text-before-edge'
| 'text-after-edge'
| 'before-edge'
| 'after-edge'
| 'hanging';
export type BaselineShift =
| 'sub'
| 'super'
| 'baseline'
| ReadonlyArray<NumberProp>
| NumberProp;
export type LengthAdjust = 'spacing' | 'spacingAndGlyphs';
export type TextPathMethod = 'align' | 'stretch';
export type TextPathSpacing = 'auto' | 'exact';
export type TextPathMidLine = 'sharp' | 'smooth';
export type Linecap = 'butt' | 'square' | 'round';
export type Linejoin = 'miter' | 'bevel' | 'round';
export interface TouchableProps {
disabled?: boolean;
onPress?: (event: GestureResponderEvent) => void;
onPressIn?: (event: GestureResponderEvent) => void;
onPressOut?: (event: GestureResponderEvent) => void;
onLongPress?: (event: GestureResponderEvent) => void;
delayPressIn?: number;
delayPressOut?: number;
delayLongPress?: number;
}
export interface ResponderProps extends ReactNative.GestureResponderHandlers {
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto';
}
export type Color = ColorValue;
export interface FillProps {
fill?: Color;
fillOpacity?: NumberProp;
fillRule?: FillRule;
}
export interface ClipProps {
clipRule?: FillRule;
clipPath?: string;
}
export interface VectorEffectProps {
vectorEffect?:
| 'none'
| 'non-scaling-stroke'
| 'nonScalingStroke'
| 'default'
| 'inherit'
| 'uri';
}
export interface DefinitionProps {
id?: string;
}
export interface StrokeProps {
stroke?: Color;
strokeWidth?: NumberProp;
strokeOpacity?: NumberProp;
strokeDasharray?: ReadonlyArray<NumberProp> | NumberProp;
strokeDashoffset?: NumberProp;
strokeLinecap?: Linecap;
strokeLinejoin?: Linejoin;
strokeMiterlimit?: NumberProp;
}
export interface FontObject {
fontStyle?: FontStyle;
fontVariant?: FontVariant;
fontWeight?: FontWeight;
fontStretch?: FontStretch;
fontSize?: NumberProp;
fontFamily?: string;
textAnchor?: TextAnchor;
textDecoration?: TextDecoration;
letterSpacing?: NumberProp;
wordSpacing?: NumberProp;
kerning?: NumberProp;
fontFeatureSettings?: string;
fontVariantLigatures?: FontVariantLigatures;
fontVariationSettings?: string;
}
export interface FontProps extends FontObject {
font?: FontObject;
}
export interface TransformObject {
translate?: NumberArray;
translateX?: NumberProp;
translateY?: NumberProp;
origin?: NumberArray;
originX?: NumberProp;
originY?: NumberProp;
scale?: NumberArray;
scaleX?: NumberProp;
scaleY?: NumberProp;
skew?: NumberArray;
skewX?: NumberProp;
skewY?: NumberProp;
rotation?: NumberProp;
x?: NumberArray;
y?: NumberArray;
}
/*
ColumnMajorTransformMatrix
[a, b, c, d, tx, ty]
This matrix can be visualized as:
╔═ ═╗
║ a c tx ║
║ b d ty ║
║ 0 0 1 ║
╚═ ═╝
*/
export type ColumnMajorTransformMatrix = [
number,
number,
number,
number,
number,
number,
];
export interface TransformProps extends TransformObject {
transform?:
| ColumnMajorTransformMatrix
| string
| TransformObject
| TransformsStyle['transform'];
}
export interface CommonMaskProps {
mask?: string;
}
export interface CommonMarkerProps {
marker?: string;
markerStart?: string;
markerMid?: string;
markerEnd?: string;
}
export interface CommonPathProps
extends FillProps,
StrokeProps,
ClipProps,
TransformProps,
VectorEffectProps,
ResponderProps,
TouchableProps,
DefinitionProps,
CommonMarkerProps,
CommonMaskProps {}
// Element props
export interface CircleProps extends CommonPathProps {
cx?: NumberProp;
cy?: NumberProp;
opacity?: NumberProp;
r?: NumberProp;
}
export const Circle: React.ComponentClass<CircleProps>;
export type Circle = React.ComponentClass<CircleProps>;
export interface ClipPathProps {
id?: string;
}
export const ClipPath: React.ComponentClass<ClipPathProps>;
export type ClipPath = React.ComponentClass<ClipPathProps>;
export const Defs: React.ComponentClass<{}>;
export type Defs = React.ComponentClass<{}>;
export interface EllipseProps extends CommonPathProps {
cx?: NumberProp;
cy?: NumberProp;
opacity?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
}
export const Ellipse: React.ComponentClass<EllipseProps>;
export type Ellipse = React.ComponentClass<EllipseProps>;
export interface GProps extends CommonPathProps, FontProps {
opacity?: NumberProp;
}
export const G: React.ComponentClass<GProps>;
export type G = React.ComponentClass<GProps>;
export interface ForeignObjectProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
}
export const ForeignObject: React.ComponentClass<ForeignObjectProps>;
export type ForeignObject = React.ComponentClass<ForeignObjectProps>;
export interface ImageProps
extends ResponderProps,
CommonMaskProps,
ClipProps,
TouchableProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
xlinkHref?: ReactNative.ImageProps['source'];
href?: ReactNative.ImageProps['source'];
preserveAspectRatio?: string;
opacity?: NumberProp;
clipPath?: string;
id?: string;
}
export const Image: React.ComponentClass<ImageProps>;
export type Image = React.ComponentClass<ImageProps>;
export interface LineProps extends CommonPathProps {
opacity?: NumberProp;
x1?: NumberProp;
x2?: NumberProp;
y1?: NumberProp;
y2?: NumberProp;
}
export const Line: React.ComponentClass<LineProps>;
export type Line = React.ComponentClass<LineProps>;
export interface LinearGradientProps {
x1?: NumberProp;
x2?: NumberProp;
y1?: NumberProp;
y2?: NumberProp;
gradientUnits?: Units;
gradientTransform?: ColumnMajorTransformMatrix | string;
id?: string;
}
export const LinearGradient: React.ComponentClass<LinearGradientProps>;
export type LinearGradient = React.ComponentClass<LinearGradientProps>;
export interface PathProps extends CommonPathProps {
d?: string;
opacity?: NumberProp;
}
export const Path: React.ComponentClass<PathProps>;
export type Path = React.ComponentClass<PathProps>;
export interface PatternProps {
id?: string;
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
patternTransform?: ColumnMajorTransformMatrix | string;
patternUnits?: Units;
patternContentUnits?: Units;
viewBox?: string;
preserveAspectRatio?: string;
}
export const Pattern: React.ComponentClass<PatternProps>;
export type Pattern = React.ComponentClass<PatternProps>;
export interface PolygonProps extends CommonPathProps {
opacity?: NumberProp;
points?: string | ReadonlyArray<NumberProp>;
}
export const Polygon: React.ComponentClass<PolygonProps>;
export type Polygon = React.ComponentClass<PolygonProps>;
export interface PolylineProps extends CommonPathProps {
opacity?: NumberProp;
points?: string | ReadonlyArray<NumberProp>;
}
export const Polyline: React.ComponentClass<PolylineProps>;
export type Polyline = React.ComponentClass<PolylineProps>;
export interface RadialGradientProps {
fx?: NumberProp;
fy?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
cx?: NumberProp;
cy?: NumberProp;
r?: NumberProp;
gradientUnits?: Units;
gradientTransform?: ColumnMajorTransformMatrix | string;
id?: string;
}
export const RadialGradient: React.ComponentClass<RadialGradientProps>;
export type RadialGradient = React.ComponentClass<RadialGradientProps>;
export interface RectProps extends CommonPathProps {
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
rx?: NumberProp;
ry?: NumberProp;
opacity?: NumberProp;
}
export const Rect: React.ComponentClass<RectProps>;
export type Rect = React.ComponentClass<RectProps>;
export interface StopProps {
stopColor?: Color;
stopOpacity?: NumberProp;
offset?: NumberProp;
}
export const Stop: React.ComponentClass<StopProps>;
export type Stop = React.ComponentClass<StopProps>;
export interface SvgProps extends GProps, ReactNative.ViewProperties {
width?: NumberProp;
height?: NumberProp;
viewBox?: string;
preserveAspectRatio?: string;
color?: Color;
title?: string;
}
// Svg is both regular and default exported
export const Svg: React.ComponentClass<SvgProps>;
export type Svg = React.ComponentClass<SvgProps>;
export default Svg;
export interface SymbolProps {
id?: string;
viewBox?: string;
preserveAspectRatio?: string;
opacity?: NumberProp;
}
export const Symbol: React.ComponentClass<SymbolProps>;
export type Symbol = React.ComponentClass<SymbolProps>;
export interface TSpanProps extends CommonPathProps, FontProps {
x?: NumberArray;
y?: NumberArray;
dx?: NumberArray;
dy?: NumberArray;
rotate?: NumberArray;
inlineSize?: NumberProp;
}
export const TSpan: React.ComponentClass<TSpanProps>;
export type TSpan = React.ComponentClass<TSpanProps>;
export interface TextSpecificProps extends CommonPathProps, FontProps {
alignmentBaseline?: AlignmentBaseline;
baselineShift?: BaselineShift;
verticalAlign?: NumberProp;
lengthAdjust?: LengthAdjust;
textLength?: NumberProp;
fontData?: null | { [name: string]: unknown };
fontFeatureSettings?: string;
}
export interface TextProps extends TextSpecificProps {
x?: NumberArray;
y?: NumberArray;
dx?: NumberArray;
dy?: NumberArray;
rotate?: NumberArray;
opacity?: NumberProp;
inlineSize?: NumberProp;
}
export const Text: React.ComponentClass<TextProps>;
export type Text = React.ComponentClass<TextProps>;
export interface TextPathProps extends TextSpecificProps {
xlinkHref?: string;
href?: string;
startOffset?: NumberProp;
method?: TextPathMethod;
spacing?: TextPathSpacing;
midLine?: TextPathMidLine;
}
export const TextPath: React.ComponentClass<TextPathProps>;
export type TextPath = React.ComponentClass<TextPathProps>;
export interface UseProps extends CommonPathProps {
xlinkHref?: string;
href?: string;
width?: NumberProp;
height?: NumberProp;
x?: NumberProp;
y?: NumberProp;
opacity?: NumberProp;
}
export const Use: React.ComponentClass<UseProps>;
export type Use = React.ComponentClass<UseProps>;
export interface MaskProps extends CommonPathProps {
id?: string;
x?: NumberProp;
y?: NumberProp;
width?: NumberProp;
height?: NumberProp;
maskTransform?: ColumnMajorTransformMatrix | string;
maskUnits?: Units;
maskContentUnits?: Units;
}
export const Mask: React.ComponentClass<MaskProps>;
export type Mask = React.ComponentClass<MaskProps>;
export interface MarkerProps {
id?: string;
viewBox?: string;
preserveAspectRatio?: string;
refX?: NumberProp;
refY?: NumberProp;
markerWidth?: NumberProp;
markerHeight?: NumberProp;
markerUnits?: MarkerUnits;
orient?: Orient | NumberProp;
}
export const Marker: React.ComponentClass<MarkerProps>;
export type Marker = React.ComponentClass<MarkerProps>;
export type Styles = { [property: string]: string };
export interface AST {
tag: string;
style?: Styles;
styles?: string;
priority?: Map<string, boolean | undefined>;
parent: AST | null;
children: (AST | string)[] | (JSX.Element | string)[];
props: {
[prop: string]: Styles | string | undefined;
};
Tag: React.ComponentType;
}
export interface XmlAST extends AST {
children: (XmlAST | string)[];
parent: XmlAST | null;
}
export interface JsxAST extends AST {
children: (JSX.Element | string)[];
}
export interface UriProps extends SvgProps {
uri: string | null;
onError?: (error: Error) => void;
override?: SvgProps;
}
export type UriState = { xml: string | null };
export interface XmlProps extends SvgProps {
xml: string | null;
onError?: (error: Error) => void;
override?: SvgProps;
}
export type XmlState = { ast: JsxAST | null };
export interface AstProps extends SvgProps {
ast: JsxAST | null;
override?: SvgProps;
}
export type Middleware = (ast: XmlAST) => XmlAST;
export function parse(source: string, middleware?: Middleware): JsxAST | null;
export const SvgAst: React.FunctionComponent<AstProps>;
export const SvgXml: React.FunctionComponent<XmlProps>;
export const SvgFromXml: React.ComponentClass<XmlProps, XmlState>;
export const SvgUri: React.FunctionComponent<UriProps>;
export const SvgFromUri: React.ComponentClass<UriProps, UriState>;
export const SvgCss: React.FunctionComponent<XmlProps>;
export const SvgWithCss: React.ComponentClass<XmlProps, XmlState>;
export const SvgCssUri: React.FunctionComponent<UriProps>;
export const SvgWithCssUri: React.ComponentClass<UriProps, UriState>;
export const inlineStyles: Middleware;

View File

@@ -4,10 +4,10 @@ const spaceReg = /\s+/;
const commaReg = /,/g;
export default function extractLengthList(
lengthList?: NumberProp[] | NumberProp,
): NumberProp[] {
lengthList?: readonly NumberProp[] | NumberProp,
): readonly NumberProp[] {
if (Array.isArray(lengthList)) {
return lengthList;
return lengthList as NumberProp[];
} else if (typeof lengthList === 'number') {
return [lengthList];
} else if (typeof lengthList === 'string') {

View File

@@ -1,8 +1,10 @@
import { NumberProp } from './types';
export default function extractPolyPoints(points: string | NumberProp[]) {
export default function extractPolyPoints(
points: string | readonly NumberProp[],
) {
const polyPoints = Array.isArray(points) ? points.join(',') : points;
return polyPoints
return (polyPoints as string)
.replace(/[^eE]-/, ' -')
.split(/(?:\s+|\s*,\s*)/g)
.join(' ');

View File

@@ -112,13 +112,17 @@ export function extractFont(props: fontProps) {
return { ...baseFont, ...ownedFont };
}
let TSpan: ComponentType;
let TSpan: ComponentType<React.PropsWithChildren<{}>>;
export function setTSpan(TSpanImplementation: ComponentType) {
TSpan = TSpanImplementation;
}
function getChild(child: undefined | string | number | ComponentType) {
export type TextChild =
| (undefined | string | number | ComponentType | React.ReactElement)
| TextChild[];
function getChild(child: TextChild) {
if (typeof child === 'string' || typeof child === 'number') {
return <TSpan>{String(child)}</TSpan>;
} else {
@@ -132,7 +136,7 @@ export type TextProps = {
dx?: NumberArray;
dy?: NumberArray;
rotate?: NumberArray;
children?: string | number | (string | number | ComponentType)[];
children?: TextChild;
inlineSize?: NumberProp;
baselineShift?: NumberProp;
verticalAlign?: NumberProp;

View File

@@ -1,11 +1,140 @@
import { Component } from 'react';
import { ColorValue, GestureResponderEvent } from 'react-native';
import {
ColorValue,
GestureResponderEvent,
GestureResponderHandlers,
LayoutChangeEvent,
} from 'react-native';
import React from 'react';
export type NumberProp = string | number;
export type NumberArray = NumberProp[] | NumberProp;
export type FillRule = 'evenodd' | 'nonzero';
export type Units = 'userSpaceOnUse' | 'objectBoundingBox';
export type TextAnchor = 'start' | 'middle' | 'end';
export type FontStyle = 'normal' | 'italic' | 'oblique';
export type FontVariant = 'normal' | 'small-caps';
export type FontWeight =
| NumberProp
| 'normal'
| 'bold'
| 'bolder'
| 'lighter'
| '100'
| '200'
| '300'
| '400'
| '500'
| '600'
| '700'
| '800'
| '900';
export type FontStretch =
| 'normal'
| 'wider'
| 'narrower'
| 'ultra-condensed'
| 'extra-condensed'
| 'condensed'
| 'semi-condensed'
| 'semi-expanded'
| 'expanded'
| 'extra-expanded'
| 'ultra-expanded';
export type TextDecoration =
| 'none'
| 'underline'
| 'overline'
| 'line-through'
| 'blink';
export type FontVariantLigatures = 'normal' | 'none';
export type AlignmentBaseline =
| 'baseline'
| 'text-bottom'
| 'alphabetic'
| 'ideographic'
| 'middle'
| 'central'
| 'mathematical'
| 'text-top'
| 'bottom'
| 'center'
| 'top'
| 'text-before-edge'
| 'text-after-edge'
| 'before-edge'
| 'after-edge'
| 'hanging';
export type BaselineShift =
| 'sub'
| 'super'
| 'baseline'
| ReadonlyArray<NumberProp>
| NumberProp;
export type LengthAdjust = 'spacing' | 'spacingAndGlyphs';
export type TextPathMethod = 'align' | 'stretch';
export type TextPathSpacing = 'auto' | 'exact';
export type TextPathMidLine = 'sharp' | 'smooth';
export type Linecap = 'butt' | 'square' | 'round';
export type Linejoin = 'miter' | 'bevel' | 'round';
export interface TouchableProps {
disabled?: boolean;
onPress?: (event: GestureResponderEvent) => void;
onPressIn?: (event: GestureResponderEvent) => void;
onPressOut?: (event: GestureResponderEvent) => void;
onLongPress?: (event: GestureResponderEvent) => void;
delayPressIn?: number;
delayPressOut?: number;
delayLongPress?: number;
}
export interface ResponderProps extends GestureResponderHandlers {
pointerEvents?: 'box-none' | 'none' | 'box-only' | 'auto';
}
export type Color = ColorValue;
export interface FillProps {
fill?: Color;
fillOpacity?: NumberProp;
fillRule?: FillRule;
}
export interface ClipProps {
clipRule?: FillRule;
clipPath?: string;
}
export interface VectorEffectProps {
vectorEffect?:
| 'none'
| 'non-scaling-stroke'
| 'nonScalingStroke'
| 'default'
| 'inherit'
| 'uri';
}
export interface DefinitionProps {
id?: string;
}
export interface StrokeProps {
stroke?: Color;
strokeWidth?: NumberProp;
strokeOpacity?: NumberProp;
strokeDasharray?: ReadonlyArray<NumberProp> | NumberProp;
strokeDashoffset?: NumberProp;
strokeLinecap?: Linecap;
strokeLinejoin?: Linejoin;
strokeMiterlimit?: NumberProp;
vectorEffect?: VectorEffect;
}
export type VectorEffect =
| 'none'
| 'non-scaling-stroke'
@@ -14,7 +143,28 @@ export type VectorEffect =
| 'inherit'
| 'uri';
export interface TransformProps {
export interface FontObject {
fontStyle?: FontStyle;
fontVariant?: FontVariant;
fontWeight?: FontWeight;
fontStretch?: FontStretch;
fontSize?: NumberProp;
fontFamily?: string;
textAnchor?: TextAnchor;
textDecoration?: TextDecoration;
letterSpacing?: NumberProp;
wordSpacing?: NumberProp;
kerning?: NumberProp;
fontFeatureSettings?: string;
fontVariantLigatures?: FontVariantLigatures;
fontVariationSettings?: string;
}
export interface FontProps extends FontObject {
font?: FontObject;
}
export interface TransformObject {
translate?: NumberArray;
translateX?: NumberProp;
translateY?: NumberProp;
@@ -30,7 +180,35 @@ export interface TransformProps {
rotation?: NumberProp;
x?: NumberArray;
y?: NumberArray;
transform?: number[] | string | TransformProps | void | undefined;
}
/*
ColumnMajorTransformMatrix
[a, b, c, d, tx, ty]
This matrix can be visualized as:
╔═ ═╗
║ a c tx ║
║ b d ty ║
║ 0 0 1 ║
╚═ ═╝
*/
export type ColumnMajorTransformMatrix = [
number,
number,
number,
number,
number,
number,
];
export interface TransformProps extends TransformObject {
transform?: ColumnMajorTransformMatrix | string | TransformObject;
// | TransformsStyle['transform']; // not used since it causes type problems
}
export interface TransformedProps {
@@ -45,17 +223,29 @@ export interface TransformedProps {
y: number;
}
export type ResponderProps = {
onPress?: () => void;
disabled?: boolean;
onPressIn?: () => void;
onPressOut?: () => void;
onLongPress?: () => void;
delayPressIn?: number;
delayPressOut?: number;
delayLongPress?: number;
pointerEvents?: string;
};
export interface CommonMaskProps {
mask?: string;
}
export interface CommonMarkerProps {
marker?: string;
markerStart?: string;
markerMid?: string;
markerEnd?: string;
}
export interface CommonPathProps
extends FillProps,
StrokeProps,
ClipProps,
TransformProps,
VectorEffectProps,
ResponderProps,
TouchableProps,
DefinitionProps,
CommonMarkerProps,
CommonMaskProps {}
export type ResponderInstanceProps = {
touchableHandleResponderMove?: (e: GestureResponderEvent) => void;
touchableHandleResponderGrant?: (e: GestureResponderEvent) => void;
@@ -68,34 +258,15 @@ export type ResponderInstanceProps = {
e: GestureResponderEvent,
) => boolean;
};
export type FillProps = {
fill?: ColorValue;
fillRule?: 'evenodd' | 'nonzero';
fillOpacity?: NumberProp;
};
export type StrokeProps = {
stroke?: ColorValue;
strokeWidth?: NumberProp;
strokeOpacity?: NumberProp;
strokeDasharray?: NumberArray;
strokeDashoffset?: NumberProp;
strokeLinecap?: Linecap;
strokeLinejoin?: Linejoin;
strokeMiterlimit?: NumberProp;
vectorEffect?: VectorEffect;
};
export type ClipProps = {
clipPath?: string;
clipRule?: 'evenodd' | 'nonzero';
};
export type extractedProps = {
name?: string;
mask?: string;
opacity?: number;
matrix?: number[];
propList?: string[];
onLayout?: () => void;
ref?: (instance: Component | null) => void;
onLayout?: (event: LayoutChangeEvent) => void;
ref?: (instance: React.Component | null) => void;
markerStart?: string;
markerMid?: string;
markerEnd?: string;
@@ -104,3 +275,13 @@ export type extractedProps = {
display?: string;
[touchableProperty: string]: unknown;
};
export interface TextSpecificProps extends CommonPathProps, FontProps {
alignmentBaseline?: AlignmentBaseline;
baselineShift?: BaselineShift;
verticalAlign?: NumberProp;
lengthAdjust?: LengthAdjust;
textLength?: NumberProp;
fontData?: null | { [name: string]: unknown };
fontFeatureSettings?: string;
}

View File

@@ -69,7 +69,7 @@ export interface AST {
props: {
[prop: string]: Styles | string | undefined;
};
Tag: ComponentType;
Tag: ComponentType<React.PropsWithChildren<{}>>;
}
export interface XmlAST extends AST {

View File

@@ -19,8 +19,5 @@
"allowSyntheticDefaultImports": true,
"types": ["react", "react-native"]
},
"files": [
"src/index.d.ts"
],
"include": ["src/index.ts"]
"include": ["src/**/*"]
}

5795
yarn.lock

File diff suppressed because it is too large Load Diff