@pantheon-systems/pds-toolkit-react 2.0.0-alpha.37 → 2.0.0-alpha.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/codemods/v1-to-v2/mappings.json +217 -28
  2. package/codemods/v1-to-v2/transforms/__testfixtures__/component-renames/basic.input.tsx +33 -0
  3. package/codemods/v1-to-v2/transforms/__testfixtures__/component-renames/basic.output.tsx +33 -0
  4. package/codemods/v1-to-v2/transforms/__testfixtures__/component-renames/only.input.tsx +8 -0
  5. package/codemods/v1-to-v2/transforms/__testfixtures__/component-renames/only.output.tsx +8 -0
  6. package/codemods/v1-to-v2/transforms/__testfixtures__/css-class-removals/basic.input.tsx +31 -0
  7. package/codemods/v1-to-v2/transforms/__testfixtures__/css-class-removals/basic.output.tsx +31 -0
  8. package/codemods/v1-to-v2/transforms/__testfixtures__/css-class-renames/basic.input.tsx +31 -0
  9. package/codemods/v1-to-v2/transforms/__testfixtures__/css-class-renames/basic.output.tsx +31 -0
  10. package/codemods/v1-to-v2/transforms/__testfixtures__/icon-name-updates/basic.input.tsx +35 -0
  11. package/codemods/v1-to-v2/transforms/__testfixtures__/icon-name-updates/basic.output.tsx +35 -0
  12. package/codemods/v1-to-v2/transforms/__testfixtures__/icon-name-updates/only.input.tsx +8 -0
  13. package/codemods/v1-to-v2/transforms/__testfixtures__/icon-name-updates/only.output.tsx +8 -0
  14. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-renames/basic.input.tsx +28 -0
  15. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-renames/basic.output.tsx +28 -0
  16. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-renames/only.input.tsx +8 -0
  17. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-renames/only.output.tsx +8 -0
  18. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-value-standardization/basic.output.tsx +10 -10
  19. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-value-standardization/only.input.tsx +21 -0
  20. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-value-standardization/only.output.tsx +21 -0
  21. package/codemods/v1-to-v2/transforms/__testfixtures__/removed-prop-values/basic.input.tsx +60 -0
  22. package/codemods/v1-to-v2/transforms/__testfixtures__/removed-prop-values/basic.output.tsx +51 -0
  23. package/codemods/v1-to-v2/transforms/__testfixtures__/removed-prop-values/only.input.tsx +8 -0
  24. package/codemods/v1-to-v2/transforms/__testfixtures__/removed-prop-values/only.output.tsx +8 -0
  25. package/codemods/v1-to-v2/transforms/__tests__/component-renames.test.js +15 -0
  26. package/codemods/v1-to-v2/transforms/__tests__/css-class-removals.test.js +6 -0
  27. package/codemods/v1-to-v2/transforms/__tests__/css-class-renames.test.js +6 -0
  28. package/codemods/v1-to-v2/transforms/__tests__/icon-name-updates.test.js +15 -0
  29. package/codemods/v1-to-v2/transforms/__tests__/prop-renames.test.js +15 -0
  30. package/codemods/v1-to-v2/transforms/__tests__/prop-value-standardization.test.js +10 -0
  31. package/codemods/v1-to-v2/transforms/__tests__/removed-prop-values.test.js +15 -0
  32. package/codemods/v1-to-v2/transforms/component-renames.js +166 -0
  33. package/codemods/v1-to-v2/transforms/css-class-removals.js +192 -0
  34. package/codemods/v1-to-v2/transforms/css-class-renames.js +114 -0
  35. package/codemods/v1-to-v2/transforms/icon-name-updates.js +124 -0
  36. package/codemods/v1-to-v2/transforms/prop-renames.js +109 -0
  37. package/codemods/v1-to-v2/transforms/prop-value-standardization.js +33 -2
  38. package/codemods/v1-to-v2/transforms/removed-prop-values.js +206 -0
  39. package/dist/components/Dropdown/Dropdown.d.ts +46 -0
  40. package/dist/components/SiteFooter/SiteFooter.d.ts +4 -1
  41. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  42. package/dist/components/UtilityBar/UtilityBar.d.ts +2 -3
  43. package/dist/components/buttons/ButtonLink/ButtonLink.d.ts +1 -3
  44. package/dist/components/buttons/CloseButton/CloseButton.d.ts +2 -2
  45. package/dist/components/buttons/FilterButton/FilterButton.d.ts +82 -0
  46. package/dist/components/buttons/SegmentedButton/SegmentedButton.d.ts +7 -1
  47. package/dist/components/cards/ActionCard/ActionCard.d.ts +2 -2
  48. package/dist/components/cards/Card/Card.d.ts +2 -2
  49. package/dist/components/icons/Icon/custom-icons.d.ts +1 -1
  50. package/dist/components/icons/Icon/generated-icon-data.d.ts +107 -30
  51. package/dist/components/navigation/Navbar/Navbar.d.ts +10 -1
  52. package/dist/components/panels/Panel/Panel.d.ts +2 -2
  53. package/dist/components/progress-indicators/ProgressBar/ProgressBar.d.ts +1 -1
  54. package/dist/components/progress-indicators/ProgressRing/ProgressRing.d.ts +10 -1
  55. package/dist/css/component-css/pds-action-card.css +1 -1
  56. package/dist/css/component-css/pds-button-link.css +1 -1
  57. package/dist/css/component-css/pds-button.css +1 -1
  58. package/dist/css/component-css/pds-card.css +1 -1
  59. package/dist/css/component-css/pds-checkbox.css +1 -1
  60. package/dist/css/component-css/pds-close-button.css +1 -1
  61. package/dist/css/component-css/pds-dropdown.css +2 -2
  62. package/dist/css/component-css/pds-filter-button.css +1 -0
  63. package/dist/css/component-css/pds-icon.css +1 -1
  64. package/dist/css/component-css/pds-index.css +23 -23
  65. package/dist/css/component-css/pds-panel.css +1 -1
  66. package/dist/css/component-css/pds-progress-ring.css +1 -1
  67. package/dist/css/component-css/pds-radio-group.css +1 -1
  68. package/dist/css/component-css/pds-segmented-button.css +1 -1
  69. package/dist/css/component-css/pds-side-nav-global.css +1 -1
  70. package/dist/css/component-css/pds-site-footer.css +1 -1
  71. package/dist/css/component-css/pds-site-search.css +1 -1
  72. package/dist/css/component-css/pds-skeleton.css +1 -1
  73. package/dist/css/component-css/pds-switch.css +2 -2
  74. package/dist/css/component-css/pds-utility-bar.css +1 -1
  75. package/dist/css/component-css/pds-vertical-empty-state.css +1 -1
  76. package/dist/css/design-tokens/variables.dark.css +6 -2
  77. package/dist/css/design-tokens/variables.global.css +0 -1
  78. package/dist/css/design-tokens/variables.light.css +4 -0
  79. package/dist/css/layout-css/pds-app-layout.css +5 -2
  80. package/dist/css/layout-css/pds-index.css +5 -2
  81. package/dist/css/layout-css/pds-sidebar-layout.css +1 -1
  82. package/dist/css/pds-components.css +23 -23
  83. package/dist/css/pds-core.css +2 -2
  84. package/dist/css/pds-layouts.css +5 -2
  85. package/dist/index.css +1 -1
  86. package/dist/index.d.ts +3 -0
  87. package/dist/index.js +1340 -1032
  88. package/dist/index.js.map +1 -1
  89. package/dist/index.source.d.ts +3 -0
  90. package/dist/layouts/AppLayout/AppLayout.d.ts +22 -2
  91. package/dist/layouts/SidebarLayout/SidebarLayout.d.ts +4 -3
  92. package/dist/layouts/ThreeItemLayout/ThreeItemLayout.d.ts +3 -3
  93. package/dist/layouts/TwoItemLayout/TwoItemLayout.d.ts +3 -3
  94. package/dist/libs/types/custom-types.d.ts +2 -2
  95. package/dist/libs/types/layout-types.d.ts +2 -1
  96. package/dist/svg/circleHalfStroke.svg +3 -0
  97. package/dist/svg/claude.svg +3 -0
  98. package/dist/svg/clock.svg +3 -0
  99. package/dist/svg/diagramVenn.svg +3 -0
  100. package/dist/svg/floppyDisk.svg +3 -0
  101. package/dist/svg/grid.svg +2 -2
  102. package/dist/svg/grid2.svg +3 -0
  103. package/dist/svg/octagonExclamation.svg +3 -0
  104. package/dist/svg/openai.svg +3 -0
  105. package/dist/svg/slider.svg +3 -0
  106. package/dist/svg/squareDashed.svg +3 -0
  107. package/dist/svg/tableColumns.svg +3 -0
  108. package/dist/utilities/FlexContainer/FlexContainer.d.ts +5 -6
  109. package/dist/utilities/grid/Grid.d.ts +58 -0
  110. package/dist/utilities/grid/GridItem.d.ts +57 -0
  111. package/package.json +5 -7
  112. /package/dist/svg/{arrowDownLeftAndArrowUpRightToCenter.svg → collapseToCenter.svg} +0 -0
  113. /package/dist/svg/{linkSimple.svg → link.svg} +0 -0
  114. /package/dist/svg/{arrowsUpDownLeftRight.svg → move.svg} +0 -0
  115. /package/dist/svg/{linkSimpleSlash.svg → unlink.svg} +0 -0
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Icon, Button } from '@pantheon-systems/pds-toolkit-react';
3
+
4
+ // Icon — matches --only=Icon, should be updated
5
+ const A = () => <Icon iconName="circlePlus" />;
6
+
7
+ // Button — not in --only list, should be left alone
8
+ const B = () => <Button iconName='circlePlusOutline' label='Add' />;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ CloseButton,
5
+ FileDiff,
6
+ GlobalWrapper,
7
+ Icon,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ // Aliased import
10
+ import { Icon as PdsIcon } from '@pantheon-systems/pds-toolkit-react';
11
+
12
+ // Simple renames
13
+ const A = () => <Button isLoading />;
14
+ const B = () => <GlobalWrapper mobileMenuMaxWidth={767} />;
15
+ const C = () => <FileDiff labelStrings={{ add: 'Added', remove: 'Removed' }} />;
16
+
17
+ // Same old prop name, different components — both should rename
18
+ const D = () => <Icon iconSize='m' iconName='star' />;
19
+ const E = () => <CloseButton iconSize='l' />;
20
+
21
+ // Aliased import — should still rename
22
+ const F = () => <PdsIcon iconSize='s' iconName='gear' />;
23
+
24
+ // Already correct — should be left alone
25
+ const G = () => <Button isWorking />;
26
+
27
+ // Non-PDS component — should be left alone
28
+ const H = () => <div isLoading />;
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ CloseButton,
5
+ FileDiff,
6
+ GlobalWrapper,
7
+ Icon,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ // Aliased import
10
+ import { Icon as PdsIcon } from '@pantheon-systems/pds-toolkit-react';
11
+
12
+ // Simple renames
13
+ const A = () => <Button isWorking />;
14
+ const B = () => <GlobalWrapper mobileMaxWidth={767} />;
15
+ const C = () => <FileDiff translationStrings={{ add: 'Added', remove: 'Removed' }} />;
16
+
17
+ // Same old prop name, different components — both should rename
18
+ const D = () => <Icon size='m' iconName='star' />;
19
+ const E = () => <CloseButton size='l' />;
20
+
21
+ // Aliased import — should still rename
22
+ const F = () => <PdsIcon size='s' iconName='gear' />;
23
+
24
+ // Already correct — should be left alone
25
+ const G = () => <Button isWorking />;
26
+
27
+ // Non-PDS component — should be left alone
28
+ const H = () => <div isLoading />;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Button, Icon } from '@pantheon-systems/pds-toolkit-react';
3
+
4
+ // Button — matches --only=Button, should be renamed
5
+ const A = () => <Button isLoading />;
6
+
7
+ // Icon — not in --only list, should be left alone
8
+ const B = () => <Icon iconSize='m' iconName='star' />;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Button, Icon } from '@pantheon-systems/pds-toolkit-react';
3
+
4
+ // Button — matches --only=Button, should be renamed
5
+ const A = () => <Button isWorking />;
6
+
7
+ // Icon — not in --only list, should be left alone
8
+ const B = () => <Icon iconSize='m' iconName='star' />;
@@ -9,19 +9,19 @@ import {
9
9
  import { IconButton as PdsIconButton } from '@pantheon-systems/pds-toolkit-react';
10
10
 
11
11
  // String literals — should be updated
12
- const A = () => <Spinner size='s' />;
13
- const B = () => <Spinner size='m' />;
14
- const C = () => <Spinner size='l' />;
15
- const D = () => <Avatar size='s' />;
16
- const E = () => <Avatar size='m' />;
12
+ const A = () => <Spinner size="s" />;
13
+ const B = () => <Spinner size="m" />;
14
+ const C = () => <Spinner size="l" />;
15
+ const D = () => <Avatar size="s" />;
16
+ const E = () => <Avatar size="m" />;
17
17
  // StatusIndicator has a different mapping: sm→xs, md→s
18
- const F = () => <StatusIndicator size='xs' />;
19
- const G = () => <StatusIndicator size='s' />;
18
+ const F = () => <StatusIndicator size="xs" />;
19
+ const G = () => <StatusIndicator size="s" />;
20
20
  // Aliased import
21
- const H = () => <PdsIconButton size='s' />;
21
+ const H = () => <PdsIconButton size="s" />;
22
22
 
23
23
  // JSX expression container — should also be updated
24
- const I = () => <Badge size={'s'} />;
24
+ const I = () => <Badge size={"s"} />;
25
25
 
26
26
  // Already correct — should be left alone
27
27
  const J = () => <Spinner size='s' />;
@@ -33,4 +33,4 @@ const K = () => <Spinner size={mySize} />;
33
33
  const L = () => <div size='sm' />;
34
34
 
35
35
  // Tooltip uses a different prop name: triggerIconSize
36
- const M = () => <Tooltip triggerIconSize='s' />;
36
+ const M = () => <Tooltip triggerIconSize="s" />;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import {
3
+ Spinner,
4
+ Avatar,
5
+ StatusIndicator,
6
+ Badge,
7
+ Tooltip,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ import { IconButton as PdsIconButton } from '@pantheon-systems/pds-toolkit-react';
10
+
11
+ // Spinner — matches --only=Spinner, should be updated
12
+ const A = () => <Spinner size='sm' />;
13
+ const B = () => <Spinner size='md' />;
14
+ const C = () => <Spinner size='lg' />;
15
+
16
+ // Other PDS components — not in --only list, should be left alone
17
+ const D = () => <Avatar size='sm' />;
18
+ const E = () => <StatusIndicator size='sm' />;
19
+ const F = () => <Badge size={'sm'} />;
20
+ const G = () => <PdsIconButton size='sm' />;
21
+ const H = () => <Tooltip triggerIconSize='sm' />;
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import {
3
+ Spinner,
4
+ Avatar,
5
+ StatusIndicator,
6
+ Badge,
7
+ Tooltip,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ import { IconButton as PdsIconButton } from '@pantheon-systems/pds-toolkit-react';
10
+
11
+ // Spinner — matches --only=Spinner, should be updated
12
+ const A = () => <Spinner size="s" />;
13
+ const B = () => <Spinner size="m" />;
14
+ const C = () => <Spinner size="l" />;
15
+
16
+ // Other PDS components — not in --only list, should be left alone
17
+ const D = () => <Avatar size='sm' />;
18
+ const E = () => <StatusIndicator size='sm' />;
19
+ const F = () => <Badge size={'sm'} />;
20
+ const G = () => <PdsIconButton size='sm' />;
21
+ const H = () => <Tooltip triggerIconSize='sm' />;
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import {
3
+ Avatar,
4
+ Button,
5
+ Card,
6
+ CodeBlock,
7
+ IconButton,
8
+ MenuButton,
9
+ Panel,
10
+ Spinner,
11
+ Switch,
12
+ } from '@pantheon-systems/pds-toolkit-react';
13
+
14
+ // Value rewrites — prop stays, value changes
15
+ const A = () => <Button variant='brand-secondary'>Click</Button>;
16
+ const B = () => <Button variant='navbar'>Click</Button>;
17
+ const C = () => (
18
+ <MenuButton variant='navbar' id='menu' label='Menu' menuItems={[]} />
19
+ );
20
+ const D = () => (
21
+ <IconButton variant='critical-hover' iconName='x' label='Close' />
22
+ );
23
+ const E = () => <Avatar size='xl' />;
24
+
25
+ // JSX expression container value rewrite
26
+ const F = () => <Button variant={'brand-secondary'}>Click</Button>;
27
+
28
+ // Unconditional prop removals
29
+ const G = () => <Spinner colorType='full-color' />;
30
+ const H = () => <CodeBlock colorType='dark' />;
31
+ const I = () => (
32
+ <Panel
33
+ hasStatusIndicator
34
+ statusType='success'
35
+ typeLabels={{ success: 'OK' }}
36
+ />
37
+ );
38
+ const J = () => (
39
+ <Switch
40
+ showStatusLabel
41
+ statusLabelPlacement='end'
42
+ onLabel='On'
43
+ offLabel='Off'
44
+ />
45
+ );
46
+
47
+ // Conditional removal — remove only deprecated gradient values, leave valid values alone
48
+ const K = () => <Card background='mint-gradient' />;
49
+ const L = () => <Card background='sundown-gradient' />;
50
+ const M = () => <Card background='default' />;
51
+
52
+ // Already correct — should be left alone
53
+ const N = () => <Button variant='secondary'>Click</Button>;
54
+
55
+ // Non-PDS component — should be left alone
56
+ const O = () => <div variant='brand-secondary' />;
57
+
58
+ // Dynamic value — cannot transform, leave as-is
59
+ const myVariant = 'brand-secondary';
60
+ const P = () => <Button variant={myVariant}>Click</Button>;
@@ -0,0 +1,51 @@
1
+ import React from 'react';
2
+ import {
3
+ Avatar,
4
+ Button,
5
+ Card,
6
+ CodeBlock,
7
+ IconButton,
8
+ MenuButton,
9
+ Panel,
10
+ Spinner,
11
+ Switch,
12
+ } from '@pantheon-systems/pds-toolkit-react';
13
+
14
+ // Value rewrites — prop stays, value changes
15
+ const A = () => <Button variant="secondary">Click</Button>;
16
+ const B = () => <Button variant="subtle">Click</Button>;
17
+ const C = () => (
18
+ <MenuButton variant="subtle" id='menu' label='Menu' menuItems={[]} />
19
+ );
20
+ const D = () => (
21
+ <IconButton variant="critical" iconName='x' label='Close' />
22
+ );
23
+ const E = () => <Avatar size="l" />;
24
+
25
+ // JSX expression container value rewrite
26
+ const F = () => <Button variant={"secondary"}>Click</Button>;
27
+
28
+ // Unconditional prop removals
29
+ const G = () => <Spinner />;
30
+ const H = () => <CodeBlock />;
31
+ const I = () => (
32
+ <Panel />
33
+ );
34
+ const J = () => (
35
+ <Switch />
36
+ );
37
+
38
+ // Conditional removal — remove only deprecated gradient values, leave valid values alone
39
+ const K = () => <Card />;
40
+ const L = () => <Card />;
41
+ const M = () => <Card background='default' />;
42
+
43
+ // Already correct — should be left alone
44
+ const N = () => <Button variant='secondary'>Click</Button>;
45
+
46
+ // Non-PDS component — should be left alone
47
+ const O = () => <div variant='brand-secondary' />;
48
+
49
+ // Dynamic value — cannot transform, leave as-is
50
+ const myVariant = 'brand-secondary';
51
+ const P = () => <Button variant={myVariant}>Click</Button>;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Button, Spinner } from '@pantheon-systems/pds-toolkit-react';
3
+
4
+ // Button — matches --only=Button, should be transformed
5
+ const A = () => <Button variant='brand-secondary'>Click</Button>;
6
+
7
+ // Spinner — not in --only list, should be left alone
8
+ const B = () => <Spinner colorType='full-color' />;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { Button, Spinner } from '@pantheon-systems/pds-toolkit-react';
3
+
4
+ // Button — matches --only=Button, should be transformed
5
+ const A = () => <Button variant="secondary">Click</Button>;
6
+
7
+ // Spinner — not in --only list, should be left alone
8
+ const B = () => <Spinner colorType='full-color' />;
@@ -0,0 +1,15 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'component-renames';
4
+
5
+ // Unfiltered: renames all components
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
7
+
8
+ // --only=IndicatorBadge: renames only IndicatorBadge; all other components untouched
9
+ defineTest(
10
+ __dirname,
11
+ transform,
12
+ { only: 'IndicatorBadge' },
13
+ `${transform}/only`,
14
+ { parser: 'tsx' },
15
+ );
@@ -0,0 +1,6 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'css-class-removals';
4
+
5
+ // CSS class removals apply to any element — no --only flag
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
@@ -0,0 +1,6 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'css-class-renames';
4
+
5
+ // CSS class renames apply to any element — no --only flag
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
@@ -0,0 +1,15 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'icon-name-updates';
4
+
5
+ // Unfiltered: updates iconName on all PDS components
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
7
+
8
+ // --only=Icon: updates only Icon's iconName; Button is untouched
9
+ defineTest(
10
+ __dirname,
11
+ transform,
12
+ { only: 'Icon' },
13
+ `${transform}/only`,
14
+ { parser: 'tsx' },
15
+ );
@@ -0,0 +1,15 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'prop-renames';
4
+
5
+ // Unfiltered: renames all components' props
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
7
+
8
+ // --only=Button: renames only Button's props; Icon and others are untouched
9
+ defineTest(
10
+ __dirname,
11
+ transform,
12
+ { only: 'Button' },
13
+ `${transform}/only`,
14
+ { parser: 'tsx' },
15
+ );
@@ -3,4 +3,14 @@ const { defineTest } = require('jscodeshift/src/testUtils');
3
3
  const transform = 'prop-value-standardization';
4
4
  const fixtures = `${__dirname}/../__testfixtures__/${transform}`;
5
5
 
6
+ // Unfiltered: rewrites all components with size migration rules
6
7
  defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
8
+
9
+ // --only=Spinner: rewrites only Spinner; all other PDS components are untouched
10
+ defineTest(
11
+ __dirname,
12
+ transform,
13
+ { only: 'Spinner' },
14
+ `${transform}/only`,
15
+ { parser: 'tsx' },
16
+ );
@@ -0,0 +1,15 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'removed-prop-values';
4
+
5
+ // Unfiltered: applies all value rewrites and prop removals
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
7
+
8
+ // --only=Button: transforms Button props only; Spinner is untouched
9
+ defineTest(
10
+ __dirname,
11
+ transform,
12
+ { only: 'Button' },
13
+ `${transform}/only`,
14
+ { parser: 'tsx' },
15
+ );
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Codemod: component-renames
3
+ *
4
+ * Renames PDS v1 components to their v2 names. Handles two import styles:
5
+ *
6
+ * 1. Root package imports (most common):
7
+ * import { IndicatorBadge } from '@pantheon-systems/pds-toolkit-react'
8
+ * → import { Badge } from '@pantheon-systems/pds-toolkit-react'
9
+ * Driven by components.renames in mappings.json.
10
+ *
11
+ * 2. Deep path imports:
12
+ * import { IndicatorBadge } from '@pantheon-systems/pds-toolkit-react/components/badges/IndicatorBadge/IndicatorBadge'
13
+ * → import { Badge } from '@pantheon-systems/pds-toolkit-react/components/badges/Badge/Badge'
14
+ * Driven by imports.pathChanges in mappings.json.
15
+ *
16
+ * In both cases, non-aliased imports also update every JSX tag in the file.
17
+ * Aliased imports preserve the local alias — only the imported name changes.
18
+ *
19
+ * Usage (all renames):
20
+ * npx jscodeshift -t codemods/v1-to-v2/transforms/component-renames.js \
21
+ * --extensions=tsx,ts,jsx,js \
22
+ * src/
23
+ *
24
+ * Usage (single component — recommended for by-component migrations):
25
+ * npx jscodeshift -t codemods/v1-to-v2/transforms/component-renames.js \
26
+ * --only=IndicatorBadge \
27
+ * --extensions=tsx,ts,jsx,js \
28
+ * src/
29
+ *
30
+ * --only accepts a comma-separated list of OLD (v1) component names.
31
+ */
32
+
33
+ const path = require('path');
34
+ const mappings = require(path.join(__dirname, '../mappings.json'));
35
+
36
+ // Build lookup for root package imports: { 'OldName': 'NewName' }
37
+ function buildRenamesLookup() {
38
+ const lookup = {};
39
+ for (const entry of mappings.components.renames) {
40
+ lookup[entry.from] = entry.to;
41
+ }
42
+ return lookup;
43
+ }
44
+
45
+ // Build list for deep path imports: [{ from, to, oldName, newName }]
46
+ function buildPathChangesLookup() {
47
+ return mappings.imports.pathChanges.map((entry) => ({
48
+ from: entry.from,
49
+ to: entry.to,
50
+ oldName: entry.from.split('/').pop(),
51
+ newName: entry.component || entry.to.split('/').pop(),
52
+ }));
53
+ }
54
+
55
+ const ALL_RENAMES = buildRenamesLookup();
56
+ const ALL_PATH_CHANGES = buildPathChangesLookup();
57
+
58
+ module.exports = function transform(file, api, options) {
59
+ const j = api.jscodeshift;
60
+ const root = j(file.source);
61
+
62
+ // Parse --only flag: comma-separated OLD (v1) component names
63
+ const onlyComponents =
64
+ options && options.only
65
+ ? new Set(
66
+ options.only
67
+ .split(',')
68
+ .map((s) => s.trim())
69
+ .filter(Boolean),
70
+ )
71
+ : null;
72
+
73
+ // Apply --only filter to both lookups
74
+ const renames = onlyComponents
75
+ ? Object.fromEntries(
76
+ Object.entries(ALL_RENAMES).filter(([from]) =>
77
+ onlyComponents.has(from),
78
+ ),
79
+ )
80
+ : ALL_RENAMES;
81
+
82
+ const pathChanges = onlyComponents
83
+ ? ALL_PATH_CHANGES.filter((p) => onlyComponents.has(p.oldName))
84
+ : ALL_PATH_CHANGES;
85
+
86
+ if (Object.keys(renames).length === 0 && pathChanges.length === 0) return;
87
+
88
+ // Track non-aliased renames so JSX tags can be updated in Step 2.
89
+ const localRenameMap = new Map(); // oldLocalName → newLocalName
90
+
91
+ let changed = false;
92
+
93
+ // Step 1: Update import declarations
94
+ root.find(j.ImportDeclaration).forEach((nodePath) => {
95
+ const source = nodePath.node.source.value;
96
+
97
+ // 1a. Root package imports
98
+ if (source === '@pantheon-systems/pds-toolkit-react') {
99
+ nodePath.node.specifiers.forEach((spec) => {
100
+ if (spec.type !== 'ImportSpecifier') return;
101
+
102
+ const importedName = spec.imported.name;
103
+ const newName = renames[importedName];
104
+ if (!newName) return;
105
+
106
+ const isAliased = spec.local.name !== spec.imported.name;
107
+ spec.imported = j.identifier(newName);
108
+ changed = true;
109
+
110
+ if (!isAliased) {
111
+ spec.local = j.identifier(newName);
112
+ localRenameMap.set(importedName, newName);
113
+ }
114
+ });
115
+ return;
116
+ }
117
+
118
+ // 1b. Deep path imports
119
+ for (const { from, to, oldName, newName } of pathChanges) {
120
+ if (!source.includes(from)) continue;
121
+
122
+ nodePath.node.source = j.stringLiteral(source.replace(from, to));
123
+ changed = true;
124
+
125
+ nodePath.node.specifiers.forEach((spec) => {
126
+ if (spec.type !== 'ImportSpecifier') return;
127
+ if (spec.imported.name !== oldName) return;
128
+
129
+ const isAliased = spec.local.name !== spec.imported.name;
130
+ spec.imported = j.identifier(newName);
131
+
132
+ if (!isAliased) {
133
+ spec.local = j.identifier(newName);
134
+ localRenameMap.set(oldName, newName);
135
+ }
136
+ });
137
+
138
+ break; // a source string can only match one path change
139
+ }
140
+ });
141
+
142
+ if (!changed) return;
143
+
144
+ // Step 2: Rewrite JSX tags for non-aliased renames
145
+ if (localRenameMap.size > 0) {
146
+ root.find(j.JSXOpeningElement).forEach((nodePath) => {
147
+ const nameNode = nodePath.node.name;
148
+ if (nameNode.type !== 'JSXIdentifier') return;
149
+
150
+ const newName = localRenameMap.get(nameNode.name);
151
+ if (newName) nodePath.node.name = j.jsxIdentifier(newName);
152
+ });
153
+
154
+ root.find(j.JSXClosingElement).forEach((nodePath) => {
155
+ const nameNode = nodePath.node.name;
156
+ if (nameNode.type !== 'JSXIdentifier') return;
157
+
158
+ const newName = localRenameMap.get(nameNode.name);
159
+ if (newName) nodePath.node.name = j.jsxIdentifier(newName);
160
+ });
161
+ }
162
+
163
+ return root.toSource();
164
+ };
165
+
166
+ module.exports.parser = 'tsx';