Skip to content

Commit 2f99a47

Browse files
authored
feat: codemod to enable v12 tile default icons (#18453)
* feat: codemod to enable v12 tile default icons * fix: test cases * fix: formatting issues * fix: formatting issues * fix: formatting issues * fix: formatting issues * fix: formatting issues
1 parent fa1abc1 commit 2f99a47

File tree

7 files changed

+551
-0
lines changed

7 files changed

+551
-0
lines changed

packages/upgrade/src/upgrades.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,64 @@ export const upgrades = [
456456
});
457457
},
458458
},
459+
{
460+
name: 'enable-v12-tile-default-icons',
461+
description: `
462+
Wrap Tile and TileGroup components with FeatureFlags enableV12TileDefaultIcons
463+
464+
Transforms:
465+
1. TileGroup with Tiles:
466+
<TileGroup>
467+
<Tile>...</Tile>
468+
</TileGroup>
469+
470+
Into:
471+
<FeatureFlags enableV12TileDefaultIcons>
472+
<TileGroup>
473+
<Tile>...</Tile>
474+
</TileGroup>
475+
</FeatureFlags>
476+
477+
2. Standalone Tile:
478+
<Tile>...</Tile>
479+
480+
Into:
481+
<FeatureFlags enableV12TileDefaultIcons>
482+
<Tile>...</Tile>
483+
</FeatureFlags>
484+
`,
485+
migrate: async (options) => {
486+
const transform = path.join(
487+
TRANSFORM_DIR,
488+
'enable-v12-tile-default-icons.js'
489+
);
490+
const paths =
491+
Array.isArray(options.paths) && options.paths.length > 0
492+
? options.paths
493+
: await glob(['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx'], {
494+
cwd: options.workspaceDir,
495+
ignore: [
496+
'**/es/**',
497+
'**/lib/**',
498+
'**/umd/**',
499+
'**/node_modules/**',
500+
'**/storybook-static/**',
501+
'**/dist/**',
502+
'**/build/**',
503+
'**/*.d.ts',
504+
'**/coverage/**',
505+
],
506+
});
507+
508+
await run({
509+
dry: !options.write,
510+
transform,
511+
paths,
512+
verbose: options.verbose,
513+
parser: 'tsx', // Enable parsing of TSX files
514+
});
515+
},
516+
},
459517
{
460518
name: 'ibm-products-update-http-errors',
461519
description:
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React from 'react';
2+
import { TileGroup, Tile, Stack } from '@carbon/react';
3+
import { FeatureFlags } from '@carbon/feature-flags';
4+
5+
function TestComponent() {
6+
return (
7+
<div>
8+
{/* Case 1: Unwrapped TileGroup */}
9+
<TileGroup legend="TestGroup" name="test">
10+
<Tile>Option 1</Tile>
11+
<Tile>Option 2</Tile>
12+
</TileGroup>
13+
14+
{/* Wrapped standalone missing flag prop */}
15+
<FeatureFlags>
16+
<TileGroup legend="Missing Attribute" name="wrapped">
17+
<Tile>Already Wrapped Option 1</Tile>
18+
<Tile>Already Wrapped Option 2</Tile>
19+
</TileGroup>
20+
</FeatureFlags>
21+
22+
{/* Case 3: Already wrapped with other attributes */}
23+
<FeatureFlags enable-v12-tile-radio-icons>
24+
<TileGroup legend="Other Attribute" name="other-wrapped">
25+
<Tile>Other Flag Option 1</Tile>
26+
</TileGroup>
27+
</FeatureFlags>
28+
29+
{/* Case 4: Already wrapped with correct attribute */}
30+
<FeatureFlags enableV12TileDefaultIcons>
31+
<TileGroup legend="Correct Wrapped" name="correct">
32+
<Tile>Correctly Wrapped Option</Tile>
33+
</TileGroup>
34+
</FeatureFlags>
35+
36+
{/* Case 5: Standalone Tiles with different scenarios */}
37+
<Stack>
38+
{/* Unwrapped standalone */}
39+
<Tile>Standalone Tile</Tile>
40+
41+
{/* Wrapped standalone missing flag prop */}
42+
<FeatureFlags>
43+
<Tile>Wrapped Standalone</Tile>
44+
</FeatureFlags>
45+
46+
{/* Wrapped standalone with other flag */}
47+
<FeatureFlags enable-v12-tile-radio-icons>
48+
<Tile>Other Flag Standalone</Tile>
49+
</FeatureFlags>
50+
51+
{/* Correctly wrapped standalone */}
52+
<FeatureFlags enableV12TileDefaultIcons>
53+
<Tile>Correct Standalone</Tile>
54+
</FeatureFlags>
55+
</Stack>
56+
57+
{/* Case 6: Nested structures */}
58+
<div className="nested">
59+
<TileGroup legend="Nested Group" name="nested">
60+
<div className="wrapper">
61+
<Tile>Nested Option 1</Tile>
62+
</div>
63+
<Tile>Nested Option 2</Tile>
64+
</TileGroup>
65+
</div>
66+
</div>
67+
);
68+
}
69+
70+
export default TestComponent;
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import React from 'react';
2+
import { TileGroup, Tile, Stack } from '@carbon/react';
3+
import { FeatureFlags } from '@carbon/feature-flags';
4+
5+
const TestComponent: React.FC = () => {
6+
return (
7+
//prettier-ignore
8+
<div>
9+
{/* Case 1: Unwrapped TileGroup */}
10+
<TileGroup legend="TestGroup" name="test">
11+
<Tile id="test-1">Option 1</Tile>
12+
<Tile id="test-2">Option 2</Tile>
13+
</TileGroup>
14+
15+
{/* Wrapped standalone missing flag prop */}
16+
<FeatureFlags>
17+
<TileGroup legend="Missing Attribute" name="wrapped">
18+
<Tile id="wrapped-1">Already Wrapped Option 1</Tile>
19+
<Tile id="wrapped-2">Already Wrapped Option 2</Tile>
20+
<Tile id="wrapped-3">Already Wrapped Option 3</Tile>
21+
</TileGroup>
22+
</FeatureFlags>
23+
24+
{/* Case 3: Already wrapped with other flags */}
25+
<FeatureFlags enable-v12-tile-radio-icons>
26+
<TileGroup legend="Other Attribute" name="other-wrapped">
27+
<Tile id="other-1">Other Flag Option 1</Tile>
28+
</TileGroup>
29+
</FeatureFlags>
30+
31+
{/* Case 4: Already wrapped with correct flag */}
32+
<FeatureFlags enableV12TileDefaultIcons>
33+
<TileGroup legend="Correct Wrapped" name="correct">
34+
<Tile id="correct-1">Correctly Wrapped Option</Tile>
35+
</TileGroup>
36+
</FeatureFlags>
37+
38+
{/* Case 5: Standalone Tiles with different scenarios */}
39+
<Stack>
40+
{/* Unwrapped standalone */}
41+
<Tile id="standalone">Standalone Tile</Tile>
42+
43+
{/* Wrapped standalone missing flag prop */}
44+
<FeatureFlags>
45+
<Tile id="wrapped-standalone">Wrapped Standalone</Tile>
46+
</FeatureFlags>
47+
48+
{/* Wrapped standalone with other flag */}
49+
<FeatureFlags enable-v12-tile-radio-icons>
50+
<Tile id="other-standalone">Other Flag Standalone</Tile>
51+
</FeatureFlags>
52+
53+
{/* Correctly wrapped standalone */}
54+
<FeatureFlags enableV12TileDefaultIcons>
55+
<Tile id="correct-standalone">Correct Standalone</Tile>
56+
</FeatureFlags>
57+
</Stack>
58+
59+
{/* Case 6: Nested structures */}
60+
<div className="nested">
61+
<TileGroup legend="Nested Group" name="nested">
62+
<div className="wrapper">
63+
<Tile id="nested-1">Nested Option 1</Tile>
64+
</div>
65+
<Tile id="nested-2">Nested Option 2</Tile>
66+
</TileGroup>
67+
</div>
68+
</div>
69+
);
70+
};
71+
72+
export default TestComponent;
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React from 'react';
2+
import { TileGroup, Tile, Stack } from '@carbon/react';
3+
import { FeatureFlags } from '@carbon/feature-flags';
4+
5+
function TestComponent() {
6+
return (
7+
(<div>
8+
{/* Case 1: Unwrapped TileGroup */}
9+
<FeatureFlags enableV12TileDefaultIcons><TileGroup legend="TestGroup" name="test">
10+
<Tile>
11+
Option 1
12+
</Tile>
13+
<Tile>
14+
Option 2
15+
</Tile>
16+
</TileGroup></FeatureFlags>
17+
{/* Wrapped standalone missing flag prop */}
18+
<FeatureFlags enableV12TileDefaultIcons>
19+
<TileGroup legend="Missing Attribute" name="wrapped">
20+
<Tile>
21+
Already Wrapped Option 1
22+
</Tile>
23+
<Tile>
24+
Already Wrapped Option 2
25+
</Tile>
26+
</TileGroup>
27+
</FeatureFlags>
28+
{/* Case 3: Already wrapped with other attributes */}
29+
<FeatureFlags enable-v12-tile-radio-icons enableV12TileDefaultIcons>
30+
<TileGroup legend="Other Attribute" name="other-wrapped">
31+
<Tile>
32+
Other Flag Option 1
33+
</Tile>
34+
</TileGroup>
35+
</FeatureFlags>
36+
{/* Case 4: Already wrapped with correct attribute */}
37+
<FeatureFlags enableV12TileDefaultIcons>
38+
<TileGroup legend="Correct Wrapped" name="correct">
39+
<Tile>
40+
Correctly Wrapped Option
41+
</Tile>
42+
</TileGroup>
43+
</FeatureFlags>
44+
{/* Case 5: Standalone Tiles with different scenarios */}
45+
<Stack>
46+
{/* Unwrapped standalone */}
47+
<FeatureFlags enableV12TileDefaultIcons><Tile>
48+
Standalone Tile
49+
</Tile></FeatureFlags>
50+
51+
{/* Wrapped standalone missing flag prop */}
52+
<FeatureFlags enableV12TileDefaultIcons>
53+
<Tile>
54+
Wrapped Standalone
55+
</Tile>
56+
</FeatureFlags>
57+
58+
{/* Wrapped standalone with other flag */}
59+
<FeatureFlags enable-v12-tile-radio-icons enableV12TileDefaultIcons>
60+
<Tile>
61+
Other Flag Standalone
62+
</Tile>
63+
</FeatureFlags>
64+
65+
{/* Correctly wrapped standalone */}
66+
<FeatureFlags enableV12TileDefaultIcons>
67+
<Tile>
68+
Correct Standalone
69+
</Tile>
70+
</FeatureFlags>
71+
</Stack>
72+
{/* Case 6: Nested structures */}
73+
<div className="nested">
74+
<FeatureFlags enableV12TileDefaultIcons><TileGroup legend="Nested Group" name="nested">
75+
<div className="wrapper">
76+
<Tile>
77+
Nested Option 1
78+
</Tile>
79+
</div>
80+
<Tile>
81+
Nested Option 2
82+
</Tile>
83+
</TileGroup></FeatureFlags>
84+
</div>
85+
</div>)
86+
);
87+
}
88+
89+
export default TestComponent;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import React from 'react';
2+
import { TileGroup, Tile, Stack } from '@carbon/react';
3+
import { FeatureFlags } from '@carbon/feature-flags';
4+
5+
const TestComponent: React.FC = () => {
6+
return (
7+
//prettier-ignore
8+
(<div>
9+
{/* Case 1: Unwrapped TileGroup */}
10+
<FeatureFlags enableV12TileDefaultIcons><TileGroup legend="TestGroup" name="test">
11+
<Tile id="test-1">Option 1</Tile>
12+
<Tile id="test-2">Option 2</Tile>
13+
</TileGroup></FeatureFlags>
14+
{/* Wrapped standalone missing flag prop */}
15+
<FeatureFlags enableV12TileDefaultIcons>
16+
<TileGroup legend="Missing Attribute" name="wrapped">
17+
<Tile id="wrapped-1">Already Wrapped Option 1</Tile>
18+
<Tile id="wrapped-2">Already Wrapped Option 2</Tile>
19+
<Tile id="wrapped-3">Already Wrapped Option 3</Tile>
20+
</TileGroup>
21+
</FeatureFlags>
22+
{/* Case 3: Already wrapped with other flags */}
23+
<FeatureFlags enable-v12-tile-radio-icons enableV12TileDefaultIcons>
24+
<TileGroup legend="Other Attribute" name="other-wrapped">
25+
<Tile id="other-1">Other Flag Option 1</Tile>
26+
</TileGroup>
27+
</FeatureFlags>
28+
{/* Case 4: Already wrapped with correct flag */}
29+
<FeatureFlags enableV12TileDefaultIcons>
30+
<TileGroup legend="Correct Wrapped" name="correct">
31+
<Tile id="correct-1">Correctly Wrapped Option</Tile>
32+
</TileGroup>
33+
</FeatureFlags>
34+
{/* Case 5: Standalone Tiles with different scenarios */}
35+
<Stack>
36+
{/* Unwrapped standalone */}
37+
<FeatureFlags enableV12TileDefaultIcons><Tile id="standalone">Standalone Tile</Tile></FeatureFlags>
38+
39+
{/* Wrapped standalone missing flag prop */}
40+
<FeatureFlags enableV12TileDefaultIcons>
41+
<Tile id="wrapped-standalone">Wrapped Standalone</Tile>
42+
</FeatureFlags>
43+
44+
{/* Wrapped standalone with other flag */}
45+
<FeatureFlags enable-v12-tile-radio-icons enableV12TileDefaultIcons>
46+
<Tile id="other-standalone">Other Flag Standalone</Tile>
47+
</FeatureFlags>
48+
49+
{/* Correctly wrapped standalone */}
50+
<FeatureFlags enableV12TileDefaultIcons>
51+
<Tile id="correct-standalone">Correct Standalone</Tile>
52+
</FeatureFlags>
53+
</Stack>
54+
{/* Case 6: Nested structures */}
55+
<div className="nested">
56+
<FeatureFlags enableV12TileDefaultIcons><TileGroup legend="Nested Group" name="nested">
57+
<div className="wrapper">
58+
<Tile id="nested-1">Nested Option 1</Tile>
59+
</div>
60+
<Tile id="nested-2">Nested Option 2</Tile>
61+
</TileGroup></FeatureFlags>
62+
</div>
63+
</div>)
64+
);
65+
};
66+
67+
export default TestComponent;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Copyright IBM Corp. 2025
3+
*
4+
* This source code is licensed under the Apache-2.0 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
const { defineTest } = require('jscodeshift/dist/testUtils');
11+
12+
defineTest(__dirname, 'enable-v12-tile-default-icons');

0 commit comments

Comments
 (0)