@instructure/ui-codemods 10.20.2-snapshot-11 → 10.20.2-snapshot-13
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.
- package/CHANGELOG.md +1 -1
- package/README.md +5 -87
- package/lib/__node_tests__/codemodHelpers.test.tsx +455 -0
- package/lib/__node_tests__/{updateV10Breaking.test.ts → codemods.test.ts} +3 -3
- package/lib/__node_tests__/{testHelpers.ts → runTest.ts} +1 -3
- package/lib/index.ts +1 -16
- package/lib/{utils → instui-codemods}/updateToV10Colors.ts +6 -7
- package/lib/updateV10Breaking.ts +12 -26
- package/lib/{helpers → utils}/codemodHelpers.ts +153 -164
- package/lib/utils/codemodTypeCheckers.ts +221 -0
- package/lib/utils/instUICodemodExecutor.ts +89 -0
- package/package.json +2 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/lib/helpers/replaceDeprecatedImports.ts +0 -546
- package/lib/helpers/replaceDeprecatedProps.ts +0 -230
- package/lib/updateImports.ts +0 -86
- package/lib/updatePropNames.ts +0 -66
- package/lib/updateV7Props.ts +0 -101
- package/lib/updateV8Breaking.ts +0 -49
- package/lib/updateV8ReactDOM.ts +0 -61
- package/lib/updateV9Breaking.ts +0 -54
- package/lib/utils/UpdateV7ButtonsLink.ts +0 -139
- package/lib/utils/requireUncached.ts +0 -28
- package/lib/utils/updateToV8Theming.ts +0 -84
- package/lib/utils/updateToV9Theming.ts +0 -70
- package/lib/utils/updateV7ButtonsClose.ts +0 -104
- package/lib/utils/updateV7ButtonsIconCircle.ts +0 -240
- package/lib/utils/updateV7ButtonsMisc.ts +0 -137
- package/lib/utils/updateV7ButtonsWithText.ts +0 -111
- package/lib/utils/updateV7FocusableView.ts +0 -105
- package/lib/utils/updateV7Heading.ts +0 -145
- package/lib/utils/updateV7Lists.ts +0 -113
- package/lib/utils/updateV7Pill.ts +0 -83
- package/lib/utils/updateV7Popover.ts +0 -133
- package/lib/utils/updateV7Tabs.ts +0 -129
- package/lib/utils/updateV8RenderProp.ts +0 -142
- package/lib/utils/updateV8ThemeProp.ts +0 -51
- package/lib/utils/warnV7ComponentDeprecations.ts +0 -96
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import {
|
|
26
|
-
addImportIfNeeded,
|
|
27
|
-
findAttribute,
|
|
28
|
-
findElements,
|
|
29
|
-
isJSXAttribue,
|
|
30
|
-
printWarning,
|
|
31
|
-
renameElements
|
|
32
|
-
} from '../helpers/codemodHelpers'
|
|
33
|
-
import { Collection, JSCodeshift, Literal } from 'jscodeshift'
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Does the following updates on a <Button>:
|
|
37
|
-
* - `variant="link" href=` -> `<Link isWithinText={false} href=..` and a
|
|
38
|
-
* warning that padding can be removed.
|
|
39
|
-
* - `variant="link-inverse" href=` ->
|
|
40
|
-
* <Link isWithinText={false} color="link-inverse" href=` and a warning
|
|
41
|
-
* that padding can be removed
|
|
42
|
-
* - `variant="link"` or `variant="link-inverse"` and no `href` attribute ->
|
|
43
|
-
* display a warning how to upgrade
|
|
44
|
-
*/
|
|
45
|
-
export default function UpdateV7ButtonsLink(
|
|
46
|
-
j: JSCodeshift,
|
|
47
|
-
root: Collection,
|
|
48
|
-
importedName: string,
|
|
49
|
-
filePath: string
|
|
50
|
-
) {
|
|
51
|
-
///// variant=link or variant=link-inverse, no href attribute display warning
|
|
52
|
-
findElements(filePath, j, root, importedName, {
|
|
53
|
-
name: 'variant',
|
|
54
|
-
value: ['link', 'link-inverse']
|
|
55
|
-
}).forEach((path) => {
|
|
56
|
-
const attributes = path.value.openingElement.attributes
|
|
57
|
-
if (!attributes) {
|
|
58
|
-
displayNoHrefWarning(filePath, path.value.loc!.start.line)
|
|
59
|
-
return
|
|
60
|
-
}
|
|
61
|
-
for (const attr of attributes) {
|
|
62
|
-
if (isJSXAttribue(attr) && attr.name.name === 'href') {
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
displayNoHrefWarning(filePath, path.value.loc!.start.line)
|
|
67
|
-
})
|
|
68
|
-
////// find the link and link-inverse variants with href
|
|
69
|
-
const linkVariants = findElements(filePath, j, root, importedName, [
|
|
70
|
-
{ name: 'variant', value: 'link' },
|
|
71
|
-
{ name: 'href' }
|
|
72
|
-
])
|
|
73
|
-
const linkInverseVariants = findElements(filePath, j, root, importedName, [
|
|
74
|
-
{ name: 'variant', value: 'link-inverse' },
|
|
75
|
-
{ name: 'href' }
|
|
76
|
-
])
|
|
77
|
-
///// insert import for Link to these and rename them
|
|
78
|
-
if (linkVariants.length > 0 || linkInverseVariants.length > 0) {
|
|
79
|
-
const linkImportName = addImportIfNeeded(j, root, 'Link', [
|
|
80
|
-
'@instructure/ui-link',
|
|
81
|
-
'@instructure/ui'
|
|
82
|
-
])
|
|
83
|
-
renameElements(filePath, linkVariants, importedName, linkImportName)
|
|
84
|
-
renameElements(filePath, linkInverseVariants, importedName, linkImportName)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
///// insert isWithinText={false} and remove variant for variant="link"
|
|
88
|
-
findAttribute(filePath, j, linkVariants, 'href').insertAfter(
|
|
89
|
-
j.jsxAttribute(
|
|
90
|
-
j.jsxIdentifier('isWithinText'),
|
|
91
|
-
j.jsxExpressionContainer(j.jsxIdentifier('false'))
|
|
92
|
-
)
|
|
93
|
-
)
|
|
94
|
-
findAttribute(filePath, j, linkVariants, 'variant').remove()
|
|
95
|
-
linkVariants.forEach((path) => {
|
|
96
|
-
displayHrefWarning(filePath, path.value.loc!.start.line)
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
///// variant="link-inverse" => color="link-inverse" isWithinText={false}
|
|
100
|
-
findAttribute(filePath, j, linkInverseVariants, 'href').insertAfter(
|
|
101
|
-
j.jsxAttribute(
|
|
102
|
-
j.jsxIdentifier('isWithinText'),
|
|
103
|
-
j.jsxExpressionContainer(j.jsxIdentifier('false'))
|
|
104
|
-
)
|
|
105
|
-
)
|
|
106
|
-
findAttribute(filePath, j, linkInverseVariants, 'variant').replaceWith(
|
|
107
|
-
(nodePath) => {
|
|
108
|
-
const { node } = nodePath
|
|
109
|
-
node.name.name = 'color'
|
|
110
|
-
;(node.value as Literal).value = 'link-inverse'
|
|
111
|
-
return nodePath.node
|
|
112
|
-
}
|
|
113
|
-
)
|
|
114
|
-
linkVariants.forEach((path) => {
|
|
115
|
-
displayHrefWarning(filePath, path.value.loc!.start.line)
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function displayHrefWarning(filePath: string, lineNumber: number) {
|
|
120
|
-
printWarning(
|
|
121
|
-
filePath,
|
|
122
|
-
lineNumber,
|
|
123
|
-
'Button with link or link-inverse variant might need the removal' +
|
|
124
|
-
' of margin/padding parameters. Also you will likely need to add ' +
|
|
125
|
-
'@instructure/ui-link as a dependency. For more see ' +
|
|
126
|
-
'https://instructure.design/v7/#button-upgrade-guide/#button-upgrade-for-version-8.0-upgrading-variant-link-or-link-inverse-upgrade-examples-for-link-variant-with-an-href-attribute-and-padding-overrides'
|
|
127
|
-
)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function displayNoHrefWarning(filePath: string, lineNumber: number) {
|
|
131
|
-
printWarning(
|
|
132
|
-
filePath,
|
|
133
|
-
lineNumber,
|
|
134
|
-
'Button with link or link-inverse variants cannot be upgraded ' +
|
|
135
|
-
'manually when it has no href prop. Also you will likely need to add ' +
|
|
136
|
-
'@instructure/ui-link as a dependency. Read more at ' +
|
|
137
|
-
'https://instructure.design/v7/#button-upgrade-guide/#button-upgrade-for-version-8.0-upgrading-variant-link-or-link-inverse-upgrade-examples-for-link-variant-with-no-href-attribute-and-padding-overrides'
|
|
138
|
-
)
|
|
139
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
export default function requireUncached(module: string) {
|
|
26
|
-
delete require.cache[require.resolve(module)]
|
|
27
|
-
return require(module)
|
|
28
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { Collection, JSCodeshift } from 'jscodeshift'
|
|
26
|
-
import {
|
|
27
|
-
addImportIfNeeded,
|
|
28
|
-
findElements,
|
|
29
|
-
findEveryImport,
|
|
30
|
-
findImport,
|
|
31
|
-
isIdentifier,
|
|
32
|
-
isMemberExpression,
|
|
33
|
-
renameElements
|
|
34
|
-
} from '../helpers/codemodHelpers'
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Does the following changes:
|
|
38
|
-
* 1. `<ApplyTheme` -> `<InstUISettingsProvider`
|
|
39
|
-
* 2. `Menu.theme` -> `Menu.componentId` (for every InstUI component)
|
|
40
|
-
*/
|
|
41
|
-
export function updateToV8Theming(
|
|
42
|
-
j: JSCodeshift,
|
|
43
|
-
root: Collection,
|
|
44
|
-
filePath: string
|
|
45
|
-
) {
|
|
46
|
-
let hasModifications = false
|
|
47
|
-
const importedName = findImport(j, root, 'ApplyTheme', [
|
|
48
|
-
'@instructure/ui',
|
|
49
|
-
'@instructure/ui-themeable'
|
|
50
|
-
])
|
|
51
|
-
// <ApplyTheme> -> <InstUISettingsProvider>
|
|
52
|
-
if (importedName) {
|
|
53
|
-
const applyThemeElements = findElements(filePath, j, root, importedName)
|
|
54
|
-
const instUISettingsProvider = addImportIfNeeded(
|
|
55
|
-
j,
|
|
56
|
-
root,
|
|
57
|
-
'InstUISettingsProvider',
|
|
58
|
-
'@instructure/emotion'
|
|
59
|
-
)
|
|
60
|
-
renameElements(
|
|
61
|
-
filePath,
|
|
62
|
-
applyThemeElements,
|
|
63
|
-
importedName,
|
|
64
|
-
instUISettingsProvider
|
|
65
|
-
)
|
|
66
|
-
hasModifications = true
|
|
67
|
-
}
|
|
68
|
-
// Menu.theme -> Menu.componentId (for every InstUI component)
|
|
69
|
-
const importedComponents = findEveryImport(j, root, '@instructure/ui', false)
|
|
70
|
-
root.find(j.MemberExpression).forEach((path) => {
|
|
71
|
-
const astNode = path.value
|
|
72
|
-
if (
|
|
73
|
-
isMemberExpression(astNode) &&
|
|
74
|
-
isIdentifier(astNode.object) &&
|
|
75
|
-
importedComponents.includes(astNode.object.name) &&
|
|
76
|
-
isIdentifier(astNode.property) &&
|
|
77
|
-
astNode.property.name === 'theme'
|
|
78
|
-
) {
|
|
79
|
-
hasModifications = true
|
|
80
|
-
astNode.property.name = 'componentId'
|
|
81
|
-
}
|
|
82
|
-
})
|
|
83
|
-
return hasModifications
|
|
84
|
-
}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { Collection, JSCodeshift } from 'jscodeshift'
|
|
26
|
-
import {
|
|
27
|
-
findElements,
|
|
28
|
-
findImport,
|
|
29
|
-
renameElements,
|
|
30
|
-
replaceImport
|
|
31
|
-
} from '../helpers/codemodHelpers'
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Does the following changes:
|
|
35
|
-
* 1. `<EmotionThemeProvider>` -> `<InstUISettingsProvider>`
|
|
36
|
-
*/
|
|
37
|
-
export function updateToV9Theming(
|
|
38
|
-
j: JSCodeshift,
|
|
39
|
-
root: Collection,
|
|
40
|
-
filePath: string
|
|
41
|
-
) {
|
|
42
|
-
let hasModifications = false
|
|
43
|
-
const importedName = findImport(j, root, 'EmotionThemeProvider', [
|
|
44
|
-
'@instructure/emotion'
|
|
45
|
-
])
|
|
46
|
-
// <EmotionThemeProvider> -> <InstUISettingsProvider>
|
|
47
|
-
if (importedName) {
|
|
48
|
-
const emotionThemeProviderElements = findElements(
|
|
49
|
-
filePath,
|
|
50
|
-
j,
|
|
51
|
-
root,
|
|
52
|
-
importedName
|
|
53
|
-
)
|
|
54
|
-
const instUISettingsProvider = replaceImport(
|
|
55
|
-
j,
|
|
56
|
-
root,
|
|
57
|
-
'EmotionThemeProvider',
|
|
58
|
-
'InstUISettingsProvider',
|
|
59
|
-
'@instructure/emotion'
|
|
60
|
-
)
|
|
61
|
-
renameElements(
|
|
62
|
-
filePath,
|
|
63
|
-
emotionThemeProviderElements,
|
|
64
|
-
importedName,
|
|
65
|
-
instUISettingsProvider
|
|
66
|
-
)
|
|
67
|
-
hasModifications = true
|
|
68
|
-
}
|
|
69
|
-
return hasModifications
|
|
70
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import { Collection, JSCodeshift, Literal } from 'jscodeshift'
|
|
26
|
-
import {
|
|
27
|
-
findAttribute,
|
|
28
|
-
findElements,
|
|
29
|
-
findImport,
|
|
30
|
-
getVisibleChildren,
|
|
31
|
-
isJSXExpressionContainer,
|
|
32
|
-
isJSXText,
|
|
33
|
-
printWarning,
|
|
34
|
-
removeAllChildren
|
|
35
|
-
} from '../helpers/codemodHelpers'
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Does the following updates on a <CloseButton>:
|
|
39
|
-
* - `buttonRef=` -> `elementRef=`
|
|
40
|
-
* - `variant="icon"` removed
|
|
41
|
-
* - `variant="icon-inverse"` -> `color="primary-inverse"`
|
|
42
|
-
*
|
|
43
|
-
* If it has children it outputs a warning on how to upgrade them
|
|
44
|
-
**/
|
|
45
|
-
export default function updateV7ButtonsClose(
|
|
46
|
-
j: JSCodeshift,
|
|
47
|
-
root: Collection,
|
|
48
|
-
filePath: string
|
|
49
|
-
) {
|
|
50
|
-
const closeButtonImportName = findImport(j, root, 'CloseButton', [
|
|
51
|
-
'@instructure/ui-buttons',
|
|
52
|
-
'@instructure/ui'
|
|
53
|
-
])
|
|
54
|
-
if (!closeButtonImportName) {
|
|
55
|
-
return false
|
|
56
|
-
}
|
|
57
|
-
///// replace <CloseButton buttonRef=.. with <CloseButton elementRef=..
|
|
58
|
-
findElements(filePath, j, root, closeButtonImportName)
|
|
59
|
-
.find(j.JSXIdentifier, { name: 'buttonRef' })
|
|
60
|
-
.replaceWith('elementRef')
|
|
61
|
-
|
|
62
|
-
///// If it has children try to move them under screenReaderLabel
|
|
63
|
-
findElements(filePath, j, root, closeButtonImportName).forEach((path) => {
|
|
64
|
-
const children = getVisibleChildren(path.value.children)
|
|
65
|
-
if (children.length == 1) {
|
|
66
|
-
const firstChild = children[0]
|
|
67
|
-
let screenReaderLabelText
|
|
68
|
-
if (isJSXText(firstChild)) {
|
|
69
|
-
screenReaderLabelText = j.stringLiteral(firstChild.value)
|
|
70
|
-
} else if (isJSXExpressionContainer(firstChild)) {
|
|
71
|
-
screenReaderLabelText = firstChild
|
|
72
|
-
}
|
|
73
|
-
path.value.openingElement.attributes!.push(
|
|
74
|
-
j.jsxAttribute(
|
|
75
|
-
j.jsxIdentifier('screenReaderLabel'),
|
|
76
|
-
screenReaderLabelText
|
|
77
|
-
)
|
|
78
|
-
)
|
|
79
|
-
removeAllChildren(path.value)
|
|
80
|
-
} else if (children.length > 1) {
|
|
81
|
-
printWarning(
|
|
82
|
-
filePath,
|
|
83
|
-
path.value.loc?.start.line,
|
|
84
|
-
'Cannot update CloseButton because it has multiple children.' +
|
|
85
|
-
'Children should be moved to the `screenReaderLabel` prop,' +
|
|
86
|
-
'You will need to update this manually.'
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
///// Remove variant="icon" prop
|
|
92
|
-
findAttribute(filePath, j, root, 'variant', 'icon').remove()
|
|
93
|
-
|
|
94
|
-
///// Change variant="icon-inverse" to color="primary-inverse"
|
|
95
|
-
findAttribute(filePath, j, root, 'variant', 'icon-inverse').replaceWith(
|
|
96
|
-
(nodePath) => {
|
|
97
|
-
const { node } = nodePath
|
|
98
|
-
node.name.name = 'color'
|
|
99
|
-
;(node.value as Literal).value = 'primary-inverse'
|
|
100
|
-
return nodePath.node
|
|
101
|
-
}
|
|
102
|
-
)
|
|
103
|
-
return true
|
|
104
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The MIT License (MIT)
|
|
3
|
-
*
|
|
4
|
-
* Copyright (c) 2015 - present Instructure, Inc.
|
|
5
|
-
*
|
|
6
|
-
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
* in the Software without restriction, including without limitation the rights
|
|
9
|
-
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
* furnished to do so, subject to the following conditions:
|
|
12
|
-
*
|
|
13
|
-
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
* copies or substantial portions of the Software.
|
|
15
|
-
*
|
|
16
|
-
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
* SOFTWARE.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import {
|
|
26
|
-
Collection,
|
|
27
|
-
JSCodeshift,
|
|
28
|
-
JSXAttribute,
|
|
29
|
-
JSXIdentifier,
|
|
30
|
-
Literal
|
|
31
|
-
} from 'jscodeshift'
|
|
32
|
-
import {
|
|
33
|
-
addImportIfNeeded,
|
|
34
|
-
findAttribute,
|
|
35
|
-
findElements,
|
|
36
|
-
getVisibleChildren,
|
|
37
|
-
isJSXElement,
|
|
38
|
-
isJSXExpressionContainer,
|
|
39
|
-
isJSXText,
|
|
40
|
-
printWarning,
|
|
41
|
-
removeAllChildren,
|
|
42
|
-
renameElements
|
|
43
|
-
} from '../helpers/codemodHelpers'
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Does the following updates on a <Button>:
|
|
47
|
-
* - variant="icon" -> <IconButton withBackground={false} withBorder={false}
|
|
48
|
-
* - variant="icon-inverse" -> <IconButton color="primary-inverse" withBackground={false} withBorder={false}
|
|
49
|
-
* - variant="circle-default" -> <IconButton color="secondary" shape="circle"
|
|
50
|
-
* - variant="circle-danger" -> <IconButton color="danger" shape="circle"
|
|
51
|
-
* - variant="icon" -> <IconButton color="secondary" shape="circle"
|
|
52
|
-
*
|
|
53
|
-
* This codemod also adds an import to `IconButton`.
|
|
54
|
-
*
|
|
55
|
-
* It also outputs a warning and does not do anything if one of these variants
|
|
56
|
-
* has visible children (it simply checks whether it has 1
|
|
57
|
-
* `<ScreenReaderContent>` child.)
|
|
58
|
-
**/
|
|
59
|
-
export default function updateV7ButtonsIconCircle(
|
|
60
|
-
j: JSCodeshift,
|
|
61
|
-
root: Collection,
|
|
62
|
-
importedName: string,
|
|
63
|
-
filePath: string
|
|
64
|
-
) {
|
|
65
|
-
// find out if the button has got any visible text inside it, in this case
|
|
66
|
-
// just display a warning, that it cannot be upgraded.
|
|
67
|
-
const buttonsWithNoText = findElements(filePath, j, root, importedName, {
|
|
68
|
-
name: 'variant',
|
|
69
|
-
value: [
|
|
70
|
-
'icon',
|
|
71
|
-
'icon-inverse',
|
|
72
|
-
'circle-default',
|
|
73
|
-
'circle-primary',
|
|
74
|
-
'circle-danger'
|
|
75
|
-
]
|
|
76
|
-
}).filter((path) => {
|
|
77
|
-
// finds all with no/ScreenReader children
|
|
78
|
-
const children = getVisibleChildren(path.value.children)
|
|
79
|
-
if (children.length == 0) {
|
|
80
|
-
return true
|
|
81
|
-
}
|
|
82
|
-
if (children.length > 1) {
|
|
83
|
-
printWarning(
|
|
84
|
-
filePath,
|
|
85
|
-
path.value.loc?.start.line,
|
|
86
|
-
'Cannot update icon/circle Button because it has multiple ' +
|
|
87
|
-
'children. You will need to update this manually.'
|
|
88
|
-
)
|
|
89
|
-
return false
|
|
90
|
-
}
|
|
91
|
-
let screenReaderChildText
|
|
92
|
-
const child = children[0]
|
|
93
|
-
if (
|
|
94
|
-
isJSXElement(child) &&
|
|
95
|
-
(child.openingElement.name as JSXIdentifier).name ===
|
|
96
|
-
'ScreenReaderContent'
|
|
97
|
-
) {
|
|
98
|
-
const screenReaderChildren = getVisibleChildren(child.children)
|
|
99
|
-
if (screenReaderChildren.length === 1) {
|
|
100
|
-
if (!screenReaderChildText) {
|
|
101
|
-
const firstChild = screenReaderChildren[0]
|
|
102
|
-
if (isJSXText(firstChild)) {
|
|
103
|
-
screenReaderChildText = j.stringLiteral(firstChild.value)
|
|
104
|
-
} else if (isJSXExpressionContainer(firstChild)) {
|
|
105
|
-
screenReaderChildText = firstChild
|
|
106
|
-
} else {
|
|
107
|
-
printWarning(
|
|
108
|
-
filePath,
|
|
109
|
-
path.value.loc?.start.line,
|
|
110
|
-
'Cannot update icon/circle Button because I cant ' +
|
|
111
|
-
'recognize whats inside its ScreenReaderContent. ' +
|
|
112
|
-
'You will need to update this manually.'
|
|
113
|
-
)
|
|
114
|
-
return false
|
|
115
|
-
}
|
|
116
|
-
} else {
|
|
117
|
-
printWarning(
|
|
118
|
-
filePath,
|
|
119
|
-
path.value.loc?.start.line,
|
|
120
|
-
'Cannot update icon/circle Button because it has ' +
|
|
121
|
-
'multiple ScreenReaderContent children. You will need to ' +
|
|
122
|
-
'update this manually.'
|
|
123
|
-
)
|
|
124
|
-
return false
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
if (screenReaderChildText) {
|
|
129
|
-
path.value.openingElement.attributes!.push(
|
|
130
|
-
j.jsxAttribute(
|
|
131
|
-
j.jsxIdentifier('screenReaderLabel'),
|
|
132
|
-
screenReaderChildText
|
|
133
|
-
)
|
|
134
|
-
)
|
|
135
|
-
removeAllChildren(path.value)
|
|
136
|
-
return true
|
|
137
|
-
}
|
|
138
|
-
printWarning(
|
|
139
|
-
filePath,
|
|
140
|
-
path.value.loc?.start.line,
|
|
141
|
-
'Cannot update icon/circle Button because it has visible ' +
|
|
142
|
-
'children. You will need to update this manually.'
|
|
143
|
-
)
|
|
144
|
-
return false
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
if (buttonsWithNoText.length == 0) {
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
// add IconButton import
|
|
151
|
-
const iconButtonImportName = addImportIfNeeded(
|
|
152
|
-
j,
|
|
153
|
-
root,
|
|
154
|
-
'IconButton',
|
|
155
|
-
'@instructure/ui-buttons'
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
// rename every <Button> to <IconButton> (or whatever alias it's imported under)
|
|
159
|
-
renameElements(filePath, buttonsWithNoText, 'Button', iconButtonImportName)
|
|
160
|
-
|
|
161
|
-
// remove variant="icon", add withBorder={false} withBackground={false}
|
|
162
|
-
const iconButton = findAttribute(
|
|
163
|
-
filePath,
|
|
164
|
-
j,
|
|
165
|
-
buttonsWithNoText,
|
|
166
|
-
'variant',
|
|
167
|
-
'icon'
|
|
168
|
-
).remove()
|
|
169
|
-
addWithBorderBackground(j, iconButton)
|
|
170
|
-
|
|
171
|
-
// change variant="icon-inverse" to color="primary-inverse" withBorder={false} withBackground={false}
|
|
172
|
-
const iconInverse = findAttribute(
|
|
173
|
-
filePath,
|
|
174
|
-
j,
|
|
175
|
-
buttonsWithNoText,
|
|
176
|
-
'variant',
|
|
177
|
-
'icon-inverse'
|
|
178
|
-
).replaceWith((nodePath) => {
|
|
179
|
-
const { node } = nodePath
|
|
180
|
-
node.name.name = 'color'
|
|
181
|
-
;(node.value as Literal).value = 'primary-inverse'
|
|
182
|
-
return nodePath.node
|
|
183
|
-
})
|
|
184
|
-
addWithBorderBackground(j, iconInverse)
|
|
185
|
-
|
|
186
|
-
// change variant="circle-default" to color="secondary" shape="circle"
|
|
187
|
-
findAttribute(filePath, j, buttonsWithNoText, 'variant', 'circle-default')
|
|
188
|
-
.replaceWith((nodePath) => {
|
|
189
|
-
const { node } = nodePath
|
|
190
|
-
node.name.name = 'color'
|
|
191
|
-
;(node.value as Literal).value = 'secondary'
|
|
192
|
-
return nodePath.node
|
|
193
|
-
})
|
|
194
|
-
.insertAfter(
|
|
195
|
-
j.jsxAttribute(j.jsxIdentifier('shape'), j.stringLiteral('circle'))
|
|
196
|
-
)
|
|
197
|
-
|
|
198
|
-
// change variant="circle-primary" to color="primary" shape="circle"
|
|
199
|
-
findAttribute(filePath, j, buttonsWithNoText, 'variant', 'circle-primary')
|
|
200
|
-
.replaceWith((nodePath) => {
|
|
201
|
-
const { node } = nodePath
|
|
202
|
-
node.name.name = 'color'
|
|
203
|
-
;(node.value as Literal).value = 'primary'
|
|
204
|
-
return nodePath.node
|
|
205
|
-
})
|
|
206
|
-
.insertAfter(
|
|
207
|
-
j.jsxAttribute(j.jsxIdentifier('shape'), j.stringLiteral('circle'))
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
// change variant="circle-danger" to color="danger" shape="circle"
|
|
211
|
-
findAttribute(filePath, j, buttonsWithNoText, 'variant', 'circle-danger')
|
|
212
|
-
.replaceWith((nodePath) => {
|
|
213
|
-
const { node } = nodePath
|
|
214
|
-
node.name.name = 'color'
|
|
215
|
-
;(node.value as Literal).value = 'danger'
|
|
216
|
-
return nodePath.node
|
|
217
|
-
})
|
|
218
|
-
.insertAfter(
|
|
219
|
-
j.jsxAttribute(j.jsxIdentifier('shape'), j.stringLiteral('circle'))
|
|
220
|
-
)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function addWithBorderBackground(
|
|
224
|
-
j: JSCodeshift,
|
|
225
|
-
root: Collection<JSXAttribute>
|
|
226
|
-
) {
|
|
227
|
-
root
|
|
228
|
-
.insertAfter(
|
|
229
|
-
j.jsxAttribute(
|
|
230
|
-
j.jsxIdentifier('withBorder'),
|
|
231
|
-
j.jsxExpressionContainer(j.jsxIdentifier('false'))
|
|
232
|
-
)
|
|
233
|
-
)
|
|
234
|
-
.insertAfter(
|
|
235
|
-
j.jsxAttribute(
|
|
236
|
-
j.jsxIdentifier('withBackground'),
|
|
237
|
-
j.jsxExpressionContainer(j.jsxIdentifier('false'))
|
|
238
|
-
)
|
|
239
|
-
)
|
|
240
|
-
}
|