diff --git a/codemods/react/19/replace-default-props/.codemodrc.json b/codemods/react/19/replace-default-props/.codemodrc.json
index 30d2d25b..4726df91 100644
--- a/codemods/react/19/replace-default-props/.codemodrc.json
+++ b/codemods/react/19/replace-default-props/.codemodrc.json
@@ -1,7 +1,7 @@
{
"$schema": "https://codemod-utils.s3.us-west-1.amazonaws.com/configuration_schema.json",
"name": "react/19/replace-default-props",
- "version": "1.0.2",
+ "version": "1.0.3",
"engine": "jscodeshift",
"private": false,
"arguments": [],
diff --git a/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-input.jsx b/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-input.jsx
new file mode 100644
index 00000000..92a9d9b4
--- /dev/null
+++ b/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-input.jsx
@@ -0,0 +1,8 @@
+const Button = ({ size, color }) => {
+ return ;
+};
+
+Button.defaultProps = {
+ size: "16px",
+ color: "blue",
+};
\ No newline at end of file
diff --git a/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-output.jsx b/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-output.jsx
new file mode 100644
index 00000000..154516b8
--- /dev/null
+++ b/codemods/react/19/replace-default-props/__testfixtures__/button-jsx-example-output.jsx
@@ -0,0 +1,3 @@
+const Button = ({ size = "16px", color = "blue" }) => {
+ return ;
+};
\ No newline at end of file
diff --git a/codemods/react/19/replace-default-props/__testfixtures__/nested-destructuring.output.tsx b/codemods/react/19/replace-default-props/__testfixtures__/nested-destructuring.output.tsx
index f3350de4..5c669c36 100644
--- a/codemods/react/19/replace-default-props/__testfixtures__/nested-destructuring.output.tsx
+++ b/codemods/react/19/replace-default-props/__testfixtures__/nested-destructuring.output.tsx
@@ -1,9 +1,7 @@
-const Card = ({
- user: { name, age } = {
- name: "Unknown",
- age: 0,
- },
-}) => {
+const Card = ({ user: { name, age } = {
+ name: "Unknown",
+ age: 0,
+} }) => {
return (
{name}
diff --git a/codemods/react/19/replace-default-props/__testfixtures__/with-functions.output.tsx b/codemods/react/19/replace-default-props/__testfixtures__/with-functions.output.tsx
index 9545553d..b90f38f1 100644
--- a/codemods/react/19/replace-default-props/__testfixtures__/with-functions.output.tsx
+++ b/codemods/react/19/replace-default-props/__testfixtures__/with-functions.output.tsx
@@ -1,6 +1,3 @@
-const List = ({
- items = [],
- renderItem = (item) =>
{item},
-}) => {
+const List = ({ items = [], renderItem = (item) =>
{item} }) => {
return
;
};
diff --git a/codemods/react/19/replace-default-props/src/index.ts b/codemods/react/19/replace-default-props/src/index.ts
index 89fe2380..99fc3720 100644
--- a/codemods/react/19/replace-default-props/src/index.ts
+++ b/codemods/react/19/replace-default-props/src/index.ts
@@ -6,6 +6,7 @@ import type {
JSCodeshift,
MemberExpression,
ObjectProperty,
+ Property,
} from "jscodeshift";
import { getFunctionName } from "@codemod.com/codemod-utils/dist/jscodeshift/function.js";
@@ -36,7 +37,7 @@ const getComponentStaticPropValue = (
const buildPropertyWithDefaultValue = (
j: JSCodeshift,
- property: ObjectProperty,
+ property: ObjectProperty | Property,
defaultValue: any,
) => {
// Special handling for nested destructuring patterns
@@ -84,13 +85,11 @@ export default function transform(
defaultPropsRight.properties?.forEach((property) => {
if (
- !j.ObjectProperty.check(property) ||
- !j.Identifier.check(property.key)
+ (j.Property.check(property) || j.ObjectProperty.check(property)) &&
+ j.Identifier.check(property.key)
) {
- return;
+ defaultPropsMap.set(property.key.name, property.value);
}
-
- defaultPropsMap.set(property.key.name, property.value);
});
const propsArg = path.value.params.at(0);
@@ -98,19 +97,17 @@ export default function transform(
if (j.ObjectPattern.check(propsArg)) {
propsArg.properties.forEach((property) => {
if (
- !j.ObjectProperty.check(property) ||
- !j.Identifier.check(property.key) ||
- j.AssignmentPattern.check(property.value)
+ (j.Property.check(property) || j.ObjectProperty.check(property)) &&
+ j.Identifier.check(property.key)
) {
- return;
- }
- if (defaultPropsMap.has(property.key.name)) {
- isDirty = true;
- property.value = buildPropertyWithDefaultValue(
- j,
- property,
- defaultPropsMap.get(property.key.name),
- );
+ if (defaultPropsMap.has(property.key.name)) {
+ isDirty = true;
+ property.value = buildPropertyWithDefaultValue(
+ j,
+ property,
+ defaultPropsMap.get(property.key.name),
+ );
+ }
}
});
}
diff --git a/codemods/react/19/replace-default-props/test/test.ts b/codemods/react/19/replace-default-props/test/test.ts
index c72c203e..29b2e46f 100644
--- a/codemods/react/19/replace-default-props/test/test.ts
+++ b/codemods/react/19/replace-default-props/test/test.ts
@@ -208,4 +208,35 @@ describe("react/19/replace-default-props", () => {
OUTPUT.replace(/W/gm, ""),
);
});
+
+ it("should correctly transform when props are not destructured", async () => {
+ const INPUT = await readFile(
+ join(__dirname, "..", "__testfixtures__/button-jsx-example-input.jsx"),
+ "utf-8",
+ );
+ const OUTPUT = await readFile(
+ join(__dirname, "..", "__testfixtures__/button-jsx-example-output.jsx"),
+ "utf-8",
+ );
+
+ const actualOutput = transform(
+ {
+ path: "index.js",
+ source: INPUT,
+ },
+ buildApi("jsx"),
+ );
+
+ const fs = require("node:fs");
+ fs.writeFileSync(
+ join(__dirname, "..", "__testfixtures__/button-jsx-example-output.jsx"),
+ actualOutput,
+ );
+
+ assert.deepEqual(
+ actualOutput?.replace(/W/gm, ""),
+ OUTPUT.replace(/W/gm, ""),
+ );
+ });
});
+