diff --git a/packages/eslint-plugin-pf-codemods/lib/rules/v5/tableActionsColumn-removed-tooltipProp.js b/packages/eslint-plugin-pf-codemods/lib/rules/v5/tableActionsColumn-removed-tooltipProp.js new file mode 100644 index 000000000..b78365069 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/lib/rules/v5/tableActionsColumn-removed-tooltipProp.js @@ -0,0 +1,131 @@ +const { getFromPackage, findVariableDeclaration } = require("../../helpers"); + +// https://github.com/patternfly/patternfly-react/pull/9382 +module.exports = { + meta: { fixable: "code" }, + create: function (context) { + const { imports } = getFromPackage(context, "@patternfly/react-table"); + + const actionsColumnImport = imports.find( + (specifier) => specifier.imported.name === "ActionsColumn" + ); + + return !actionsColumnImport + ? {} + : { + JSXOpeningElement(node) { + if (actionsColumnImport.local?.name !== node.name?.name) { + return; + } + + const itemsProp = node.attributes.find( + (attr) => attr.name?.name === "items" + ); + const getItemsFromVariable = (variableDeclaration) => { + const variableNodeProperty = variableDeclaration?.defs?.[0]?.node; + + if ( + variableNodeProperty?.init?.type === "ArrowFunctionExpression" + ) { + return variableNodeProperty.init.body?.elements; + } + + if (variableNodeProperty?.init?.type === "ArrayExpression") { + return variableNodeProperty.init.elements; + } + }; + + let itemsPropValue; + if (itemsProp.value.expression?.type === "Identifier") { + const currentScope = context.getSourceCode().getScope(node); + const itemsPropDeclaration = findVariableDeclaration( + itemsProp.value.expression.name, + currentScope + ); + itemsPropValue = getItemsFromVariable(itemsPropDeclaration); + } else { + itemsPropValue = itemsProp.value.expression?.elements; + } + + const getItemsWithTooltipProp = (itemsArray) => + itemsArray?.filter((element) => + element?.properties?.find( + (property) => property?.key?.name === "tooltip" + ) + ); + + const itemsWithTooltip = getItemsWithTooltipProp(itemsPropValue); + + if (itemsWithTooltip?.length) { + const getTooltipPropValue = (tooltipProp) => { + const { type, value, name } = tooltipProp.value; + + if (type === "Literal") { + return `"${value}"`; + } + + if (type === "Identifier") { + return `${name}`; + } + + if (type === "JSXElement") { + return context.getSourceCode().getText(tooltipProp.value); + } + }; + + itemsWithTooltip.forEach((itemWithTooltip) => { + context.report({ + node, + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + fix(fixer) { + const fixes = []; + const tooltipProperty = itemWithTooltip.properties.find( + (property) => property.key.name === "tooltip" + ); + const tooltipPropValue = + getTooltipPropValue(tooltipProperty); + const tooltipPropsProperty = + itemWithTooltip.properties.find( + (property) => property.key.name === "tooltipProps" + ); + const tooltipPropsContent = + tooltipPropsProperty?.value?.properties?.find( + (prop) => prop?.key?.name === "content" + ); + + if (tooltipPropsProperty && !tooltipPropsContent) { + fixes.push( + fixer.insertTextBefore( + tooltipPropsProperty.value.properties[0], + `content: ${tooltipPropValue}, ` + ) + ); + + const tooltipPropertyHasComma = + context.getSourceCode().getTokenAfter(tooltipProperty) + .value === ","; + const { range } = tooltipProperty; + fixes.push( + fixer.removeRange([ + range[0], + tooltipPropertyHasComma ? range[1] + 1 : range[1], + ]) + ); + } else if (!tooltipPropsProperty && tooltipProperty) { + fixes.push( + fixer.replaceText( + tooltipProperty, + `tooltipProps: { content: ${tooltipPropValue} }` + ) + ); + } + + return fixes; + }, + }); + }); + } + }, + }; + }, +}; diff --git a/packages/eslint-plugin-pf-codemods/test/rules/v5/tableActionsColumn-removed-tooltipProp.js b/packages/eslint-plugin-pf-codemods/test/rules/v5/tableActionsColumn-removed-tooltipProp.js new file mode 100644 index 000000000..5655e3385 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/test/rules/v5/tableActionsColumn-removed-tooltipProp.js @@ -0,0 +1,82 @@ +const ruleTester = require("../../ruletester"); +const rule = require("../../../lib/rules/v5/tableActionsColumn-removed-tooltipProp"); + +ruleTester.run("tableActionsColumn-removed-tooltipProp", rule, { + valid: [ + { + code: `import { ActionsColumn } from '@patternfly/react-table'; `, + }, + // No @patternfly/react-table import + { + code: ``, + }, + ], + invalid: [ + // No existing tooltipProps prop + { + code: `import { ActionsColumn } from '@patternfly/react-table'; `, + output: `import { ActionsColumn } from '@patternfly/react-table'; `, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + // Pre-existing tooltipProps prop + { + code: `import { ActionsColumn } from '@patternfly/react-table'; `, + output: `import { ActionsColumn } from '@patternfly/react-table'; `, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + // Variable identifier + { + code: `import { ActionsColumn } from '@patternfly/react-table'; const actionItems = [{tooltip: "test"}]; `, + output: `import { ActionsColumn } from '@patternfly/react-table'; const actionItems = [{tooltipProps: { content: "test" }}]; `, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + // Arrow function identifier + { + code: `import { ActionsColumn } from '@patternfly/react-table'; const actionItems = () => [{tooltip: "test"}]; `, + output: `import { ActionsColumn } from '@patternfly/react-table'; const actionItems = () => [{tooltipProps: { content: "test" }}]; `, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + // Variable for tooltip prop value + { + code: `import { ActionsColumn } from '@patternfly/react-table'; const tooltipContet = 'test'; `, + output: `import { ActionsColumn } from '@patternfly/react-table'; const tooltipContet = 'test'; `, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + // JSXElement for tooltip prop value + { + code: `import { ActionsColumn } from '@patternfly/react-table'; Test}]} />`, + output: `import { ActionsColumn } from '@patternfly/react-table'; Test }}]} />`, + errors: [ + { + message: `The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface.`, + type: "JSXOpeningElement", + }, + ], + }, + ], +}); diff --git a/packages/pf-codemods/README.md b/packages/pf-codemods/README.md index cbcf7b92e..5db5ffcda 100644 --- a/packages/pf-codemods/README.md +++ b/packages/pf-codemods/README.md @@ -2855,6 +2855,39 @@ Table and TableComposable's `ActionsColumn` has been updated to use our new impl `collapseAllAriaLabel` on `ThExpandType` has been updated to a `string` from `''`. Workarounds casting this property to an empty string are no longer required. +### tableActionsColumn-removed-tooltipProp [(#9382)](https://github.com/patternfly/patternfly-react/pull/9382) + +The "tooltip" property has been removed from ActionsColumn's "item" prop interface. Instead a "content" property should be passed into the "tooltipProps" property of the "items" interface. + +#### Examples + +In: + +```jsx + + + +const actionItems = [{tooltip: "test"}]; + + +const actionItems = () => [{tooltip: "test"}]; + +``` + +Out: + +```jsx + + + +const actionItems = [{tooltipProps: { content: "test" }}]; + + +const actionItems = () => [{tooltipProps: { content: "test" }}]; + +``` + + ### tableComposable-remove-hasSelectableRowCaption [(#8352)](https://github.com/patternfly/patternfly-react/pull/8352) We've removed the deprecated `hasSelectableRowCaption` prop.