From 8e2ffb65d340032b8b2929a1640a051a5d7eb6a3 Mon Sep 17 00:00:00 2001 From: Pavel Klibani Date: Wed, 7 Aug 2024 22:17:05 +0200 Subject: [PATCH] Feat(codemod): Add codemod for Link underline prop - replacing the `isUnderlined` prop with a new `underline` prop and set it to "always" if true --- .../src/transforms/v3/web-react/README.md | 24 +++++++ .../link-underline-prop.input.tsx | 12 ++++ .../link-underline-prop.output.tsx | 12 ++++ .../__tests__/link-underline-prop.test.ts | 3 + .../v3/web-react/link-underline-prop.ts | 67 +++++++++++++++++++ 5 files changed, 118 insertions(+) create mode 100644 packages/codemods/src/transforms/v3/web-react/README.md create mode 100644 packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-prop.input.tsx create mode 100644 packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-prop.output.tsx create mode 100644 packages/codemods/src/transforms/v3/web-react/__tests__/link-underline-prop.test.ts create mode 100644 packages/codemods/src/transforms/v3/web-react/link-underline-prop.ts 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..8bf50c8ed4 --- /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-underline-prop` — Link `isUnderlined` to `underline` prop change + +This codemod updates the `Link` component by replacing the `isUnderlined` prop with a new `underline` prop, setting it to "always". + +#### Usage + +```sh +npx @lmc-eu/spirit-codemods -p -t v3/web-react/link-underline-prop +``` + +#### Example + +```diff +- ++ +``` diff --git a/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-prop.input.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-prop.input.tsx new file mode 100644 index 0000000000..90af8e3291 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-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-underline-prop.output.tsx b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-prop.output.tsx new file mode 100644 index 0000000000..bee72185fc --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__testfixtures__/link-underline-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-underline-prop.test.ts b/packages/codemods/src/transforms/v3/web-react/__tests__/link-underline-prop.test.ts new file mode 100644 index 0000000000..c087c25003 --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/__tests__/link-underline-prop.test.ts @@ -0,0 +1,3 @@ +import { testTransform } from '../../../../../tests/testUtils'; + +testTransform(__dirname, 'link-underline-prop'); diff --git a/packages/codemods/src/transforms/v3/web-react/link-underline-prop.ts b/packages/codemods/src/transforms/v3/web-react/link-underline-prop.ts new file mode 100644 index 0000000000..045154e5af --- /dev/null +++ b/packages/codemods/src/transforms/v3/web-react/link-underline-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 = 'underline'; + 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;