From 1572df0a2e0e9b4cff3de598a1ccd7164f16fb04 Mon Sep 17 00:00:00 2001 From: samjt Date: Wed, 7 Sep 2022 18:25:01 +0200 Subject: [PATCH] Generate typescript for SVGs when using svgr and typescript option (#8411) Co-authored-by: Niklas Mischkulnig <4586894+mischnic@users.noreply.github.com> --- .../svg-react-typescript/.svgrrc.json | 3 +++ .../integration/svg-react-typescript/icon.svg | 14 ++++++++++++++ .../integration/svg-react-typescript/index.html | 1 + .../svg-react-typescript/package.json | 8 ++++++++ .../integration/svg-react-typescript/react.ts | 8 ++++++++ .../integration/svg-react-typescript/yarn.lock | 0 .../core/integration-tests/test/svg-react.js | 17 +++++++++++++++++ .../svg-react/src/SvgReactTransformer.js | 8 ++++++-- 8 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/.svgrrc.json create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/icon.svg create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/index.html create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/package.json create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/react.ts create mode 100644 packages/core/integration-tests/test/integration/svg-react-typescript/yarn.lock diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/.svgrrc.json b/packages/core/integration-tests/test/integration/svg-react-typescript/.svgrrc.json new file mode 100644 index 00000000000..d5c892de764 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-react-typescript/.svgrrc.json @@ -0,0 +1,3 @@ +{ + "typescript": true +} \ No newline at end of file diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/icon.svg b/packages/core/integration-tests/test/integration/svg-react-typescript/icon.svg new file mode 100644 index 00000000000..a0aeec0dc8f --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-react-typescript/icon.svg @@ -0,0 +1,14 @@ + + + + + + + diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/index.html b/packages/core/integration-tests/test/integration/svg-react-typescript/index.html new file mode 100644 index 00000000000..ceb8dab6b68 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-react-typescript/index.html @@ -0,0 +1 @@ + diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/package.json b/packages/core/integration-tests/test/integration/svg-react-typescript/package.json new file mode 100644 index 00000000000..9a0a8c08bd5 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-react-typescript/package.json @@ -0,0 +1,8 @@ +{ + "source": "react.ts", + "main": "icons.js", + "types": "types.d.ts", + "dependencies": { + "react": "*" + } +} diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/react.ts b/packages/core/integration-tests/test/integration/svg-react-typescript/react.ts new file mode 100644 index 00000000000..73a2f6f2aa2 --- /dev/null +++ b/packages/core/integration-tests/test/integration/svg-react-typescript/react.ts @@ -0,0 +1,8 @@ + +interface SVGRComponent + extends React.StatelessComponent> {} + +import React from 'react'; +import ReactIcon from './icon.svg'; +const Icon:SVGRComponent = ReactIcon; +export default Icon; diff --git a/packages/core/integration-tests/test/integration/svg-react-typescript/yarn.lock b/packages/core/integration-tests/test/integration/svg-react-typescript/yarn.lock new file mode 100644 index 00000000000..e69de29bb2d diff --git a/packages/core/integration-tests/test/svg-react.js b/packages/core/integration-tests/test/svg-react.js index 2a625577767..dff63a48577 100644 --- a/packages/core/integration-tests/test/svg-react.js +++ b/packages/core/integration-tests/test/svg-react.js @@ -19,4 +19,21 @@ describe('svg-react', function () { assert(file.includes('const SvgIcon =')); assert(file.includes('_react.createElement("svg"')); }); + it('should support transforming SVGs to typescript react components', async function () { + let b = await bundle( + path.join(__dirname, '/integration/svg-react-typescript/react.ts'), + { + defaultConfig: path.join( + __dirname, + 'integration/custom-configs/.parcelrc-svg-react', + ), + }, + ); + let file = await outputFS.readFile(b.getBundles()[0].filePath, 'utf-8'); + let types = await outputFS.readFile(b.getBundles()[1].filePath, 'utf-8'); + + assert(!file.includes('inkscape')); + assert(file.includes('react.createElement("svg"')); + assert(types.includes('const Icon: SVGRComponent')); + }); }); diff --git a/packages/transformers/svg-react/src/SvgReactTransformer.js b/packages/transformers/svg-react/src/SvgReactTransformer.js index 640b526139e..5b9db020881 100644 --- a/packages/transformers/svg-react/src/SvgReactTransformer.js +++ b/packages/transformers/svg-react/src/SvgReactTransformer.js @@ -17,7 +17,11 @@ function getComponentName(filePath) { } export default (new Transformer({ - async transform({asset}) { + async loadConfig({config}) { + let conf = await config.getConfig(['.svgrrc.json', '.svgrrc']); + return conf?.contents; + }, + async transform({asset, config}) { let code = await asset.getCode(); let componentName = getComponentName(asset.filePath); @@ -33,7 +37,7 @@ export default (new Transformer({ }, ); - asset.type = 'jsx'; + asset.type = config?.typescript ? 'tsx' : 'jsx'; asset.bundleBehavior = null; asset.setCode(jsx);