diff --git a/packages/eslint-plugin-pf-codemods/src/rules/helpers/JSXAttributes.ts b/packages/eslint-plugin-pf-codemods/src/rules/helpers/JSXAttributes.ts
index 99d85b62e..ea4fa8812 100644
--- a/packages/eslint-plugin-pf-codemods/src/rules/helpers/JSXAttributes.ts
+++ b/packages/eslint-plugin-pf-codemods/src/rules/helpers/JSXAttributes.ts
@@ -1,7 +1,17 @@
-import { JSXElement, JSXAttribute } from "estree-jsx";
+import { Rule, Scope } from "eslint";
+import {
+ JSXElement,
+ JSXAttribute,
+ JSXOpeningElement,
+ MemberExpression,
+} from "estree-jsx";
-export function getAttribute(node: JSXElement, attributeName: string) {
- return node.openingElement.attributes.find(
+export function getAttribute(
+ node: JSXElement | JSXOpeningElement,
+ attributeName: string
+) {
+ const nodeProperty = node.type === "JSXElement" ? node.openingElement : node;
+ return nodeProperty.attributes.find(
(attr) => attr.type === "JSXAttribute" && attr.name.name === attributeName
) as JSXAttribute | undefined;
}
@@ -15,3 +25,74 @@ export function getExpression(node?: JSXAttribute["value"]) {
return node.expression;
}
}
+
+function getMemberExpression(node: MemberExpression) {
+ if (!node) {
+ return;
+ }
+ const { object, property } = node;
+
+ return { object, property };
+}
+
+export function getVariableDeclaration(
+ name: string,
+ scope: Scope.Scope | null
+) {
+ while (scope !== null) {
+ const variable = scope.variables.find((v) => v.name === name);
+
+ if (variable) {
+ return variable;
+ }
+
+ scope = scope.upper;
+ }
+ return undefined;
+}
+
+export function getVariableValue(name: string, scope: Scope.Scope | null) {
+ const variableDeclaration = getVariableDeclaration(name, scope);
+
+ if (!variableDeclaration) {
+ return;
+ }
+
+ const variableInit = variableDeclaration.defs.length
+ ? variableDeclaration.defs[0].node.init
+ : undefined;
+
+ if (!variableInit) {
+ return;
+ }
+ if (variableInit.type === "Literal") {
+ return variableInit.value;
+ }
+ if (variableInit.type === "MemberExpression") {
+ return getMemberExpression(variableInit);
+ }
+}
+
+export function getAttributeValue(
+ context: Rule.RuleContext,
+ node?: JSXAttribute["value"]
+) {
+ if (!node) {
+ return;
+ }
+
+ const valueType = node.type;
+
+ if (valueType === "Literal") {
+ return node.value;
+ }
+
+ const isExpressionContainer = valueType === "JSXExpressionContainer";
+ if (isExpressionContainer && node.expression.type === "Identifier") {
+ const variableScope = context.getSourceCode().getScope(node);
+ return getVariableValue(node.expression.name, variableScope);
+ }
+ if (isExpressionContainer && node.expression.type === "MemberExpression") {
+ return getMemberExpression(node.expression);
+ }
+}
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/helpers/helpers.js b/packages/eslint-plugin-pf-codemods/src/rules/helpers/helpers.js
index a9c3bfb74..e6962c976 100644
--- a/packages/eslint-plugin-pf-codemods/src/rules/helpers/helpers.js
+++ b/packages/eslint-plugin-pf-codemods/src/rules/helpers/helpers.js
@@ -1,6 +1,7 @@
import { getFromPackage } from './getFromPackage';
import { pfPackageMatches } from './pfPackageMatches';
import { findAncestor } from './findAncestor';
+import { getVariableDeclaration } from './JSXAttributes';
const evk = require('eslint-visitor-keys');
@@ -492,7 +493,7 @@ export function addCallbackParam(
if (propProperties.type === 'ArrowFunctionExpression') {
propProperties.params = attribute.value?.expression?.params;
} else if (propProperties.type === 'Identifier') {
- const matchingVariable = findVariableDeclaration(
+ const matchingVariable = getVariableDeclaration(
propProperties.name,
context.getSourceCode().getScope(node)
);
@@ -763,16 +764,3 @@ export function getAllJSXElements(context) {
return jsxElements;
}
-
-export function findVariableDeclaration(name, scope) {
- while (scope !== null) {
- const variable = scope.variables.find((v) => v.name === name);
-
- if (variable) {
- return variable;
- }
-
- scope = scope.upper;
- }
- return undefined;
-}
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.md
new file mode 100644
index 000000000..f187e8aa0
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.md
@@ -0,0 +1,19 @@
+### drawerContent-replace-noBackground-colorVariant [(#10211)](https://github.com/patternfly/patternfly-react/pull/10211)
+
+The "no-background" value of the `colorVariant` prop on DrawerContent has been removed, and a new "primary" value has been added.
+
+Additionally, a new DrawerContentColorVariant enum has been added and should be used instead of the DrawerColorVariant enum. The fix when the DrawerColorVariant enum is being used will replace the `colorVariant` prop value with a string.
+
+#### Examples
+
+In:
+
+```jsx
+%inputExample%
+```
+
+Out:
+
+```jsx
+%outputExample%
+```
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.test.ts
new file mode 100644
index 000000000..560ab8eb0
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.test.ts
@@ -0,0 +1,87 @@
+const ruleTester = require("../../ruletester");
+import * as rule from "./drawerContent-replace-noBackground-colorVariant";
+
+ruleTester.run("drawerContent-replace-noBackground-colorVariant", rule, {
+ valid: [
+ {
+ code: ``,
+ },
+ {
+ code: ``,
+ },
+ {
+ code: `import { DrawerContent } from '@patternfly/react-core'; `,
+ },
+ {
+ code: `import { DrawerContent, DrawerContentColorVariant } from '@patternfly/react-core'; `,
+ },
+ {
+ code: `import { DrawerContent } from '@patternfly/react-core'; `,
+ },
+ {
+ code: `import { DrawerContent } from '@patternfly/react-core'; `,
+ },
+ ],
+ invalid: [
+ {
+ code: `import { DrawerContent } from '@patternfly/react-core'; `,
+ output: `import { DrawerContent } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: `The "no-background" value of the \`colorVariant\` prop on DrawerContent has been removed.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { DrawerContent } from '@patternfly/react-core'; const color = "no-background"; `,
+ output: `import { DrawerContent } from '@patternfly/react-core'; const color = "no-background"; `,
+ errors: [
+ {
+ message: `The "no-background" value of the \`colorVariant\` prop on DrawerContent has been removed.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; `,
+ output: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: `The DrawerContentColorVariant enum should be used instead of the DrawerColorVariant enum when passed to the DrawerContent component. This fix will replace the colorVariant prop value with a string.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; `,
+ output: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: `The "no-background" value of the \`colorVariant\` prop on DrawerContent has been removed.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; const color = DrawerColorVariant.default; `,
+ output: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; const color = DrawerColorVariant.default; `,
+ errors: [
+ {
+ message: `The DrawerContentColorVariant enum should be used instead of the DrawerColorVariant enum when passed to the DrawerContent component. This fix will replace the colorVariant prop value with a string.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ {
+ code: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; const color = DrawerColorVariant.noBackground; `,
+ output: `import { DrawerContent, DrawerColorVariant } from '@patternfly/react-core'; const color = DrawerColorVariant.noBackground; `,
+ errors: [
+ {
+ message: `The "no-background" value of the \`colorVariant\` prop on DrawerContent has been removed.`,
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ ],
+});
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts
new file mode 100644
index 000000000..d8af25ac4
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContent-replace-noBackground-colorVariant.ts
@@ -0,0 +1,94 @@
+import { Rule } from "eslint";
+import { JSXOpeningElement, MemberExpression } from "estree-jsx";
+import { getFromPackage, getAttribute, getAttributeValue } from "../../helpers";
+
+// https://github.com/patternfly/patternfly-react/pull/10211
+module.exports = {
+ meta: { fixable: "code" },
+ create: function (context: Rule.RuleContext) {
+ const { imports } = getFromPackage(context, "@patternfly/react-core");
+
+ const drawerContentImport = imports.find(
+ (specifier) => specifier.imported.name === "DrawerContent"
+ );
+ const drawerColorVariantEnumImport = imports.find(
+ (specifier) => specifier.imported.name === "DrawerColorVariant"
+ );
+ const validDrawerContentValues = ["default", "primary", "secondary"];
+
+ return !drawerContentImport
+ ? {}
+ : {
+ JSXOpeningElement(node: JSXOpeningElement) {
+ if (
+ !(
+ node.name.type === "JSXIdentifier" &&
+ drawerContentImport.local.name === node.name.name
+ )
+ ) {
+ return;
+ }
+ const colorVariantProp = getAttribute(node, "colorVariant");
+
+ if (!colorVariantProp) {
+ return;
+ }
+
+ const colorVariantValue = getAttributeValue(
+ context,
+ colorVariantProp.value
+ );
+ const drawerColorVariantLocalName =
+ drawerColorVariantEnumImport &&
+ drawerColorVariantEnumImport.local.name;
+ const hasPatternFlyEnum =
+ colorVariantValue.object &&
+ colorVariantValue.object.name === drawerColorVariantLocalName;
+ const hasNoBackgroundValue = colorVariantValue.property
+ ? hasPatternFlyEnum &&
+ colorVariantValue.property.name === "noBackground"
+ : colorVariantValue === "no-background";
+
+ if (!hasPatternFlyEnum && !hasNoBackgroundValue) {
+ return;
+ }
+
+ const message = hasNoBackgroundValue
+ ? 'The "no-background" value of the `colorVariant` prop on DrawerContent has been removed.'
+ : "The DrawerContentColorVariant enum should be used instead of the DrawerColorVariant enum when passed to the DrawerContent component. This fix will replace the colorVariant prop value with a string.";
+ context.report({
+ node,
+ message,
+ fix(fixer) {
+ const fixes = [];
+ if (hasNoBackgroundValue) {
+ fixes.push(fixer.replaceText(colorVariantProp, ""));
+ }
+
+ if (!hasNoBackgroundValue && hasPatternFlyEnum) {
+ const enumPropertyName = colorVariantValue.property.name;
+ fixes.push(
+ fixer.replaceText(
+ colorVariantProp,
+ validDrawerContentValues.includes(enumPropertyName)
+ ? `colorVariant="${colorVariantValue.property.name}"`
+ : ""
+ )
+ );
+ }
+
+ if (!hasNoBackgroundValue && !hasPatternFlyEnum) {
+ fixes.push(
+ fixer.replaceText(
+ colorVariantProp,
+ `colorVariant="${colorVariantValue}"`
+ )
+ );
+ }
+ return fixes;
+ },
+ });
+ },
+ };
+ },
+};
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantInput.tsx
new file mode 100644
index 000000000..6a0ec1fa2
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantInput.tsx
@@ -0,0 +1,15 @@
+import { DrawerContent, DrawerColorVariant } from "@patternfly/react-core";
+
+export const DrawerContentReplaceNoBackgroundColorVariantInput = () => {
+ const stringColor = "no-background";
+ const enumColor = DrawerColorVariant.default;
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+};
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantOutput.tsx
new file mode 100644
index 000000000..0e30848c3
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/drawerContentReplaceNoBackgroundColorVariant/drawerContentReplaceNoBackgroundColorVariantOutput.tsx
@@ -0,0 +1,15 @@
+import { DrawerContent, DrawerColorVariant } from "@patternfly/react-core";
+
+export const DrawerContentReplaceNoBackgroundColorVariantInput = () => {
+ const stringColor = "no-background";
+ const enumColor = DrawerColorVariant.default;
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+};