diff --git a/packages/eslint-plugin-pf-codemods/index.js b/packages/eslint-plugin-pf-codemods/index.js
index f981627ac..053210a51 100644
--- a/packages/eslint-plugin-pf-codemods/index.js
+++ b/packages/eslint-plugin-pf-codemods/index.js
@@ -33,6 +33,7 @@ const rules = {
"tab-title-text": require('./lib/rules/tab-title-text'),
"table-removed-transforms": require('./lib/rules/table-removed-transforms'),
"select-rename-checkbox": require('./lib/rules/select-rename-checkbox'),
+ "use-page-header-tools": require('./lib/rules/use-page-header-tools'),
};
module.exports = {
diff --git a/packages/eslint-plugin-pf-codemods/lib/rules/use-page-header-tools.js b/packages/eslint-plugin-pf-codemods/lib/rules/use-page-header-tools.js
new file mode 100644
index 000000000..3f6e87324
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/lib/rules/use-page-header-tools.js
@@ -0,0 +1,81 @@
+const { getPackageImports } = require('../helpers');
+
+const renames = {
+ 'Toolbar': 'PageHeaderTools',
+ 'ToolbarGroup': 'PageHeaderToolsGroup',
+ 'ToolbarItem': 'PageHeaderToolsItem'
+};
+
+const propMap = {
+ toolbar: 'headerTools',
+ avatar: ''
+}
+
+module.exports = {
+ create: function(context) {
+ const imports = getPackageImports(context, '@patternfly/react-core')
+ .filter(specifier => Object.keys(renames).includes(specifier.imported.name));
+ const pageHeaderImports = getPackageImports(context, '@patternfly/react-core')
+ .filter(specifier => specifier.imported.name === 'PageHeader');
+
+ return !imports && !pageHeaderImports ? {} : {
+ ImportSpecifier(node) {
+ if (node.parent.source.value === '@patternfly/react-core'
+ //renamed imports would go here ?
+ ) {
+ context.report({
+ node,
+ message: `${node.name} has been renamed ${renames[node.name]}`,
+ fix(fixer) {
+ return fixer.replaceText(node, `${renames[node.name]}`);
+ }
+ });
+ }
+ },
+ // For Toolbar -> PageHeaderTools, ToolbarGroup -> PageHeaderToolsGroup, and ToolbarItem -> PageHeaderToolsItem
+ JSXIdentifier(node) {
+
+ // For PageHeader prop renames
+ const imp = pageHeaderImports
+ .filter(imp => imp.imported.name === 'PageHeader')
+ .find(imp => imp.local.name === node.name.name);
+ if (imp) {
+ const alreadyFixed = node.attributes
+ .map(attr => attr.name.name)
+ .includes('data-codemods');
+ if (!alreadyFixed) {
+ const isOpeningPageHeader = node.parent.type === 'JSXIdentifier' && node.name === 'PageHeader';
+ node.attributes
+ .filter(node => propMap.hasOwnProperty(node.name.name))
+ .forEach(attribute => {
+ const newName = propMap[attribute.name.name];
+ context.report({
+ node,
+ message: `${node.name.name} has replaced ${attribute.name.name} prop with ${newName}`,
+ fix(fixer) {
+ // Delete entire prop if newName is empty
+ return fixer.replaceText(
+ !newName ? attribute : attribute.name + `${isOpeningPageHeader ? ' data-codemods="true" ' : ''}`,
+ newName
+ );
+ }
+ })
+ });
+ }
+ }
+ },
+ // For Toolbar -> PageHeaderTools, ToolbarGroup -> PageHeaderToolsGroup, and ToolbarItem -> PageHeaderToolsItem
+ JSXIdentifier(node) {
+ if (imports.map(imp => imp.local.name).includes(node.name)) {
+ context.report({
+ node,
+ message: `${node.name} renamed to ${renames[node.name]}`,
+ fix(fixer) {
+ return fixer.replaceText(node, `${renames[node.name]}`);
+ }
+ });
+ }
+ }
+ };
+ }
+};
\ No newline at end of file
diff --git a/packages/eslint-plugin-pf-codemods/test/rules/use-page-header-tools.js b/packages/eslint-plugin-pf-codemods/test/rules/use-page-header-tools.js
new file mode 100644
index 000000000..b7c732391
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/test/rules/use-page-header-tools.js
@@ -0,0 +1,102 @@
+const ruleTester = require("./ruletester");
+const rule = require("../../lib/rules/use-page-header-tools");
+
+ruleTester.run("card-rename-components", rule, {
+ valid: [
+ {
+ code: `import { Page, PageHeader, PageHeaderTools, PageHeaderToolsGroup, PageHeaderToolsItem } from '@patternfly/react-core';
+
+
+
+
+
+
+ }
+ />
+`
+ },
+ {
+ // no @patternfly import
+ code: `
+
+
+
+
+
+
+}
+/>
+`
+ }
+ ],
+ invalid: [
+ {
+ code: `import { Page, PageHeader, Toolbar, ToolbarGroup, ToolbarItem } from '@patternfly/react-core';
+
+
+
+
+
+
+ }
+ />
+`,
+ output: `import { Page, PageHeader, PageHeaderTools, PageHeaderToolsGroup, PageHeaderToolsItem } from '@patternfly/react-core';
+
+
+
+
+
+
+ }
+ />
+`,
+ errors: [
+ {
+ message: 'add missing imports CardTitle, CardHeaderMain from @patternfly/react-core',
+ type: 'ImportSpecifier'
+ },
+ {
+ message: "PageHeader has replaced toolbar prop with headerTools",
+ type: "JSXIdentifier"
+ },
+ {
+ message: "Toolbar renamed to PageHeaderTools",
+ type: "JSXIdentifier"
+ },
+ {
+ message: "ToolbarGroup renamed to PageHeaderToolsGroup",
+ type: "JSXIdentifier"
+ },
+ {
+ message: "ToolbarItem renamed to PageHeaderToolsItem",
+ type: "JSXIdentifier"
+ },
+ {
+ message: "ToolbarGroup renamed to PageHeaderToolsGroup",
+ type: "JSXIdentifier"
+ },
+ {
+ message: "Toolbar renamed to PageHeaderTools",
+ type: "JSXIdentifier"
+ },
+ ]
+ },
+ {
+ code: `import { Avatar, PageHeader } from '@patternfly/react-core';
+ } />`,
+ output: `import { Card, PageHeader, PageHeaderTools } from '@patternfly/react-core';
+ } />`,
+ errors: [
+ {
+ message: "avatar prop has been removed for PageHeader",
+ type: "JSXIdentifier"
+ },
+ ]
+ }
+ ]
+});