diff --git a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
index 821807f9..98278099 100644
--- a/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
+++ b/packages/eslint-plugin-pf-codemods/src/ruleCustomization.ts
@@ -4,6 +4,7 @@
*/
export const betaRuleNames: string[] = [
"data-codemods-cleanup",
+ "enable-animations",
"kebabToggle-replace-with-menuToggle",
];
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.md b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.md
new file mode 100644
index 00000000..4b446912
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.md
@@ -0,0 +1,49 @@
+### enable-animations
+
+This rule adds the `hasAnimations` prop to PatternFly components that support animations. This is an optional enhancement that enables smoother transitions and animations in your UI components.
+
+The following components will have `hasAnimations` added:
+- AlertGroup
+- DualListSelector
+- FormFieldGroupExpandable
+- SearchInput
+- TreeView
+- Table (from @patternfly/react-table)
+
+This rule can only run using the `--only enable-animations` option.
+
+#### Examples
+
+In:
+
+```jsx
+import { AlertGroup, TreeView } from '@patternfly/react-core';
+import { Table } from '@patternfly/react-table';
+
+export const Example = () => (
+ <>
+
+ {/* alerts */}
+
+
+
+ >
+);
+```
+
+Out:
+
+```jsx
+import { AlertGroup, TreeView } from '@patternfly/react-core';
+import { Table } from '@patternfly/react-table';
+
+export const Example = () => (
+ <>
+
+ {/* alerts */}
+
+
+
+ >
+);
+```
\ No newline at end of file
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.test.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.test.ts
new file mode 100644
index 00000000..70aeaa0a
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.test.ts
@@ -0,0 +1,152 @@
+const ruleTester = require("../../ruletester");
+import * as rule from "./enable-animations";
+
+ruleTester.run("enable-animations", rule, {
+ valid: [
+ // No imports, should not trigger
+ {
+ code: ``,
+ },
+ // Already has hasAnimations prop
+ {
+ code: `import { AlertGroup } from '@patternfly/react-core'; `,
+ },
+ // Already has hasAnimations with value
+ {
+ code: `import { AlertGroup } from '@patternfly/react-core'; `,
+ },
+ // Table already has hasAnimations
+ {
+ code: `import { Table } from '@patternfly/react-table'; `,
+ },
+ // Non-target component should not be affected
+ {
+ code: `import { Button } from '@patternfly/react-core'; `,
+ },
+ ],
+ invalid: [
+ // AlertGroup without hasAnimations
+ {
+ code: `import { AlertGroup } from '@patternfly/react-core'; `,
+ output: `import { AlertGroup } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // DualListSelector without hasAnimations
+ {
+ code: `import { DualListSelector } from '@patternfly/react-core'; `,
+ output: `import { DualListSelector } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // TreeView without hasAnimations
+ {
+ code: `import { TreeView } from '@patternfly/react-core'; `,
+ output: `import { TreeView } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // SearchInput without hasAnimations
+ {
+ code: `import { SearchInput } from '@patternfly/react-core'; `,
+ output: `import { SearchInput } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // FormFieldGroupExpandable without hasAnimations
+ {
+ code: `import { FormFieldGroupExpandable } from '@patternfly/react-core'; `,
+ output: `import { FormFieldGroupExpandable } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // Table from react-table without hasAnimations
+ {
+ code: `import { Table } from '@patternfly/react-table'; `,
+ output: `import { Table } from '@patternfly/react-table'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // Multiple components in one file
+ {
+ code: `import { AlertGroup, TreeView } from '@patternfly/react-core';
+ <>
+
+
+ >`,
+ output: `import { AlertGroup, TreeView } from '@patternfly/react-core';
+ <>
+
+
+ >`,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // Component with existing props
+ {
+ code: `import { AlertGroup } from '@patternfly/react-core'; `,
+ output: `import { AlertGroup } from '@patternfly/react-core'; `,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ // Self-closing and regular tags
+ {
+ code: `import { DualListSelector } from '@patternfly/react-core';
+ <>
+
+
+ >`,
+ output: `import { DualListSelector } from '@patternfly/react-core';
+ <>
+
+
+ >`,
+ errors: [
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ {
+ message: "Consider adding hasAnimations prop to enable component animations.",
+ type: "JSXOpeningElement",
+ },
+ ],
+ },
+ ],
+});
\ No newline at end of file
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.ts b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.ts
new file mode 100644
index 00000000..40ff3a17
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.ts
@@ -0,0 +1,75 @@
+import { Rule } from "eslint";
+import { JSXOpeningElement } from "estree-jsx";
+import { getFromPackage, checkMatchingJSXOpeningElement } from "../../helpers";
+
+// Rule to add hasAnimations prop to components that support animations
+module.exports = {
+ meta: { fixable: "code" },
+ create: function (context: Rule.RuleContext) {
+ // Get imports from both react-core and react-table packages
+ const { imports: coreImports } = getFromPackage(
+ context,
+ "@patternfly/react-core"
+ );
+ const { imports: tableImports } = getFromPackage(
+ context,
+ "@patternfly/react-table"
+ );
+
+ // Components that support hasAnimations prop
+ const targetComponents = [
+ "FormFieldGroupExpandable",
+ "DualListSelector",
+ "TreeView",
+ "AlertGroup",
+ "SearchInput"
+ ];
+
+ // Table comes from react-table package
+ const tableComponents = ["Table"];
+
+ // Filter imports to only include target components
+ const targetCoreImports = coreImports.filter((specifier) =>
+ targetComponents.includes(specifier.imported.name)
+ );
+
+ const targetTableImports = tableImports.filter((specifier) =>
+ tableComponents.includes(specifier.imported.name)
+ );
+
+ const allTargetImports = [...targetCoreImports, ...targetTableImports];
+
+ const message =
+ "Consider adding hasAnimations prop to enable component animations.";
+
+ return allTargetImports.length === 0
+ ? {}
+ : {
+ JSXOpeningElement(node: JSXOpeningElement) {
+ if (checkMatchingJSXOpeningElement(node, allTargetImports)) {
+ // Check if hasAnimations prop already exists
+ const hasAnimationsAttribute = node.attributes.find(
+ (attr) =>
+ attr.type === "JSXAttribute" &&
+ attr.name.type === "JSXIdentifier" &&
+ attr.name.name === "hasAnimations"
+ );
+
+ // Only add prop if it doesn't already exist
+ if (!hasAnimationsAttribute) {
+ context.report({
+ node,
+ message,
+ fix(fixer) {
+ return fixer.insertTextAfter(
+ node.name,
+ " hasAnimations"
+ );
+ },
+ });
+ }
+ }
+ },
+ };
+ },
+};
\ No newline at end of file
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsInput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsInput.tsx
new file mode 100644
index 00000000..8b129e58
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsInput.tsx
@@ -0,0 +1,15 @@
+import { AlertGroup, TreeView, DualListSelector, SearchInput, FormFieldGroupExpandable } from "@patternfly/react-core";
+import { Table } from "@patternfly/react-table";
+
+export const EnableAnimationsInput = () => (
+ <>
+
+ {/* alerts */}
+
+
+
+
+
+
+ >
+);
\ No newline at end of file
diff --git a/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsOutput.tsx b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsOutput.tsx
new file mode 100644
index 00000000..3c111b5e
--- /dev/null
+++ b/packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enableAnimationsOutput.tsx
@@ -0,0 +1,15 @@
+import { AlertGroup, TreeView, DualListSelector, SearchInput, FormFieldGroupExpandable } from "@patternfly/react-core";
+import { Table } from "@patternfly/react-table";
+
+export const EnableAnimationsOutput = () => (
+ <>
+
+ {/* alerts */}
+
+
+
+
+
+
+ >
+);
\ No newline at end of file