diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.jsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.jsx
deleted file mode 100644
index c08e4c5a2529..000000000000
--- a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.jsx
+++ /dev/null
@@ -1,2 +0,0 @@
-const Kitten1 = props => ;
-export default Kitten1;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.tsx
new file mode 100644
index 000000000000..57094f9b4584
--- /dev/null
+++ b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/Kitten1SVG.tsx
@@ -0,0 +1,3 @@
+import type { SVGProps } from "react";
+const Kitten1 = (props: SVGProps) => ;
+export default Kitten1;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.jsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.jsx
deleted file mode 100644
index fe47f0a75b3a..000000000000
--- a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.jsx
+++ /dev/null
@@ -1,2 +0,0 @@
-const Logo = props => ;
-export default Logo;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.tsx
new file mode 100644
index 000000000000..161fa55dc367
--- /dev/null
+++ b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/complex/output/mySvgs/LogoSVG.tsx
@@ -0,0 +1,3 @@
+import type { SVGProps } from "react";
+const Logo = (props: SVGProps) => ;
+export default Logo;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/AsRenderProp.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/AsRenderProp.jsx
similarity index 100%
rename from packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/AsRenderProp.tsx
rename to packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/AsRenderProp.jsx
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/Simple.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/Simple.jsx
similarity index 100%
rename from packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/Simple.tsx
rename to packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/input/Simple.jsx
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/AsRenderProp.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/AsRenderProp.jsx
similarity index 100%
rename from packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/AsRenderProp.tsx
rename to packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/AsRenderProp.jsx
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/Simple.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/Simple.jsx
similarity index 100%
rename from packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/Simple.tsx
rename to packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/simple/output/Simple.jsx
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.jsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.jsx
deleted file mode 100644
index c10ecf62f32d..000000000000
--- a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.jsx
+++ /dev/null
@@ -1,2 +0,0 @@
-const Kitten1WithDashes = props => ;
-export default Kitten1WithDashes;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.tsx
new file mode 100644
index 000000000000..851269b61d21
--- /dev/null
+++ b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/Kitten1WithDashesSVG.tsx
@@ -0,0 +1,3 @@
+import type { SVGProps } from "react";
+const Kitten1WithDashes = (props: SVGProps) => ;
+export default Kitten1WithDashes;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.jsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.jsx
deleted file mode 100644
index fe47f0a75b3a..000000000000
--- a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.jsx
+++ /dev/null
@@ -1,2 +0,0 @@
-const Logo = props => ;
-export default Logo;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.tsx b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.tsx
new file mode 100644
index 000000000000..161fa55dc367
--- /dev/null
+++ b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/__testfixtures__/srcAlias/output/web/src/mySvgs/LogoSVG.tsx
@@ -0,0 +1,3 @@
+import type { SVGProps } from "react";
+const Logo = (props: SVGProps) => ;
+export default Logo;
diff --git a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/replaceComponentSvgs.ts b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/replaceComponentSvgs.ts
index e8164cea6fc9..3b1a2a204182 100644
--- a/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/replaceComponentSvgs.ts
+++ b/packages/codemods/src/codemods/v6.x.x/replaceComponentSvgs/replaceComponentSvgs.ts
@@ -5,10 +5,19 @@ import { transform as svgrTransform } from '@svgr/core'
import type { API, FileInfo, StringLiteral } from 'jscodeshift'
import pascalcase from 'pascalcase'
+import { getPaths } from '@redwoodjs/project-config'
+
+/**
+ * @param svgFilePath Full path to the existing svg file
+ * @param outputPath Full path to the output file
+ * @param componentName Name of the React component to generate inside the output file
+ * @param typescript Whether to generate TypeScript code
+ */
async function convertSvgToReactComponent(
svgFilePath: string,
outputPath: string,
- componentName: string
+ componentName: string,
+ typescript: boolean
) {
const svgContents = await fs.readFile(svgFilePath, 'utf-8')
@@ -17,6 +26,7 @@ async function convertSvgToReactComponent(
{
jsxRuntime: 'automatic',
plugins: ['@svgr/plugin-jsx'],
+ typescript,
},
{
componentName: componentName,
@@ -25,16 +35,16 @@ async function convertSvgToReactComponent(
await fs.writeFile(outputPath, jsCode)
+ console.log()
console.log(`SVG converted to React component: ${outputPath}`)
}
export default async function transform(file: FileInfo, api: API) {
const j = api.jscodeshift
-
const root = j(file.source)
- // Do this lazily
- const { getPaths } = await import('@redwoodjs/project-config')
+ // If the input file is TypeScript, we'll generate TypeScript SVG components
+ const isTS = file.path.endsWith('.tsx')
// Find all import declarations with "*.svg" import
const svgImports = root.find(j.ImportDeclaration).filter((path) => {
@@ -46,6 +56,7 @@ export default async function transform(file: FileInfo, api: API) {
filePath: string
importSourcePath: StringLiteral
}> = []
+
// Process each import declaration
svgImports.forEach((importDeclaration) => {
const importSpecifiers = importDeclaration.node.specifiers
@@ -99,10 +110,10 @@ export default async function transform(file: FileInfo, api: API) {
if (svgsToConvert.length > 0) {
// if there are any svgs used as components, or render props, convert the svg to a react component
await Promise.all(
- svgsToConvert.map(async ({ filePath, importSourcePath }) => {
+ svgsToConvert.map(async (svg) => {
const svgFileNameWithoutExtension = path.basename(
- filePath,
- path.extname(filePath)
+ svg.filePath,
+ path.extname(svg.filePath)
)
const componentName = pascalcase(svgFileNameWithoutExtension)
@@ -111,15 +122,20 @@ export default async function transform(file: FileInfo, api: API) {
// The absolute path to the new file
const outputPath = path.join(
- path.dirname(filePath),
- `${newFileName}.jsx`
+ path.dirname(svg.filePath),
+ `${newFileName}.${isTS ? 'tsx' : 'jsx'}`
)
try {
- await convertSvgToReactComponent(filePath, outputPath, componentName)
+ await convertSvgToReactComponent(
+ svg.filePath,
+ outputPath,
+ componentName,
+ isTS
+ )
} catch (error: any) {
console.error(
- `Error converting ${filePath} to React component: ${error.message}`
+ `Error converting ${svg.filePath} to React component: ${error.message}`
)
// Don't proceed if SVGr fails
@@ -129,8 +145,8 @@ export default async function transform(file: FileInfo, api: API) {
// If SVGr is successful, change the import path
// '../../bazinga.svg' -> '../../BazingaSVG'
// Use extname, incase ext casing does not match
- importSourcePath.value = importSourcePath.value.replace(
- `${svgFileNameWithoutExtension}${path.extname(filePath)}`,
+ svg.importSourcePath.value = svg.importSourcePath.value.replace(
+ `${svgFileNameWithoutExtension}${path.extname(svg.filePath)}`,
newFileName
)
})