@mui/x-codemod 6.0.0-alpha.11
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/README.md +128 -0
- package/codemod.js +80 -0
- package/package.json +51 -0
- package/util/propsToObject.js +54 -0
- package/util/readFile.js +16 -0
- package/util/renameClassKey.js +29 -0
- package/util/renameProps.js +19 -0
- package/v6.0.0/component-rename-prop/index.js +20 -0
- package/v6.0.0/localization-provider-rename-locale/index.js +20 -0
- package/v6.0.0/preset-safe/index.js +16 -0
- package/v6.0.0/text-props-to-localeText/index.js +101 -0
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# @mui/x-codemod
|
|
2
|
+
|
|
3
|
+
> Codemod scripts for MUI X
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@mui/x-codemod)
|
|
6
|
+
[](https://www.npmjs.com/package/@mui/x-codemod)
|
|
7
|
+
|
|
8
|
+
This repository contains a collection of codemod scripts based for use with
|
|
9
|
+
[jscodeshift](https://github.com/facebook/jscodeshift) that help update MUI X APIs.
|
|
10
|
+
|
|
11
|
+
## Setup & run
|
|
12
|
+
|
|
13
|
+
<!-- #default-branch-switch -->
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx @mui/x-codemod <codemod> <paths...>
|
|
17
|
+
|
|
18
|
+
Applies a `@mui/x-codemod` to the specified paths
|
|
19
|
+
|
|
20
|
+
Positionals:
|
|
21
|
+
codemod The name of the codemod [string]
|
|
22
|
+
paths Paths forwarded to `jscodeshift` [string]
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--version Show version number [boolean]
|
|
26
|
+
--help Show help [boolean]
|
|
27
|
+
--parser which parser for jscodeshift to use.
|
|
28
|
+
[string] [default: 'tsx']
|
|
29
|
+
--jscodeshift Pass options directly to jscodeshift [array]
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
npx @mui/x-codemod v6.0.0/preset-safe src
|
|
33
|
+
npx @mui/x-codemod v6.0.0/component-rename-prop src --
|
|
34
|
+
--component=DataGrid --from=prop --to=newProp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### `jscodeshift` options
|
|
38
|
+
|
|
39
|
+
To pass more options directly to jscodeshift, use `--jscodeshift=...`. For example:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
// single option
|
|
43
|
+
npx @mui/x-codemod --jscodeshift=--run-in-band
|
|
44
|
+
// multiple options
|
|
45
|
+
npx @mui/x-codemod --jscodeshift=--cpus=1 --jscodeshift=--print --jscodeshift=--dry --jscodeshift=--verbose=2
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
See all available options [here](https://github.com/facebook/jscodeshift#usage-cli).
|
|
49
|
+
|
|
50
|
+
### `Recast` Options
|
|
51
|
+
|
|
52
|
+
Options to [recast](https://github.com/benjamn/recast)'s printer can be provided
|
|
53
|
+
through jscodeshift's `printOptions` command line argument
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
npx @mui/x-codemod <transform> <path> --jscodeshift="--printOptions='{\"quote\":\"double\"}'"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Included scripts
|
|
60
|
+
|
|
61
|
+
### v6.0.0
|
|
62
|
+
|
|
63
|
+
#### 🚀 `preset-safe`
|
|
64
|
+
|
|
65
|
+
A combination of all important transformers for migrating v5 to v6. ⚠️ This codemod should be run only once.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
npx @mui/x-codemod v6.0.0/preset-safe <path|folder>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The list includes these transformers
|
|
72
|
+
|
|
73
|
+
- [`localization-provider-rename-locale`](#localization-provider-rename-locale)
|
|
74
|
+
- [`text-props-to-localeText`](#text-props-to-localeText)
|
|
75
|
+
|
|
76
|
+
#### `localization-provider-rename-locale`
|
|
77
|
+
|
|
78
|
+
Renames `locale` into `adapterLocale` (or `LocalizationProvider`)
|
|
79
|
+
|
|
80
|
+
```diff
|
|
81
|
+
<LocalizationProvider
|
|
82
|
+
dateAdapter={AdapterDayjs}
|
|
83
|
+
- locale="fr"
|
|
84
|
+
+ adapterLocale="fr"
|
|
85
|
+
>
|
|
86
|
+
{children}
|
|
87
|
+
</LocalizationProvider
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
npx @mui/x-codemod v6.0.0/localization-provider-rename-locale <path>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
#### `text-props-to-localeText`
|
|
96
|
+
|
|
97
|
+
Replace props used for localization such as `cancelText` to their corresponding `localeText` key.
|
|
98
|
+
|
|
99
|
+
```diff
|
|
100
|
+
<DatePicker
|
|
101
|
+
- cancelText="Cancelar"
|
|
102
|
+
+ localeText={{
|
|
103
|
+
+ cancelButtonLabel: "Cancelar"
|
|
104
|
+
+ }}
|
|
105
|
+
/>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```sh
|
|
109
|
+
npx @mui/x-codemod v6.0.0/text-props-to-localeText <path>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
If you were always using the same text value in all your components, consider moving those translation from the component to the `LocalizationProvider` by hand.
|
|
113
|
+
|
|
114
|
+
```diff
|
|
115
|
+
<LocalizationProvider
|
|
116
|
+
dateAdapter={AdapterDayjs}
|
|
117
|
+
+ localeText={{ cancelButtonLabel: "Cancelar" }}
|
|
118
|
+
>
|
|
119
|
+
<DatePicker
|
|
120
|
+
- localeText={{ cancelButtonLabel: "Cancelar" }}
|
|
121
|
+
/>
|
|
122
|
+
<DateTimePicker
|
|
123
|
+
- localeText={{ cancelButtonLabel: "Cancelar" }}
|
|
124
|
+
/>
|
|
125
|
+
</LocalizationProvider>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
You can find more details about this breaking change in [the migration guide](https://next.mui.com/x/migration/migration-pickers-v5/#rename-the-locale-prop-on-localizationprovider).
|
package/codemod.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
5
|
+
var _child_process = _interopRequireDefault(require("child_process"));
|
|
6
|
+
var _fs = require("fs");
|
|
7
|
+
var _path = _interopRequireDefault(require("path"));
|
|
8
|
+
var _yargs = _interopRequireDefault(require("yargs"));
|
|
9
|
+
const jscodeshiftPackage = require('jscodeshift/package.json');
|
|
10
|
+
const jscodeshiftDirectory = _path.default.dirname(require.resolve('jscodeshift'));
|
|
11
|
+
const jscodeshiftExecutable = _path.default.join(jscodeshiftDirectory, jscodeshiftPackage.bin.jscodeshift);
|
|
12
|
+
async function runTransform(transform, files, flags, codemodFlags) {
|
|
13
|
+
const transformerSrcPath = _path.default.resolve(__dirname, './src', transform);
|
|
14
|
+
const transformerBuildPath = _path.default.resolve(__dirname, transform);
|
|
15
|
+
let transformerPath;
|
|
16
|
+
try {
|
|
17
|
+
await _fs.promises.stat(transformerSrcPath);
|
|
18
|
+
transformerPath = transformerSrcPath;
|
|
19
|
+
} catch (srcPathError) {
|
|
20
|
+
try {
|
|
21
|
+
await _fs.promises.stat(transformerBuildPath);
|
|
22
|
+
transformerPath = transformerBuildPath;
|
|
23
|
+
} catch (buildPathError) {
|
|
24
|
+
if (buildPathError.code === 'ENOENT') {
|
|
25
|
+
throw new Error(`Transform '${transform}' not found. Check out ${_path.default.resolve(__dirname, './README.md for a list of available codemods.')}`);
|
|
26
|
+
}
|
|
27
|
+
throw buildPathError;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const args = [
|
|
31
|
+
// can't directly spawn `jscodeshiftExecutable` due to https://github.com/facebook/jscodeshift/issues/424
|
|
32
|
+
jscodeshiftExecutable, '--transform', transformerPath, ...codemodFlags, '--extensions', 'js,ts,jsx,tsx', '--parser', flags.parser || 'tsx', '--ignore-pattern', '**/node_modules/**', ...flags.jscodeshift];
|
|
33
|
+
args.push(...files);
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line no-console -- debug information
|
|
36
|
+
console.log(`Executing command: jscodeshift ${args.join(' ')}`);
|
|
37
|
+
const jscodeshiftProcess = _child_process.default.spawnSync('node', args, {
|
|
38
|
+
stdio: 'inherit'
|
|
39
|
+
});
|
|
40
|
+
if (jscodeshiftProcess.error) {
|
|
41
|
+
throw jscodeshiftProcess.error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function run(argv) {
|
|
45
|
+
const {
|
|
46
|
+
codemod,
|
|
47
|
+
paths,
|
|
48
|
+
_: other,
|
|
49
|
+
jscodeshift,
|
|
50
|
+
parser
|
|
51
|
+
} = argv;
|
|
52
|
+
return runTransform(codemod, paths.map(filePath => _path.default.resolve(filePath)), {
|
|
53
|
+
jscodeshift,
|
|
54
|
+
parser
|
|
55
|
+
}, other || []);
|
|
56
|
+
}
|
|
57
|
+
_yargs.default.command({
|
|
58
|
+
command: '$0 <codemod> <paths...>',
|
|
59
|
+
describe: 'Applies a `@mui/x-codemod` to the specified paths',
|
|
60
|
+
// @ts-expect-error
|
|
61
|
+
builder: command => {
|
|
62
|
+
return command.positional('codemod', {
|
|
63
|
+
description: 'The name of the codemod',
|
|
64
|
+
type: 'string'
|
|
65
|
+
}).positional('paths', {
|
|
66
|
+
array: true,
|
|
67
|
+
description: 'Paths forwarded to `jscodeshift`',
|
|
68
|
+
type: 'string'
|
|
69
|
+
}).option('parser', {
|
|
70
|
+
description: 'which parser for jscodeshift to use',
|
|
71
|
+
default: 'tsx',
|
|
72
|
+
type: 'string'
|
|
73
|
+
}).option('jscodeshift', {
|
|
74
|
+
description: '(Advanced) Pass options directly to jscodeshift',
|
|
75
|
+
default: [],
|
|
76
|
+
type: 'array'
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
handler: run
|
|
80
|
+
}).scriptName('npx @mui/x-codemod').example('$0 v6.0.0/localization-provider-rename-locale src', 'Run "localization-provider-rename-locale" codemod on "src" path').example('$0 v6.0.0/component-rename-prop src -- --component=DataGrid --from=prop --to=newProp', 'Run "component-rename-prop" codemod in "src" path on "DataGrid" component with custom "from" and "to" arguments').help().parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mui/x-codemod",
|
|
3
|
+
"version": "6.0.0-alpha.11",
|
|
4
|
+
"bin": "./codemod.js",
|
|
5
|
+
"private": false,
|
|
6
|
+
"author": "MUI Team",
|
|
7
|
+
"description": "Codemod scripts for MUI X.",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"react",
|
|
10
|
+
"react-component",
|
|
11
|
+
"mui",
|
|
12
|
+
"codemod",
|
|
13
|
+
"jscodeshift"
|
|
14
|
+
],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/x-codemod/**/*.test.ts'",
|
|
17
|
+
"typescript": "tsc -p tsconfig.json",
|
|
18
|
+
"prebuild": "rimraf build",
|
|
19
|
+
"copy-files": "cpy README.md build && cpy package.json build",
|
|
20
|
+
"build": "node ../../scripts/build.mjs node --ignore 'src/types.ts' && yarn copy-files"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/mui/mui-x.git",
|
|
25
|
+
"directory": "packages/x-codemod"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"homepage": "https://github.com/mui/mui-x/tree/next/packages/x-codemod",
|
|
29
|
+
"funding": {
|
|
30
|
+
"type": "opencollective",
|
|
31
|
+
"url": "https://opencollective.com/mui"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@babel/core": "^7.20.2",
|
|
35
|
+
"@babel/runtime": "^7.20.1",
|
|
36
|
+
"@babel/traverse": "^7.20.1",
|
|
37
|
+
"jscodeshift": "0.13.1",
|
|
38
|
+
"jscodeshift-add-imports": "^1.0.10",
|
|
39
|
+
"yargs": "^17.6.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/jscodeshift": "^0.11.5"
|
|
43
|
+
},
|
|
44
|
+
"sideEffects": false,
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=14.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = propsToObject;
|
|
7
|
+
function propsToObject({
|
|
8
|
+
j,
|
|
9
|
+
root,
|
|
10
|
+
componentName,
|
|
11
|
+
aliasName,
|
|
12
|
+
propName,
|
|
13
|
+
props
|
|
14
|
+
}) {
|
|
15
|
+
function buildObject(node, value) {
|
|
16
|
+
const shorthand = node.value.expression && node.value.expression.name === node.name.name;
|
|
17
|
+
const property = j.objectProperty(j.identifier(node.name.name), node.value.expression ? node.value.expression : node.value);
|
|
18
|
+
property.shorthand = shorthand;
|
|
19
|
+
value.push(property);
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
const result = aliasName ? root.find(j.JSXElement, {
|
|
23
|
+
openingElement: {
|
|
24
|
+
name: {
|
|
25
|
+
property: {
|
|
26
|
+
name: componentName
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}) : root.findJSXElements(componentName);
|
|
31
|
+
return result.forEach(path => {
|
|
32
|
+
// @ts-expect-error
|
|
33
|
+
if (!aliasName || aliasName && path.node.openingElement.name.object.name === aliasName) {
|
|
34
|
+
let propValue = [];
|
|
35
|
+
const attributes = path.node.openingElement.attributes;
|
|
36
|
+
attributes?.forEach((node, index) => {
|
|
37
|
+
// Only transform whitelisted props
|
|
38
|
+
if (node.type === 'JSXAttribute' && props.includes(node.name.name)) {
|
|
39
|
+
propValue = buildObject(node, propValue);
|
|
40
|
+
delete attributes[index];
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
if (propValue.length > 0) {
|
|
44
|
+
const propNameAttr = attributes?.find(attr => attr.type === 'JSXAttribute' && attr.name.name === propName);
|
|
45
|
+
if (propNameAttr && propNameAttr.type === 'JSXAttribute') {
|
|
46
|
+
// @ts-expect-error
|
|
47
|
+
(propNameAttr.value.expression?.properties || []).push(...j.objectExpression(propValue).properties);
|
|
48
|
+
} else {
|
|
49
|
+
attributes?.push(j.jsxAttribute(j.jsxIdentifier(propName), j.jsxExpressionContainer(j.objectExpression(propValue))));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
package/util/readFile.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = readFile;
|
|
8
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
9
|
+
var _os = require("os");
|
|
10
|
+
function readFile(filePath) {
|
|
11
|
+
const fileContents = _fs.default.readFileSync(filePath, 'utf8').toString();
|
|
12
|
+
if (_os.EOL !== '\n') {
|
|
13
|
+
return fileContents.replace(/\n/g, _os.EOL);
|
|
14
|
+
}
|
|
15
|
+
return fileContents;
|
|
16
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = renameClassKey;
|
|
7
|
+
function renameClassKey({
|
|
8
|
+
root,
|
|
9
|
+
componentName,
|
|
10
|
+
classes,
|
|
11
|
+
printOptions
|
|
12
|
+
}) {
|
|
13
|
+
const source = root.findJSXElements(componentName).forEach(path => {
|
|
14
|
+
path.node.openingElement.attributes?.forEach(node => {
|
|
15
|
+
if (node.type === 'JSXAttribute' && node.name.name === 'classes') {
|
|
16
|
+
// @ts-expect-error
|
|
17
|
+
node.value?.expression?.properties?.forEach(subNode => {
|
|
18
|
+
if (Object.keys(classes).includes(subNode.key.name)) {
|
|
19
|
+
subNode.key.name = classes[subNode.key.name];
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}).toSource(printOptions);
|
|
25
|
+
return Object.entries(classes).reduce((result, [currentKey, newKey]) => {
|
|
26
|
+
const regex = new RegExp(`.Mui${componentName}-${currentKey}`, 'gm');
|
|
27
|
+
return result.replace(regex, `.Mui${componentName}-${newKey}`);
|
|
28
|
+
}, source);
|
|
29
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = renameProps;
|
|
7
|
+
function renameProps({
|
|
8
|
+
root,
|
|
9
|
+
componentName,
|
|
10
|
+
props
|
|
11
|
+
}) {
|
|
12
|
+
return root.findJSXElements(componentName).forEach(path => {
|
|
13
|
+
path.node.openingElement.attributes?.forEach(node => {
|
|
14
|
+
if (node.type === 'JSXAttribute' && Object.keys(props).includes(node.name.name)) {
|
|
15
|
+
node.name.name = props[node.name.name];
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = transformer;
|
|
8
|
+
var _renameProps = _interopRequireDefault(require("../../util/renameProps"));
|
|
9
|
+
function transformer(file, api, options) {
|
|
10
|
+
const j = api.jscodeshift;
|
|
11
|
+
const root = j(file.source);
|
|
12
|
+
const printOptions = options.printOptions;
|
|
13
|
+
return (0, _renameProps.default)({
|
|
14
|
+
root,
|
|
15
|
+
componentName: options.component,
|
|
16
|
+
props: {
|
|
17
|
+
[options.from]: options.to
|
|
18
|
+
}
|
|
19
|
+
}).toSource(printOptions);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = transformer;
|
|
8
|
+
var _renameProps = _interopRequireDefault(require("../../util/renameProps"));
|
|
9
|
+
function transformer(file, api, options) {
|
|
10
|
+
const j = api.jscodeshift;
|
|
11
|
+
const root = j(file.source);
|
|
12
|
+
const printOptions = options.printOptions;
|
|
13
|
+
return (0, _renameProps.default)({
|
|
14
|
+
root,
|
|
15
|
+
componentName: 'LocalizationProvider',
|
|
16
|
+
props: {
|
|
17
|
+
locale: 'adapterLocale'
|
|
18
|
+
}
|
|
19
|
+
}).toSource(printOptions);
|
|
20
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = transformer;
|
|
8
|
+
var _localizationProviderRenameLocale = _interopRequireDefault(require("../localization-provider-rename-locale"));
|
|
9
|
+
var _textPropsToLocaleText = _interopRequireDefault(require("../text-props-to-localeText"));
|
|
10
|
+
function transformer(file, api, options) {
|
|
11
|
+
file.source = (0, _localizationProviderRenameLocale.default)(file, api, options);
|
|
12
|
+
|
|
13
|
+
// Should be run before the renaming of components such as `ClockPicker` to `TimeClock`.
|
|
14
|
+
file.source = (0, _textPropsToLocaleText.default)(file, api, options);
|
|
15
|
+
return file.source;
|
|
16
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.default = transformer;
|
|
8
|
+
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
9
|
+
const defaultPropsToKey = {
|
|
10
|
+
cancelText: ['cancelButtonLabel'],
|
|
11
|
+
okText: ['okButtonLabel'],
|
|
12
|
+
todayText: ['todayButtonLabel'],
|
|
13
|
+
clearText: ['clearButtonLabel'],
|
|
14
|
+
endText: ['end'],
|
|
15
|
+
getClockLabelText: ['clockLabelText'],
|
|
16
|
+
getHoursClockNumberText: ['hoursClockNumberText'],
|
|
17
|
+
getMinutesClockNumberText: ['minutesClockNumberText'],
|
|
18
|
+
getSecondsClockNumberText: ['secondsClockNumberText'],
|
|
19
|
+
getViewSwitchingButtonText: ['calendarViewSwitchingButtonAriaLabel'],
|
|
20
|
+
startText: ['start']
|
|
21
|
+
};
|
|
22
|
+
const isMonthSwitchComponent = {
|
|
23
|
+
DatePicker: true,
|
|
24
|
+
StaticDatePicker: true,
|
|
25
|
+
MobileDatePicker: true,
|
|
26
|
+
DesktopDatePicker: true,
|
|
27
|
+
DateRangePicker: true,
|
|
28
|
+
StaticDateRangePicker: true,
|
|
29
|
+
MobileDateRangePicker: true,
|
|
30
|
+
DesktopDateRangePicker: true,
|
|
31
|
+
CalendarPicker: true,
|
|
32
|
+
// Special cases of DateTimePickers present in both
|
|
33
|
+
DateTimePicker: true,
|
|
34
|
+
StaticDateTimePicker: true,
|
|
35
|
+
MobileDateTimePicker: true,
|
|
36
|
+
DesktopDateTimePicker: true
|
|
37
|
+
};
|
|
38
|
+
const isViewSwitchComponent = {
|
|
39
|
+
TimePicker: true,
|
|
40
|
+
StaticTimePicker: true,
|
|
41
|
+
MobileTimePicker: true,
|
|
42
|
+
DesktopTimePicker: true,
|
|
43
|
+
DateTimePicker: true,
|
|
44
|
+
ClockPicker: true,
|
|
45
|
+
// Special cases of DateTimePickers present in both
|
|
46
|
+
StaticDateTimePicker: true,
|
|
47
|
+
MobileDateTimePicker: true,
|
|
48
|
+
DesktopDateTimePicker: true
|
|
49
|
+
};
|
|
50
|
+
const needsWrapper = {
|
|
51
|
+
ClockPicker: true,
|
|
52
|
+
CalendarPicker: true
|
|
53
|
+
};
|
|
54
|
+
const impactedComponents = ['DateRangePicker', 'CalendarPicker', 'ClockPicker', 'DatePicker', 'DateRangePicker', 'DateRangePickerDay', 'DateTimePicker', 'DesktopDatePicker', 'DesktopDateRangePicker', 'DesktopDateTimePicker', 'DesktopTimePicker', 'MobileDatePicker', 'MobileDateRangePicker', 'MobileDateTimePicker', 'MobileTimePicker', 'StaticDatePicker', 'StaticDateRangePicker', 'StaticDateTimePicker', 'StaticTimePicker', 'TimePicker'];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {import('jscodeshift').FileInfo} file
|
|
58
|
+
* @param {import('jscodeshift').API} api
|
|
59
|
+
*/
|
|
60
|
+
function transformer(file, api, options) {
|
|
61
|
+
const j = api.jscodeshift;
|
|
62
|
+
const printOptions = options.printOptions;
|
|
63
|
+
const root = j(file.source);
|
|
64
|
+
impactedComponents.forEach(componentName => {
|
|
65
|
+
const propsToKey = (0, _extends2.default)({}, defaultPropsToKey, {
|
|
66
|
+
leftArrowButtonText: [...(isViewSwitchComponent[componentName] ? ['openPreviousView'] : []), ...(isMonthSwitchComponent[componentName] ? ['previousMonth'] : [])],
|
|
67
|
+
rightArrowButtonText: [...(isViewSwitchComponent[componentName] ? ['openNextView'] : []), ...(isMonthSwitchComponent[componentName] ? ['nextMonth'] : [])]
|
|
68
|
+
});
|
|
69
|
+
root.findJSXElements(componentName).forEach(path => {
|
|
70
|
+
const newLocaleText = [];
|
|
71
|
+
const attributes = path.node.openingElement.attributes;
|
|
72
|
+
attributes.forEach((node, index) => {
|
|
73
|
+
if (node.type === 'JSXAttribute' && propsToKey[node.name.name] !== undefined) {
|
|
74
|
+
const newNames = propsToKey[node.name.name];
|
|
75
|
+
newNames.forEach(newName => {
|
|
76
|
+
const property = j.objectProperty(j.identifier(newName), node.value.expression ? node.value.expression : j.literal(node.value.value));
|
|
77
|
+
property.shorthand = node.value.expression && node.value.expression.name === newName;
|
|
78
|
+
newLocaleText.push(property);
|
|
79
|
+
});
|
|
80
|
+
delete attributes[index];
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (newLocaleText.length > 0) {
|
|
84
|
+
if (needsWrapper[componentName]) {
|
|
85
|
+
// From : https://www.codeshiftcommunity.com/docs/react/#wrapping-components
|
|
86
|
+
|
|
87
|
+
// Create a new JSXElement called "LocalizationProvider" and use the original component as children
|
|
88
|
+
const wrappedComponent = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('LocalizationProvider'), [
|
|
89
|
+
// Add the new localeText prop
|
|
90
|
+
j.jsxAttribute(j.jsxIdentifier('localeText'), j.jsxExpressionContainer(j.objectExpression(newLocaleText)))]), j.jsxClosingElement(j.jsxIdentifier('LocalizationProvider')), [path.value] // Pass in the original component as children
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
j(path).replaceWith(wrappedComponent);
|
|
94
|
+
} else {
|
|
95
|
+
attributes.push(j.jsxAttribute(j.jsxIdentifier('localeText'), j.jsxExpressionContainer(j.objectExpression(newLocaleText))));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
return root.toSource(printOptions);
|
|
101
|
+
}
|