diff --git a/packages/forma-36-codemod/package.json b/packages/forma-36-codemod/package.json index 80e307c40b..93a0c646a6 100644 --- a/packages/forma-36-codemod/package.json +++ b/packages/forma-36-codemod/package.json @@ -1,7 +1,7 @@ { "name": "@contentful/f36-codemod", "description": "Forma 36 Codemod", - "version": "4.5.0", + "version": "5.0.0-alpha.0", "main": "bin/f36-codemod.mjs", "license": "MIT", "files": [ @@ -21,8 +21,7 @@ "devDependencies": { "@types/semver": "^7.3.12", "eslint": "^8.43.0", - "jest": "^29.3.1", - "@contentful/f36-icons": "^4.0.0" + "jest": "^29.3.1" }, "publishConfig": { "registry": "https://npm.pkg.github.com/", diff --git a/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.input.js b/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.input.js index a9de714e6a..0aa2488411 100644 --- a/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.input.js +++ b/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.input.js @@ -6,8 +6,11 @@ import { InfoCircleIcon, } from '@contentful/f36-icons'; -; -; +; +; ; ; -; +; + +const largeIcon = true; + diff --git a/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.output.js b/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.output.js index a76d9b39eb..ced6ad8b50 100644 --- a/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.output.js +++ b/packages/forma-36-codemod/transforms/__testfixtures__/v5/icons.output.js @@ -1,7 +1,10 @@ -import { CaretDownIcon, CaretUpIcon, XIcon, TrashSimpleIcon, InfoFillIcon } from "@contentful/f36-icons-alpha"; +import { CaretDownIcon, CaretUpIcon, XIcon, TrashSimpleIcon, InfoIcon } from "@contentful/f36-icons-alpha"; -; -; +; +; ; ; -; +; + +const largeIcon = true; + diff --git a/packages/forma-36-codemod/transforms/v5/icons.js b/packages/forma-36-codemod/transforms/v5/icons.js index edb1633c20..479a452c54 100644 --- a/packages/forma-36-codemod/transforms/v5/icons.js +++ b/packages/forma-36-codemod/transforms/v5/icons.js @@ -2,8 +2,15 @@ const { getComponentLocalName, changeComponentName, changeImport, + changeProperties, + deleteProperty, + updateTernaryValues, + updatePropertyValue, + getProperty, + hasProperty, } = require('../../utils'); const { shouldSkipUpdateImport, getImport } = require('../../utils/config'); +const { isConditionalExpression } = require('../../utils/updateTernaryValues'); // V4 icon name : V5 icon name const iconsMap = { @@ -134,6 +141,78 @@ module.exports = function (file, api) { components.forEach(({ localName, v4IconName }) => { const newComponentName = `${iconsMap[v4IconName]}Icon`; + source = changeProperties(j, source, { + componentName: localName, + fn(attributes) { + let modifiedAttributes = attributes; + + // Remove variant prop + modifiedAttributes = deleteProperty(modifiedAttributes, { + propertyName: 'variant', + file, + }); + + // Update size prop + if (hasProperty(modifiedAttributes, { propertyName: 'size' })) { + let size = getProperty(modifiedAttributes, { + propertyName: 'size', + }); + + // update conditional expressions + if (isConditionalExpression(size.value, j)) { + modifiedAttributes = updatePropertyValue(modifiedAttributes, { + j, + propertyName: 'size', + propertyValue: (value) => { + const valueMap = { + large: 'medium', + xlarge: 'medium', + }; + + const updatedValue = updateTernaryValues(value, { + j, + valueMap, + }); + + return updatedValue; + }, + }); + } + + size = getProperty(modifiedAttributes, { + propertyName: 'size', + }); + + // If ternary has same value for true and false, simplify + if (size.value.value === undefined) { + const matches = size.value.match(/\{'(\w+?)'\}/); + if (matches[1]) { + modifiedAttributes = updatePropertyValue(modifiedAttributes, { + j, + propertyName: 'size', + propertyValue: () => { + return j.literal(matches[1]); + }, + }); + } + } + size = getProperty(modifiedAttributes, { + propertyName: 'size', + }); + + // Remove size prop if value is 'large', 'xlarge' or 'medium' + if (['large', 'xlarge', 'medium'].includes(size.value.value)) { + modifiedAttributes = deleteProperty(modifiedAttributes, { + propertyName: 'size', + file, + }); + } + } + + return modifiedAttributes; + }, + }); + source = changeComponentName(j, source, { componentName: localName, outputComponentName: newComponentName, diff --git a/packages/forma-36-codemod/utils/updateTernaryValues.js b/packages/forma-36-codemod/utils/updateTernaryValues.js index 881018be2f..9b0a3474c3 100644 --- a/packages/forma-36-codemod/utils/updateTernaryValues.js +++ b/packages/forma-36-codemod/utils/updateTernaryValues.js @@ -32,9 +32,13 @@ function updateTernaryValues(value, { j, valueMap = {} }) { const consequent = getValueFor('consequent', commonArgs); const alternate = getValueFor('alternate', commonArgs); - j(expression).replaceWith( - j.conditionalExpression(expression.value.test, consequent, alternate), - ); + if (consequent.value === alternate.value) { + j(expression).replaceWith(j.literal(consequent.value)); + } else { + j(expression).replaceWith( + j.conditionalExpression(expression.value.test, consequent, alternate), + ); + } }) .toSource({ quote: 'single' }); }