diff --git a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts index bdeee66e9..a44e2e16b 100644 --- a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts +++ b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts @@ -13,6 +13,7 @@ export const warningRules = [ "datePicker-warn-appendTo-default-value-changed", "datetimepicker-warn-helperText", "deprecatedSelect-warn-markupUpdated", + "drawerHead-warn-updated-markup", "emptyState-warn-change-structure", "formControls-updated-markup", "horizontalSubnav-warn-ariaLabel", diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.md new file mode 100644 index 000000000..31ccd3ff6 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.md @@ -0,0 +1,17 @@ +### drawer-remove-props [(#10036)](https://github.com/patternfly/patternfly-react/pull/10036) + +The `hasNoPadding` prop has been removed from DrawerHead. + +#### Examples + +In: + +```jsx +%inputExample% +``` + +Out: + +```jsx +%outputExample% +``` diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.test.ts new file mode 100644 index 000000000..ae44da474 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.test.ts @@ -0,0 +1,25 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./drawerHead-remove-hasNoPadding-prop"; + +ruleTester.run("drawerHead-remove-hasNoPadding-prop", rule, { + valid: [ + { + code: ``, + }, + { + code: `import { DrawerHead } from '@patternfly/react-core'; `, + }, + ], + invalid: [ + { + code: `import { DrawerHead } from '@patternfly/react-core'; `, + output: `import { DrawerHead } from '@patternfly/react-core'; `, + errors: [ + { + message: `The \`hasNoPadding\` prop has been removed from DrawerHead.`, + type: "JSXOpeningElement", + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.ts new file mode 100644 index 000000000..a6ba7d4ce --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHead-remove-hasNoPadding-prop.ts @@ -0,0 +1,14 @@ +import { renameProps } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/10036 +module.exports = { + meta: { fixable: "code" }, + create: renameProps({ + DrawerHead: { + hasNoPadding: { + newName: "", + message: "The `hasNoPadding` prop has been removed from DrawerHead.", + }, + }, + }), +}; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropInput.tsx new file mode 100644 index 000000000..1e6bbdc08 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropInput.tsx @@ -0,0 +1,3 @@ +import { DrawerHead } from "@patternfly/react-core"; + +export const DrawerRemovePropsInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropOutput.tsx new file mode 100644 index 000000000..38ef2ac7e --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadRemoveHasNoPaddingProp/drawerHeadRemoveHasNoPaddingPropOutput.tsx @@ -0,0 +1,3 @@ +import { DrawerHead } from "@patternfly/react-core"; + +export const DrawerRemovePropsInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.md new file mode 100644 index 000000000..300bc29d0 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.md @@ -0,0 +1,3 @@ +### drawerHead-warn-updated-markup [(#10036)](https://github.com/patternfly/patternfly-react/pull/10036) + +DrawerPanelBody is no longer rendered internally to DrawerHead. We recommend using these components independent of one another and to not pass DrawerPanelBody to DrawerHead. diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.test.ts new file mode 100644 index 000000000..7e9196ef9 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.test.ts @@ -0,0 +1,22 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./drawerHead-warn-updated-markup"; + +ruleTester.run("drawerHead-warn-updated-markup", rule, { + valid: [ + { + code: ``, + }, + ], + invalid: [ + { + code: `import { DrawerHead } from '@patternfly/react-core'; `, + output: `import { DrawerHead } from '@patternfly/react-core'; `, + errors: [ + { + message: `DrawerPanelBody is no longer rendered internally to DrawerHead. We recommend using these components independent of one another and to not pass DrawerPanelBody to DrawerHead.`, + type: "JSXOpeningElement", + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.ts new file mode 100644 index 000000000..a495c17ae --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHead-warn-updated-markup.ts @@ -0,0 +1,38 @@ +import { getFromPackage } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/10036 +module.exports = { + meta: {}, + create: function (context: { + report: (arg0: { + node: any; + message: string; + fix?(fixer: any): any; + }) => void; + }) { + const { imports } = getFromPackage(context, "@patternfly/react-core"); + + const componentImports = imports.filter( + (specifier: { imported: { name: string } }) => + specifier.imported.name === "DrawerHead" + ); + + return !componentImports.length + ? {} + : { + JSXOpeningElement(node: { name: { name: any }; attributes: any[] }) { + if ( + componentImports + .map((imp: { local: { name: any } }) => imp.local.name) + .includes(node.name.name) + ) { + context.report({ + node, + message: + "DrawerPanelBody is no longer rendered internally to DrawerHead. We recommend using these components independent of one another and to not pass DrawerPanelBody to DrawerHead.", + }); + } + }, + }; + }, +}; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupInput.tsx new file mode 100644 index 000000000..bd7edd4c8 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupInput.tsx @@ -0,0 +1,3 @@ +import { DrawerHead } from "@patternfly/react-core"; + +export const DrawerHeadWarnUpdatedMarkupInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupOutput.tsx new file mode 100644 index 000000000..bd7edd4c8 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerHeadWarnUpdatedMarkup/drawerHeadWarnUpdatedMarkupOutput.tsx @@ -0,0 +1,3 @@ +import { DrawerHead } from "@patternfly/react-core"; + +export const DrawerHeadWarnUpdatedMarkupInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.md new file mode 100644 index 000000000..d3a4833e9 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.md @@ -0,0 +1,19 @@ +### drawer-replace-colorVariant-light200 [(#10017)](https://github.com/patternfly/patternfly-react/pull/10017) [(#10036)](https://github.com/patternfly/patternfly-react/pull/10036) + +The "light-200" value for the `colorVariant` prop has been replaced with the "secondary" value for DrawerContent, DrawerPanelContent, and DrawerSection components. + +Additionally, the `light200` property for the DrawerColorVariant enum has been replaced with the `secondary` property. + +#### Examples + +In: + +```jsx +%inputExample% +``` + +Out: + +```jsx +%outputExample% +``` diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.test.ts new file mode 100644 index 000000000..13d937ecd --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.test.ts @@ -0,0 +1,77 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./drawer-replace-colorVariant-light200"; + +const affectedDrawerComponents = [ + "DrawerContent", + "DrawerPanelContent", + "DrawerSection", +]; +const validTests: { code: string }[] = []; +const invalidTests: { + code: string; + output: string; + errors: { message: string; type: string }[]; +}[] = []; +affectedDrawerComponents.forEach((component) => { + validTests.push({ + code: `<${component} colorVariant="light-200" />`, + }); + validTests.push({ + code: `<${component} colorVariant={DrawerColorVariant.light200} />`, + }); + validTests.push({ + code: `import { ${component} } from '@patternfly/react-core'; <${component} colorVariant="secondary" />`, + }); + validTests.push({ + code: `import { ${component}, DrawerColorVariant } from '@patternfly/react-core'; <${component} colorVariant={DrawerColorVariant.secondary} />`, + }); + + invalidTests.push({ + code: `import { ${component} } from '@patternfly/react-core'; <${component} colorVariant="light-200" />`, + output: `import { ${component} } from '@patternfly/react-core'; <${component} colorVariant="secondary" />`, + errors: [ + { + message: `The "light-200" value for the \`colorVariant\` prop has been replaced with the "secondary" value for ${component}.`, + type: "JSXOpeningElement", + }, + ], + }); +}); + +ruleTester.run("drawer-replace-colorVariant-light200", rule, { + valid: [ + { + code: ``, + }, + { + code: `import { DrawerColorVariant } from '@patternfly/react-core'; `, + }, + ...validTests, + ], + invalid: [ + { + code: `import { DrawerColorVariant } from '@patternfly/react-core'; `, + output: `import { DrawerColorVariant } from '@patternfly/react-core'; `, + errors: [ + { + message: + "The `light200` property for the DrawerColorVariant enum has been replaced with the `secondary` property.", + type: "MemberExpression", + }, + ], + }, + // Should work outside of JSXOpeningElements + { + code: `import { DrawerColorVariant } from '@patternfly/react-core'; const drawerVariant = DrawerColorVariant.light200;`, + output: `import { DrawerColorVariant } from '@patternfly/react-core'; const drawerVariant = DrawerColorVariant.secondary;`, + errors: [ + { + message: + "The `light200` property for the DrawerColorVariant enum has been replaced with the `secondary` property.", + type: "MemberExpression", + }, + ], + }, + ...invalidTests, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.ts new file mode 100644 index 000000000..98cc8a7fc --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawer-replace-colorVariant-light200.ts @@ -0,0 +1,84 @@ +import { getFromPackage, findVariableDeclaration } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/10017 +// https://github.com/patternfly/patternfly-react/pull/10036 +// Possible TODOs: check for variable references passed in as values +module.exports = { + meta: { fixable: "code" }, + create: function (context: { + getScope: () => { + upper: any; + variables: { defs: { node: { init: { value: string } } }[] }[]; + }; + report: (arg0: { + node: any; + message: string; + fix(fixer: any): any; + }) => void; + }) { + const { imports } = getFromPackage(context, "@patternfly/react-core"); + + const componentImports = imports.filter( + (specifier: { imported: { name: string } }) => + ["DrawerContent", "DrawerPanelContent", "DrawerSection"].includes( + specifier.imported.name + ) + ); + const colorVariantEnumImport = imports.filter( + (specifier: { imported: { name: string } }) => + specifier.imported.name === "DrawerColorVariant" + ); + + return !componentImports.length && !colorVariantEnumImport.length + ? {} + : { + MemberExpression(node: { + object: { name: string }; + property: { name: string }; + }) { + if ( + colorVariantEnumImport + .map((imp: { local: { name: any } }) => imp.local.name) + .includes(node.object.name) + ) { + if (node.property.name === "light200") { + context.report({ + node, + message: + "The `light200` property for the DrawerColorVariant enum has been replaced with the `secondary` property.", + fix(fixer: { + replaceText: (arg0: any, arg1: string) => any; + }) { + return fixer.replaceText(node.property, "secondary"); + }, + }); + } + } + }, + JSXOpeningElement(node: { name: { name: any }; attributes: any[] }) { + if ( + componentImports + .map((imp: { local: { name: any } }) => imp.local.name) + .includes(node.name.name) + ) { + const attribute = node.attributes.find( + (attr: { name: { name: string } }) => + attr.name?.name === "colorVariant" + ); + + if (attribute && attribute.value.value === "light-200") { + context.report({ + node, + message: `The "light-200" value for the \`colorVariant\` prop has been replaced with the "secondary" value for ${node.name.name}.`, + fix(fixer: { + replaceText: (arg0: any, arg1: string) => any; + }) { + return fixer.replaceText(attribute.value, '"secondary"'); + }, + }); + } + } + }, + }; + }, +}; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Input.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Input.tsx new file mode 100644 index 000000000..af5d1344a --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Input.tsx @@ -0,0 +1,8 @@ +import { DrawerContent, DrawerColorVariant } from "@patternfly/react-core"; + +export const DrawerReplaceColorVariantLight200Input = () => ( + <> + + + +); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Output.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Output.tsx new file mode 100644 index 000000000..d7aa46575 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerReplaceColorVariantLight200/drawerReplaceColorVariantLight200Output.tsx @@ -0,0 +1,8 @@ +import { DrawerContent, DrawerColorVariant } from "@patternfly/react-core"; + +export const DrawerReplaceColorVariantLight200Input = () => ( + <> + + + +);