diff --git a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-card.test.ts b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-card.test.ts index 60c73d19a1d..dae4db91728 100644 --- a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-card.test.ts +++ b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-card.test.ts @@ -91,7 +91,7 @@ it('should migrate the Card component', async () => { expect(result).toMatchInlineSnapshot(` "const App = () => ( <> - + Create Razorpay Payments Links and share them with your customers from the Razorpay Dashboard or using APIs and start accepting payments. Check the advantages, payment methods, international currency support and more. @@ -99,7 +99,7 @@ it('should migrate the Card component', async () => { - + Create Razorpay Payments Links and share them with your customers from the Razorpay Dashboard or using APIs and start accepting payments. Check the advantages, payment methods, international currency support and more. diff --git a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-colors.test.ts b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-colors.test.ts index 2ac6136a093..408623f3a94 100644 --- a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-colors.test.ts +++ b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-colors.test.ts @@ -120,8 +120,8 @@ it('should update the theme in BladeProvider', async () => { ); expect(result).toMatchInlineSnapshot(` - "import { BladeProvider } from "@razorpay/blade-rebranded/components"; - import { bladeTheme } from "@razorpay/blade-rebranded/tokens"; + "import { BladeProvider } from '@razorpay/blade/components'; + import { bladeTheme } from '@razorpay/blade/tokens'; const AppWrapper = () => { return ( @@ -156,8 +156,8 @@ it('should update the theme in BladeProvider', async () => { ); expect(result).toMatchInlineSnapshot(` - "import { BladeProvider } from "@razorpay/blade-rebranded/components"; - import { bladeTheme } from "@razorpay/blade-rebranded/tokens"; + "import { BladeProvider } from '@razorpay/blade/components'; + import { bladeTheme } from '@razorpay/blade/tokens'; const AppWrapper = () => { return ( diff --git a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-contrast-intent-variant.test.ts b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-contrast-intent-variant.test.ts index d270d39bdb2..4e06a82e59c 100644 --- a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-contrast-intent-variant.test.ts +++ b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-contrast-intent-variant.test.ts @@ -121,6 +121,10 @@ it('should remove variant/intent prop in favor of color prop', async () => { + + + + ); `, @@ -192,6 +196,10 @@ it('should remove variant/intent prop in favor of color prop', async () => { + + + + );" `); diff --git a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-table.test.ts b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-table.test.ts new file mode 100644 index 00000000000..91638cebcb6 --- /dev/null +++ b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-table.test.ts @@ -0,0 +1,182 @@ +import { applyTransform } from '@hypermod/utils'; +import * as transformer from '..'; + +it('should migrate the ActionList component', async () => { + const result = await applyTransform( + transformer, + ` + const App = () => ( + <> + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + ); + `, + { parser: 'tsx' }, + ); + + expect(result).toMatchInlineSnapshot(` + "const App = () => ( + <> + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + + {(tableData) => ( + <> + + + ID + Amount + Account + + + + {tableData.map((tableItem, index) => ( + + + {tableItem.paymentId} + + + + + {tableItem.account} + + ))} + + + )} +
+ + );" + `); +}); diff --git a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-typography.test.ts b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-typography.test.ts index 68d2f8898cb..c0129b1a246 100644 --- a/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-typography.test.ts +++ b/packages/blade/codemods/brand-refresh/transformers/__tests__/migrate-typography.test.ts @@ -333,7 +333,7 @@ it('should correctly convert Title to Heading component', async () => { ); expect(result).toMatchInlineSnapshot(` - "import { Heading } from "@razorpay/blade-rebranded/components"; + "import { Heading } from '@razorpay/blade/components'; const App = () => ( <> Lorem ipsum diff --git a/packages/blade/codemods/brand-refresh/transformers/index.ts b/packages/blade/codemods/brand-refresh/transformers/index.ts index dbe368f984e..4b810997526 100644 --- a/packages/blade/codemods/brand-refresh/transformers/index.ts +++ b/packages/blade/codemods/brand-refresh/transformers/index.ts @@ -5,7 +5,7 @@ import migrateCardComponent from './migrate-card'; import migrateBadgeComponent from './migrate-badge'; import migrateContrastIntentAndColorProps from './migrate-contrast-intent-color-props'; import migrateTypographyComponents from './migrate-typography'; -import migrateActionListComponent from './migrate-actionlist'; +import migrateActionListAndTable from './migrate-actionlist-and-table'; import { red, isExpression } from './utils'; // eslint-disable-next-line import/extensions import colorTokensMapping from './colorTokensMapping.json'; @@ -92,14 +92,22 @@ const transformer: Transform = (file, api, options) => { // Update the themeTokens prop in BladeProvider try { root - .find(j.JSXElement) - .filter((path) => path.value.openingElement.name.name === 'BladeProvider') - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'themeTokens') - .replaceWith((path) => { - path.node.value.expression.name = 'bladeTheme'; + .find(j.JSXElement, { + openingElement: { + name: { + name: 'BladeProvider', + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'themeTokens', + }, + }) + .replaceWith(({ node }) => { + node.value.expression.name = 'bladeTheme'; - return path.node; + return node; }); } catch (error) { console.error( @@ -113,13 +121,19 @@ const transformer: Transform = (file, api, options) => { // Update color token value based on the context try { root - .find(j.JSXElement) - .filter((path) => - /(Text|Title|Code|Display|Heading|Box|Icon)/i.test(path.value.openingElement.name.name), - ) + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => /(Text|Title|Code|Display|Heading|Box|Icon)/i.test(name), + }, + }, + }) // Find all color props - .find(j.JSXAttribute) - .filter((path) => path.node.name.name.toLowerCase().includes('color')) + .find(j.JSXAttribute, { + name: { + name: (name) => name.toLowerCase().includes('color'), + }, + }) .replaceWith((path) => { const { node, parent } = path; @@ -174,27 +188,22 @@ const transformer: Transform = (file, api, options) => { migrateCardComponent({ root, j, file }); migrateAmountComponent({ root, j, file }); migrateDividerComponent({ root, j, file }); - migrateActionListComponent({ root, j, file }); + migrateActionListAndTable({ root, j, file }); migrateDropdownComponent({ root, j, file }); - // Update ImportDeclaration from "@razorpay/blade/components" to "@razorpay/blade-rebranded/components" // Update ImportSpecifier from "paymentTheme"/"bankingTheme" to "bladeTheme" try { root - .find(j.ImportDeclaration) - .filter((path) => - /@razorpay\/blade\/(components|utils|tokens)/i.test(path.value.source.value as string), - ) - .replaceWith((path) => { - path.value.source.value = (path.value.source.value as string).replace( - 'blade', - 'blade-rebranded', - ); - - return path.node; + .find(j.ImportDeclaration, { + source: { + value: '@razorpay/blade/tokens', + }, + }) + .find(j.ImportSpecifier, { + imported: { + name: (name) => ['paymentTheme', 'bankingTheme'].includes(name), + }, }) - .find(j.ImportSpecifier) - .filter((path) => ['paymentTheme', 'bankingTheme'].includes(path.value.imported.name)) .replaceWith((path) => { path.value.imported.name = 'bladeTheme'; @@ -203,7 +212,7 @@ const transformer: Transform = (file, api, options) => { } catch (error) { console.error( red( - `⛔️ ${file.path}: Oops! Ran into an issue while updating the ImportDeclaration from "@razorpay/blade" to "@razorpay/blade-rebranded".`, + `⛔️ ${file.path}: Oops! Ran into an issue while updating the ImportSpecifier from "paymentTheme"/"bankingTheme" to "bladeTheme".`, ), `\n${red(error.stack)}\n`, ); diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist-and-table.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist-and-table.ts new file mode 100644 index 00000000000..f4e2ae0c257 --- /dev/null +++ b/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist-and-table.ts @@ -0,0 +1,32 @@ +import { red } from './utils'; + +function migrateActionListAndTable({ root, j, file }): void { + // ActionList & Table components: Remove the `surfaceLevel` prop + // -> + // ->
+ try { + root + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => ['ActionList', 'Table'].includes(name), + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'surfaceLevel', + }, + }) + .remove(); + } catch (error) { + console.error( + red( + `⛔️ ${file.path}: Oops! Ran into an issue while removing the "surfaceLevel" prop from "ActionList"/"Table".`, + ), + `\n${red(error.stack)}\n`, + ); + } +} + +export default migrateActionListAndTable; diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist.ts deleted file mode 100644 index c0e6e7bc8d8..00000000000 --- a/packages/blade/codemods/brand-refresh/transformers/migrate-actionlist.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { red } from './utils'; - -function migrateActionListComponent({ root, j, file }): void { - // ActionList component: Remove surfaceLevel prop - // -> - try { - root - .find(j.JSXElement) - .filter((path) => path.value.openingElement.name.name === 'ActionList') - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'surfaceLevel') - .remove(); - } catch (error) { - console.error( - red( - `⛔️ ${file.path}: Oops! Ran into an issue while removing the "surfaceLevel" prop from "ActionList".`, - ), - `\n${red(error.stack)}\n`, - ); - } -} - -export default migrateActionListComponent; diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-amount.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-amount.ts index d7b0800ee51..d2193c41284 100644 --- a/packages/blade/codemods/brand-refresh/transformers/migrate-amount.ts +++ b/packages/blade/codemods/brand-refresh/transformers/migrate-amount.ts @@ -4,10 +4,13 @@ import { red, isExpression } from './utils'; function migrateAmountComponent({ root, j, file }): void { try { root - .find(j.JSXElement) - .filter((path) => - ['Amount', 'CardHeaderAmount'].includes(path.value.openingElement.name.name), - ) + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => ['Amount', 'CardHeaderAmount'].includes(name), + }, + }, + }) .replaceWith((path) => { const { node } = path; diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-badge.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-badge.ts index 847fd30fa06..6820da24da5 100644 --- a/packages/blade/codemods/brand-refresh/transformers/migrate-badge.ts +++ b/packages/blade/codemods/brand-refresh/transformers/migrate-badge.ts @@ -4,14 +4,18 @@ import { red } from './utils'; function migrateBadgeComponent({ root, j, file }): void { try { root - .find(j.JSXElement) - .filter( - (path) => - path.value.openingElement.name.name === 'Badge' || - path.value.openingElement.name.name === 'CardHeaderBadge', - ) - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'fontWeight') + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => ['Badge', 'CardHeaderBadge'].includes(name), + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'fontWeight', + }, + }) .remove(); } catch (error) { console.error( diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-card.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-card.ts index cdb6c29021b..e2e7baa1e0d 100644 --- a/packages/blade/codemods/brand-refresh/transformers/migrate-card.ts +++ b/packages/blade/codemods/brand-refresh/transformers/migrate-card.ts @@ -1,28 +1,35 @@ import { red } from './utils'; -// Card component Migration -// -> -function migrateCardComponent({ root, j, file }): void { +// Card components Migration +// -> +function migrateCardAndTable({ root, j, file }): void { try { root - .find(j.JSXElement) - .filter((path) => ['Card'].includes(path.value.openingElement.name.name)) - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'surfaceLevel') + .find(j.JSXElement, { + openingElement: { + name: { + name: 'Card', + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'surfaceLevel', + }, + }) .replaceWith((path) => { const { node } = path; const surfaceLevelMap = { - 2: 'surface.background.gray.intense', - 3: 'surface.background.gray.moderate', + 1: 'surface.background.subtle', + 2: 'surface.background.gray.moderate', + 3: 'surface.background.gray.intense', }; node.name.name = 'backgroundColor'; node.value = j.literal(surfaceLevelMap[node.value.expression.value]); - delete node.value.expression; - return node; }); } catch (error) { @@ -33,4 +40,4 @@ function migrateCardComponent({ root, j, file }): void { } } -export default migrateCardComponent; +export default migrateCardAndTable; diff --git a/packages/blade/codemods/brand-refresh/transformers/migrate-contrast-intent-color-props.ts b/packages/blade/codemods/brand-refresh/transformers/migrate-contrast-intent-color-props.ts index fb80ce75038..f08e0b5f36e 100644 --- a/packages/blade/codemods/brand-refresh/transformers/migrate-contrast-intent-color-props.ts +++ b/packages/blade/codemods/brand-refresh/transformers/migrate-contrast-intent-color-props.ts @@ -4,13 +4,17 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { // Break `contrast="high"` prop from Typography & ProgressBar Components try { root - .find(j.JSXElement) - .filter((path) => - ['Text', 'Title', 'Display', 'Heading', 'ProgressBar', 'CardHeaderText'].includes( - path.value.openingElement.name.name, - ), - ) - .find(j.JSXAttribute) // Find all props + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => + ['Text', 'Title', 'Display', 'Heading', 'ProgressBar', 'CardHeaderText'].includes( + name, + ), + }, + }, + }) + .find(j.JSXAttribute) .filter( (path, index, self) => ['Text', 'Title', 'Display', 'Heading', 'ProgressBar', 'CardHeaderText'].includes( @@ -36,19 +40,26 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { // Bade/Counter/IconButton/Alert Components: Change `contrast` prop to `emphasis` try { root - .find(j.JSXElement) - .filter((path) => - [ - 'Badge', - 'Counter', - 'IconButton', - 'Alert', - 'CardHeaderBadge', - 'CardHeaderCounter', - ].includes(path.value.openingElement.name.name), - ) - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'contrast') + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => + [ + 'Badge', + 'Counter', + 'IconButton', + 'Alert', + 'CardHeaderBadge', + 'CardHeaderCounter', + ].includes(name), + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'contrast', + }, + }) .replaceWith((path) => { path.node.name.name = 'emphasis'; @@ -85,13 +96,58 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { ); } + // Spinner: Change `contrast` prop to `color` + // -> + try { + root + .find(j.JSXElement, { + openingElement: { + name: { + name: 'Spinner', + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'contrast', + }, + }) + .replaceWith((path) => { + path.node.name.name = 'color'; + + const contrastToColorMap = { + high: 'white', + low: 'primary', + }; + + path.node.value.value = contrastToColorMap[path.node.value.value]; + + return path.node; + }); + } catch (error) { + console.error( + red( + `⛔️ ${file.path}: Oops! Ran into an issue while updating the "contrast" prop in Spinner.`, + ), + `\n${red(error.stack)}\n`, + ); + } + // Remove 'contrast' prop from the Skeleton Component try { root - .find(j.JSXElement) - .filter((path) => path.value.openingElement.name.name === 'Skeleton') - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'contrast') + .find(j.JSXElement, { + openingElement: { + name: { + name: 'Skeleton', + }, + }, + }) + .find(j.JSXAttribute, { + name: { + name: 'contrast', + }, + }) .remove(); } catch (error) { console.error( @@ -105,22 +161,26 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { // Remove deprecated 'intent'/'variant' props in favor of color try { root - .find(j.JSXElement) - .filter((path) => - [ - 'Alert', - 'Badge', - 'Counter', - 'Chip', - 'ChipGroup', - 'Indicator', - 'ProgressBar', - 'Amount', - 'CardHeaderBadge', - 'CardHeaderCounter', - 'CardHeaderAmount', - ].includes(path.value.openingElement.name.name), - ) + .find(j.JSXElement, { + openingElement: { + name: { + name: (name) => + [ + 'Alert', + 'Badge', + 'Counter', + 'Chip', + 'ChipGroup', + 'Indicator', + 'ProgressBar', + 'Amount', + 'CardHeaderBadge', + 'CardHeaderCounter', + 'CardHeaderAmount', + ].includes(name), + }, + }, + }) .replaceWith((path) => { const { node } = path; @@ -165,11 +225,14 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { return node; }) - .find(j.JSXAttribute) - .filter((path) => path.node.name.name === 'intent' || path.node.name.name === 'variant') + .find(j.JSXAttribute, { + name: { + name: (name) => name === 'intent' || name === 'variant', + }, + }) + // Remove duplicate intent/variant props .filter( (path, index, self) => - (path.node.name.name === 'intent' || path.node.name.name === 'variant') && index === self.findIndex((obj) => path.node.start === obj.node.start), ) .replaceWith((path) => { @@ -189,27 +252,38 @@ function migrateContrastIntentAndColorProps({ root, j, file }): void { ); } - // Change color="default" to color="primary" in Button/Link/Badge/Counter/Chip/ChipGroup + // Change color="default" to color="primary" in Button/Link/Badge/Counter/Chip/ChipGroup/Spinner //
+ +
+ ```