From 1f246aa5673f2610715776df14408ad3eb573d6e Mon Sep 17 00:00:00 2001 From: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:38:23 -0500 Subject: [PATCH] feat(Tabs): updated props and markup (#578) * feat(Tabs): updated props and markup * Added rule for isSecondary renamed to isSubtab * Added rule to warn about scroll button markup change --- .../src/ruleCustomization.ts | 1 + .../tabs-renamed-isSecondary-prop.md | 17 +++++++ .../tabs-renamed-isSecondary-prop.test.ts | 25 ++++++++++ .../tabs-renamed-isSecondary-prop.ts | 15 ++++++ .../tabsRenamedIsSecondaryPropInput.tsx | 3 ++ .../tabsRenamedIsSecondaryPropOutput.tsx | 3 ++ .../tabs-replace-variant-light300.md | 17 +++++++ .../tabs-replace-variant-light300.test.ts | 25 ++++++++++ .../tabs-replace-variant-light300.ts | 49 +++++++++++++++++++ .../tabsReplaceVariantLight300Input.tsx | 5 ++ .../tabsReplaceVariantLight300Output.tsx | 5 ++ .../v6/tabsUpdateMarkup/tabs-update-markup.md | 7 +++ .../tabs-update-markup.test.ts | 22 +++++++++ .../v6/tabsUpdateMarkup/tabs-update-markup.ts | 44 +++++++++++++++++ .../tabsUpdateMarkupInput.tsx | 3 ++ .../tabsUpdateMarkupOutput.tsx | 3 ++ 16 files changed, 244 insertions(+) create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.md create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.test.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropInput.tsx create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropOutput.tsx create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.md create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.test.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Input.tsx create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Output.tsx create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.md create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.test.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.ts create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupInput.tsx create mode 100644 packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupOutput.tsx diff --git a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts index 43be75691..d72b510ff 100644 --- a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts +++ b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts @@ -29,6 +29,7 @@ export const warningRules = [ "simpleFileUpload-warn-changes", "table-warn-actionsColumn", "table-warn-thExpandType", + "tabs-update-markup", "tabs-warn-children-type-changed", "tooltip-warn-triggerRef-may-be-required", "wizard-warn-button-order", diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.md new file mode 100644 index 000000000..c15f35bb0 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.md @@ -0,0 +1,17 @@ +### tabs-renamed-isSecondary-prop [(#10044)](https://github.com/patternfly/patternfly-react/pull/10044) + +The `isSecondary` prop for Tabs has been renamed to \`isSubtab\`. + +#### Examples + +In: + +```jsx +%inputExample% +``` + +Out: + +```jsx +%outputExample% +``` diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.test.ts new file mode 100644 index 000000000..2c89e6b5c --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.test.ts @@ -0,0 +1,25 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./tabs-renamed-isSecondary-prop"; + +ruleTester.run("tabs-renamed-isSecondary-prop", rule, { + valid: [ + { + code: ``, + }, + { + code: `import { Tabs } from '@patternfly/react-core'; `, + }, + ], + invalid: [ + { + code: `import { Tabs } from '@patternfly/react-core'; `, + output: `import { Tabs } from '@patternfly/react-core'; `, + errors: [ + { + message: `The \`isSecondary\` prop for Tabs has been renamed to \`isSubtab\`.`, + type: "JSXOpeningElement", + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.ts new file mode 100644 index 000000000..93e0f90eb --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabs-renamed-isSecondary-prop.ts @@ -0,0 +1,15 @@ +import { renameProps } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/10044 +module.exports = { + meta: { fixable: "code" }, + create: renameProps({ + Tabs: { + isSecondary: { + newName: "isSubtab", + message: + "The `isSecondary` prop for Tabs has been renamed to `isSubtab`.", + }, + }, + }), +}; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropInput.tsx new file mode 100644 index 000000000..0b7b8902e --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropInput.tsx @@ -0,0 +1,3 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsRenamedIsSecondaryPropInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropOutput.tsx new file mode 100644 index 000000000..c3ba24df8 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsRenamedIsSecondaryProp/tabsRenamedIsSecondaryPropOutput.tsx @@ -0,0 +1,3 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsRenamedIsSecondaryPropInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.md new file mode 100644 index 000000000..b025c4f09 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.md @@ -0,0 +1,17 @@ +### tabs-replace-variant-light300 [(#9930)](https://github.com/patternfly/patternfly-react/pull/9930) [(#10044)](https://github.com/patternfly/patternfly-react/pull/10044) + +The "light300" value for the `variant` prop on Tabs has been replaced with the "secondary" value. + +#### Examples + +In: + +```jsx +%inputExample% +``` + +Out: + +```jsx +%outputExample% +``` diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.test.ts new file mode 100644 index 000000000..aa170fba9 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.test.ts @@ -0,0 +1,25 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./tabs-replace-variant-light300"; + +ruleTester.run("tabs-replace-variant-light300", rule, { + valid: [ + { + code: ``, + }, + { + code: `import { Tabs } from '@patternfly/react-core'; `, + }, + ], + invalid: [ + { + code: `import { Tabs } from '@patternfly/react-core'; `, + output: `import { Tabs } from '@patternfly/react-core'; `, + errors: [ + { + message: `The "light300" value for the \`variant\` prop on Tabs has been replaced with the "secondary" value.`, + type: "JSXOpeningElement", + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.ts new file mode 100644 index 000000000..6b522cddb --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabs-replace-variant-light300.ts @@ -0,0 +1,49 @@ +import { getFromPackage } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/9930 +// https://github.com/patternfly/patternfly-react/pull/10044 +module.exports = { + meta: { fixable: "code" }, + create: function (context: { + report: (arg0: { + node: any; + message: string; + fix(fixer: any): any; + }) => void; + }) { + const { imports, exports } = getFromPackage( + context, + "@patternfly/react-core" + ); + + const tabsImport = imports.find( + (specifier: { imported: { name: string }; local: { name: string } }) => + specifier.imported.name === "Tabs" + ); + + return !tabsImport + ? {} + : { + JSXOpeningElement(node: { name: { name: any }; attributes: any[] }) { + if (node.name.name === tabsImport.local.name) { + const attribute = node.attributes.find( + (attr: { name: { name: string }; value: { value: string } }) => + attr.name?.name === "variant" + ); + if (attribute && attribute.value.value === "light300") { + context.report({ + node, + message: + 'The "light300" value for the `variant` prop on Tabs has been replaced with the "secondary" value.', + 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/tabsReplaceVariantLight300/tabsReplaceVariantLight300Input.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Input.tsx new file mode 100644 index 000000000..9ad7b53b7 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Input.tsx @@ -0,0 +1,5 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsReplaceVariantLight300Input = () => ( + +); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Output.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Output.tsx new file mode 100644 index 000000000..49047c604 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsReplaceVariantLight300/tabsReplaceVariantLight300Output.tsx @@ -0,0 +1,5 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsReplaceVariantLight300Input = () => ( + +); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.md new file mode 100644 index 000000000..ba01c2faf --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.md @@ -0,0 +1,7 @@ +### tabs-update-markup [(#10044)](https://github.com/patternfly/patternfly-react/pull/10044) + +The markup for the Tabs scroll buttons have been updated in the following ways: + +- Replaced the native `button` HTML element internally with our Button components +- Added a wrapper `div` around them +- Removed styling when the `isSubtab` (previously `isSecondary`) prop is true diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.test.ts new file mode 100644 index 000000000..ef50f5fe3 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.test.ts @@ -0,0 +1,22 @@ +const ruleTester = require("../../ruletester"); +import * as rule from "./tabs-update-markup"; + +ruleTester.run("tabs-update-markup", rule, { + valid: [ + { + code: `import { Tabs } from 'someOtherPackage';`, + }, + ], + invalid: [ + { + code: `import { Tabs } from '@patternfly/react-core';`, + output: `import { Tabs } from '@patternfly/react-core';`, + errors: [ + { + message: `The markup for the Tabs scroll buttons has been updated. They are now rendered with a div wrapper, use our Button component, and no longer have adjusted styling when the \`isSubtab\` prop is true.`, + type: "ImportDeclaration", + }, + ], + }, + ], +}); diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.ts new file mode 100644 index 000000000..42b168982 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabs-update-markup.ts @@ -0,0 +1,44 @@ +import { getFromPackage } from "../../helpers"; + +// https://github.com/patternfly/patternfly-react/pull/10044 +module.exports = { + meta: { fixable: "code" }, + create: function (context: { + report: (arg0: { + node: any; + message: string; + fix?(fixer: any): any; + }) => void; + }) { + const { imports, exports } = getFromPackage( + context, + "@patternfly/react-core" + ); + + const tabsImport = imports.find( + (specifier: { imported: { name: string } }) => + specifier.imported.name === "Tabs" + ); + + return !tabsImport + ? {} + : { + ImportDeclaration(node: { + specifiers: { imported: { name: string } }[]; + }) { + if ( + node.specifiers.find( + (specifier: { imported: { name: string } }) => + specifier.imported.name === tabsImport.imported.name + ) + ) { + context.report({ + node, + message: + "The markup for the Tabs scroll buttons has been updated. They are now rendered with a div wrapper, use our Button component, and no longer have adjusted styling when the `isSubtab` prop is true.", + }); + } + }, + }; + }, +}; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupInput.tsx new file mode 100644 index 000000000..bced10252 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupInput.tsx @@ -0,0 +1,3 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsUpdateMarkupInput = () => ; diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupOutput.tsx new file mode 100644 index 000000000..bced10252 --- /dev/null +++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/tabsUpdateMarkup/tabsUpdateMarkupOutput.tsx @@ -0,0 +1,3 @@ +import { Tabs } from "@patternfly/react-core"; + +export const TabsUpdateMarkupInput = () => ;