From 506f2683354bcb42a9b1ac9e8d34abcf9eabfe6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kry=C5=A1p=C3=ADn?= Date: Thu, 9 May 2024 11:24:36 +0200 Subject: [PATCH] Feat(codemods): Add Tabs props rename codemod #DS-1096 Rename TabItem prop `forTab` to `forTabPane`. Rename TabPane prop `tabId` to `id`. --- .../tabs-tabitem-tabpane-props.input.tsx | 10 +++ .../tabs-tabitem-tabpane-props.output.tsx | 10 +++ .../tabs-tabitem-tabpane-props.test.ts | 3 + .../web-react/tabs-tabitem-tabpane-props.ts | 80 +++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.input.tsx create mode 100644 packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.output.tsx create mode 100644 packages/codemods/src/transforms/v2/web-react/__tests__/tabs-tabitem-tabpane-props.test.ts create mode 100644 packages/codemods/src/transforms/v2/web-react/tabs-tabitem-tabpane-props.ts diff --git a/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.input.tsx b/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.input.tsx new file mode 100644 index 0000000000..fcafc9fa32 --- /dev/null +++ b/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.input.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +// @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. +import { TabItem, TabPane } from '@lmc-eu/spirit-web-react'; + +export const MyComponent = () => ( + <> + + + +); diff --git a/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.output.tsx b/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.output.tsx new file mode 100644 index 0000000000..63dff51076 --- /dev/null +++ b/packages/codemods/src/transforms/v2/web-react/__testfixtures__/tabs-tabitem-tabpane-props.output.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +// @ts-ignore: No declaration -- The library is not installed; we don't need to install it for fixtures. +import { TabItem, TabPane } from '@lmc-eu/spirit-web-react'; + +export const MyComponent = () => ( + <> + + + +); diff --git a/packages/codemods/src/transforms/v2/web-react/__tests__/tabs-tabitem-tabpane-props.test.ts b/packages/codemods/src/transforms/v2/web-react/__tests__/tabs-tabitem-tabpane-props.test.ts new file mode 100644 index 0000000000..a36eba14d8 --- /dev/null +++ b/packages/codemods/src/transforms/v2/web-react/__tests__/tabs-tabitem-tabpane-props.test.ts @@ -0,0 +1,3 @@ +import { testTransform } from '../../../../../tests/testUtils'; + +testTransform(__dirname, 'tabs-tabitem-tabpane-props'); diff --git a/packages/codemods/src/transforms/v2/web-react/tabs-tabitem-tabpane-props.ts b/packages/codemods/src/transforms/v2/web-react/tabs-tabitem-tabpane-props.ts new file mode 100644 index 0000000000..66f97ad8b1 --- /dev/null +++ b/packages/codemods/src/transforms/v2/web-react/tabs-tabitem-tabpane-props.ts @@ -0,0 +1,80 @@ +import { API, FileInfo } from 'jscodeshift'; + +const transform = (fileInfo: FileInfo, api: API) => { + const j = api.jscodeshift; + const root = j(fileInfo.source); + + // Find import statements for the specific module and TabItem or TabPane specifier + const importStatements = root.find(j.ImportDeclaration, { + source: { + value: (value: string) => /^@lmc-eu\/spirit-web-react(\/.*)?$/.test(value), + }, + }); + + // Check if the module is imported + if (importStatements.length > 0) { + const tabItemComponentSpecifier = importStatements.find(j.ImportSpecifier, { + imported: { + type: 'Identifier', + name: 'TabItem', + }, + }); + + const tabPaneComponentSpecifier = importStatements.find(j.ImportSpecifier, { + imported: { + type: 'Identifier', + name: 'TabPane', + }, + }); + + // Check if TabItem specifier is present + if (tabItemComponentSpecifier.length > 0) { + // Find TabItem components in the module + const components = root.find(j.JSXOpeningElement, { + name: { + type: 'JSXIdentifier', + name: 'TabItem', + }, + }); + + // Rename 'forTab' attribute to 'forTabPane' + components + .find(j.JSXAttribute, { + name: { + type: 'JSXIdentifier', + name: 'forTab', + }, + }) + .forEach((attributePath) => { + attributePath.node.name.name = 'forTabPane'; + }); + } + + // Check if TabPane specifier is present + if (tabPaneComponentSpecifier.length > 0) { + // Find TabPane components in the module + const components = root.find(j.JSXOpeningElement, { + name: { + type: 'JSXIdentifier', + name: 'TabPane', + }, + }); + + // Rename 'tabId' attribute to 'id' + components + .find(j.JSXAttribute, { + name: { + type: 'JSXIdentifier', + name: 'tabId', + }, + }) + .forEach((attributePath) => { + attributePath.node.name.name = 'id'; + }); + } + } + + return root.toSource(); +}; + +export default transform;