@kaizen/components 1.74.3 → 1.75.0

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 (27) hide show
  1. package/bin/codemod.sh +1 -0
  2. package/codemods/README.md +6 -0
  3. package/codemods/migrateGuidanceBlockActionsToActionsSlot/index.ts +21 -0
  4. package/codemods/migrateGuidanceBlockActionsToActionsSlot/migrateGuidanceBlockActionsToActionsSlot.spec.ts +122 -0
  5. package/codemods/migrateGuidanceBlockActionsToActionsSlot/migrateGuidanceBlockActionsToActionsSlot.ts +102 -0
  6. package/codemods/migrateGuidanceBlockActionsToActionsSlot/transformActionsToActionsSlot.spec.ts +196 -0
  7. package/codemods/migrateGuidanceBlockActionsToActionsSlot/transformActionsToActionsSlot.ts +71 -0
  8. package/codemods/utils/createProp.ts +1 -1
  9. package/codemods/utils/index.ts +1 -0
  10. package/codemods/utils/transformV1ButtonPropsToButtonOrLinkButton.spec.tsx +199 -0
  11. package/codemods/utils/transformV1ButtonPropsToButtonOrLinkButton.ts +195 -0
  12. package/dist/cjs/GuidanceBlock/GuidanceBlock.cjs +49 -84
  13. package/dist/cjs/GuidanceBlock/GuidanceBlock.module.css.cjs +0 -2
  14. package/dist/esm/GuidanceBlock/GuidanceBlock.mjs +50 -84
  15. package/dist/esm/GuidanceBlock/GuidanceBlock.module.css.mjs +0 -2
  16. package/dist/styles.css +1117 -1126
  17. package/dist/types/GuidanceBlock/GuidanceBlock.d.ts +8 -4
  18. package/package.json +1 -2
  19. package/src/GuidanceBlock/GuidanceBlock.module.css +0 -9
  20. package/src/GuidanceBlock/GuidanceBlock.tsx +48 -87
  21. package/src/GuidanceBlock/_docs/GuidanceBlock--migration-guide.mdx +77 -0
  22. package/src/GuidanceBlock/_docs/GuidanceBlock.mdx +35 -6
  23. package/src/GuidanceBlock/_docs/GuidanceBlock.stickersheet.stories.tsx +60 -27
  24. package/src/GuidanceBlock/_docs/GuidanceBlock.stories.tsx +205 -4
  25. package/src/Notification/InlineNotification/_docs/InlineNotification.stories.tsx +1 -0
  26. package/src/__next__/Button/_docs/Button--migration-guide.mdx +3 -3
  27. package/src/__next__/Tag/Tag/_docs/Tag.stories.tsx +10 -0
package/bin/codemod.sh CHANGED
@@ -35,6 +35,7 @@ if npx tsx@latest $CODEMOD_PATH $TARGET_DIR; then
35
35
  echo "Run linting and prettier to correct issues with re-writes"
36
36
  else
37
37
  echo "Codemod '$codemodFileName' could not be run in '$TARGET_DIR'"
38
+ echo "Check if '$CODEMOD_PATH' exists and is in the current version of the @kaizen/components"
38
39
  exit 1
39
40
  fi
40
41
 
@@ -109,6 +109,12 @@ Released in `1.73.1`
109
109
 
110
110
  Migrates V1 `Button` and `IconButton` component to next `Button` or `LinkButton`.
111
111
 
112
+ ### `migrateGuidanceBlockActionsToActionsSlot`
113
+
114
+ Migrates GuidanceBlock `actions` props into `actionsSlot` with `Button` or `LinkButton` component.
115
+
116
+ Released in `1.74.0`
117
+
112
118
  #### Props
113
119
 
114
120
  - `label` becomes `children`
@@ -0,0 +1,21 @@
1
+ import { transformComponentsInDir } from '../utils'
2
+ import { migrateGuidanceBlockActionsToActionsSlot } from './migrateGuidanceBlockActionsToActionsSlot'
3
+
4
+ const run = (): void => {
5
+ console.log('~(-_- ~) Running migrateGuidanceBlockActionsToActionsSlot upgrade (~ -_-)~')
6
+
7
+ const targetDir = process.argv[2]
8
+ if (!targetDir) {
9
+ process.exit(1)
10
+ }
11
+
12
+ transformComponentsInDir(targetDir, ['GuidanceBlock'], (tagNames) => [
13
+ migrateGuidanceBlockActionsToActionsSlot(tagNames),
14
+ ])
15
+
16
+ console.log(
17
+ '---\nIt is recommended that the `upgradeIconV1` codemod if any v1 icons have been migrated',
18
+ )
19
+ }
20
+
21
+ run()
@@ -0,0 +1,122 @@
1
+ import { parseJsx } from '../__tests__/utils'
2
+ import {
3
+ getKaioTagNamesMapByComponentName,
4
+ printAst,
5
+ transformSource,
6
+ type TransformSourceArgs,
7
+ } from '../utils'
8
+ import { migrateGuidanceBlockActionsToActionsSlot } from './migrateGuidanceBlockActionsToActionsSlot'
9
+
10
+ const transformGuidanceBlock = (sourceFile: TransformSourceArgs['sourceFile']): string => {
11
+ const kaioTagNamesMap = getKaioTagNamesMapByComponentName(sourceFile, ['GuidanceBlock'])
12
+ return transformSource({
13
+ sourceFile,
14
+ transformers: [migrateGuidanceBlockActionsToActionsSlot(kaioTagNamesMap!)],
15
+ })
16
+ }
17
+
18
+ describe('transformActionsToButtonNext()', () => {
19
+ it('imports Button from the /next path and transforms all button-like actions prop into a Button component', () => {
20
+ const inputAst = parseJsx(`
21
+ import { GuidanceBlock } from "@kaizen/components"
22
+ <GuidanceBlock
23
+ layout="default"
24
+ illustration={<Informative alt="" />}
25
+ content={<div>Test</div>}
26
+ actions={{
27
+ primary: {
28
+ label: 'Primary action',
29
+ onClick: () => alert('click 1'),
30
+ },
31
+ secondary: {
32
+ label: 'Secondary action',
33
+ onClick: () => alert('click 2'),
34
+ },
35
+ }}
36
+ />`)
37
+ const outputAst = parseJsx(`
38
+ import { GuidanceBlock } from "@kaizen/components"
39
+ import { Button } from "@kaizen/components/next"
40
+ <GuidanceBlock
41
+ layout="default"
42
+ illustration={<Informative alt="" />}
43
+ content={<div>Test</div>}
44
+ actionsSlot={<><Button onPress={() => alert('click 1')} variant="secondary" size="large">Primary action</Button><Button onPress={() => alert('click 2')} variant="tertiary" size="large">Secondary action</Button></>}
45
+ />
46
+ `)
47
+
48
+ expect(transformGuidanceBlock(inputAst)).toBe(printAst(outputAst))
49
+ })
50
+ it('imports and transforms all button-like and link-like actions prop into a Button and LinkButton', () => {
51
+ const inputAst = parseJsx(`
52
+ import { GuidanceBlock } from "@kaizen/components"
53
+ <GuidanceBlock
54
+ layout="default"
55
+ illustration={<Informative alt="" />}
56
+ content={<div>Test</div>}
57
+ actions={{
58
+ primary: {
59
+ label: 'Primary action',
60
+ onClick: () => alert('click 1'),
61
+ },
62
+ secondary: {
63
+ label: 'Secondary action',
64
+ href: "#secondary"
65
+ },
66
+ }}
67
+ />`)
68
+ const outputAst = parseJsx(`
69
+ import { GuidanceBlock, LinkButton } from "@kaizen/components"
70
+ import { Button } from "@kaizen/components/next"
71
+ <GuidanceBlock
72
+ layout="default"
73
+ illustration={<Informative alt="" />}
74
+ content={<div>Test</div>}
75
+ actionsSlot={<><Button onPress={() => alert('click 1')} variant="secondary" size="large">Primary action</Button><LinkButton href="#secondary" variant="tertiary" size="large">Secondary action</LinkButton></>}
76
+ />
77
+ `)
78
+
79
+ expect(transformGuidanceBlock(inputAst)).toBe(printAst(outputAst))
80
+ })
81
+ it('does not redeclare imports if found', () => {
82
+ const inputAst = parseJsx(`
83
+ import { GuidanceBlock } from "@kaizen/components"
84
+ import { Button } from "@kaizen/components/next"
85
+ const MockLayout = () => (
86
+ <>
87
+ <GuidanceBlock
88
+ layout="default"
89
+ illustration={<Informative alt="" />}
90
+ content={<div>Test</div>}
91
+ actions={{
92
+ primary: {
93
+ label: 'Primary action',
94
+ onClick: () => alert('click 1'),
95
+ },
96
+ secondary: {
97
+ label: 'Secondary action',
98
+ href: "#secondary"
99
+ },
100
+ }}
101
+ />
102
+ <Button onPress={() => alert('page click 1')} variant="primary" size="large">Page button</Button>
103
+ </>
104
+ )`)
105
+ const outputAst = parseJsx(`
106
+ import { GuidanceBlock, LinkButton } from "@kaizen/components"
107
+ import { Button } from "@kaizen/components/next"
108
+ const MockLayout = () => (
109
+ <>
110
+ <GuidanceBlock
111
+ layout="default"
112
+ illustration={<Informative alt="" />}
113
+ content={<div>Test</div>}
114
+ actionsSlot={<><Button onPress={() => alert('click 1')} variant="secondary" size="large">Primary action</Button><LinkButton href="#secondary" variant="tertiary" size="large">Secondary action</LinkButton></>}
115
+ />
116
+ <Button onPress={() => alert('page click 1')} variant="primary" size="large">Page button</Button>
117
+ </>
118
+ )`)
119
+
120
+ expect(transformGuidanceBlock(inputAst)).toBe(printAst(outputAst))
121
+ })
122
+ })
@@ -0,0 +1,102 @@
1
+ import ts from 'typescript'
2
+ import {
3
+ getKaioTagName,
4
+ setImportToAdd,
5
+ updateKaioImports,
6
+ type TagImportAttributesMap,
7
+ type UpdateKaioImportsArgs,
8
+ } from '../utils'
9
+ import { transformActionsToActionsSlot } from './transformActionsToActionsSlot'
10
+
11
+ const BUTTON_IMPORT_DESTINATION = '@kaizen/components/next'
12
+ const LINKBUTTON_IMPORT_DESTINATION = '@kaizen/components'
13
+
14
+ export const migrateGuidanceBlockActionsToActionsSlot =
15
+ (tagsMap: TagImportAttributesMap): ts.TransformerFactory<ts.SourceFile> =>
16
+ (context) =>
17
+ (rootNode) => {
18
+ const importsToRemove: UpdateKaioImportsArgs['importsToRemove'] = new Map()
19
+ const importsToAdd: UpdateKaioImportsArgs['importsToAdd'] = new Map()
20
+
21
+ const importedTargetButtonTagName = getKaioTagName(
22
+ rootNode,
23
+ 'Button',
24
+ BUTTON_IMPORT_DESTINATION,
25
+ )
26
+
27
+ const importedTargetLinkButtonTagName = getKaioTagName(
28
+ rootNode,
29
+ 'LinkButton',
30
+ LINKBUTTON_IMPORT_DESTINATION,
31
+ )
32
+
33
+ const visit = (node: ts.Node): ts.Node => {
34
+ if (ts.isJsxSelfClosingElement(node)) {
35
+ const tagName = node.tagName.getText()
36
+ const tagImportAttributes = tagsMap.get(tagName)
37
+
38
+ if (!tagImportAttributes) return node
39
+ if (
40
+ tagName === 'GuidanceBlock' ||
41
+ tagImportAttributes.importModuleName === 'GuidanceBlock'
42
+ ) {
43
+ const componentProps: ts.JsxAttributeLike[] = node.attributes.properties.reduce<
44
+ ts.JsxAttributeLike[]
45
+ >((guidanceBlockProps, prop) => {
46
+ if (ts.isJsxAttribute(prop)) {
47
+ const propName = prop.name.getText()
48
+ const propValue = prop.initializer as ts.JsxExpression
49
+
50
+ if (propName === 'actions') {
51
+ const transformedActions = transformActionsToActionsSlot(
52
+ propValue.getChildren()[1] as ts.ObjectLiteralExpression,
53
+ )
54
+
55
+ if (transformedActions?.importsToAdd) {
56
+ transformedActions.importsToAdd.forEach((importToAdd) => {
57
+ if (importToAdd === 'Button') {
58
+ setImportToAdd(importsToAdd, BUTTON_IMPORT_DESTINATION, {
59
+ componentName: 'Button',
60
+ alias:
61
+ importedTargetButtonTagName !== 'Button'
62
+ ? importedTargetButtonTagName
63
+ : undefined,
64
+ })
65
+ }
66
+ if (importToAdd === 'LinkButton') {
67
+ setImportToAdd(importsToAdd, LINKBUTTON_IMPORT_DESTINATION, {
68
+ componentName: 'LinkButton',
69
+ alias:
70
+ importedTargetLinkButtonTagName !== 'LinkButton'
71
+ ? importedTargetLinkButtonTagName
72
+ : undefined,
73
+ })
74
+ }
75
+ })
76
+ }
77
+
78
+ return transformedActions?.actionsSlotAttr
79
+ ? [...guidanceBlockProps, transformedActions.actionsSlotAttr]
80
+ : guidanceBlockProps
81
+ }
82
+
83
+ return [...guidanceBlockProps, prop]
84
+ }
85
+ return [...guidanceBlockProps, prop]
86
+ }, [])
87
+
88
+ return ts.factory.createJsxSelfClosingElement(
89
+ ts.factory.createIdentifier(tagName),
90
+ undefined,
91
+ ts.factory.createJsxAttributes(componentProps),
92
+ )
93
+ }
94
+ return ts.visitEachChild(node, visit, context)
95
+ }
96
+ return ts.visitEachChild(node, visit, context)
97
+ }
98
+
99
+ const node = ts.visitNode(rootNode, visit)
100
+
101
+ return updateKaioImports({ importsToRemove, importsToAdd })(context)(node as ts.SourceFile)
102
+ }
@@ -0,0 +1,196 @@
1
+ import ts from 'typescript'
2
+ import { parseJsx } from '../__tests__/utils'
3
+ import { printAst } from '../utils'
4
+ import { transformActionsToActionsSlot } from './transformActionsToActionsSlot'
5
+
6
+ export const mockedTransformer =
7
+ (kaioComponentName: string) =>
8
+ (context: ts.TransformationContext) =>
9
+ (rootNode: ts.Node): ts.Node => {
10
+ const visit = (node: ts.Node): ts.Node => {
11
+ if (ts.isJsxSelfClosingElement(node)) {
12
+ const componentProps: ts.JsxAttributeLike[] = node.attributes.properties.reduce<
13
+ ts.JsxAttributeLike[]
14
+ >((guidanceBlockProps, prop) => {
15
+ if (ts.isJsxAttribute(prop)) {
16
+ const propName = prop.name.getText()
17
+ const propValue = prop.initializer as ts.JsxExpression
18
+
19
+ if (propName === 'actions') {
20
+ const transformedActions = transformActionsToActionsSlot(
21
+ propValue.getChildren()[1] as ts.ObjectLiteralExpression,
22
+ )
23
+
24
+ return transformedActions?.actionsSlotAttr
25
+ ? [...guidanceBlockProps, transformedActions.actionsSlotAttr]
26
+ : guidanceBlockProps
27
+ }
28
+
29
+ return [...guidanceBlockProps, prop]
30
+ }
31
+ return [...guidanceBlockProps, prop]
32
+ }, [])
33
+
34
+ return ts.factory.createJsxSelfClosingElement(
35
+ ts.factory.createIdentifier(kaioComponentName),
36
+ undefined,
37
+ ts.factory.createJsxAttributes(componentProps),
38
+ )
39
+ }
40
+ return ts.visitEachChild(node, visit, context)
41
+ }
42
+ return ts.visitNode(rootNode, visit)
43
+ }
44
+
45
+ const transformInput = (
46
+ sourceFile: ts.SourceFile,
47
+ kaioComponentName: string = 'GuidanceBlock',
48
+ ): string => {
49
+ const result = ts.transform(sourceFile, [mockedTransformer(kaioComponentName)])
50
+ const transformedSource = result.transformed[0] as ts.SourceFile
51
+ return printAst(transformedSource)
52
+ }
53
+
54
+ describe('transformActionsToActionsSlot()', () => {
55
+ it('transforms button-like and link-like actions prop into a Button and LinkButton', () => {
56
+ const inputAst = parseJsx(`
57
+ <GuidanceBlock
58
+ layout="default"
59
+ illustration={<Informative alt="" />}
60
+ content={<div>Test</div>}
61
+ actions={{
62
+ primary: {
63
+ label: 'Primary action',
64
+ onClick: () => alert('click 1'),
65
+ },
66
+ secondary: {
67
+ label: 'Secondary action',
68
+ href: "#secondary"
69
+ },
70
+ }}
71
+ />`)
72
+ const outputAst = parseJsx(`
73
+ <GuidanceBlock
74
+ layout="default"
75
+ illustration={<Informative alt="" />}
76
+ content={<div>Test</div>}
77
+ actionsSlot={<><Button onPress={() => alert('click 1')} variant="secondary" size="large">Primary action</Button><LinkButton href="#secondary" variant="tertiary" size="large">Secondary action</LinkButton></>}
78
+ />
79
+ `)
80
+
81
+ expect(transformInput(inputAst)).toBe(printAst(outputAst))
82
+ })
83
+ it('transforms a primary action with all v1 Button props to expected Button outputs', () => {
84
+ const inputAst = parseJsx(`
85
+ <GuidanceBlock
86
+ layout="default"
87
+ illustration={<Informative alt="" />}
88
+ content={<div>Test</div>}
89
+ actions={{
90
+ primary: {
91
+ label: 'Learn more',
92
+ onClick: () => alert('tada: 🎉'),
93
+ tooltip: {
94
+ text: 'Opens in a new tab',
95
+ mood: 'cautionary',
96
+ },
97
+ badge: {
98
+ text: 'New',
99
+ },
100
+ destructive: true,
101
+ disabled: hasCondition ? true : false,
102
+ reversed: true,
103
+ icon: <Icon name="arrow_forward" shouldMirrorInRTL isPresentational />,
104
+ iconPosition: 'end',
105
+ size: 'small',
106
+ working: true,
107
+ workingLabel: 'Loading...',
108
+ workingLabelHidden: true,
109
+ disableTabFocusAndIUnderstandTheAccessibilityImplications: true,
110
+ 'data-custom-attr': 'custom-attr',
111
+ },
112
+ }}
113
+ />`)
114
+ const outputAst = parseJsx(`
115
+ <GuidanceBlock
116
+ layout="default"
117
+ illustration={<Informative alt=""/>}
118
+ content={<div>Test</div>}
119
+ actionsSlot={<><Button
120
+ onPress={() => alert('tada: 🎉')}
121
+ tooltip={{text: 'Opens in a new tab',mood: 'cautionary',}}
122
+ badge={{ text: 'New', }}
123
+ isDisabled={hasCondition ? true : false}
124
+ isReversed
125
+ icon={<Icon name="arrow_forward" shouldMirrorInRTL isPresentational/>}
126
+ iconPosition='end'
127
+ size="medium"
128
+ isPending pendingLabel='Loading...'
129
+ hasHiddenPendingLabel
130
+ data-custom-attr='custom-attr'
131
+ variant="secondary"
132
+ >Learn more</Button></>}/>
133
+ `)
134
+
135
+ expect(transformInput(inputAst).replace(/\s+/g, ' ')).toBe(
136
+ printAst(outputAst).replace(/\s+/g, ' '),
137
+ )
138
+ })
139
+
140
+ it('Passes custom data attributes and old props to be caught by type errors', () => {
141
+ const inputAst = parseJsx(`
142
+ <GuidanceBlock
143
+ layout="default"
144
+ illustration={<Informative alt="" />}
145
+ content={<div>Test</div>}
146
+ actions={{
147
+ primary: {
148
+ label: 'Learn more',
149
+ onClick: () => alert('tada: 🎉'),
150
+ tooltip: {
151
+ text: 'Opens in a new tab',
152
+ mood: 'cautionary',
153
+ },
154
+ badge: {
155
+ text: 'New',
156
+ },
157
+ destructive: true,
158
+ disabled: hasCondition ? true : false,
159
+ reversed: true,
160
+ icon: <Icon name="arrow_forward" shouldMirrorInRTL isPresentational />,
161
+ iconPosition: 'end',
162
+ size: 'small',
163
+ working: true,
164
+ workingLabel: 'Loading...',
165
+ workingLabelHidden: true,
166
+ disableTabFocusAndIUnderstandTheAccessibilityImplications: true,
167
+ 'data-custom-attr': 'custom-attr',
168
+ },
169
+ }}
170
+ />`)
171
+ const outputAst = parseJsx(`
172
+ <GuidanceBlock
173
+ layout="default"
174
+ illustration={<Informative alt=""/>}
175
+ content={<div>Test</div>}
176
+ actionsSlot={<><Button
177
+ onPress={() => alert('tada: 🎉')}
178
+ tooltip={{text: 'Opens in a new tab',mood: 'cautionary',}}
179
+ badge={{ text: 'New', }}
180
+ isDisabled={hasCondition ? true : false}
181
+ isReversed
182
+ icon={<Icon name="arrow_forward" shouldMirrorInRTL isPresentational/>}
183
+ iconPosition='end'
184
+ size="medium"
185
+ isPending pendingLabel='Loading...'
186
+ hasHiddenPendingLabel
187
+ data-custom-attr='custom-attr'
188
+ variant="secondary"
189
+ >Learn more</Button></>}/>
190
+ `)
191
+
192
+ expect(transformInput(inputAst).replace(/\s+/g, ' ')).toBe(
193
+ printAst(outputAst).replace(/\s+/g, ' '),
194
+ )
195
+ })
196
+ })
@@ -0,0 +1,71 @@
1
+ import ts from 'typescript'
2
+ import { transformV1ButtonPropsToButtonOrLinkButton } from '../utils'
3
+
4
+ type GuidanceBlockTransformedActions = {
5
+ importsToAdd: string[]
6
+ actionsSlotAttr: ts.JsxAttributeLike
7
+ }
8
+
9
+ /**
10
+ * A function that transforms a GuidanceBlock v1 button object literal into an new actionsSlot prop as JSX elements
11
+ * expects that the node passed in will be an ObjectLiteralExpression, ie:
12
+ * `{primary: {...buttonV1Props}, secondary: {...buttonV1Props}}`
13
+ */
14
+ export const transformActionsToActionsSlot = (
15
+ node: ts.ObjectLiteralExpression,
16
+ ): GuidanceBlockTransformedActions | undefined => {
17
+ if (ts.isObjectLiteralExpression(node)) {
18
+ const newImports: (string | undefined)[] = []
19
+
20
+ const primaryAction = node.properties.find((prop) => prop?.name?.getText() === 'primary') as
21
+ | ts.PropertyAssignment
22
+ | undefined
23
+
24
+ const secondaryAction = node.properties.find(
25
+ (prop) => prop?.name?.getText() === 'secondary',
26
+ ) as ts.PropertyAssignment | undefined
27
+
28
+ let primaryButton: ts.JsxSelfClosingElement | ts.JsxElement | undefined = undefined
29
+ let secondaryButton: ts.JsxSelfClosingElement | ts.JsxElement | undefined = undefined
30
+
31
+ if (primaryAction) {
32
+ const actionValue = primaryAction.initializer as ts.ObjectLiteralExpression
33
+ const transformedComponent = transformV1ButtonPropsToButtonOrLinkButton(
34
+ actionValue,
35
+ 'secondary',
36
+ )
37
+ primaryButton = transformedComponent.component
38
+ newImports.push(transformedComponent.import)
39
+ }
40
+
41
+ if (secondaryAction) {
42
+ const actionValue = secondaryAction?.initializer as ts.ObjectLiteralExpression
43
+ const transformedComponent = transformV1ButtonPropsToButtonOrLinkButton(
44
+ actionValue,
45
+ 'tertiary',
46
+ )
47
+ secondaryButton = transformedComponent.component
48
+ newImports.push(transformedComponent.import)
49
+ }
50
+
51
+ if (primaryButton || secondaryButton) {
52
+ const newActionsSlotAttr = ts.factory.createJsxAttribute(
53
+ ts.factory.createIdentifier('actionsSlot'),
54
+ ts.factory.createJsxExpression(
55
+ undefined,
56
+ ts.factory.createJsxFragment(
57
+ ts.factory.createJsxOpeningFragment(),
58
+ [primaryButton, secondaryButton].filter(Boolean) as ts.JsxChild[],
59
+ ts.factory.createJsxJsxClosingFragment(),
60
+ ),
61
+ ),
62
+ )
63
+
64
+ return {
65
+ actionsSlotAttr: newActionsSlotAttr,
66
+ importsToAdd: newImports.filter(Boolean) as string[],
67
+ }
68
+ }
69
+ }
70
+ return undefined
71
+ }
@@ -1,10 +1,10 @@
1
1
  import ts from 'typescript'
2
2
 
3
3
  export const createProp = (
4
+ // Transforms `propName={true}` to `propName`
4
5
  name: string,
5
6
  value?: ts.JsxAttributeValue | undefined,
6
7
  ): ts.JsxAttribute => {
7
- // Transforms `propName={true}` to `propName`
8
8
  if (value && ts.isJsxExpression(value) && value.expression?.kind === ts.SyntaxKind.TrueKeyword) {
9
9
  return ts.factory.createJsxAttribute(ts.factory.createIdentifier(name), undefined)
10
10
  }
@@ -8,3 +8,4 @@ export * from './transformComponentsInDir'
8
8
  export * from './transformSource'
9
9
  export * from './updateKaioImports'
10
10
  export * from './updateJsxElementWithNewProps'
11
+ export * from './transformV1ButtonPropsToButtonOrLinkButton'