Skip to content

Commit e7e93e5

Browse files
fix: split table hasAnimations fix with cli option (#848)
* fix: split table hasAnimations fix with cli option Signed-off-by: gitdallas <[email protected]> * fix/add tests for hasAnimations after cli split Signed-off-by: gitdallas <[email protected]> * change cli verbiate for hasanimations Signed-off-by: gitdallas <[email protected]> * Update packages/pf-codemods/index.js Co-authored-by: Eric Olkowski <[email protected]> --------- Signed-off-by: gitdallas <[email protected]> Co-authored-by: Eric Olkowski <[email protected]>
1 parent 0377978 commit e7e93e5

File tree

3 files changed

+80
-31
lines changed

3 files changed

+80
-31
lines changed

packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.test.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,30 @@ const valid = [
1818
];
1919

2020
const invalid = [
21+
// --- Without includeTable (default) ---
22+
{
23+
code: "import { Table } from '@patternfly/react-table'; <Table />",
24+
output: "import { Table } from '@patternfly/react-table'; <Table />",
25+
errors: [
26+
{
27+
message: "Consider adding hasAnimations prop to enable component animations.",
28+
type: "JSXOpeningElement"
29+
}
30+
]
31+
},
32+
// --- With includeTable: true ---
33+
{
34+
code: "import { Table } from '@patternfly/react-table'; <Table />",
35+
output: "import { Table } from '@patternfly/react-table'; <Table hasAnimations />",
36+
errors: [
37+
{
38+
message: "Consider adding hasAnimations prop to enable component animations.",
39+
type: "JSXOpeningElement"
40+
}
41+
],
42+
options: [{ includeTable: true }]
43+
},
44+
// --- Core components (unchanged) ---
2145
{
2246
code: "import { AlertGroup } from '@patternfly/react-core'; <AlertGroup />",
2347
output: "import { AlertGroup } from '@patternfly/react-core'; <AlertGroup hasAnimations />",
@@ -78,27 +102,11 @@ const invalid = [
78102
}
79103
]
80104
},
81-
{
82-
code: "import { Table } from '@patternfly/react-table'; <Table />",
83-
output: "import { Table } from '@patternfly/react-table'; <Table hasAnimations />",
84-
errors: [
85-
{
86-
message: "Consider adding hasAnimations prop to enable component animations.",
87-
type: "JSXOpeningElement"
88-
}
89-
]
90-
},
91105
{
92106
code: `import { AlertGroup, TreeView } from '@patternfly/react-core';
93-
<>
94-
<AlertGroup />
95-
<TreeView />
96-
</>`,
107+
<><AlertGroup /><TreeView /></>`,
97108
output: `import { AlertGroup, TreeView } from '@patternfly/react-core';
98-
<>
99-
<AlertGroup hasAnimations />
100-
<TreeView hasAnimations />
101-
</>`,
109+
<><AlertGroup hasAnimations /><TreeView hasAnimations /></>`,
102110
errors: [
103111
{
104112
message: "Consider adding hasAnimations prop to enable component animations.",

packages/eslint-plugin-pf-codemods/src/rules/v6/enableAnimations/enable-animations.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import { Rule } from "eslint";
22
import { JSXOpeningElement, JSXAttribute } from "estree-jsx";
3-
import { getFromPackage, checkMatchingJSXOpeningElement } from "../../helpers";
3+
import { getFromPackage, checkMatchingJSXOpeningElement, getNodeName } from "../../helpers";
44
import { getAttribute, getAttributeValue } from "../../helpers/JSXAttributes";
55

66
// Rule to add hasAnimations prop to components that support animations
77
module.exports = {
88
meta: { fixable: "code" },
99
create: function (context: Rule.RuleContext) {
10+
// Get options from context (set by CLI)
11+
const includeTable =
12+
(context.settings && context.settings.enableAnimationsIncludeTable) ||
13+
(context.options && context.options[0] && context.options[0].includeTable) ||
14+
false;
15+
1016
// Get imports from both react-core and react-table packages
1117
const { imports: coreImports } = getFromPackage(
1218
context,
@@ -34,6 +40,7 @@ module.exports = {
3440
targetComponents.includes(specifier.imported.name)
3541
);
3642

43+
// Always include Table imports for detection, but only add hasAnimations if includeTable is true
3744
const targetTableImports = tableImports.filter((specifier) =>
3845
tableComponents.includes(specifier.imported.name)
3946
);
@@ -68,20 +75,14 @@ module.exports = {
6875
return true;
6976
}
7077

71-
// Helper function to get component name from node
72-
function getComponentName(node: JSXOpeningElement): string | null {
73-
if (node.name.type === "JSXIdentifier") {
74-
return node.name.name;
75-
}
76-
return null;
77-
}
78+
7879

7980
return allTargetImports.length === 0
8081
? {}
8182
: {
8283
JSXOpeningElement(node: JSXOpeningElement) {
8384
if (checkMatchingJSXOpeningElement(node, allTargetImports)) {
84-
const componentName = getComponentName(node);
85+
const componentName = getNodeName(node);
8586

8687
// Special handling for DualListSelector - only add hasAnimations if isTree is true
8788
if (componentName === "DualListSelector" && !hasValidIsTreeProp(node)) {
@@ -98,10 +99,13 @@ module.exports = {
9899

99100
// Only add prop if it doesn't already exist
100101
if (!hasAnimationsAttribute) {
102+
// For Table, only apply the fix if includeTable is true
103+
const shouldApplyFix = componentName !== "Table" || includeTable;
104+
101105
context.report({
102106
node,
103107
message,
104-
fix(fixer) {
108+
fix: shouldApplyFix ? (fixer) => {
105109
// Insert hasAnimations at the end of existing attributes
106110
if (node.attributes.length > 0) {
107111
const lastAttribute = node.attributes[node.attributes.length - 1];
@@ -110,7 +114,7 @@ module.exports = {
110114
// No existing attributes, insert after component name
111115
return fixer.insertTextAfter(node.name, " hasAnimations");
112116
}
113-
},
117+
} : undefined,
114118
});
115119
}
116120
}

packages/pf-codemods/index.js

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,13 @@ async function getRulesToRemove(options) {
7373
const pfVersions = ["v6", "v5", "v4"];
7474
let selectedVersion = pfVersions.find((version) => options[version]);
7575

76-
if (!selectedVersion) {
76+
// If only enable-animations is being run, skip the PatternFly version prompt and default to v6 logic
77+
let skipVersionPrompt = false;
78+
if (options.only && options.only.split(",").length === 1 && options.only.includes("enable-animations")) {
79+
skipVersionPrompt = true;
80+
}
81+
82+
if (!selectedVersion && !skipVersionPrompt) {
7783
const inquirer = await import("inquirer");
7884
const answer = await inquirer.default.prompt([
7985
{
@@ -87,8 +93,9 @@ async function getRulesToRemove(options) {
8793
],
8894
},
8995
]);
90-
9196
selectedVersion = answer.version;
97+
} else if (skipVersionPrompt) {
98+
return [];
9299
}
93100

94101
return pfVersions.flatMap((version) =>
@@ -99,6 +106,33 @@ async function getRulesToRemove(options) {
99106
async function runCodemods(path, otherPaths, options) {
100107
const prefix = "@patternfly/pf-codemods/";
101108

109+
// Determine if enable-animations is being run
110+
let enableAnimationsRule = false;
111+
if (options.only) {
112+
enableAnimationsRule = options.only.split(",").includes("enable-animations");
113+
} else {
114+
enableAnimationsRule = Object.keys(configs.recommended.rules).includes(prefix + "enable-animations");
115+
}
116+
117+
let enableAnimationsIncludeTable = false;
118+
if (enableAnimationsRule) {
119+
const inquirer = await import("inquirer");
120+
const answer = await inquirer.default.prompt([
121+
{
122+
type: "list",
123+
name: "includeTable",
124+
message:
125+
"This will update several React Core components. Would you like to include Table? (Note: Opting into table animations may require structural updates in your codebase. See our release highlights for more information.)",
126+
choices: [
127+
{ name: "Just React Core components", value: false },
128+
{ name: "React Core and Table components", value: true },
129+
],
130+
default: 0,
131+
},
132+
]);
133+
enableAnimationsIncludeTable = answer.includeTable;
134+
}
135+
102136
if (options.only) {
103137
// Set rules to error like eslint likes
104138
configs.recommended.rules = options.only.split(",").reduce((acc, rule) => {
@@ -159,6 +193,9 @@ async function runCodemods(path, otherPaths, options) {
159193
{},
160194
...rulesArr.filter(filterFunc).map((r) => r.rule)
161195
),
196+
settings: enableAnimationsRule ? {
197+
enableAnimationsIncludeTable: enableAnimationsIncludeTable
198+
} : {}
162199
},
163200
});
164201
});

0 commit comments

Comments
 (0)