Skip to content

Commit

Permalink
fix(typescript): fix react-native support #465 (#488)
Browse files Browse the repository at this point in the history
Co-authored-by: Johannes Kann <johannes.kann@syre.com>
  • Loading branch information
Ztarbox and Johannes Kann committed Nov 15, 2020
1 parent 0eb8085 commit d61e0cf
Show file tree
Hide file tree
Showing 5 changed files with 180 additions and 15 deletions.
Expand Up @@ -76,6 +76,17 @@ export default \\"logo.svg\\";
export { SvgComponent as Component };"
`;
exports[`plugin javascript with "native" and "expandProps" option adds import from "react-native-svg" and adds props 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent(props) {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin javascript with "native" option adds import from "react-native-svg" 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
Expand All @@ -87,6 +98,30 @@ function SvgComponent() {
export default SvgComponent;"
`;
exports[`plugin javascript with "native", "ref" and "expandProps" option adds import from "react-native-svg" and adds props and adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent(props, svgRef) {
return <Svg><g /></Svg>;
}
const ForwardRef = React.forwardRef(SvgComponent);
export default ForwardRef;"
`;
exports[`plugin javascript with "native", "ref" option adds import from "react-native-svg" and adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent(props, svgRef) {
return <Svg><g /></Svg>;
}
const ForwardRef = React.forwardRef(SvgComponent);
export default ForwardRef;"
`;
exports[`plugin javascript with "native.expo" option adds import from "react-native-svg" & from "expo" 1`] = `
"import * as React from \\"react\\";
import \\"expo\\";
Expand Down Expand Up @@ -219,6 +254,17 @@ export default \\"logo.svg\\";
export { SvgComponent as Component };"
`;
exports[`plugin typescript with "native" and "expandProps" option adds import from "react-native-svg" and adds props 1`] = `
"import * as React from \\"react\\";
import Svg, { SvgProps } from \\"react-native-svg\\";
function SvgComponent(props: SvgProps) {
return <Svg><g /></Svg>;
}
export default SvgComponent;"
`;
exports[`plugin typescript with "native" option adds import from "react-native-svg" 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
Expand All @@ -230,6 +276,30 @@ function SvgComponent() {
export default SvgComponent;"
`;
exports[`plugin typescript with "native", "ref" and "expandProps" option adds import from "react-native-svg" and adds props and adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
import Svg, { SvgProps } from \\"react-native-svg\\";
function SvgComponent(props: SvgProps, svgRef?: React.Ref<React.Component<SvgProps>>) {
return <Svg><g /></Svg>;
}
const ForwardRef = React.forwardRef(SvgComponent);
export default ForwardRef;"
`;
exports[`plugin typescript with "native", "ref" option adds import from "react-native-svg" and adds ForwardRef component 1`] = `
"import * as React from \\"react\\";
import Svg from \\"react-native-svg\\";
function SvgComponent(props: {}, svgRef?: React.Ref<React.Component<SvgProps>>) {
return <Svg><g /></Svg>;
}
const ForwardRef = React.forwardRef(SvgComponent);
export default ForwardRef;"
`;
exports[`plugin typescript with "native.expo" option adds import from "react-native-svg" & from "expo" 1`] = `
"import * as React from \\"react\\";
import \\"expo\\";
Expand Down
34 changes: 34 additions & 0 deletions packages/babel-plugin-transform-svg-component/src/index.test.js
Expand Up @@ -94,6 +94,40 @@ describe('plugin', () => {
})
})

describe('with "native", "ref" option', () => {
it('adds import from "react-native-svg" and adds ForwardRef component', () => {
const { code } = testPlugin(language)('<Svg><g /></Svg>', {
state: { componentName: 'SvgComponent' },
native: true,
ref: true,
})
expect(code).toMatchSnapshot()
})
})

describe('with "native" and "expandProps" option', () => {
it('adds import from "react-native-svg" and adds props', () => {
const { code } = testPlugin(language)('<Svg><g /></Svg>', {
state: { componentName: 'SvgComponent' },
native: true,
expandProps: true,
})
expect(code).toMatchSnapshot()
})
})

describe('with "native", "ref" and "expandProps" option', () => {
it('adds import from "react-native-svg" and adds props and adds ForwardRef component', () => {
const { code } = testPlugin(language)('<Svg><g /></Svg>', {
state: { componentName: 'SvgComponent' },
native: true,
expandProps: true,
ref: true,
})
expect(code).toMatchSnapshot()
})
})

describe('with "memo" option', () => {
it('wrap component in "React.memo"', () => {
const { code } = testPlugin(language)('<svg><g /></svg>', {
Expand Down
21 changes: 16 additions & 5 deletions packages/babel-plugin-transform-svg-component/src/util.js
Expand Up @@ -62,7 +62,10 @@ function addTypeAnotation(obj, typeAnnotation, opts) {
return { ...obj, typeAnnotation }
}

function getSvgPropsTypeAnnotation(t) {
function getSvgPropsTypeAnnotation(t, opts) {
if (opts.native) {
return t.genericTypeAnnotation(t.identifier('SvgProps'))
}
return genericTypeAnnotation(
qualifiedTypeIdentifier(t.identifier('React'), t.identifier('SVGProps')),
typeParameters([genericTypeAnnotation(t.identifier('SVGSVGElement'))]),
Expand Down Expand Up @@ -104,13 +107,13 @@ export const getProps = ({ types: t }, opts) => {

if (opts.expandProps) {
propsTypeAnnotation = intersectionTypeAnnotation([
getSvgPropsTypeAnnotation(t),
getSvgPropsTypeAnnotation(t, opts),
propsTypeAnnotation,
])
}
} else {
propsTypeAnnotation = opts.expandProps
? getSvgPropsTypeAnnotation(t)
? getSvgPropsTypeAnnotation(t, opts)
: t.objectPattern([])
}

Expand All @@ -132,7 +135,11 @@ export const getProps = ({ types: t }, opts) => {
genericTypeAnnotation(
qualifiedTypeIdentifier(t.identifier('React'), t.identifier('Ref')),
typeParameters([
genericTypeAnnotation(t.identifier('SVGSVGElement')),
opts.native
? genericTypeAnnotation(
qualifiedTypeIdentifier(t.identifier('React'), t.identifier('Component')),
typeParameters([genericTypeAnnotation(t.identifier('SvgProps'))]))
: genericTypeAnnotation(t.identifier('SVGSVGElement')),
]),
),
),
Expand Down Expand Up @@ -175,9 +182,13 @@ export const getImport = ({ types: t }, opts) => {
if (opts.native.expo) {
importDeclarations.push(t.importDeclaration([], t.stringLiteral('expo')))
} else {
const imports = [t.importDefaultSpecifier(t.identifier('Svg'))];
if (opts.typescript && opts.expandProps) {
imports.push(t.importSpecifier(t.identifier('SvgProps'), t.identifier('SvgProps')));
}
importDeclarations.push(
t.importDeclaration(
[t.importDefaultSpecifier(t.identifier('Svg'))],
imports,
t.stringLiteral('react-native-svg'),
),
)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/__snapshots__/convert.test.js.snap
Expand Up @@ -450,7 +450,7 @@ exports[`convert config should support options 18 1`] = `
function SvgComponent(props) {
return (
<svg width={88} height={88} {...props}>
<svg width={88} height={88} xmlns=\\"http://www.w3.org/2000/svg\\" {...props}>
<g
stroke=\\"#063855\\"
strokeWidth={2}
Expand Down
68 changes: 59 additions & 9 deletions yarn.lock
Expand Up @@ -4219,7 +4219,7 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "^2.1.1"

debug@^3.1.0:
debug@^3.1.0, debug@^3.2.6:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
Expand Down Expand Up @@ -4261,6 +4261,11 @@ dedent@^0.7.0:
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=

deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==

deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
Expand Down Expand Up @@ -4359,6 +4364,11 @@ detect-indent@^5.0.0:
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=

detect-libc@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=

detect-newline@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651"
Expand Down Expand Up @@ -5899,7 +5909,7 @@ humanize-ms@^1.2.1:
dependencies:
ms "^2.0.0"

iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.13:
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
Expand Down Expand Up @@ -6025,7 +6035,7 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=

ini@^1.3.2, ini@^1.3.4:
ini@^1.3.2, ini@^1.3.4, ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
Expand Down Expand Up @@ -7763,6 +7773,15 @@ natural-compare@^1.4.0:
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=

needle@^2.2.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.4.1.tgz#14af48732463d7475696f937626b1b993247a56a"
integrity sha512-x/gi6ijr4B7fwl6WYL9FwlCvRQKGlUNvnceho8wxkwXqN8jvVmmmATTmZPRRG7b/yC1eode26C2HO9jl78Du9g==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
sax "^1.2.4"

neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c"
Expand Down Expand Up @@ -7872,6 +7891,22 @@ node-notifier@^6.0.0:
shellwords "^0.1.1"
which "^1.3.1"

node-pre-gyp@*:
version "0.14.0"
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83"
integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==
dependencies:
detect-libc "^1.0.2"
mkdirp "^0.5.1"
needle "^2.2.1"
nopt "^4.0.1"
npm-packlist "^1.1.6"
npmlog "^4.0.2"
rc "^1.2.7"
rimraf "^2.6.1"
semver "^5.3.0"
tar "^4.4.2"

node-releases@^1.1.53:
version "1.1.53"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4"
Expand Down Expand Up @@ -7962,7 +7997,7 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1:
semver "^5.6.0"
validate-npm-package-name "^3.0.0"

npm-packlist@^1.4.4:
npm-packlist@^1.1.6, npm-packlist@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
Expand Down Expand Up @@ -7994,7 +8029,7 @@ npm-run-path@^4.0.0:
dependencies:
path-key "^3.0.0"

npmlog@^4.1.2:
npmlog@^4.0.2, npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
Expand Down Expand Up @@ -9271,6 +9306,16 @@ range-parser@~1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==

rc@^1.2.7:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"

react-is@^16.12.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
Expand Down Expand Up @@ -9702,7 +9747,7 @@ rimraf@2.6.3:
dependencies:
glob "^7.1.3"

rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3:
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
Expand Down Expand Up @@ -9827,7 +9872,7 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"

sax@~1.2.4:
sax@^1.2.4, sax@~1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
Expand Down Expand Up @@ -9861,7 +9906,7 @@ semver-regex@^2.0.0:
resolved "https://registry.yarnpkg.com/semver-regex/-/semver-regex-2.0.0.tgz#a93c2c5844539a770233379107b38c7b4ac9d338"
integrity sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==

"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.1, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
Expand Down Expand Up @@ -10488,6 +10533,11 @@ strip-json-comments@^3.0.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180"
integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==

strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo=

strong-log-transformer@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10"
Expand Down Expand Up @@ -10596,7 +10646,7 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==

tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
tar@^4.4.10, tar@^4.4.12, tar@^4.4.2, tar@^4.4.8:
version "4.4.13"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
Expand Down

1 comment on commit d61e0cf

@vercel
Copy link

@vercel vercel bot commented on d61e0cf Nov 15, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.