diff --git a/packages/codemods/src/transforms/v3/web-react/README.md b/packages/codemods/src/transforms/v3/web-react/README.md new file mode 100644 index 0000000000..49a2a985da --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/README.md @@ -0,0 +1,24 @@ +# Web-React v3 Codemods + +This is a collection of codemods for updating Web-React v3 components. + +You can find instructions on how to run these codemods in the main package [README](https://github.com/lmc-eu/spirit-design-system/blob/main/packages/codemods/README.md). + +## Included Scripts + +### `v3/web-react/link-underlined-prop` — Link `isUnderlined` to `udnerlined` prop change + +This codemod updates the `Link` component by replacing the `isUnderlined` prop with a new `underlined` prop, setting it to "always". + +#### Usage + +```sh +npx @lmc-eu/spirit-codemods -p -t v3/web-react/link-underlined-prop +``` + +#### Example + +```diff +- ++ +``` diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx new file mode 100644 index 0000000000..90af8e3291 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.input.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +// @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. +import { Link } from '@lmc-eu/spirit-web-react'; + +export const MyComponent = () => ( + <> + + + + + +); diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx new file mode 100644 index 0000000000..35c1fbb249 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underlined-prop.output.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +// @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. +import { Link } from '@lmc-eu/spirit-web-react'; + +export const MyComponent = () => ( + <> + + + + + +); diff --git a/packages/codemods/src/transforms/v3/web-react/__tests__/link-underlined-prop.test.ts b/packages/codemods/src/transforms/v3/web-react/__tests__/link-underlined-prop.test.ts new file mode 100644 index 0000000000..233c471c45 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__tests__/link-underlined-prop.test.ts @@ -0,0 +1,3 @@ +import { testTransform } from '../../../../../tests/testUtils'; + +testTransform(__dirname, 'link-underlined-prop'); diff --git a/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts b/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts new file mode 100644 index 0000000000..608fced2e3 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/link-underlined-prop.ts @@ -0,0 +1,67 @@ +import { + API, + FileInfo, + Collection, + JSCodeshift, + JSXElement, + JSXAttribute, + ImportDeclaration, + JSXOpeningElement, +} from 'jscodeshift'; + +const transform = (fileInfo: FileInfo, api: API): string => { + const j: JSCodeshift = api.jscodeshift; + const root: Collection = j(fileInfo.source); + + // Find import statements for the specific module + const importStatements: Collection = root.find(j.ImportDeclaration, { + source: { + value: (value: string): boolean => /^@lmc-eu\/spirit-web-react(\/.*)?$/.test(value), + }, + }); + + // Check if the module is imported + if (importStatements.length > 0) { + // Find Link components in the code + const linkComponents: Collection = root.find(j.JSXOpeningElement, { + name: { + type: 'JSXIdentifier', + name: 'Link', + }, + }); + + linkComponents.forEach((path) => { + if (path.node && path.node.attributes) { + // Find the isUnderlined attribute + path.node.attributes.forEach((attr, index) => { + if (attr.type === 'JSXAttribute' && (attr as JSXAttribute).name.name === 'isUnderlined') { + const jsxAttr = attr as JSXAttribute; + // Check if the attribute value is true + if ( + jsxAttr.value === null || + (jsxAttr.value?.type === 'JSXExpressionContainer' && + jsxAttr.value.expression.type === 'BooleanLiteral' && + jsxAttr.value.expression.value === true) || + (jsxAttr.value?.type === 'Literal' && jsxAttr.value.value === true) + ) { + // Change isUnderlined to underline="always" + jsxAttr.name.name = 'underlined'; + jsxAttr.value = j.literal('always'); + } else if ( + jsxAttr.value?.type === 'JSXExpressionContainer' && + jsxAttr.value.expression.type === 'BooleanLiteral' && + jsxAttr.value.expression.value === false + ) { + // If isUnderlined is set to false, remove the attribute + path.node.attributes?.splice(index, 1); + } + } + }); + } + }); + } + + return root.toSource(); +}; + +export default transform;