Code mod for Salt Design System packages, features include
- Upgrade
@salt-ds/*to latest version - React props migration due to deprecation, or warning when not possible
- Import statement updates due to components being moved from lab to core
- CSS variable renames due to deprecation
- Warn invalid Salt CSS variables
npx salt-codemod --dryRun
Use --help to see all available options.
The script will first attempt to upgrade all @salt-ds/* packages using npm-check-updates. You can skip it via --skipUpgrade.
JavaScript files are included based on tsConfig.json using ts-morph, which can be cusmised via --tsconfig "./another/path/tsConfig.json". You may override this entirely and provide files by --tsSourceGlob, which may help in a monorepo setup.
Invalid CSS variables are extracted from @salt-ds/theme/index.css, which path can be changed using --themeCss. By default all *.css|ts|tsx will be included for scanning and processing, you can change it using --cssModeGlob.
There is --mode option available if you just want to run React or CSS part of the codemod.
This experimental feature migrates FormField components from @salt-ds/lab to @salt-ds/core. It transforms the label and helperText props into child elements.
npx salt-codemod --migrateFormControlsBefore:
import { FormField } from "@salt-ds/lab";
<FormField label="Username" helperText="Enter your username">
<Input />
</FormField>After:
import { FormField, FormFieldLabel, FormFieldHelperText } from "@salt-ds/core";
<FormField>
<FormFieldLabel>Username</FormFieldLabel>
<Input />
<FormFieldHelperText>Enter your username</FormFieldHelperText>
</FormField>The migration handles:
- String literal props (
label="Name") - JSX expression props (
label={variable},label={getLabel()}) - Template literals (
label={\Hello ${name}`}`) - Conditional expressions (
label={isRequired ? "Required" : "Optional"}) - Aliased imports (
import { FormField as FF }) - Multiple FormField instances in the same file
- Nested FormField components
Note: This feature is off by default. Enable it with --migrateFormControls.
This codemod currently supports @salt-ds/core versions 1.0.0 through 1.54.2.
To add support for newer @salt-ds versions, follow these steps:
Update LATEST_SUPPORTED_VERSION in utils/args.js:
export const LATEST_SUPPORTED_VERSION = "1.XX.0";Create a new migration file migration/coreXXXX.js (e.g., core1540.js for v1.54.0):
import { moveNamedImports } from "./utils.js";
// MMM DD, YYYY (use npm publish date)
export function reactXXXX(file) {
// https://github.com/jpmorganchase/salt-ds/releases/tag/%40salt-ds%2Fcore%40X.XX.0
// https://github.com/jpmorganchase/salt-ds/releases/tag/%40salt-ds%2Flab%40X.X.X-alpha.XX
// Component migrations (if any)
["ComponentName", "ComponentNameProps"].forEach((x) => {
moveNamedImports(file, {
namedImportText: x,
from: "@salt-ds/lab",
to: "@salt-ds/core",
});
});
}
// CSS migrations (if any)
export const cssXXXXRenameMap = [
["--old-variable", "--new-variable"],
];Getting the correct publish date:
npm view @salt-ds/core@X.XX.0 time.X.XX.0Add imports:
import { reactXXXX, cssXXXXRenameMap } from "./migration/coreXXXX.js";Add version constant:
const vXXXX = parse("X.XX.0");Add React migration logic (around line 204-318):
if (gt(vXXXX, fromVersion) && lte(vXXXX, toVersion)) {
reactXXXX(file);
}Add CSS migration logic (around line 377-415, if CSS changes exist):
if (gt(vXXXX, fromVersion) && lte(vXXXX, toVersion)) {
cssMigrationMapArray.push(...cssXXXXRenameMap);
}Add smoke tests in __tests__/smoke.spec.js:
import { reactXXXX } from "../migration/coreXXXX";
test("reactXXXX", () => {
const file = createFileWithContent(`import { Component } from "@salt-ds/lab";
export const App = () => <Component />;
`);
reactXXXX(file);
expect(file.getText().includes(`from "@salt-ds/core"`)).toBeTruthy();
});npx changesetSelect "minor" and describe: "Supports upto @salt-ds/core@X.XX.0"
npm testmoveNamedImports(file, {
namedImportText: "ComponentName",
from: "@salt-ds/lab",
to: "@salt-ds/core",
});for (const declaration of file.getImportDeclarations()) {
renameNamedImports(declaration, {
moduleSpecifier: "@salt-ds/core",
from: "OldName",
to: "NewName",
});
}replaceReactAttribute(file, {
elementName: "Button",
attributeFrom: "variant",
valueFrom: `"cta"`,
attributeTo: "sentiment",
valueTo: `"accented"`,
});movePropToNewChildElement(file, {
packageName: "@salt-ds/lab",
elementName: "FormField",
propName: "label",
newChildName: "FormFieldLabel",
newChildPackageName: "@salt-ds/core",
});This transforms <FormField label="Name"> into:
<FormField>
<FormFieldLabel>Name</FormFieldLabel>
</FormField>Theme package CSS variable changes are tracked separately. Check:
npm view @salt-ds/theme time --json | grep -E '"X\.XX\.0"'yarn to install all dependencies.
Run npm link in the root folder, then you'll able to run salt-codemod as if it's a command. npm unlink to undo.