diff --git a/.changeset/fluffy-owls-breathe.md b/.changeset/fluffy-owls-breathe.md new file mode 100644 index 00000000000..44580dcfe39 --- /dev/null +++ b/.changeset/fluffy-owls-breathe.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris-migrator': patch +--- + +Update `createInlineComment` to format text with RegExp diff --git a/.changeset/fresh-rats-pay.md b/.changeset/fresh-rats-pay.md new file mode 100644 index 00000000000..a81a8f6ab05 --- /dev/null +++ b/.changeset/fresh-rats-pay.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris-migrator': patch +--- + +Add support to replace Identifiers along with JSXIdentifiers for Text migration diff --git a/.changeset/light-mayflies-drive.md b/.changeset/light-mayflies-drive.md new file mode 100644 index 00000000000..3608ff3c196 --- /dev/null +++ b/.changeset/light-mayflies-drive.md @@ -0,0 +1,5 @@ +--- +'@shopify/polaris-migrator': minor +--- + +Renamed and split migrations based on scope and type (react, scss, and styles) diff --git a/polaris-migrator/README.md b/polaris-migrator/README.md index 549e1e8f7e9..d5b26d0b21c 100644 --- a/polaris-migrator/README.md +++ b/polaris-migrator/README.md @@ -19,22 +19,22 @@ npx @shopify/polaris-migrator ### v10 -#### `replace-text-component` +#### `react-replace-text-component` Replace legacy text components `DisplayText`, `Heading`, `Subheading`, `Caption`, `TextStyle`, and `VisuallyHidden` with the new single `Text` component. ```diff - Display text - Heading -+ Display text -+ Heading ++ Display text ++ Heading ``` ```sh -npx @shopify/polaris-migrator replace-text-component +npx @shopify/polaris-migrator react-replace-text-component ``` -#### `rename-component-prop` +#### `react-rename-component-prop` A generic codemod to rename any component prop. @@ -46,39 +46,81 @@ A generic codemod to rename any component prop. ``` ```sh -npx @shopify/polaris-migrator rename-component-prop --component=MyComponent --from=prop --to=newProp +npx @shopify/polaris-migrator react-rename-component-prop --component=MyComponent --from=prop --to=newProp ``` -### `replace-spacing-lengths` +### v9 -Replace lengths and functions (`px`, `rem` and `rem()`) in spacing declarations (`padding`, `margin`, and `gap`) with the corresponding Polaris spacing token. +For projects that use the [`@use` rule](https://sass-lang.com/documentation/at-rules/use), all Sass related migrations (ex: `replace-sass-spacing`) accept a `namespace` flag to target a specific `.`. + +```sh +npx @shopify/polaris-migrator --namespace="legacy-polaris-v8" +``` + +### `scss-replace-breakpoints` + +Replace legacy static breakpoint mixins with the new Polaris [media query variables](https://github.com/Shopify/polaris/blob/main/documentation/guides/migrating-from-v9-to-v10.md#media-query-variables). ```diff -- padding: 16px; -+ padding: var(--p-space-4); +- @include page-content-when-layout-not-stacked {} ++ @media #{$p-breakpoints-md-up} {} +``` -- margin: 1rem; -+ margin: var(--p-space-4); +```sh +npx @shopify/polaris-migrator scss-replace-breakpoints +``` -- gap: rem(16px); -+ gap: var(--p-space-4); +### `scss-replace-border` + +Replace usage of the legacy SCSS `border()`) function in `border` declarations with corresponding Polaris [shape](https://polaris.shopify.com/tokens/shape) token. + +```diff +- border: border(); ++ border: var(--p-border-base); + +- border: border(divider); ++ border: var(--p-border-divider); ``` ```sh -npx @shopify/polaris-migrator replace-spacing-lengths +npx @shopify/polaris-migrator scss-replace-border ``` -### v9 +### `scss-replace-border-radius` -For projects that use the [`@use` rule](https://sass-lang.com/documentation/at-rules/use), all Sass related migrations (ex: `replace-sass-spacing`) accept a `namespace` flag to target a specific `.`. +Replace usage of the legacy SCSS `border-radius()`) function in `border-radius` declarations with corresponding Polaris [shape](https://polaris.shopify.com/tokens/shape) tokens. + +```diff +- border-radius: border-radius(); ++ border-radius: var(--p-border-radius-1); + +- border-radius: border-radius(large); ++ border-radius: var(--p-border-radius-large); +``` + +```sh +npx @shopify/polaris-migrator scss-replace-border-radius +``` + +### `scss-replace-border-width` + +Replace usage of the legacy SCSS `border-width()`) function in `border` and `border-width` declarations with corresponding Polaris [shape](https://polaris.shopify.com/tokens/shape) tokens. + +```diff +- border-width: border-width(); ++ border-width: var(--p-border-width-1); + +- border-width: border-width(thick); ++ border-width: var(--p-border-width-2); +``` ```sh -npx @shopify/polaris-migrator --namespace="legacy-polaris-v8" +npx @shopify/polaris-migrator scss-replace-border-width ``` -### `replace-sass-color` +### `scss-replace-color` -Replace the legacy Sass `color()` function with the supported CSS custom property token equivalent (ex: `var(--p-surface)`). This will only replace a limited subset of mapped values. See the [color-maps.ts](https://github.com/Shopify/polaris/blob/main/polaris-migrator/src/migrations/replace-sass-color/color-maps.ts) for a full list of color mappings based on the CSS property. +Replace the legacy SCSS `color()` function with the supported CSS custom property token equivalent (ex: `var(--p-surface)`). This will only replace a limited subset of mapped values. See the [color-maps.ts](https://github.com/Shopify/polaris/blob/main/polaris-migrator/src/migrations/replace-sass-color/color-maps.ts) for a full list of color mappings based on the CSS property. ```diff - color: color('ink'); @@ -88,104 +130,112 @@ Replace the legacy Sass `color()` function with the supported CSS custom propert ``` ```sh -npx @shopify/polaris-migrator replace-sass-color +npx @shopify/polaris-migrator scss-replace-color ``` -### `replace-sass-spacing` +### `scss-replace-duration` -Replace the legacy Sass `spacing()` function with the supported CSS custom property token equivalent (ex: `var(--p-space-4)`). +Replace the legacy SCSS `duration()` function with the corresponding Polaris [motion](https://polaris.shopify.com/tokens/motion) token. ```diff -- padding: spacing(); -- margin: spacing(loose) spacing(tight); -+ padding: var(--p-space-4); -+ margin: var(--p-space-5) var(--p-space-2); +- transition-duration: legacy-polaris-v8.duration('slow'); ++ transition-duration: var(--p-duration-300); + +- transition: opacity legacy-polaris-v8.duration('slow') linear; ++ transition: opacity var(--p-duration-300) linear; ``` ```sh -npx @shopify/polaris-migrator replace-sass-spacing +npx @shopify/polaris-migrator scss-replace-duration ``` -### `replace-static-breakpoint-mixins` +### `scss-replace-easing` -Replace legacy static breakpoint mixins with the new Polaris [media query variables](https://github.com/Shopify/polaris/blob/main/documentation/guides/migrating-from-v9-to-v10.md#media-query-variables). +Replace the legacy SCSS `easing()` function with the corresponding Polaris [motion](https://polaris.shopify.com/tokens/motion) token. ```diff -- @include page-content-when-layout-not-stacked {} -+ @media #{$p-breakpoints-md-up} {} +- transition-timing-function: legacy-polaris-v8.easing('in'); ++ transition-timing-function: var(--p-ease-in); + +- transition: opacity 300ms legacy-polaris-v8.easing('in'); ++ transition: opacity 300ms var(--p-ease-in); ``` ```sh -npx @shopify/polaris-migrator replace-static-breakpoint-mixins +npx @shopify/polaris-migrator scss-replace-easing ``` -### `replace-static-mixins-with-declarations` +### `scss-replace-font-family` -Replace legacy static mixins with their corresponding declarations and CSS custom properties. +Replace legacy SCSS `font-family()` function with the corresponding Polaris [font](https://polaris.shopify.com/tokens/font) token. ```diff -- @include text-emphasis-normal; -+ color: var(--p-text); -+ font-weight: var(--p-font-weight-regular); +- font-family: font-family(monospace); ++ font-family: var(--p-font-family-mono); ``` ```sh -npx @shopify/polaris-migrator replace-static-mixins-with-declarations +npx @shopify/polaris-migrator scss-replace-font-family ``` -### `replace-typography-declarations` +### `scss-replace-font-size` -Replace legacy Typography functions and hardcoded lengths with Polaris custom properties for `font-family`, `font-size`, `font-weight`, and `line-height` declarations. +Replace legacy SCSS `font-size()` function with the corresponding Polaris [font](https://polaris.shopify.com/tokens/font) token. ```diff -- font-family: font-family(monospace); -+ font-family: var(--p-font-family-mono); - - font-size: font-size(input, base); -+ font-size: var(--p-font-size-200); ++ font-size: var(--p-font-size-200);; +``` -- font-weight: 400; -+ font-weight: var(--p-font-weight-regular); +```sh +npx @shopify/polaris-migrator scss-replace-font-size +``` +### `scss-replace-line-height` + +Replace legacy SCSS `line-height()` function with the corresponding Polaris [font](https://polaris.shopify.com/tokens/font) token. + +```diff - line-height: line-height(caption, base); + font-family: var(--p-font-line-height-2); ``` ```sh -npx @shopify/polaris-migrator replace-typography-declarations +npx @shopify/polaris-migrator scss-replace-line-height ``` -### `replace-border-declarations` +### `scss-replace-spacing` -Replace lengths (`px`, `rem`) and legacy Sass functions (`rem()`,`border()`, `border-width()`, `border-radius()`) in border declarations (`border`, `border-width`, and `border-radius`) with the corresponding Polaris [shape](https://polaris.shopify.com/tokens/shape) token. +Replace the legacy SCSS `spacing()` function with the supported CSS custom property token equivalent (ex: `var(--p-space-4)`). ```diff -- border: 1px solid transparent; -+ border: var(--p-border-width-1) solid transparent; - -- border: border(); -+ border: var(--p-border-base); +- padding: spacing(); +- margin: spacing(loose) spacing(tight); ++ padding: var(--p-space-4); ++ margin: var(--p-space-5) var(--p-space-2); +``` -- border-width: 0.0625rem; -+ border-width: var(--p-border-width-1); +```sh +npx @shopify/polaris-migrator scss-replace-spacing +``` -- border-width: border-width(thick); -+ border-width: var(--p-border-width-2); +### `scss-replace-text-emphasis` -- border-radius: 4px; -+ border-radius: var(--p-border-radius-1); +Replace legacy static mixins with their corresponding declarations and CSS custom properties. -- border-radius: border-radius(large); -+ border-radius: var(--p-border-radius-large); +```diff +- @include text-emphasis-normal; ++ color: var(--p-text); ++ font-weight: var(--p-font-weight-regular); ``` ```sh -npx @shopify/polaris-migrator replace-border-declarations +npx @shopify/polaris-migrator scss-replace-text-emphasis ``` -### `replace-sass-z-index` +### `scss-replace-z-index` -Replace the legacy Sass `z-index()` function with the supported CSS custom property token equivalent (ex: `var(--p-z-1)`). +Replace the legacy SCSS `z-index()` function with the supported CSS custom property token equivalent (ex: `var(--p-z-1)`). Any invocations of `z-index()` that correspond to a z-index design-token i.e. `--p-z-1` will be replaced with a css variable declaration. This includes invocations to the `$fixed-element-stacking-order` sass map i.e. `z-index(modal, $fixed-element-stacking-order)`. @@ -232,38 +282,86 @@ In these cases you may also want to run `npx sass-migrator module --migra Be aware that this may also create additional code changes in your codebase, we recommend running this only if there are large number of instances of migrations from `z-index` to `map.get`. Otherwise it may be easier to add `use 'sass:map'` to the top of your `.scss` file manually. ```sh -npx @shopify/polaris-migrator replace-sass-spacing +npx @shopify/polaris-migrator scss-replace-z-index +``` + +### `styles-tokenize-font` + +Replace legacy static font values with Polaris custom properties for `font-size`, `font-weight`, and `line-height` declarations. + +```diff +- font-size: 16px; ++ font-size: var(--p-font-size-200); + +- font-weight: 400; ++ font-weight: var(--p-font-weight-regular); + +- line-height: 20px; ++ font-family: var(--p-font-line-height-2); +``` + +```sh +npx @shopify/polaris-migrator styles-tokenize-font ``` -### `replace-sass-transition` +### `styles-tokenize-motion` -Replace timings (`ms`, `s`) and legacy Sass functions (`duration()`,`easing()`) in transition declarations (`transition`, `transition-duration`, `transition-delay`, and `transition-timing-function`) with the corresponding Polaris [motion](https://polaris.shopify.com/tokens/motion) token. +Replace timings (`ms`, `s`) in transition declarations (`transition`, `transition-duration`, `transition-delay`, and `transition-timing-function`) with the corresponding Polaris [motion](https://polaris.shopify.com/tokens/motion) token. ```diff - transition-duration: 100ms; + transition-duration: var(--p-duration-100); -- transition-duration: legacy-polaris-v8.duration('slow'); -+ transition-duration: var(--p-duration-300); - - transition-timing-function: linear; + transition-timing-function: var(--p-linear); -- transition-timing-function: legacy-polaris-v8.easing('in'); -+ transition-timing-function: var(--p-ease-in); - - transition: opacity 100ms linear; + transition: opacity var(--p-duration-100) linear; -- transition: opacity legacy-polaris-v8.duration('slow') linear; -+ transition: opacity var(--p-duration-300) linear; - - transition: opacity 100ms linear, left 100ms linear; + transition: opacity var(--p-duration-100) linear, left var(--p-duration-100) linear; ``` ```sh -npx @shopify/polaris-migrator replace-sass-transition +npx @shopify/polaris-migrator styles-tokenize-motion +``` + +### `styles-tokenize-shape` + +Replace usage of the legacy SCSS `rem()` function and hard-coded lengths (`px`, `rem`) in `border`, `border-width`, and `border-radius` declarations with corresponding Polaris [shape](https://polaris.shopify.com/tokens/shape) token. + +```diff +- border: 1px solid transparent; ++ border: var(--p-border-width-1) solid transparent; + +- border-width: 0.0625rem; ++ border-width: var(--p-border-width-1); + +- border-radius: 4px; ++ border-radius: var(--p-border-radius-1); +``` + +```sh +npx @shopify/polaris-migrator replace-border-declarations +``` + +### `styles-tokenize-space` + +Replace lengths and functions (`px`, `rem` and `rem()`) in spacing declarations (`padding`, `margin`, and `gap`) with the corresponding Polaris spacing token. + +```diff +- padding: 16px; ++ padding: var(--p-space-4); + +- margin: 1rem; ++ margin: var(--p-space-4); + +- gap: rem(16px); ++ gap: var(--p-space-4); +``` + +```sh +npx @shopify/polaris-migrator styles-tokenize-space ``` ## Creating Migrations @@ -272,42 +370,42 @@ Sometimes referred to as "codemods", migrations are JavaScript functions which m `polaris-migrator` supports two types of migrations: -- SASS Migrations +- SCSS Migrations - Typescript Migrations -### Creating a SASS migration +### Creating a SCSS migration -Run `yarn new-migration` to generate a new migration from the `sass-migration` template: +Run `yarn new-migration` to generate a new migration from the `scss-migration` template: ```sh ❯ yarn new-migration $ yarn workspace @shopify/polaris-migrator generate $ plop ? [PLOP] Please choose a generator. (Use arrow keys) -❯ sass-migration +❯ scss-migration typescript-migration ``` -Next, provide the name of your migration. For example; `replace-sass-function`: +Next, provide the name of your migration. For example; `scss-replace-function`: ```sh ? [PLOP] Please choose a generator. sass-migration -? Name of the migration (e.g. replace-sass-layout) replace-sass-function +? Name of the migration (e.g. scss-replace-function) scss-replace-function ``` The generator will create the following files in the `migrations` folder: ``` migrations -└── replace-sass-function - ├── replace-sass-function.ts +└── scss-replace-function + ├── scss-replace-function.ts └── tests - ├── replace-sass-function.input.scss - ├── replace-sass-function.output.scss - └── replace-sass-function.test.ts + ├── scss-replace-function.input.scss + ├── scss-replace-function.output.scss + └── scss-replace-function.test.ts ``` -#### The SASS migration function +#### The SCSS migration function Each migrator has a default export adhering to the [Stylelint Rule API](https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md). A PostCSS AST is passed as the `root` and can be mutated inline, or emit warning/error reports. @@ -352,15 +450,15 @@ const replaceHelloWorld: PolarisMigrator = (_, {methods}, context) => { export default createSassMigrator('replace-hello-world', replaceHelloWorld); ``` -A more complete example can be seen in [`replace-spacing-lengths.ts`](https://github.com/Shopify/polaris/blob/main/polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts). +A more complete example can be seen in [`styles-tokenize-space.ts`](https://github.com/Shopify/polaris/blob/main/polaris-migrator/src/migrations/styles-tokenize-space/styles-tokenize-space.ts). #### Testing The template will also generate starting test files you can use to test your migration. In your migrations `tests` folder, you can see 3 files: -- `replace-sass-function.test.ts` – Runs the fixtures and sets up additional migration options -- `replace-sass-function.input.scss` – The starting source input -- `replace-sass-function.output.scss` – The expected output after migration +- `scss-replace-function.test.ts` – Runs the fixtures and sets up additional migration options +- `scss-replace-function.input.scss` – The starting source input +- `scss-replace-function.output.scss` – The expected output after migration The main test file will load the input/output fixtures to test your migration against. You can configure additional fixtures and test migration options (see the `replace-sass-spacing.test.ts` as an example). @@ -369,7 +467,7 @@ The main test file will load the input/output fixtures to test your migration ag Run tests locally from workspace root by filtering to the migrations package: ```sh -npx turbo run test --filter=polaris-migrator -- replace-sass-function +npx turbo run test --filter=polaris-migrator -- scss-replace-function ``` ### Testing in another codebase @@ -380,7 +478,7 @@ In your PR, you can add a comment with the text `/snapit` to create a new [snaps ```sh # example snapshot release -npx @shopify/polaris-migrator@0.0.0-snapshot-release-20220919213536 replace-sass-function "./app/**/*.scss" +npx @shopify/polaris-migrator@0.0.0-snapshot-release-20220919213536 scss-replace-function "./app/**/*.scss" ``` ### Linting and formatting migrations diff --git a/polaris-migrator/package.json b/polaris-migrator/package.json index ba45387ee61..897b3226392 100644 --- a/polaris-migrator/package.json +++ b/polaris-migrator/package.json @@ -41,8 +41,7 @@ "meow": "^9.0.0", "postcss": "^8.4.14", "postcss-scss": "^4.0.4", - "postcss-value-parser": "^4.2.0", - "prettier": "^2.7.1" + "postcss-value-parser": "^4.2.0" }, "devDependencies": { "@types/is-git-clean": "^1.1.0", @@ -54,6 +53,7 @@ "@shopify/polaris": "^10.10.1", "plop": "^3.1.1", "plop-dir": "^0.0.5", + "prettier": "^2.7.1", "type-fest": "^2.19.0" } } diff --git a/polaris-migrator/plopfile.mjs b/polaris-migrator/plopfile.mjs index 6dfcb5831aa..fa907d47369 100644 --- a/polaris-migrator/plopfile.mjs +++ b/polaris-migrator/plopfile.mjs @@ -10,16 +10,16 @@ const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); // eslint-disable-next-line import/no-default-export export default async function run(plop) { plop.setGenerator( - 'sass-migration', + 'scss-migration', await plopDir({ plop, - templateDir: path.join(__dirname, './templates/sass-migration'), + templateDir: path.join(__dirname, './templates/scss-migration'), outputDir: path.join(__dirname, './src/migrations'), prompts: [ { name: 'migrationName', message: 'Name of the migration', - suffix: ' (e.g. replace-sass-layout)', + suffix: ' (e.g. scss-replace-function)', validate: (input) => validateMigrationName(plop, input), }, ], @@ -36,7 +36,7 @@ export default async function run(plop) { { name: 'migrationName', message: 'Name of the migration', - suffix: ' (e.g. replace-component-layout)', + suffix: ' (e.g. component-replace-prop)', validate: (input) => validateMigrationName(plop, input), }, ], diff --git a/polaris-migrator/src/migrations/rename-component-prop/rename-component-prop.ts b/polaris-migrator/src/migrations/react-rename-component-prop/react-rename-component-prop.ts similarity index 91% rename from polaris-migrator/src/migrations/rename-component-prop/rename-component-prop.ts rename to polaris-migrator/src/migrations/react-rename-component-prop/react-rename-component-prop.ts index bb0af2f6141..1be13fddd22 100644 --- a/polaris-migrator/src/migrations/rename-component-prop/rename-component-prop.ts +++ b/polaris-migrator/src/migrations/react-rename-component-prop/react-rename-component-prop.ts @@ -2,7 +2,7 @@ import type {API, FileInfo, Options} from 'jscodeshift'; import {renameProps} from '../../utilities/jsx'; -export default function renameComponentProp( +export default function reactRenameComponentProp( file: FileInfo, {jscodeshift: j}: API, options: Options, diff --git a/polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.input.tsx b/polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.input.tsx similarity index 100% rename from polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.input.tsx rename to polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.input.tsx diff --git a/polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.output.tsx b/polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.output.tsx similarity index 100% rename from polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.output.tsx rename to polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.output.tsx diff --git a/polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.test.ts b/polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.test.ts similarity index 71% rename from polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.test.ts rename to polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.test.ts index 9d0f468ab35..82e29285600 100644 --- a/polaris-migrator/src/migrations/rename-component-prop/tests/rename-component-prop.test.ts +++ b/polaris-migrator/src/migrations/react-rename-component-prop/tests/react-rename-component-prop.test.ts @@ -1,7 +1,7 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'rename-component-prop'; -const fixtures = ['rename-component-prop']; +const migration = 'react-rename-component-prop'; +const fixtures = ['react-rename-component-prop']; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/replace-text-component/replace-text-component.ts b/polaris-migrator/src/migrations/react-replace-text-components/react-replace-text-components.ts similarity index 93% rename from polaris-migrator/src/migrations/replace-text-component/replace-text-component.ts rename to polaris-migrator/src/migrations/react-replace-text-components/react-replace-text-components.ts index 51de781e77e..dc024ba72b0 100644 --- a/polaris-migrator/src/migrations/replace-text-component/replace-text-component.ts +++ b/polaris-migrator/src/migrations/react-replace-text-components/react-replace-text-components.ts @@ -10,7 +10,7 @@ export interface MigrationOptions extends Options { relative: boolean; } -export default function replaceTextComponent( +export default function reactReplaceTextComponents( file: FileInfo, {jscodeshift: j}: API, options: MigrationOptions, diff --git a/polaris-migrator/src/migrations/replace-text-component/steps/replace-display-text.ts b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-display-text.ts similarity index 87% rename from polaris-migrator/src/migrations/replace-text-component/steps/replace-display-text.ts rename to polaris-migrator/src/migrations/react-replace-text-components/steps/replace-display-text.ts index f4cc9e05694..ad16491d784 100644 --- a/polaris-migrator/src/migrations/replace-text-component/steps/replace-display-text.ts +++ b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-display-text.ts @@ -12,7 +12,7 @@ import { normalizeImportSourcePaths, updateImports, } from '../../../utilities/imports'; -import type {MigrationOptions} from '../replace-text-component'; +import type {MigrationOptions} from '../react-replace-text-components'; const displayTextSizeMap = { small: 'headingLg', @@ -59,4 +59,11 @@ export function replaceDisplayText( insertJSXAttribute(j, element, 'as', 'p'); } }); + + source + .find(j.Identifier) + .filter((path) => path.node.name === localElementName) + .forEach((path) => { + path.node.name = 'Text'; + }); } diff --git a/polaris-migrator/src/migrations/replace-text-component/steps/replace-other.ts b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-other.ts similarity index 89% rename from polaris-migrator/src/migrations/replace-text-component/steps/replace-other.ts rename to polaris-migrator/src/migrations/react-replace-text-components/steps/replace-other.ts index c7cf4228edc..05cfbbd3df0 100644 --- a/polaris-migrator/src/migrations/replace-text-component/steps/replace-other.ts +++ b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-other.ts @@ -12,7 +12,7 @@ import { normalizeImportSourcePaths, updateImports, } from '../../../utilities/imports'; -import type {MigrationOptions} from '../replace-text-component'; +import type {MigrationOptions} from '../react-replace-text-components'; const components = { Heading: { @@ -78,5 +78,12 @@ export function replaceOther( insertJSXAttribute(j, element, 'visuallyHidden'); } }); + + source + .find(j.Identifier) + .filter((path) => path.node.name === localElementName) + .forEach((path) => { + path.node.name = 'Text'; + }); }); } diff --git a/polaris-migrator/src/migrations/replace-text-component/steps/replace-text-style.ts b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-text-style.ts similarity index 93% rename from polaris-migrator/src/migrations/replace-text-component/steps/replace-text-style.ts rename to polaris-migrator/src/migrations/react-replace-text-components/steps/replace-text-style.ts index f445fe17d54..390e3090fc0 100644 --- a/polaris-migrator/src/migrations/replace-text-component/steps/replace-text-style.ts +++ b/polaris-migrator/src/migrations/react-replace-text-components/steps/replace-text-style.ts @@ -16,7 +16,7 @@ import { normalizeImportSourcePaths, updateImports, } from '../../../utilities/imports'; -import type {MigrationOptions} from '../replace-text-component'; +import type {MigrationOptions} from '../react-replace-text-components'; const variationMap = { strong: {fontWeight: 'bold'}, @@ -114,4 +114,11 @@ export function replaceTextStyle( insertJSXAttribute(j, element, 'as', 'span'); } }); + + source + .find(j.Identifier) + .filter((path) => path.node.name === localElementName) + .forEach((path) => { + path.node.name = 'Text'; + }); } diff --git a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components.input.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.input.tsx similarity index 92% rename from polaris-migrator/src/migrations/replace-text-component/tests/replace-components.input.tsx rename to polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.input.tsx index e66f9b5041e..d81f72a0ae2 100644 --- a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components.input.tsx +++ b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.input.tsx @@ -8,7 +8,12 @@ import { VisuallyHidden, } from '@shopify/polaris'; +const noop = (..._: any) => {}; + export function App() { + const textStyle = TextStyle; + noop(textStyle); + return ( <> Display text diff --git a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components.output.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.output.tsx similarity index 82% rename from polaris-migrator/src/migrations/replace-text-component/tests/replace-components.output.tsx rename to polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.output.tsx index 44dff8d6017..ea1cb7297b2 100644 --- a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components.output.tsx +++ b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.output.tsx @@ -1,7 +1,12 @@ import React from 'react'; import {Text, InlineCode} from '@shopify/polaris'; +const noop = (..._: any) => {}; + export function App() { + const textStyle = Text; + noop(textStyle); + return ( <> @@ -16,16 +21,16 @@ export function App() { Display text - + Heading - + Heading - + Subheading - + Subheading diff --git a/polaris-migrator/src/migrations/replace-text-component/tests/replace-text-component.test.ts b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.test.ts similarity index 61% rename from polaris-migrator/src/migrations/replace-text-component/tests/replace-text-component.test.ts rename to polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.test.ts index 7addf1e5a8c..e8caefcafce 100644 --- a/polaris-migrator/src/migrations/replace-text-component/tests/replace-text-component.test.ts +++ b/polaris-migrator/src/migrations/react-replace-text-components/tests/react-replace-text-components.test.ts @@ -1,7 +1,11 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'replace-text-component'; -const fixtures = ['replace-components-relative']; +const migration = 'react-replace-text-components'; +const fixtures = [ + 'react-replace-text-components', + 'with-identifier', + 'with-relative', +]; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.input.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.input.tsx new file mode 100644 index 00000000000..bf8d962ba5e --- /dev/null +++ b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.input.tsx @@ -0,0 +1,27 @@ +import '@shopify/react-testing/matchers'; + +import React from 'react'; +import { + DisplayText, + Heading, + Subheading, + Caption, + TextStyle, + VisuallyHidden, +} from '@shopify/polaris'; + +const mount = (..._: any) => {}; +const MyComponent = () =>
; + +describe('MyComponent', () => { + it('renders', () => { + const container = mount(); + + expect(container).not.toContainReactComponent(DisplayText); + expect(container).not.toContainReactComponent(Heading); + expect(container).not.toContainReactComponent(Subheading); + expect(container).not.toContainReactComponent(Caption); + expect(container).not.toContainReactComponent(TextStyle); + expect(container).not.toContainReactComponent(VisuallyHidden); + }); +}); diff --git a/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.output.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.output.tsx new file mode 100644 index 00000000000..148ce6375b3 --- /dev/null +++ b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-identifier.output.tsx @@ -0,0 +1,20 @@ +import '@shopify/react-testing/matchers'; + +import React from 'react'; +import {Text} from '@shopify/polaris'; + +const mount = (..._: any) => {}; +const MyComponent = () =>
; + +describe('MyComponent', () => { + it('renders', () => { + const container = mount(); + + expect(container).not.toContainReactComponent(Text); + expect(container).not.toContainReactComponent(Text); + expect(container).not.toContainReactComponent(Text); + expect(container).not.toContainReactComponent(Text); + expect(container).not.toContainReactComponent(Text); + expect(container).not.toContainReactComponent(Text); + }); +}); diff --git a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components-relative.input.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-relative.input.tsx similarity index 100% rename from polaris-migrator/src/migrations/replace-text-component/tests/replace-components-relative.input.tsx rename to polaris-migrator/src/migrations/react-replace-text-components/tests/with-relative.input.tsx diff --git a/polaris-migrator/src/migrations/replace-text-component/tests/replace-components-relative.output.tsx b/polaris-migrator/src/migrations/react-replace-text-components/tests/with-relative.output.tsx similarity index 100% rename from polaris-migrator/src/migrations/replace-text-component/tests/replace-components-relative.output.tsx rename to polaris-migrator/src/migrations/react-replace-text-components/tests/with-relative.output.tsx diff --git a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.test.ts b/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.test.ts deleted file mode 100644 index c76267cc0e8..00000000000 --- a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {check} from '../../../utilities/testUtils'; - -const migration = 'replace-border-declarations'; -const fixtures = ['replace-border-declarations', 'with-namespace']; - -for (const fixture of fixtures) { - check(__dirname, { - fixture, - migration, - extension: 'scss', - options: { - namespace: fixture.includes('with-namespace') - ? 'legacy-polaris-v8' - : undefined, - }, - }); -} diff --git a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.output.scss b/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.output.scss deleted file mode 100644 index 26bbdab8b6b..00000000000 --- a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.output.scss +++ /dev/null @@ -1,212 +0,0 @@ -.duration-simple-string-arg { - opacity: 1; - transition-duration: var(--p-duration-0); - transition-duration: var(--p-duration-100); - transition-duration: var(--p-duration-200); - transition-duration: var(--p-duration-300); - transition-duration: var(--p-duration-400); - transition-duration: var(--p-duration-500); -} - -.duration-simple-non-string-arg { - opacity: 1; - transition-duration: var(--p-duration-200); - transition-duration: var(--p-duration-0); - transition-duration: var(--p-duration-100); - transition-duration: var(--p-duration-200); - transition-duration: var(--p-duration-300); - transition-duration: var(--p-duration-400); - transition-duration: var(--p-duration-500); -} - -.duration-simple-constant { - opacity: 1; - transition-duration: var(--p-duration-0); - transition-duration: var(--p-duration-0); - transition-duration: var(--p-duration-0); - transition-duration: var(--p-duration-50); - transition-duration: var(--p-duration-50); - transition-duration: var(--p-duration-100); - transition-duration: var(--p-duration-100); - transition-duration: var(--p-duration-150); - transition-duration: var(--p-duration-150); - transition-duration: var(--p-duration-200); - transition-duration: var(--p-duration-200); - transition-duration: var(--p-duration-250); - transition-duration: var(--p-duration-250); - transition-duration: var(--p-duration-300); - transition-duration: var(--p-duration-300); - transition-duration: var(--p-duration-350); - transition-duration: var(--p-duration-350); - transition-duration: var(--p-duration-400); - transition-duration: var(--p-duration-400); - transition-duration: var(--p-duration-450); - transition-duration: var(--p-duration-450); - transition-duration: var(--p-duration-500); - transition-duration: var(--p-duration-500); - transition-duration: var(--p-duration-5000); -} - -.duration-compound-string-arg { - opacity: 1; - transition: opacity var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear); -} - -.duration-compound-non-string-arg { - opacity: 1; - transition: opacity var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear); -} - -.duration-compound-constant { - opacity: 1; - transition: opacity var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-50) var(--p-linear); - transition: opacity var(--p-duration-50) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-150) var(--p-linear); - transition: opacity var(--p-duration-150) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-250) var(--p-linear); - transition: opacity var(--p-duration-250) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-350) var(--p-linear); - transition: opacity var(--p-duration-350) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-450) var(--p-linear); - transition: opacity var(--p-duration-450) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear); - transition: opacity var(--p-duration-5000) var(--p-linear); -} - -.duration-multiple-string-arg { - opacity: 1; - transition: opacity var(--p-duration-0) var(--p-linear), - left var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear), - left var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear), - left var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear), - left var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear), - left var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear), - left var(--p-duration-500) var(--p-linear); -} - -.duration-multiple-non-string-arg { - opacity: 1; - transition: opacity var(--p-duration-200) var(--p-linear), - left var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear), - left var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear), - left var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear), - left var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear), - left var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear), - left var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear), - left var(--p-duration-500) var(--p-linear); -} - -.duration-multiple-constant { - opacity: 1; - transition: opacity var(--p-duration-0) var(--p-linear), - left var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear), - left var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-0) var(--p-linear), - left var(--p-duration-0) var(--p-linear); - transition: opacity var(--p-duration-50) var(--p-linear), - left var(--p-duration-50) var(--p-linear); - transition: opacity var(--p-duration-50) var(--p-linear), - left var(--p-duration-50) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear), - left var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-100) var(--p-linear), - left var(--p-duration-100) var(--p-linear); - transition: opacity var(--p-duration-150) var(--p-linear), - left var(--p-duration-150) var(--p-linear); - transition: opacity var(--p-duration-150) var(--p-linear), - left var(--p-duration-150) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear), - left var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-200) var(--p-linear), - left var(--p-duration-200) var(--p-linear); - transition: opacity var(--p-duration-250) var(--p-linear), - left var(--p-duration-250) var(--p-linear); - transition: opacity var(--p-duration-250) var(--p-linear), - left var(--p-duration-250) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear), - left var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-300) var(--p-linear), - left var(--p-duration-300) var(--p-linear); - transition: opacity var(--p-duration-350) var(--p-linear), - left var(--p-duration-350) var(--p-linear); - transition: opacity var(--p-duration-350) var(--p-linear), - left var(--p-duration-350) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear), - left var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-400) var(--p-linear), - left var(--p-duration-400) var(--p-linear); - transition: opacity var(--p-duration-450) var(--p-linear), - left var(--p-duration-450) var(--p-linear); - transition: opacity var(--p-duration-450) var(--p-linear), - left var(--p-duration-450) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear), - left var(--p-duration-500) var(--p-linear); - transition: opacity var(--p-duration-500) var(--p-linear), - left var(--p-duration-500) var(--p-linear); - transition: opacity var(--p-duration-5000) var(--p-linear), - left var(--p-duration-5000) var(--p-linear); -} - -.edges { - // sass calculation - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Numeric operator detected. - // warning: No matching duration token for '33ms'. - // transition: (legacy-polaris-v8.duration() - 33ms) fill var(--p-linear) 33ms; - transition: (legacy-polaris-v8.duration() - 33ms) fill linear 33ms; - // Duration comes after easing func - transition: opacity var(--p-linear) var(--p-duration-500); - // Duration + Delay - transition: opacity var(--p-duration-400) var(--p-linear) - var(--p-duration-100); - // Duration + Delay after easing func - transition: opacity var(--p-linear) var(--p-duration-400) - var(--p-duration-100); - // foobar isn't a valid duration key - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unknown duration key 'foobar'. - transition-duration: legacy-polaris-v8.duration(foobar); - // can't process variables - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Cannot statically analyse SASS variable $foo. - transition-duration: $foo; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Cannot statically analyse SASS variable $foo. - // transition: opacity $foo var(--p-duration-500); - transition: opacity $foo 0.5s; -} diff --git a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.output.scss b/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.output.scss deleted file mode 100644 index 538388962db..00000000000 --- a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.output.scss +++ /dev/null @@ -1,241 +0,0 @@ -.easing-simple-string-arg { - opacity: 1; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing('anticipate'); - transition-timing-function: var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing('excite'); - transition-timing-function: var(--p-ease-in); - transition-timing-function: var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing('overshoot'); -} - -.easing-simple-non-string-arg { - opacity: 1; - transition-timing-function: var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing(anticipate); - transition-timing-function: var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing(excite); - transition-timing-function: var(--p-ease-in); - transition-timing-function: var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: legacy-polaris-v8.easing(overshoot); -} - -.easing-simple-builtins { - opacity: 1; - transition-timing-function: var(--p-linear); - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: linear(1); - transition-timing-function: var(--p-ease); - transition-timing-function: var(--p-ease-in); - transition-timing-function: var(--p-ease-out); - transition-timing-function: var(--p-ease-in-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: step-start; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: step-end; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. - transition-timing-function: steps(1, jump-end); -} - -.easing-shorthand-string-arg { - opacity: 1; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("anticipate"); - transition: opacity 300ms legacy-polaris-v8.easing('anticipate'); - transition: opacity var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("excite"); - transition: opacity 300ms legacy-polaris-v8.easing('excite'); - transition: opacity var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("overshoot"); - transition: opacity 300ms legacy-polaris-v8.easing('overshoot'); -} - -.easing-shorthand-non-string-arg { - opacity: 1; - transition: opacity var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(anticipate); - transition: opacity 300ms legacy-polaris-v8.easing(anticipate); - transition: opacity var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(excite); - transition: opacity 300ms legacy-polaris-v8.easing(excite); - transition: opacity var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(overshoot); - transition: opacity 300ms legacy-polaris-v8.easing(overshoot); -} - -.easing-shorthand-builtins { - opacity: 1; - transition: opacity var(--p-duration-300) var(--p-linear); - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) linear(1); - transition: opacity 300ms linear(1); - transition: opacity var(--p-duration-300) var(--p-ease); - transition: opacity var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out); - transition: opacity var(--p-duration-300) var(--p-ease-in-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) cubic-bezier(0, 0, 1, 1); - transition: opacity 300ms cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) step-start; - transition: opacity 300ms step-start; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) step-end; - transition: opacity 300ms step-end; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) steps(1, jump-end); - transition: opacity 300ms steps(1, jump-end); -} - -.easing-multiple-string-arg { - opacity: 1; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("anticipate"), left var(--p-duration-300) legacy-polaris-v8.easing("anticipate"); - transition: opacity 300ms legacy-polaris-v8.easing('anticipate'), - left 300ms legacy-polaris-v8.easing('anticipate'); - transition: opacity var(--p-duration-300) var(--p-ease), - left var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("excite"), left var(--p-duration-300) legacy-polaris-v8.easing("excite"); - transition: opacity 300ms legacy-polaris-v8.easing('excite'), - left 300ms legacy-polaris-v8.easing('excite'); - transition: opacity var(--p-duration-300) var(--p-ease-in), - left var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out), - left var(--p-duration-300) var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing("overshoot"), left var(--p-duration-300) legacy-polaris-v8.easing("overshoot"); - transition: opacity 300ms legacy-polaris-v8.easing('overshoot'), - left 300ms legacy-polaris-v8.easing('overshoot'); -} - -.easing-multiple-non-string-arg { - opacity: 1; - transition: opacity var(--p-duration-300) var(--p-ease), - left var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(anticipate), left var(--p-duration-300) legacy-polaris-v8.easing(anticipate); - transition: opacity 300ms legacy-polaris-v8.easing(anticipate), - left 300ms legacy-polaris-v8.easing(anticipate); - transition: opacity var(--p-duration-300) var(--p-ease), - left var(--p-duration-300) var(--p-ease); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(excite), left var(--p-duration-300) legacy-polaris-v8.easing(excite); - transition: opacity 300ms legacy-polaris-v8.easing(excite), - left 300ms legacy-polaris-v8.easing(excite); - transition: opacity var(--p-duration-300) var(--p-ease-in), - left var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out), - left var(--p-duration-300) var(--p-ease-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) legacy-polaris-v8.easing(overshoot), left var(--p-duration-300) legacy-polaris-v8.easing(overshoot); - transition: opacity 300ms legacy-polaris-v8.easing(overshoot), - left 300ms legacy-polaris-v8.easing(overshoot); -} - -.easing-multiple-builtins { - opacity: 1; - transition: opacity var(--p-duration-300) var(--p-linear), - left var(--p-duration-300) var(--p-linear); - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) linear(1), left var(--p-duration-300) linear(1); - transition: opacity 300ms linear(1), left 300ms linear(1); - transition: opacity var(--p-duration-300) var(--p-ease), - left var(--p-duration-300) var(--p-ease); - transition: opacity var(--p-duration-300) var(--p-ease-in), - left var(--p-duration-300) var(--p-ease-in); - transition: opacity var(--p-duration-300) var(--p-ease-out), - left var(--p-duration-300) var(--p-ease-out); - transition: opacity var(--p-duration-300) var(--p-ease-in-out), - left var(--p-duration-300) var(--p-ease-in-out); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) cubic-bezier(0, 0, 1, 1), left var(--p-duration-300) cubic-bezier(0, 0, 1, 1); - transition: opacity 300ms cubic-bezier(0, 0, 1, 1), - left 300ms cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) step-start, left var(--p-duration-300) step-start; - transition: opacity 300ms step-start, left 300ms step-start; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. - // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) step-end, left var(--p-duration-300) step-start; - transition: opacity 300ms step-end, left 300ms step-start; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. - // transition: opacity var(--p-duration-300) steps(1, jump-end), left var(--p-duration-300) steps(1, jump-end); - transition: opacity 300ms steps(1, jump-end), left 300ms steps(1, jump-end); -} - -$easingFunc: 'ease-in'; - -.edges { - // Without an easing function - transition: fill var(--p-duration-300); - // Unknown values are flagged - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function 'foobar'. - transition-timing-function: legacy-polaris-v8.easing(foobar); - // Can only handle hard coded values - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Unexpected easing function '$easingFunc'. - transition-timing-function: legacy-polaris-v8.easing($easingFunc); - // can't process variables - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Cannot statically analyse SASS variable $foo. - transition-timing-function: $foo; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // warning: Cannot statically analyse SASS variable $foo. - // transition: opacity $foo var(--p-duration-500); - transition: opacity $foo 0.5s; -} diff --git a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-transition.test.ts b/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-transition.test.ts deleted file mode 100644 index 0073e523e22..00000000000 --- a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-transition.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {check} from '../../../utilities/testUtils'; - -const migration = 'replace-sass-transition'; -const fixtures = ['replace-sass-duration', 'replace-sass-easing']; - -for (const fixture of fixtures) { - check(__dirname, { - fixture, - migration, - extension: 'scss', - options: { - namespace: 'legacy-polaris-v8', - }, - }); -} diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.test.ts b/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.test.ts deleted file mode 100644 index f622bab5ec3..00000000000 --- a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {check} from '../../../utilities/testUtils'; - -const migration = 'replace-static-breakpoint-mixins'; -const fixtures = ['replace-static-breakpoint-mixins', 'with-namespace']; - -for (const fixture of fixtures) { - check(__dirname, { - fixture, - migration, - extension: 'scss', - options: { - namespace: fixture.includes('with-namespace') - ? 'legacy-polaris-v8' - : undefined, - }, - }); -} diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.test.ts b/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.test.ts deleted file mode 100644 index 82ed0cab8e7..00000000000 --- a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {check} from '../../../utilities/testUtils'; - -const migration = 'replace-static-mixins-with-declarations'; -const fixtures = ['replace-static-mixins-with-declarations', 'with-namespace']; - -for (const fixture of fixtures) { - check(__dirname, { - fixture, - migration, - extension: 'scss', - options: { - namespace: fixture.includes('with-namespace') - ? 'legacy-polaris-v8' - : undefined, - }, - }); -} diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.test.ts b/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.test.ts deleted file mode 100644 index 97bf94cbbe1..00000000000 --- a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import {check} from '../../../utilities/testUtils'; - -const migration = 'replace-typography-declarations'; -const fixtures = ['replace-typography-declarations', 'with-namespace']; - -for (const fixture of fixtures) { - check(__dirname, { - fixture, - migration, - extension: 'scss', - options: { - namespace: fixture.includes('with-namespace') - ? 'legacy-polaris-v8' - : undefined, - }, - }); -} diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.input.scss deleted file mode 100644 index c802ae29dd3..00000000000 --- a/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.input.scss +++ /dev/null @@ -1,78 +0,0 @@ -@use 'global-styles/legacy-polaris-v8'; - -.font-family { - font-family: sans-serif; - font-family: legacy-polaris-v8.font-family(); - font-family: legacy-polaris-v8.font-family(base); - font-family: legacy-polaris-v8.font-family(monospace); -} - -.font-size { - // LENGTHS - font-size: 12px; - font-size: 1rem; - // Ignore - font-size: 1em; - font-size: #{1px}; - // Comment - font-size: 10px; - font-size: 12px + 1px; - - // FONT-SIZE FUNCTION - font-size: legacy-polaris-v8.font-size(caption); - font-size: legacy-polaris-v8.font-size(caption, base); - font-size: legacy-polaris-v8.font-size(caption, large-screen); - // Comment - font-size: legacy-polaris-v8.font-size($invalid); - font-size: legacy-polaris-v8.font-size(caption, $invalid); - font-size: legacy-polaris-v8.font-size(); - font-size: legacy-polaris-v8.font-size(caption, base, $too-many-args); - - // REM FUNCTION - font-size: legacy-polaris-v8.rem(12px); - font-size: legacy-polaris-v8.rem(1rem); - // Comment - font-size: legacy-polaris-v8.rem(1em); - font-size: legacy-polaris-v8.rem(10px); - font-size: legacy-polaris-v8.rem($invalid); - font-size: legacy-polaris-v8.rem(); - font-size: legacy-polaris-v8.rem(12px, $too-many-args); - font-size: legacy-polaris-v8.rem(12px) 1px; - font-size: legacy-polaris-v8.rem(1px) 12px; - font-size: legacy-polaris-v8.rem(#{10px + 2px}) 12px; - font-size: legacy-polaris-v8.rem(12px) + #{10px + 2px}; -} - -.font-weight { - // LENGTHS - font-weight: 400; - font-weight: 700; - // Comment - font-weight: 300; - font-weight: 400 + 300; - - // ALIAS - font-weight: normal; - font-weight: bold; - // Comment - font-weight: bolder; -} - -.font-line-height { - // LENGTHS - line-height: 16px; - line-height: 1rem; - // Comment - line-height: 10px; - - // LINE-HEIGHT FUNCTION - line-height: legacy-polaris-v8.line-height(caption); - line-height: legacy-polaris-v8.line-height(caption, base); - line-height: legacy-polaris-v8.line-height(caption, large-screen); - line-height: legacy-polaris-v8.line-height(display-x-large, base); - // Comment - line-height: legacy-polaris-v8.line-height($invalid); - line-height: legacy-polaris-v8.line-height(caption, $invalid); - line-height: legacy-polaris-v8.line-height(); - line-height: legacy-polaris-v8.line-height(caption, base, $too-many-args); -} diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.output.scss deleted file mode 100644 index dee669d496b..00000000000 --- a/polaris-migrator/src/migrations/replace-typography-declarations/tests/with-namespace.output.scss +++ /dev/null @@ -1,124 +0,0 @@ -@use 'global-styles/legacy-polaris-v8'; - -.font-family { - font-family: sans-serif; - font-family: var(--p-font-family-sans); - font-family: var(--p-font-family-sans); - font-family: var(--p-font-family-mono); -} - -.font-size { - // LENGTHS - font-size: var(--p-font-size-75); - font-size: var(--p-font-size-200); - // Ignore - font-size: 1em; - font-size: #{1px}; - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: 10px; - font-size: 10px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: var(--p-font-size-75) + 1px; - font-size: 12px + 1px; - - // FONT-SIZE FUNCTION - font-size: 0.8125rem; - font-size: 0.8125rem; - font-size: var(--p-font-size-75); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.font-size($invalid); - font-size: legacy-polaris-v8.font-size($invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.font-size(caption, $invalid); - font-size: legacy-polaris-v8.font-size(caption, $invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.font-size(); - font-size: legacy-polaris-v8.font-size(); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.font-size(caption, base, $too-many-args); - font-size: legacy-polaris-v8.font-size(caption, base, $too-many-args); - - // REM FUNCTION - font-size: var(--p-font-size-75); - font-size: var(--p-font-size-200); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(1em); - font-size: legacy-polaris-v8.rem(1em); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(10px); - font-size: legacy-polaris-v8.rem(10px); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem($invalid); - font-size: legacy-polaris-v8.rem($invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(); - font-size: legacy-polaris-v8.rem(); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(var(--p-font-size-75), $too-many-args); - font-size: legacy-polaris-v8.rem(12px, $too-many-args); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: var(--p-font-size-75) 1px; - font-size: legacy-polaris-v8.rem(12px) 1px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(1px) var(--p-font-size-75); - font-size: legacy-polaris-v8.rem(1px) 12px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: legacy-polaris-v8.rem(#{10px + 2px}) var(--p-font-size-75); - font-size: legacy-polaris-v8.rem(#{10px + 2px}) 12px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: var(--p-font-size-75) + #{10px + 2px}; - font-size: legacy-polaris-v8.rem(12px) + #{10px + 2px}; -} - -.font-weight { - // LENGTHS - font-weight: var(--p-font-weight-regular); - font-weight: var(--p-font-weight-bold); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-weight: 300; - font-weight: 300; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-weight: var(--p-font-weight-regular) + 300; - font-weight: 400 + 300; - - // ALIAS - font-weight: var(--p-font-weight-regular); - font-weight: var(--p-font-weight-bold); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-weight: bolder; - font-weight: bolder; -} - -.font-line-height { - // LENGTHS - line-height: var(--p-font-line-height-1); - line-height: var(--p-font-line-height-1); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: 10px; - line-height: 10px; - - // LINE-HEIGHT FUNCTION - line-height: var(--p-font-line-height-2); - line-height: var(--p-font-line-height-2); - line-height: var(--p-font-line-height-1); - line-height: 2.25rem; - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: legacy-polaris-v8.line-height($invalid); - line-height: legacy-polaris-v8.line-height($invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: legacy-polaris-v8.line-height(caption, $invalid); - line-height: legacy-polaris-v8.line-height(caption, $invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: legacy-polaris-v8.line-height(); - line-height: legacy-polaris-v8.line-height(); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: legacy-polaris-v8.line-height(caption, base, $too-many-args); - line-height: legacy-polaris-v8.line-height(caption, base, $too-many-args); -} diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/scss-replace-border-radius.ts b/polaris-migrator/src/migrations/scss-replace-border-radius/scss-replace-border-radius.ts new file mode 100644 index 00000000000..706aa437298 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/scss-replace-border-radius.ts @@ -0,0 +1,124 @@ +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + getFunctionArgs, + isNumericOperator, + isSassFunction, + namespace, + NamespaceOptions, + StopWalkingFunctionNodes, + createInlineComment, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceBorderRadius( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedBorderRadius = namespace('border-radius', options); + + return { + postcssPlugin: 'scss-replace-border-radius', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + if (!borderRadiusProps.has(decl.prop)) return; + + /** + * A collection of transformable values to migrate (e.g. decl lengths, functions, etc.) + * + * Note: This is evaluated at the end of each visitor execution to determine whether + * or not to replace the declaration or insert a comment. + */ + const targets: {replaced: boolean}[] = []; + let hasNumericOperator = false; + const parsedValue = valueParser(decl.value); + + handleBorderRadiusProps(); + + if (targets.some(({replaced}) => !replaced || hasNumericOperator)) { + // Insert comment if the declaration value contains calculations + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } else { + decl.value = parsedValue.toString(); + } + + // + // Handler + // + + function handleBorderRadiusProps() { + parsedValue.walk((node) => { + if (isNumericOperator(node)) { + hasNumericOperator = true; + return; + } + + if (node.type === 'function') { + if (isSassFunction(namespacedBorderRadius, node)) { + targets.push({replaced: false}); + + const args = getFunctionArgs(node); + + if (!(args.length === 0 || args.length === 1)) return; + + // `border-radius()` args reference: + // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L655 + const value = args[0] ?? 'base'; + + if (!isKeyOf(borderRadiusFunctionMap, value)) return; + + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: borderRadiusFunctionMap[value], + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: borderRadiusFunctionMap[value].length, + }, + ]; + + targets[targets.length - 1]!.replaced = true; + } + + return StopWalkingFunctionNodes; + } + }); + } + }, + }; +}; + +const borderRadiusProps = new Set([ + 'border-radius', + 'border-top-left-radius', + 'border-top-right-radius', + 'border-bottom-left-radius', + 'border-bottom-right-radius', +]); + +const borderRadiusFunctionMap = { + '': '--p-border-radius-base', + base: '--p-border-radius-base', + "'base'": '--p-border-radius-base', + large: '--p-border-radius-large', + "'large'": '--p-border-radius-large', +} as const; diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.input.scss b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.input.scss new file mode 100644 index 00000000000..92bf9a6ff91 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.input.scss @@ -0,0 +1,17 @@ +/* stylelint-disable */ + +.border-radius { + /* Migrate */ + border-radius: border-radius(); + border-radius: border-radius(base); + border-radius: border-radius(large); + + /* Ignore */ + border-radius: calc(border-radius(base) * 2); + border-radius: calc(border-radius() * rem(1px)); + + /* Comment */ + border-radius: border-radius(base) * 2; + border-radius: border-radius() * rem(1px); + border-top-right-radius: border-radius() * rem(4px); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.output.scss b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.output.scss new file mode 100644 index 00000000000..3c93d56ccd4 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.output.scss @@ -0,0 +1,23 @@ +/* stylelint-disable */ + +.border-radius { + /* Migrate */ + border-radius: var(--p-border-radius-base); + border-radius: var(--p-border-radius-base); + border-radius: var(--p-border-radius-large); + + /* Ignore */ + border-radius: calc(border-radius(base) * 2); + border-radius: calc(border-radius() * rem(1px)); + + /* Comment */ + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-radius: var(--p-border-radius-base) * 2; + border-radius: border-radius(base) * 2; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-radius: var(--p-border-radius-base) * rem(1px); + border-radius: border-radius() * rem(1px); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-top-right-radius: var(--p-border-radius-base) * rem(4px); + border-top-right-radius: border-radius() * rem(4px); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.test.ts b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.test.ts new file mode 100644 index 00000000000..69b903f1943 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/scss-replace-border-radius.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-border-radius'; +const fixtures = ['scss-replace-border-radius', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.input.scss new file mode 100644 index 00000000000..83524fb6ab8 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.input.scss @@ -0,0 +1,21 @@ +/* stylelint-disable */ +@use 'global-styles/legacy-polaris-v8'; + +.border-radius { + /* Migrate */ + border-radius: legacy-polaris-v8.border-radius(); + border-radius: legacy-polaris-v8.border-radius(base); + border-radius: legacy-polaris-v8.border-radius(large); + + /* Ignore */ + border-radius: calc(legacy-polaris-v8.border-radius(base) * 2); + border-radius: calc( + legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px) + ); + + /* Comment */ + border-radius: legacy-polaris-v8.border-radius(base) * 2; + border-radius: legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px); + border-top-right-radius: legacy-polaris-v8.border-radius() * + legacy-polaris-v8.rem(4px); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.output.scss new file mode 100644 index 00000000000..8f1642d4c58 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-radius/tests/with-namespace.output.scss @@ -0,0 +1,27 @@ +/* stylelint-disable */ +@use 'global-styles/legacy-polaris-v8'; + +.border-radius { + /* Migrate */ + border-radius: var(--p-border-radius-base); + border-radius: var(--p-border-radius-base); + border-radius: var(--p-border-radius-large); + + /* Ignore */ + border-radius: calc(legacy-polaris-v8.border-radius(base) * 2); + border-radius: calc( + legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px) + ); + + /* Comment */ + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-radius: var(--p-border-radius-base) * 2; + border-radius: legacy-polaris-v8.border-radius(base) * 2; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-radius: var(--p-border-radius-base) * legacy-polaris-v8.rem(1px); + border-radius: legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // border-top-right-radius: var(--p-border-radius-base) * legacy-polaris-v8.rem(4px); + border-top-right-radius: legacy-polaris-v8.border-radius() * + legacy-polaris-v8.rem(4px); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/scss-replace-border-width.ts b/polaris-migrator/src/migrations/scss-replace-border-width/scss-replace-border-width.ts new file mode 100644 index 00000000000..9ee7fa63975 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/scss-replace-border-width.ts @@ -0,0 +1,131 @@ +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + getFunctionArgs, + isSassFunction, + namespace, + isNumericOperator, + NamespaceOptions, + StopWalkingFunctionNodes, + createInlineComment, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceBorderWidth( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedBorderWidth = namespace('border-width', options); + + return { + postcssPlugin: 'scss-replace-border-width', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + if (!borderProps.has(decl.prop)) return; + + /** + * A collection of transformable values to migrate (e.g. decl lengths, functions, etc.) + * + * Note: This is evaluated at the end of each visitor execution to determine whether + * or not to replace the declaration or insert a comment. + */ + const targets: {replaced: boolean}[] = []; + let hasNumericOperator = false; + const parsedValue = valueParser(decl.value); + + handleBorderProps(); + + if (targets.some(({replaced}) => !replaced || hasNumericOperator)) { + // Insert comment if the declaration value contains calculations + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } else { + decl.value = parsedValue.toString(); + } + + // + // Handlers + // + + function handleBorderProps() { + parsedValue.walk((node) => { + if (isNumericOperator(node)) { + hasNumericOperator = true; + return; + } + + if (node.type === 'function') { + if (isSassFunction(namespacedBorderWidth, node)) { + targets.push({replaced: false}); + + const args = getFunctionArgs(node); + + if (!(args.length === 0 || args.length === 1)) return; + + // `border-width()` args reference: + // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L616 + const value = args[0] ?? 'base'; + + if (!isKeyOf(borderWidthFunctionMap, value)) return; + + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: borderWidthFunctionMap[value], + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: borderWidthFunctionMap[value].length, + }, + ]; + + targets[targets.length - 1]!.replaced = true; + } + + return StopWalkingFunctionNodes; + } + }); + } + }, + }; +}; + +const borderProps = new Set([ + 'border', + 'border-top', + 'border-right', + 'border-bottom', + 'border-left', + 'border-width', + 'border-top-width', + 'border-right-width', + 'border-bottom-width', + 'border-left-width', +]); + +const borderWidthFunctionMap = { + '': '--p-border-width-1', + base: '--p-border-width-1', + "'base'": '--p-border-width-1', + thick: '--p-border-width-2', + "'thick'": '--p-border-width-2', + thicker: '--p-border-width-3', + "'thicker'": '--p-border-width-3', +} as const; diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.input.scss b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.input.scss new file mode 100644 index 00000000000..4199d2e9c82 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.input.scss @@ -0,0 +1,15 @@ +/* stylelint-disable */ + +.border { + /* Migrate */ + border: border-width() solid var(--p-border-subdued); + border: border-width(base) solid var(--p-border-subdued); + border: border-width(thick) solid var(--p-border-subdued); + border: border-width(thicker) solid var(--p-border-subdued); + border-width: border-width('thicker'); + + /* Ignore */ + border-width: calc(-1 * border-width()); + border-width: calc($var * border-width()); + border-width: rem(1px) rem(10px - border-width()); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.output.scss b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.output.scss new file mode 100644 index 00000000000..eedfbe975ea --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.output.scss @@ -0,0 +1,15 @@ +/* stylelint-disable */ + +.border { + /* Migrate */ + border: var(--p-border-width-1) solid var(--p-border-subdued); + border: var(--p-border-width-1) solid var(--p-border-subdued); + border: var(--p-border-width-2) solid var(--p-border-subdued); + border: var(--p-border-width-3) solid var(--p-border-subdued); + border-width: var(--p-border-width-3); + + /* Ignore */ + border-width: calc(-1 * border-width()); + border-width: calc($var * border-width()); + border-width: rem(1px) rem(10px - border-width()); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.test.ts b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.test.ts new file mode 100644 index 00000000000..8f2ca4eb2d6 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/tests/scss-replace-border-width.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-border-width'; +const fixtures = ['scss-replace-border-width', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.input.scss new file mode 100644 index 00000000000..c38b7116114 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.input.scss @@ -0,0 +1,17 @@ +/* stylelint-disable */ +@use 'global-styles/legacy-polaris-v8'; + +.border { + /* Migrate */ + border: legacy-polaris-v8.border-width() solid var(--p-border-subdued); + border: legacy-polaris-v8.border-width(base) solid var(--p-border-subdued); + border: legacy-polaris-v8.border-width(thick) solid var(--p-border-subdued); + border: legacy-polaris-v8.border-width(thicker) solid var(--p-border-subdued); + border-width: legacy-polaris-v8.border-width('thicker'); + + /* Ignore */ + border-width: calc(-1 * legacy-polaris-v8.border-width()); + border-width: calc($var * legacy-polaris-v8.border-width()); + border-width: legacy-polaris-v8.rem(1px) + legacy-polaris-v8.rem(10px - legacy-polaris-v8.border-width()); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.output.scss new file mode 100644 index 00000000000..4f673b07f1f --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border-width/tests/with-namespace.output.scss @@ -0,0 +1,17 @@ +/* stylelint-disable */ +@use 'global-styles/legacy-polaris-v8'; + +.border { + /* Migrate */ + border: var(--p-border-width-1) solid var(--p-border-subdued); + border: var(--p-border-width-1) solid var(--p-border-subdued); + border: var(--p-border-width-2) solid var(--p-border-subdued); + border: var(--p-border-width-3) solid var(--p-border-subdued); + border-width: var(--p-border-width-3); + + /* Ignore */ + border-width: calc(-1 * legacy-polaris-v8.border-width()); + border-width: calc($var * legacy-polaris-v8.border-width()); + border-width: legacy-polaris-v8.rem(1px) + legacy-polaris-v8.rem(10px - legacy-polaris-v8.border-width()); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border/scss-replace-border.ts b/polaris-migrator/src/migrations/scss-replace-border/scss-replace-border.ts new file mode 100644 index 00000000000..4417d25a114 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border/scss-replace-border.ts @@ -0,0 +1,119 @@ +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + getFunctionArgs, + isSassFunction, + namespace, + NamespaceOptions, + createInlineComment, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceBorder( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedBorder = namespace('border', options); + + return { + postcssPlugin: 'scss-replace-border', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + if (!borderProps.has(decl.prop)) return; + + /** + * A collection of transformable values to migrate (e.g. decl lengths, functions, etc.) + * + * Note: This is evaluated at the end of each visitor execution to determine whether + * or not to replace the declaration or insert a comment. + */ + const targets: {replaced: boolean}[] = []; + const parsedValue = valueParser(decl.value); + + handleBorderProps(); + + if (targets.some(({replaced}) => !replaced)) { + // Insert comment if the declaration value contains calculations + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } else { + decl.value = parsedValue.toString(); + } + + // + // Handlers + // + + function handleBorderProps() { + parsedValue.walk((node) => { + if ( + node.type === 'function' && + isSassFunction(namespacedBorder, node) + ) { + targets.push({replaced: false}); + + const args = getFunctionArgs(node); + + if (!(args.length === 0 || args.length === 1)) return; + + // `border()` args reference: + // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L641 + const value = args[0] ?? 'base'; + + if (!isKeyOf(borderFunctionMap, value)) return; + + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: borderFunctionMap[value], + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: borderFunctionMap[value].length, + }, + ]; + + targets[targets.length - 1]!.replaced = true; + } + }); + } + }, + }; +}; + +const borderProps = new Set([ + 'border', + 'border-top', + 'border-right', + 'border-bottom', + 'border-left', +]); + +const borderFunctionMap = { + '': '--p-border-base', + base: '--p-border-base', + "'base'": '--p-border-base', + dark: '--p-border-dark', + "'dark'": '--p-border-dark', + transparent: '--p-border-transparent', + "'transparent'": '--p-border-transparent', + divider: ' --p-border-divider', + "'divider'": ' --p-border-divider', +} as const; diff --git a/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.input.scss b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.input.scss new file mode 100644 index 00000000000..9633ef3398b --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.input.scss @@ -0,0 +1,13 @@ +/* stylelint-disable */ + +.border { + border: border(); + border: border(base); + border: border('base'); + border: border(dark); + border: border('dark'); + border-bottom: border(transparent); + border: border('transparent'); + border: border(divider); + border-left: border('divider'); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.output.scss b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.output.scss new file mode 100644 index 00000000000..b18004d14a5 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.output.scss @@ -0,0 +1,13 @@ +/* stylelint-disable */ + +.border { + border: var(--p-border-base); + border: var(--p-border-base); + border: var(--p-border-base); + border: var(--p-border-dark); + border: var(--p-border-dark); + border-bottom: var(--p-border-transparent); + border: var(--p-border-transparent); + border: var(--p-border-divider); + border-left: var(--p-border-divider); +} diff --git a/polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.test.ts b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.test.ts similarity index 74% rename from polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.test.ts rename to polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.test.ts index 06782fe95a6..c499b9184bb 100644 --- a/polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.test.ts +++ b/polaris-migrator/src/migrations/scss-replace-border/tests/scss-replace-border.test.ts @@ -1,7 +1,7 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'replace-sass-color'; -const fixtures = ['replace-sass-color', 'with-namespace']; +const migration = 'scss-replace-border'; +const fixtures = ['scss-replace-border', 'with-namespace']; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.input.scss new file mode 100644 index 00000000000..160068c85d2 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.input.scss @@ -0,0 +1,15 @@ +/* stylelint-disable */ + +@use 'global-styles/legacy-polaris-v8'; + +.border { + border: legacy-polaris-v8.border(); + border: legacy-polaris-v8.border(base); + border: legacy-polaris-v8.border('base'); + border: legacy-polaris-v8.border(dark); + border: legacy-polaris-v8.border('dark'); + border-bottom: legacy-polaris-v8.border(transparent); + border: legacy-polaris-v8.border('transparent'); + border: legacy-polaris-v8.border(divider); + border-left: legacy-polaris-v8.border('divider'); +} diff --git a/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.output.scss new file mode 100644 index 00000000000..749761f4ea1 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-border/tests/with-namespace.output.scss @@ -0,0 +1,15 @@ +/* stylelint-disable */ + +@use 'global-styles/legacy-polaris-v8'; + +.border { + border: var(--p-border-base); + border: var(--p-border-base); + border: var(--p-border-base); + border: var(--p-border-dark); + border: var(--p-border-dark); + border-bottom: var(--p-border-transparent); + border: var(--p-border-transparent); + border: var(--p-border-divider); + border-left: var(--p-border-divider); +} diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/replace-static-breakpoint-mixins.ts b/polaris-migrator/src/migrations/scss-replace-breakpoints/scss-replace-breakpoints.ts similarity index 94% rename from polaris-migrator/src/migrations/replace-static-breakpoint-mixins/replace-static-breakpoint-mixins.ts rename to polaris-migrator/src/migrations/scss-replace-breakpoints/scss-replace-breakpoints.ts index 7a7ecaf25b4..5af2c9ea1d0 100644 --- a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/replace-static-breakpoint-mixins.ts +++ b/polaris-migrator/src/migrations/scss-replace-breakpoints/scss-replace-breakpoints.ts @@ -33,7 +33,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { ); return { - postcssPlugin: 'ReplaceStaticBreakpointMixins', + postcssPlugin: 'scss-replace-breakpoints', AtRule(atRule) { if (atRule.name !== 'include') return; @@ -50,7 +50,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { }; }; -export default function replaceStaticMixinsWithDeclarations( +export default function sassReplaceBreakpoints( fileInfo: FileInfo, _: API, options: Options, diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.input.scss b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.input.scss rename to polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.input.scss diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.output.scss b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/replace-static-breakpoint-mixins.output.scss rename to polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.output.scss diff --git a/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.test.ts b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.test.ts new file mode 100644 index 00000000000..cfe155f59ff --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/scss-replace-breakpoints.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-breakpoints'; +const fixtures = ['scss-replace-breakpoints', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/scss-replace-breakpoints/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-breakpoints/tests/with-namespace.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-breakpoint-mixins/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/scss-replace-breakpoints/tests/with-namespace.output.scss diff --git a/polaris-migrator/src/migrations/replace-sass-color/replace-sass-color.ts b/polaris-migrator/src/migrations/scss-replace-color/scss-replace-color.ts similarity index 98% rename from polaris-migrator/src/migrations/replace-sass-color/replace-sass-color.ts rename to polaris-migrator/src/migrations/scss-replace-color/scss-replace-color.ts index f13c715ed19..36330220e89 100644 --- a/polaris-migrator/src/migrations/replace-sass-color/replace-sass-color.ts +++ b/polaris-migrator/src/migrations/scss-replace-color/scss-replace-color.ts @@ -12,7 +12,7 @@ import { } from '../../utilities/sass'; import {isKeyOf} from '../../utilities/type-guards'; -export default function replaceSassColors( +export default function scssReplaceColor( file: FileInfo, _: API, options: Options, @@ -30,7 +30,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { const namespacedColor = namespace('color', options); return { - postcssPlugin: 'replace-sass-color', + postcssPlugin: 'scss-replace-color', Declaration(decl) { // @ts-expect-error - Skip if processed so we don't process it again if (decl[processed]) return; diff --git a/polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.input.scss b/polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.input.scss rename to polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.output.scss b/polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-color/tests/replace-sass-color.output.scss rename to polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.output.scss diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-sass-spacing.test.ts b/polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.test.ts similarity index 74% rename from polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-sass-spacing.test.ts rename to polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.test.ts index 0dae8875670..65484c8cec0 100644 --- a/polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-sass-spacing.test.ts +++ b/polaris-migrator/src/migrations/scss-replace-color/tests/scss-replace-color.test.ts @@ -1,7 +1,7 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'replace-sass-spacing'; -const fixtures = ['replace-spacing', 'with-namespace']; +const migration = 'scss-replace-color'; +const fixtures = ['scss-replace-color', 'with-namespace']; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/replace-sass-color/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-color/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-color/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/scss-replace-color/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-color/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-color/tests/with-namespace.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-color/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/scss-replace-color/tests/with-namespace.output.scss diff --git a/polaris-migrator/src/migrations/scss-replace-duration/scss-replace-duration.ts b/polaris-migrator/src/migrations/scss-replace-duration/scss-replace-duration.ts new file mode 100644 index 00000000000..c2cecd80b34 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-duration/scss-replace-duration.ts @@ -0,0 +1,77 @@ +import valueParser from 'postcss-value-parser'; + +import { + namespace, + isSassFunction, + isNumericOperator, + createSassMigrator, + setNodeValue, + StopWalkingFunctionNodes, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +const DEFAULT_DURATION = 'base'; + +const durationMap = { + none: '--p-duration-0', + fast: '--p-duration-100', + base: '--p-duration-200', + slow: '--p-duration-300', + slower: '--p-duration-400', + slowest: '--p-duration-500', +}; + +export default createSassMigrator( + 'replace-sass-transition', + (_, {methods, options}, context) => { + const namespacedDuration = namespace('duration', options); + + return (root) => { + methods.walkDecls(root, (decl) => { + const parsedValue = valueParser(decl.value); + + parsedValue.walk((node) => { + if (isNumericOperator(node)) { + methods.report({ + node: decl, + severity: 'warning', + message: 'Numeric operator detected.', + }); + } + + if (isSassFunction(namespacedDuration, node)) { + const duration = node.nodes[0]?.value ?? DEFAULT_DURATION; + + if (!isKeyOf(durationMap, duration)) { + methods.report({ + severity: 'warning', + node: decl, + message: `Unknown duration key '${duration}'.`, + }); + return StopWalkingFunctionNodes; + } + + const durationCustomProperty = durationMap[duration]; + const targetValue = `var(${durationCustomProperty})`; + + if (context.fix) { + setNodeValue(node, targetValue); + } else { + methods.report({ + severity: 'error', + node: decl, + message: `Replace duration with token: ${targetValue}`, + }); + } + + return StopWalkingFunctionNodes; + } + }); + + if (context.fix) { + decl.value = parsedValue.toString(); + } + }); + }; + }, +); diff --git a/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.input.scss b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.input.scss new file mode 100644 index 00000000000..00a7f53c590 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.input.scss @@ -0,0 +1,68 @@ +.duration-simple-string-arg { + transition-duration: duration('none'); + transition-duration: duration('fast'); + transition-duration: duration('base'); + transition-duration: duration('slow'); + transition-duration: duration('slower'); + transition-duration: duration('slowest'); +} + +.duration-simple-non-string-arg { + transition-duration: duration(); + transition-duration: duration(none); + transition-duration: duration(fast); + transition-duration: duration(base); + transition-duration: duration(slow); + transition-duration: duration(slower); + transition-duration: duration(slowest); +} + +.duration-compound-string-arg { + transition: opacity duration('none') linear; + transition: opacity duration('fast') linear; + transition: opacity duration('base') linear; + transition: opacity duration('slow') linear; + transition: opacity duration('slower') linear; + transition: opacity duration('slowest') linear; +} + +.duration-compound-non-string-arg { + transition: opacity duration() linear; + transition: opacity duration(none) linear; + transition: opacity duration(fast) linear; + transition: opacity duration(base) linear; + transition: opacity duration(slow) linear; + transition: opacity duration(slower) linear; + transition: opacity duration(slowest) linear; +} + +.duration-multiple-string-arg { + transition: opacity duration('none') linear, left duration('none') linear; + transition: opacity duration('fast') linear, left duration('fast') linear; + transition: opacity duration('base') linear, left duration('base') linear; + transition: opacity duration('slow') linear, left duration('slow') linear; + transition: opacity duration('slower') linear, left duration('slower') linear; + transition: opacity duration('slowest') linear, + left duration('slowest') linear; +} + +.duration-multiple-non-string-arg { + transition: opacity duration() linear, left duration() linear; + transition: opacity duration(none) linear, left duration(none) linear; + transition: opacity duration(fast) linear, left duration(fast) linear; + transition: opacity duration(base) linear, left duration(base) linear; + transition: opacity duration(slow) linear, left duration(slow) linear; + transition: opacity duration(slower) linear, left duration(slower) linear; + transition: opacity duration(slowest) linear, left duration(slowest) linear; +} + +.duration-edges { + // sass calculation + transition: (duration() - 33ms) fill linear 33ms; + // Duration + Delay + transition: opacity duration(slower) linear duration(fast); + // Duration + Delay after easing func + transition: opacity linear duration(slower) duration(fast); + // foobar isn't a valid duration key + transition-duration: duration(foobar); +} diff --git a/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.output.scss b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.output.scss new file mode 100644 index 00000000000..d064f2db9ed --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.output.scss @@ -0,0 +1,85 @@ +.duration-simple-string-arg { + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-500); +} + +.duration-simple-non-string-arg { + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-500); +} + +.duration-compound-string-arg { + transition: opacity var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear; +} + +.duration-compound-non-string-arg { + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear; +} + +.duration-multiple-string-arg { + transition: opacity var(--p-duration-0) linear, + left var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear, + left var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear, + left var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear, + left var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear, + left var(--p-duration-500) linear; +} + +.duration-multiple-non-string-arg { + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-0) linear, + left var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear, + left var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear, + left var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear, + left var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear, + left var(--p-duration-500) linear; +} + +.duration-edges { + // sass calculation + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Numeric operator detected. + // transition: (var(--p-duration-200) - 33ms) fill linear 33ms; + transition: (duration() - 33ms) fill linear 33ms; + // Duration + Delay + transition: opacity var(--p-duration-400) linear var(--p-duration-100); + // Duration + Delay after easing func + transition: opacity linear var(--p-duration-400) var(--p-duration-100); + // foobar isn't a valid duration key + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unknown duration key 'foobar'. + transition-duration: duration(foobar); +} diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.test.ts b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.test.ts similarity index 72% rename from polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.test.ts rename to polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.test.ts index 599e28a54b3..be6eee24c82 100644 --- a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.test.ts +++ b/polaris-migrator/src/migrations/scss-replace-duration/tests/scss-replace-duration.test.ts @@ -1,7 +1,7 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'replace-spacing-lengths'; -const fixtures = ['replace-spacing-lengths', 'with-namespace']; +const migration = 'scss-replace-duration'; +const fixtures = ['scss-replace-duration', 'with-namespace']; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.input.scss b/polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.input.scss similarity index 53% rename from polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.input.scss rename to polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.input.scss index 11ea0ce75cf..297dc162fb6 100644 --- a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-duration.input.scss +++ b/polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.input.scss @@ -1,5 +1,6 @@ +@use 'global-styles/legacy-polaris-v8'; + .duration-simple-string-arg { - opacity: 1; transition-duration: legacy-polaris-v8.duration('none'); transition-duration: legacy-polaris-v8.duration('fast'); transition-duration: legacy-polaris-v8.duration('base'); @@ -9,7 +10,6 @@ } .duration-simple-non-string-arg { - opacity: 1; transition-duration: legacy-polaris-v8.duration(); transition-duration: legacy-polaris-v8.duration(none); transition-duration: legacy-polaris-v8.duration(fast); @@ -19,36 +19,7 @@ transition-duration: legacy-polaris-v8.duration(slowest); } -.duration-simple-constant { - opacity: 1; - transition-duration: 0; - transition-duration: 0ms; - transition-duration: 0s; - transition-duration: 50ms; - transition-duration: 0.05s; - transition-duration: 100ms; - transition-duration: 0.1s; - transition-duration: 150ms; - transition-duration: 0.15s; - transition-duration: 200ms; - transition-duration: 0.2s; - transition-duration: 250ms; - transition-duration: 0.25s; - transition-duration: 300ms; - transition-duration: 0.3s; - transition-duration: 350ms; - transition-duration: 0.35s; - transition-duration: 400ms; - transition-duration: 0.4s; - transition-duration: 450ms; - transition-duration: 0.45s; - transition-duration: 500ms; - transition-duration: 0.5s; - transition-duration: 5s; -} - .duration-compound-string-arg { - opacity: 1; transition: opacity legacy-polaris-v8.duration('none') linear; transition: opacity legacy-polaris-v8.duration('fast') linear; transition: opacity legacy-polaris-v8.duration('base') linear; @@ -58,7 +29,6 @@ } .duration-compound-non-string-arg { - opacity: 1; transition: opacity legacy-polaris-v8.duration() linear; transition: opacity legacy-polaris-v8.duration(none) linear; transition: opacity legacy-polaris-v8.duration(fast) linear; @@ -68,36 +38,7 @@ transition: opacity legacy-polaris-v8.duration(slowest) linear; } -.duration-compound-constant { - opacity: 1; - transition: opacity 0 linear; - transition: opacity 0ms linear; - transition: opacity 0s linear; - transition: opacity 50ms linear; - transition: opacity 0.05s linear; - transition: opacity 100ms linear; - transition: opacity 0.1s linear; - transition: opacity 150ms linear; - transition: opacity 0.15s linear; - transition: opacity 200ms linear; - transition: opacity 0.2s linear; - transition: opacity 250ms linear; - transition: opacity 0.25s linear; - transition: opacity 300ms linear; - transition: opacity 0.3s linear; - transition: opacity 350ms linear; - transition: opacity 0.35s linear; - transition: opacity 400ms linear; - transition: opacity 0.4s linear; - transition: opacity 450ms linear; - transition: opacity 0.45s linear; - transition: opacity 500ms linear; - transition: opacity 0.5s linear; - transition: opacity 5s linear; -} - .duration-multiple-string-arg { - opacity: 1; transition: opacity legacy-polaris-v8.duration('none') linear, left legacy-polaris-v8.duration('none') linear; transition: opacity legacy-polaris-v8.duration('fast') linear, @@ -113,7 +54,6 @@ } .duration-multiple-non-string-arg { - opacity: 1; transition: opacity legacy-polaris-v8.duration() linear, left legacy-polaris-v8.duration() linear; transition: opacity legacy-polaris-v8.duration(none) linear, @@ -130,39 +70,9 @@ left legacy-polaris-v8.duration(slowest) linear; } -.duration-multiple-constant { - opacity: 1; - transition: opacity 0 linear, left 0 linear; - transition: opacity 0ms linear, left 0ms linear; - transition: opacity 0s linear, left 0s linear; - transition: opacity 50ms linear, left 50ms linear; - transition: opacity 0.05s linear, left 0.05s linear; - transition: opacity 100ms linear, left 100ms linear; - transition: opacity 0.1s linear, left 0.1s linear; - transition: opacity 150ms linear, left 150ms linear; - transition: opacity 0.15s linear, left 0.15s linear; - transition: opacity 200ms linear, left 200ms linear; - transition: opacity 0.2s linear, left 0.2s linear; - transition: opacity 250ms linear, left 250ms linear; - transition: opacity 0.25s linear, left 0.25s linear; - transition: opacity 300ms linear, left 300ms linear; - transition: opacity 0.3s linear, left 0.3s linear; - transition: opacity 350ms linear, left 350ms linear; - transition: opacity 0.35s linear, left 0.35s linear; - transition: opacity 400ms linear, left 400ms linear; - transition: opacity 0.4s linear, left 0.4s linear; - transition: opacity 450ms linear, left 450ms linear; - transition: opacity 0.45s linear, left 0.45s linear; - transition: opacity 500ms linear, left 500ms linear; - transition: opacity 0.5s linear, left 0.5s linear; - transition: opacity 5s linear, left 5s linear; -} - -.edges { +.duration-edges { // sass calculation transition: (legacy-polaris-v8.duration() - 33ms) fill linear 33ms; - // Duration comes after easing func - transition: opacity linear 0.5s; // Duration + Delay transition: opacity legacy-polaris-v8.duration(slower) linear legacy-polaris-v8.duration(fast); @@ -171,7 +81,4 @@ legacy-polaris-v8.duration(fast); // foobar isn't a valid duration key transition-duration: legacy-polaris-v8.duration(foobar); - // can't process variables - transition-duration: $foo; - transition: opacity $foo 0.5s; } diff --git a/polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.output.scss new file mode 100644 index 00000000000..49513236d84 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-duration/tests/with-namespace.output.scss @@ -0,0 +1,87 @@ +@use 'global-styles/legacy-polaris-v8'; + +.duration-simple-string-arg { + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-500); +} + +.duration-simple-non-string-arg { + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-500); +} + +.duration-compound-string-arg { + transition: opacity var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear; +} + +.duration-compound-non-string-arg { + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear; +} + +.duration-multiple-string-arg { + transition: opacity var(--p-duration-0) linear, + left var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear, + left var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear, + left var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear, + left var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear, + left var(--p-duration-500) linear; +} + +.duration-multiple-non-string-arg { + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-0) linear, + left var(--p-duration-0) linear; + transition: opacity var(--p-duration-100) linear, + left var(--p-duration-100) linear; + transition: opacity var(--p-duration-200) linear, + left var(--p-duration-200) linear; + transition: opacity var(--p-duration-300) linear, + left var(--p-duration-300) linear; + transition: opacity var(--p-duration-400) linear, + left var(--p-duration-400) linear; + transition: opacity var(--p-duration-500) linear, + left var(--p-duration-500) linear; +} + +.duration-edges { + // sass calculation + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Numeric operator detected. + // transition: (var(--p-duration-200) - 33ms) fill linear 33ms; + transition: (legacy-polaris-v8.duration() - 33ms) fill linear 33ms; + // Duration + Delay + transition: opacity var(--p-duration-400) linear var(--p-duration-100); + // Duration + Delay after easing func + transition: opacity linear var(--p-duration-400) var(--p-duration-100); + // foobar isn't a valid duration key + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unknown duration key 'foobar'. + transition-duration: legacy-polaris-v8.duration(foobar); +} diff --git a/polaris-migrator/src/migrations/scss-replace-easing/scss-replace-easing.ts b/polaris-migrator/src/migrations/scss-replace-easing/scss-replace-easing.ts new file mode 100644 index 00000000000..dc5f399b5e3 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-easing/scss-replace-easing.ts @@ -0,0 +1,82 @@ +import valueParser from 'postcss-value-parser'; + +import { + namespace, + isSassFunction, + isNumericOperator, + createSassMigrator, + setNodeValue, + StopWalkingFunctionNodes, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +const DEFAULT_EASING = 'base'; + +const easingMap = { + base: '--p-ease', + in: '--p-ease-in', + out: '--p-ease-out', +}; + +const deprecatedEasingFuncs = ['anticipate', 'excite', 'overshoot']; + +export default createSassMigrator( + 'scss-replace-easing', + (_, {methods, options}, context) => { + const namespacedEasing = namespace('easing', options); + + return (root) => { + methods.walkDecls(root, (decl) => { + const parsedValue = valueParser(decl.value); + + parsedValue.walk((node) => { + if (isNumericOperator(node)) { + methods.report({ + node: decl, + severity: 'warning', + message: 'Numeric operator detected.', + }); + return; + } + + if (isSassFunction(namespacedEasing, node)) { + const easing = node.nodes[0]?.value ?? DEFAULT_EASING; + + if (!isKeyOf(easingMap, easing)) { + const comment = deprecatedEasingFuncs.includes(easing) + ? `The ${easing} easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values.` + : `Unexpected easing function '${easing}'.`; + + methods.report({ + severity: 'warning', + node: decl, + message: comment, + }); + + return StopWalkingFunctionNodes; + } + + const easingCustomProperty = easingMap[easing]; + const targetValue = `var(${easingCustomProperty})`; + + if (context.fix) { + setNodeValue(node, targetValue); + } else { + methods.report({ + severity: 'error', + node: decl, + message: `Replace easing function with token: ${targetValue}`, + }); + } + + return StopWalkingFunctionNodes; + } + }); + + if (context.fix) { + decl.value = parsedValue.toString(); + } + }); + }; + }, +); diff --git a/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.input.scss b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.input.scss new file mode 100644 index 00000000000..86f533159b1 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.input.scss @@ -0,0 +1,68 @@ +.easing-simple-string-arg { + transition-timing-function: easing('anticipate'); + transition-timing-function: easing('base'); + transition-timing-function: easing('excite'); + transition-timing-function: easing('in'); + transition-timing-function: easing('out'); + transition-timing-function: easing('overshoot'); +} + +.easing-simple-non-string-arg { + transition-timing-function: easing(); + transition-timing-function: easing(anticipate); + transition-timing-function: easing(base); + transition-timing-function: easing(excite); + transition-timing-function: easing(in); + transition-timing-function: easing(out); + transition-timing-function: easing(overshoot); +} + +.easing-shorthand-string-arg { + transition: opacity 300ms easing('anticipate'); + transition: opacity 300ms easing('base'); + transition: opacity 300ms easing('excite'); + transition: opacity 300ms easing('in'); + transition: opacity 300ms easing('out'); + transition: opacity 300ms easing('overshoot'); +} + +.easing-shorthand-non-string-arg { + transition: opacity 300ms easing(); + transition: opacity 300ms easing(anticipate); + transition: opacity 300ms easing(base); + transition: opacity 300ms easing(excite); + transition: opacity 300ms easing(in); + transition: opacity 300ms easing(out); + transition: opacity 300ms easing(overshoot); +} + +.easing-multiple-string-arg { + transition: opacity 300ms easing('anticipate'), + left 300ms easing('anticipate'); + transition: opacity 300ms easing('base'), left 300ms easing('base'); + transition: opacity 300ms easing('excite'), left 300ms easing('excite'); + transition: opacity 300ms easing('in'), left 300ms easing('in'); + transition: opacity 300ms easing('out'), left 300ms easing('out'); + transition: opacity 300ms easing('overshoot'), left 300ms easing('overshoot'); +} + +.easing-multiple-non-string-arg { + transition: opacity 300ms easing(), left 300ms easing(); + transition: opacity 300ms easing(anticipate), left 300ms easing(anticipate); + transition: opacity 300ms easing(base), left 300ms easing(base); + transition: opacity 300ms easing(excite), left 300ms easing(excite); + transition: opacity 300ms easing(in), left 300ms easing(in); + transition: opacity 300ms easing(out), left 300ms easing(out); + transition: opacity 300ms easing(overshoot), left 300ms easing(overshoot); +} + +$easingFunc: 'ease-in'; + +.edges { + // Unknown values are flagged + transition-timing-function: easing(foobar); + // Can only handle hard coded values + transition-timing-function: easing($easingFunc); + // Value replacement with legacy easing function value + transition: opacity 300ms easing(base), left 300ms easing(overshoot); +} diff --git a/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.output.scss b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.output.scss new file mode 100644 index 00000000000..d792846a674 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.output.scss @@ -0,0 +1,111 @@ +.easing-simple-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing('anticipate'); + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing('excite'); + transition-timing-function: var(--p-ease-in); + transition-timing-function: var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing('overshoot'); +} + +.easing-simple-non-string-arg { + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing(anticipate); + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing(excite); + transition-timing-function: var(--p-ease-in); + transition-timing-function: var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: easing(overshoot); +} + +.easing-shorthand-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('anticipate'); + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('excite'); + transition: opacity 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('overshoot'); +} + +.easing-shorthand-non-string-arg { + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(anticipate); + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(excite); + transition: opacity 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(overshoot); +} + +.easing-multiple-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('anticipate'), + left 300ms easing('anticipate'); + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('excite'), left 300ms easing('excite'); + transition: opacity 300ms var(--p-ease-in), left 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out), left 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing('overshoot'), left 300ms easing('overshoot'); +} + +.easing-multiple-non-string-arg { + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(anticipate), left 300ms easing(anticipate); + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(excite), left 300ms easing(excite); + transition: opacity 300ms var(--p-ease-in), left 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out), left 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms easing(overshoot), left 300ms easing(overshoot); +} + +$easingFunc: 'ease-in'; + +.edges { + // Unknown values are flagged + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'foobar'. + transition-timing-function: easing(foobar); + // Can only handle hard coded values + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function '$easingFunc'. + transition-timing-function: easing($easingFunc); + // Value replacement with legacy easing function value + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity 300ms var(--p-ease), left 300ms easing(overshoot); + transition: opacity 300ms easing(base), left 300ms easing(overshoot); +} diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.test.ts b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.test.ts similarity index 73% rename from polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.test.ts rename to polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.test.ts index d1618ac2149..1625b4969c1 100644 --- a/polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.test.ts +++ b/polaris-migrator/src/migrations/scss-replace-easing/tests/scss-replace-easing.test.ts @@ -1,7 +1,7 @@ import {check} from '../../../utilities/testUtils'; -const migration = 'replace-sass-z-index'; -const fixtures = ['replace-sass-z-index', 'with-namespace']; +const migration = 'scss-replace-easing'; +const fixtures = ['scss-replace-easing', 'with-namespace']; for (const fixture of fixtures) { check(__dirname, { diff --git a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.input.scss b/polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.input.scss similarity index 59% rename from polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.input.scss rename to polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.input.scss index a786cc742fd..74179e31892 100644 --- a/polaris-migrator/src/migrations/replace-sass-transition/tests/replace-sass-easing.input.scss +++ b/polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.input.scss @@ -1,5 +1,6 @@ +@use 'global-styles/legacy-polaris-v8'; + .easing-simple-string-arg { - opacity: 1; transition-timing-function: legacy-polaris-v8.easing('anticipate'); transition-timing-function: legacy-polaris-v8.easing('base'); transition-timing-function: legacy-polaris-v8.easing('excite'); @@ -9,7 +10,6 @@ } .easing-simple-non-string-arg { - opacity: 1; transition-timing-function: legacy-polaris-v8.easing(); transition-timing-function: legacy-polaris-v8.easing(anticipate); transition-timing-function: legacy-polaris-v8.easing(base); @@ -19,24 +19,7 @@ transition-timing-function: legacy-polaris-v8.easing(overshoot); } -.easing-simple-builtins { - opacity: 1; - transition-timing-function: linear; - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - transition-timing-function: linear(1); - transition-timing-function: ease; - transition-timing-function: ease-in; - transition-timing-function: ease-out; - transition-timing-function: ease-in-out; - transition-timing-function: cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - transition-timing-function: step-start; - transition-timing-function: step-end; - transition-timing-function: steps(1, jump-end); -} - .easing-shorthand-string-arg { - opacity: 1; transition: opacity 300ms legacy-polaris-v8.easing('anticipate'); transition: opacity 300ms legacy-polaris-v8.easing('base'); transition: opacity 300ms legacy-polaris-v8.easing('excite'); @@ -46,7 +29,6 @@ } .easing-shorthand-non-string-arg { - opacity: 1; transition: opacity 300ms legacy-polaris-v8.easing(); transition: opacity 300ms legacy-polaris-v8.easing(anticipate); transition: opacity 300ms legacy-polaris-v8.easing(base); @@ -56,24 +38,7 @@ transition: opacity 300ms legacy-polaris-v8.easing(overshoot); } -.easing-shorthand-builtins { - opacity: 1; - transition: opacity 300ms linear; - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - transition: opacity 300ms linear(1); - transition: opacity 300ms ease; - transition: opacity 300ms ease-in; - transition: opacity 300ms ease-out; - transition: opacity 300ms ease-in-out; - transition: opacity 300ms cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - transition: opacity 300ms step-start; - transition: opacity 300ms step-end; - transition: opacity 300ms steps(1, jump-end); -} - .easing-multiple-string-arg { - opacity: 1; transition: opacity 300ms legacy-polaris-v8.easing('anticipate'), left 300ms legacy-polaris-v8.easing('anticipate'); transition: opacity 300ms legacy-polaris-v8.easing('base'), @@ -89,7 +54,6 @@ } .easing-multiple-non-string-arg { - opacity: 1; transition: opacity 300ms legacy-polaris-v8.easing(), left 300ms legacy-polaris-v8.easing(); transition: opacity 300ms legacy-polaris-v8.easing(anticipate), @@ -106,33 +70,14 @@ left 300ms legacy-polaris-v8.easing(overshoot); } -.easing-multiple-builtins { - opacity: 1; - transition: opacity 300ms linear, left 300ms linear; - // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function - transition: opacity 300ms linear(1), left 300ms linear(1); - transition: opacity 300ms ease, left 300ms ease; - transition: opacity 300ms ease-in, left 300ms ease-in; - transition: opacity 300ms ease-out, left 300ms ease-out; - transition: opacity 300ms ease-in-out, left 300ms ease-in-out; - transition: opacity 300ms cubic-bezier(0, 0, 1, 1), - left 300ms cubic-bezier(0, 0, 1, 1); - // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function - transition: opacity 300ms step-start, left 300ms step-start; - transition: opacity 300ms step-end, left 300ms step-start; - transition: opacity 300ms steps(1, jump-end), left 300ms steps(1, jump-end); -} - $easingFunc: 'ease-in'; .edges { - // Without an easing function - transition: fill 300ms; // Unknown values are flagged transition-timing-function: legacy-polaris-v8.easing(foobar); // Can only handle hard coded values transition-timing-function: legacy-polaris-v8.easing($easingFunc); - // can't process variables - transition-timing-function: $foo; - transition: opacity $foo 0.5s; + // Value replacement with legacy easing function value + transition: opacity 300ms legacy-polaris-v8.easing(base), + left 300ms legacy-polaris-v8.easing(overshoot); } diff --git a/polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.output.scss new file mode 100644 index 00000000000..d6a1d3fbc34 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-easing/tests/with-namespace.output.scss @@ -0,0 +1,119 @@ +@use 'global-styles/legacy-polaris-v8'; + +.easing-simple-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing('anticipate'); + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing('excite'); + transition-timing-function: var(--p-ease-in); + transition-timing-function: var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing('overshoot'); +} + +.easing-simple-non-string-arg { + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing(anticipate); + transition-timing-function: var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing(excite); + transition-timing-function: var(--p-ease-in); + transition-timing-function: var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: legacy-polaris-v8.easing(overshoot); +} + +.easing-shorthand-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('anticipate'); + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('excite'); + transition: opacity 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('overshoot'); +} + +.easing-shorthand-non-string-arg { + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(anticipate); + transition: opacity 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(excite); + transition: opacity 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(overshoot); +} + +.easing-multiple-string-arg { + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('anticipate'), + left 300ms legacy-polaris-v8.easing('anticipate'); + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('excite'), + left 300ms legacy-polaris-v8.easing('excite'); + transition: opacity 300ms var(--p-ease-in), left 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out), left 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing('overshoot'), + left 300ms legacy-polaris-v8.easing('overshoot'); +} + +.easing-multiple-non-string-arg { + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The anticipate easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(anticipate), + left 300ms legacy-polaris-v8.easing(anticipate); + transition: opacity 300ms var(--p-ease), left 300ms var(--p-ease); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The excite easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(excite), + left 300ms legacy-polaris-v8.easing(excite); + transition: opacity 300ms var(--p-ease-in), left 300ms var(--p-ease-in); + transition: opacity 300ms var(--p-ease-out), left 300ms var(--p-ease-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + transition: opacity 300ms legacy-polaris-v8.easing(overshoot), + left 300ms legacy-polaris-v8.easing(overshoot); +} + +$easingFunc: 'ease-in'; + +.edges { + // Unknown values are flagged + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'foobar'. + transition-timing-function: legacy-polaris-v8.easing(foobar); + // Can only handle hard coded values + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function '$easingFunc'. + transition-timing-function: legacy-polaris-v8.easing($easingFunc); + // Value replacement with legacy easing function value + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: The overshoot easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity 300ms var(--p-ease), left 300ms legacy-polaris-v8.easing(overshoot); + transition: opacity 300ms legacy-polaris-v8.easing(base), + left 300ms legacy-polaris-v8.easing(overshoot); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/scss-replace-font-family.ts b/polaris-migrator/src/migrations/scss-replace-font-family/scss-replace-font-family.ts new file mode 100644 index 00000000000..72fd0689400 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/scss-replace-font-family.ts @@ -0,0 +1,93 @@ +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + createInlineComment, + getFunctionArgs, + isSassFunction, + namespace, + NamespaceOptions, + StopWalkingFunctionNodes, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceFontFamily( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedFontFamily = namespace('font-family', options); + + return { + postcssPlugin: 'scss-replace-font-family', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + let needsComment = false; + let needsFix = false; + const parsedValue = valueParser(decl.value); + + parsedValue.walk((node) => { + if (isSassFunction(namespacedFontFamily, node)) { + const args = getFunctionArgs(node); + + // `font-family()` args reference: + // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L945 + const family = args[0] ?? 'base'; + + if (!isKeyOf(fontFamilyMap, family)) { + needsComment = true; + return StopWalkingFunctionNodes; + } + + const fontFamilyCustomProperty = fontFamilyMap[family]; + + needsFix = true; + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: fontFamilyCustomProperty, + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: fontFamilyCustomProperty.length, + }, + ]; + + return StopWalkingFunctionNodes; + } + }); + + if (needsComment) { + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } + + if (needsFix) { + decl.value = parsedValue.toString(); + } + + // @ts-expect-error - Mark the declaration as processed + decl[processed] = true; + }, + }; +}; + +const fontFamilyMap = { + base: '--p-font-family-sans', + monospace: '--p-font-family-mono', +}; diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.input.scss b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.input.scss new file mode 100644 index 00000000000..90e6fc64a15 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.input.scss @@ -0,0 +1,6 @@ +.font-family { + font-family: sans-serif; + font-family: font-family(); + font-family: font-family(base); + font-family: font-family(monospace); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.output.scss b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.output.scss new file mode 100644 index 00000000000..30ee98afdab --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.output.scss @@ -0,0 +1,6 @@ +.font-family { + font-family: sans-serif; + font-family: var(--p-font-family-sans); + font-family: var(--p-font-family-sans); + font-family: var(--p-font-family-mono); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.test.ts b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.test.ts new file mode 100644 index 00000000000..b8d15ecf4c0 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/tests/scss-replace-font-family.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-font-family'; +const fixtures = ['scss-replace-font-family', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.input.scss new file mode 100644 index 00000000000..e01f6b5f5d7 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.input.scss @@ -0,0 +1,8 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-family { + font-family: sans-serif; + font-family: legacy-polaris-v8.font-family(); + font-family: legacy-polaris-v8.font-family(base); + font-family: legacy-polaris-v8.font-family(monospace); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.output.scss new file mode 100644 index 00000000000..c785e29c78a --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-family/tests/with-namespace.output.scss @@ -0,0 +1,8 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-family { + font-family: sans-serif; + font-family: var(--p-font-family-sans); + font-family: var(--p-font-family-sans); + font-family: var(--p-font-family-mono); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/scss-replace-font-size.ts b/polaris-migrator/src/migrations/scss-replace-font-size/scss-replace-font-size.ts new file mode 100644 index 00000000000..249addf4e52 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/scss-replace-font-size.ts @@ -0,0 +1,148 @@ +/* eslint-disable line-comment-position */ + +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + createInlineComment, + getFunctionArgs, + isSassFunction, + namespace, + NamespaceOptions, + StopWalkingFunctionNodes, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceFont( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedFontSize = namespace('font-size', options); + + return { + postcssPlugin: 'scss-replace-font', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + let needsFix = false; + let needsComment = false; + const parsedValue = valueParser(decl.value); + + parsedValue.walk((node) => { + if (isSassFunction(namespacedFontSize, node)) { + const args = getFunctionArgs(node); + + // `font-size()` args reference: + // https://github.com/Shopify/polaris/blob/1738f17c739e06dcde4653a9783ca367e38b4e32/documentation/guides/legacy-polaris-v8-public-api.scss#L977 + const styleArg = args[0]; + const variantArg = args[1] ?? 'base'; + + if ( + !( + isKeyOf(fontSizeMap, styleArg) && + isKeyOf(fontSizeMap[styleArg], variantArg) + ) + ) { + needsComment = true; + return StopWalkingFunctionNodes; + } + + needsFix = true; + const fontSizeVariant = fontSizeMap[styleArg][variantArg]; + + if (fontSizeVariant.startsWith('--')) { + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: fontSizeVariant, + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: fontSizeVariant.length, + }, + ]; + } else { + // @ts-expect-error: We are intentionally changing the node type + node.type = 'word'; + node.value = fontSizeVariant; + } + return StopWalkingFunctionNodes; + } + }); + + if (needsComment) { + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } + + if (needsFix) { + decl.value = parsedValue.toString(); + } + + // @ts-expect-error - Mark the declaration as processed + decl[processed] = true; + }, + }; +}; + +const fontSizeMap = { + caption: { + base: '0.8125rem', // 13px + 'large-screen': '--p-font-size-75', + }, + heading: { + base: '1.0625rem', // 17px + 'large-screen': '--p-font-size-200', + }, + subheading: { + base: '0.8125rem', // 13px + 'large-screen': '--p-font-size-75', + }, + input: { + base: '--p-font-size-200', + 'large-screen': '--p-font-size-100', + }, + body: { + base: '0.9375rem', // 15px + 'large-screen': '--p-font-size-100', + }, + button: { + base: '0.9375rem', // 15px + 'large-screen': '--p-font-size-100', + }, + 'button-large': { + base: '1.0625rem', // 17px + 'large-screen': '--p-font-size-200', + }, + 'display-x-large': { + base: '1.6875rem', // 27px + 'large-screen': '2.625rem', // 42px + }, + 'display-large': { + base: '--p-font-size-400', + 'large-screen': '--p-font-size-500', + }, + 'display-medium': { + base: '1.3125rem', // 21px + 'large-screen': '1.625rem', // 26px + }, + 'display-small': { + base: '--p-font-size-200', + 'large-screen': '--p-font-size-300', + }, +}; diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.input.scss b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.input.scss new file mode 100644 index 00000000000..e505a60654a --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.input.scss @@ -0,0 +1,9 @@ +.font-size { + font-size: font-size(caption); + font-size: font-size(caption, base); + font-size: font-size(caption, large-screen); + // Comment + font-size: font-size($invalid); + font-size: font-size(caption, $invalid); + font-size: font-size(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.output.scss b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.output.scss new file mode 100644 index 00000000000..5981047d94d --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.output.scss @@ -0,0 +1,15 @@ +.font-size { + font-size: 0.8125rem; + font-size: 0.8125rem; + font-size: var(--p-font-size-75); + // Comment + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: font-size($invalid); + font-size: font-size($invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: font-size(caption, $invalid); + font-size: font-size(caption, $invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: font-size(); + font-size: font-size(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.test.ts b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.test.ts new file mode 100644 index 00000000000..58b6a10ebda --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/tests/scss-replace-font-size.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-font-size'; +const fixtures = ['scss-replace-font-size', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.input.scss new file mode 100644 index 00000000000..0f2b7456c60 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.input.scss @@ -0,0 +1,11 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-size { + font-size: legacy-polaris-v8.font-size(caption); + font-size: legacy-polaris-v8.font-size(caption, base); + font-size: legacy-polaris-v8.font-size(caption, large-screen); + // Comment + font-size: legacy-polaris-v8.font-size($invalid); + font-size: legacy-polaris-v8.font-size(caption, $invalid); + font-size: legacy-polaris-v8.font-size(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.output.scss new file mode 100644 index 00000000000..ed966b59d7f --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-font-size/tests/with-namespace.output.scss @@ -0,0 +1,17 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-size { + font-size: 0.8125rem; + font-size: 0.8125rem; + font-size: var(--p-font-size-75); + // Comment + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.font-size($invalid); + font-size: legacy-polaris-v8.font-size($invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.font-size(caption, $invalid); + font-size: legacy-polaris-v8.font-size(caption, $invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.font-size(); + font-size: legacy-polaris-v8.font-size(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/scss-replace-line-height.ts b/polaris-migrator/src/migrations/scss-replace-line-height/scss-replace-line-height.ts new file mode 100644 index 00000000000..eee5add6211 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/scss-replace-line-height.ts @@ -0,0 +1,143 @@ +/* eslint-disable line-comment-position */ + +import type {FileInfo, API, Options} from 'jscodeshift'; +import postcss, {Plugin} from 'postcss'; +import valueParser from 'postcss-value-parser'; + +import {POLARIS_MIGRATOR_COMMENT} from '../../constants'; +import { + createInlineComment, + getFunctionArgs, + isSassFunction, + namespace, + NamespaceOptions, + StopWalkingFunctionNodes, +} from '../../utilities/sass'; +import {isKeyOf} from '../../utilities/type-guards'; + +export default function scssReplaceLineHeight( + fileInfo: FileInfo, + _: API, + options: Options, +) { + return postcss(plugin(options)).process(fileInfo.source, { + syntax: require('postcss-scss'), + }).css; +} + +const processed = Symbol('processed'); + +interface PluginOptions extends Options, NamespaceOptions {} + +const plugin = (options: PluginOptions = {}): Plugin => { + const namespacedLineHeight = namespace('line-height', options); + + return { + postcssPlugin: 'scss-replace-line-height', + Declaration(decl) { + // @ts-expect-error - Skip if processed so we don't process it again + if (decl[processed]) return; + + let needsFix = false; + let needsComment = false; + const parsedValue = valueParser(decl.value); + + parsedValue.walk((node) => { + if (isSassFunction(namespacedLineHeight, node)) { + const args = getFunctionArgs(node); + + // `line-height()` args reference: + // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L961 + const styleArg = args[0]; + const variantArg = args[1] ?? 'base'; + + if ( + !( + isKeyOf(lineHeightMap, styleArg) && + isKeyOf(lineHeightMap[styleArg], variantArg) + ) + ) { + needsComment = true; + return StopWalkingFunctionNodes; + } + + needsFix = true; + const lineHeightVariant = lineHeightMap[styleArg][variantArg]; + + if (lineHeightVariant.startsWith('--')) { + node.value = 'var'; + node.nodes = [ + { + type: 'word', + value: lineHeightVariant, + sourceIndex: node.nodes[0]?.sourceIndex ?? 0, + sourceEndIndex: lineHeightVariant.length, + }, + ]; + } else { + // @ts-expect-error: We are intentionally changing the node type + node.type = 'word'; + node.value = lineHeightVariant; + } + + return StopWalkingFunctionNodes; + } + }); + + if (needsComment) { + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); + decl.before( + createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), + ); + } + + if (needsFix) { + decl.value = parsedValue.toString(); + } + + // @ts-expect-error - Mark the declaration as processed + decl[processed] = true; + }, + }; +}; + +const lineHeightMap = { + caption: { + base: '--p-font-line-height-2', + 'large-screen': '--p-font-line-height-1', + }, + heading: { + base: '--p-font-line-height-3', + }, + subheading: { + base: '--p-font-line-height-1', + }, + input: { + base: '--p-font-line-height-3', + }, + body: { + base: '--p-font-line-height-2', + }, + button: { + base: '--p-font-line-height-1', + }, + 'button-large': { + base: '--p-font-line-height-2', + }, + 'display-x-large': { + base: '2.25rem', // 36px + 'large-screen': '2.75rem', // 44px + }, + 'display-large': { + base: '--p-font-line-height-4', + 'large-screen': '--p-font-line-height-5', + }, + 'display-medium': { + base: '--p-font-line-height-4', + 'large-screen': '--p-font-line-height-5', + }, + 'display-small': { + base: '--p-font-line-height-3', + 'large-screen': '--p-font-line-height-4', + }, +}; diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.input.scss b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.input.scss new file mode 100644 index 00000000000..a12e13944ab --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.input.scss @@ -0,0 +1,10 @@ +.font-line-height { + line-height: line-height(caption); + line-height: line-height(caption, base); + line-height: line-height(caption, large-screen); + line-height: line-height(display-x-large, base); + // Comment + line-height: line-height($invalid); + line-height: line-height(caption, $invalid); + line-height: line-height(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.output.scss b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.output.scss new file mode 100644 index 00000000000..6b4dc9271f8 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.output.scss @@ -0,0 +1,16 @@ +.font-line-height { + line-height: var(--p-font-line-height-2); + line-height: var(--p-font-line-height-2); + line-height: var(--p-font-line-height-1); + line-height: 2.25rem; + // Comment + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: line-height($invalid); + line-height: line-height($invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: line-height(caption, $invalid); + line-height: line-height(caption, $invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: line-height(); + line-height: line-height(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.test.ts b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.test.ts new file mode 100644 index 00000000000..43b0435c250 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/tests/scss-replace-line-height.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-line-height'; +const fixtures = ['scss-replace-line-height', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.input.scss new file mode 100644 index 00000000000..fa3e2a9d1ed --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.input.scss @@ -0,0 +1,12 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-line-height { + line-height: legacy-polaris-v8.line-height(caption); + line-height: legacy-polaris-v8.line-height(caption, base); + line-height: legacy-polaris-v8.line-height(caption, large-screen); + line-height: legacy-polaris-v8.line-height(display-x-large, base); + // Comment + line-height: legacy-polaris-v8.line-height($invalid); + line-height: legacy-polaris-v8.line-height(caption, $invalid); + line-height: legacy-polaris-v8.line-height(); +} diff --git a/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.output.scss new file mode 100644 index 00000000000..2de4d6ccf73 --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-line-height/tests/with-namespace.output.scss @@ -0,0 +1,18 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-line-height { + line-height: var(--p-font-line-height-2); + line-height: var(--p-font-line-height-2); + line-height: var(--p-font-line-height-1); + line-height: 2.25rem; + // Comment + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: legacy-polaris-v8.line-height($invalid); + line-height: legacy-polaris-v8.line-height($invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: legacy-polaris-v8.line-height(caption, $invalid); + line-height: legacy-polaris-v8.line-height(caption, $invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // line-height: legacy-polaris-v8.line-height(); + line-height: legacy-polaris-v8.line-height(); +} diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/replace-sass-spacing.ts b/polaris-migrator/src/migrations/scss-replace-spacing/scss-replace-spacing.ts similarity index 94% rename from polaris-migrator/src/migrations/replace-sass-spacing/replace-sass-spacing.ts rename to polaris-migrator/src/migrations/scss-replace-spacing/scss-replace-spacing.ts index 3bdc29429c1..fbb11c48614 100644 --- a/polaris-migrator/src/migrations/replace-sass-spacing/replace-sass-spacing.ts +++ b/polaris-migrator/src/migrations/scss-replace-spacing/scss-replace-spacing.ts @@ -77,9 +77,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { if (hasNumericOperator(parsedValue)) { // Insert comment if the declaration value contains calculations - decl.before( - createInlineComment(POLARIS_MIGRATOR_COMMENT, {prose: true}), - ); + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); decl.before( createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), ); @@ -93,7 +91,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { }; }; -export default function replaceSassSpacing( +export default function scssReplaceSpacing( file: FileInfo, _: API, options: Options, diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-spacing.input.scss b/polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-spacing.input.scss rename to polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-spacing.output.scss b/polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-spacing/tests/replace-spacing.output.scss rename to polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.output.scss diff --git a/polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.test.ts b/polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.test.ts new file mode 100644 index 00000000000..cecd03e415f --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-spacing/tests/scss-replace-spacing.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-spacing'; +const fixtures = ['scss-replace-spacing', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-spacing/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-spacing/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/scss-replace-spacing/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-spacing/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-spacing/tests/with-namespace.output.scss similarity index 92% rename from polaris-migrator/src/migrations/replace-sass-spacing/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/scss-replace-spacing/tests/with-namespace.output.scss index 37317eef3eb..6e4ed7a4eed 100644 --- a/polaris-migrator/src/migrations/replace-sass-spacing/tests/with-namespace.output.scss +++ b/polaris-migrator/src/migrations/scss-replace-spacing/tests/with-namespace.output.scss @@ -17,7 +17,7 @@ padding: -#{legacy-polaris-v8.spacing()}; // With other functions // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // padding: calc(#{legacy-polaris-v8.rem(16px)} + var(--p-space-4)); + // padding: calc( #{legacy-polaris-v8.rem(16px)} + var(--p-space-4) ); padding: calc( #{legacy-polaris-v8.rem(16px)} + #{legacy-polaris-v8.spacing()} ); diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/replace-static-mixins-with-declarations.ts b/polaris-migrator/src/migrations/scss-replace-text-emphasis/scss-replace-text-emphasis.ts similarity index 92% rename from polaris-migrator/src/migrations/replace-static-mixins-with-declarations/replace-static-mixins-with-declarations.ts rename to polaris-migrator/src/migrations/scss-replace-text-emphasis/scss-replace-text-emphasis.ts index a6f667a6473..16e7f99a21d 100644 --- a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/replace-static-mixins-with-declarations.ts +++ b/polaris-migrator/src/migrations/scss-replace-text-emphasis/scss-replace-text-emphasis.ts @@ -30,7 +30,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { ); return { - postcssPlugin: 'replace-static-mixins-with-declarations', + postcssPlugin: 'scss-replace-text-emphasis', AtRule(atRule) { if (atRule.name !== 'include') return; @@ -51,7 +51,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { }; }; -export default function replaceStaticMixinsWithDeclarations( +export default function sassReplaceTextEmphasis( fileInfo: FileInfo, _: API, options: Options, diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.input.scss b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.input.scss rename to polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.input.scss diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.output.scss b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/replace-static-mixins-with-declarations.output.scss rename to polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.output.scss diff --git a/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.test.ts b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.test.ts new file mode 100644 index 00000000000..4b6b535f17a --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/scss-replace-text-emphasis.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-text-emphasis'; +const fixtures = ['scss-replace-text-emphasis', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/with-namespace.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-static-mixins-with-declarations/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/scss-replace-text-emphasis/tests/with-namespace.output.scss diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/replace-sass-z-index.ts b/polaris-migrator/src/migrations/scss-replace-z-index/scss-replace-z-index.ts similarity index 98% rename from polaris-migrator/src/migrations/replace-sass-z-index/replace-sass-z-index.ts rename to polaris-migrator/src/migrations/scss-replace-z-index/scss-replace-z-index.ts index c4e6b46ca24..b229ec5a32a 100644 --- a/polaris-migrator/src/migrations/replace-sass-z-index/replace-sass-z-index.ts +++ b/polaris-migrator/src/migrations/scss-replace-z-index/scss-replace-z-index.ts @@ -48,7 +48,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { options, ); return { - postcssPlugin: 'replace-sass-z-index', + postcssPlugin: 'scss-replace-z-index', Declaration(decl) { // @ts-expect-error - Skip if processed so we don't process it again if (decl[processed]) return; @@ -124,7 +124,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { }; }; -export default function replaceSassZIndex( +export default function scssReplaceZIndex( fileInfo: FileInfo, _: API, options: Options, diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.input.scss b/polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.input.scss rename to polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.output.scss b/polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-z-index/tests/replace-sass-z-index.output.scss rename to polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.output.scss diff --git a/polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.test.ts b/polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.test.ts new file mode 100644 index 00000000000..1c5cea9385b --- /dev/null +++ b/polaris-migrator/src/migrations/scss-replace-z-index/tests/scss-replace-z-index.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'scss-replace-z-index'; +const fixtures = ['scss-replace-z-index', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/scss-replace-z-index/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-z-index/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/scss-replace-z-index/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-sass-z-index/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/scss-replace-z-index/tests/with-namespace.output.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-sass-z-index/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/scss-replace-z-index/tests/with-namespace.output.scss diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/replace-typography-declarations.ts b/polaris-migrator/src/migrations/styles-tokenize-font/styles-tokenize-font.ts similarity index 50% rename from polaris-migrator/src/migrations/replace-typography-declarations/replace-typography-declarations.ts rename to polaris-migrator/src/migrations/styles-tokenize-font/styles-tokenize-font.ts index de4782e34a5..890594a50ae 100644 --- a/polaris-migrator/src/migrations/replace-typography-declarations/replace-typography-declarations.ts +++ b/polaris-migrator/src/migrations/styles-tokenize-font/styles-tokenize-font.ts @@ -1,5 +1,3 @@ -/* eslint-disable line-comment-position */ - import type {FileInfo, API, Options} from 'jscodeshift'; import postcss, {Plugin} from 'postcss'; import valueParser from 'postcss-value-parser'; @@ -16,10 +14,11 @@ import { namespace, NamespaceOptions, toTransformablePx, + StopWalkingFunctionNodes, } from '../../utilities/sass'; import {isKeyOf} from '../../utilities/type-guards'; -export default function replaceTypographyDeclarations( +export default function stylesTokenizeFont( fileInfo: FileInfo, _: API, options: Options, @@ -34,19 +33,15 @@ const processed = Symbol('processed'); interface PluginOptions extends Options, NamespaceOptions {} const plugin = (options: PluginOptions = {}): Plugin => { - const namespacedFontFamily = namespace('font-family', options); - const namespacedFontSize = namespace('font-size', options); - const namespacedLineHeight = namespace('line-height', options); const namespacedRem = namespace('rem', options); return { - postcssPlugin: 'replace-typography-declarations', + postcssPlugin: 'styles-tokenize-font', Declaration(decl) { // @ts-expect-error - Skip if processed so we don't process it again if (decl[processed]) return; const handlers = { - 'font-family': handleFontFamily, 'font-size': handleFontSize, 'font-weight': handleFontWeight, 'line-height': handleFontLineHeight, @@ -68,9 +63,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { handlers[decl.prop](); if (targets.some(({replaced}) => !replaced || hasNumericOperator)) { - decl.before( - createInlineComment(POLARIS_MIGRATOR_COMMENT, {prose: true}), - ); + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); decl.before( createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), ); @@ -82,47 +75,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { // Handlers // - function handleFontFamily() { - parsedValue.walk((node) => { - if (isNumericOperator(node)) { - hasNumericOperator = true; - return; - } - - if (node.type === 'function') { - if (isSassFunction(namespacedFontFamily, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 0 || args.length === 1)) return; - - // `font-family()` args reference: - // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L945 - const family = args[0] ?? 'base'; - - if (!isKeyOf(fontFamilyMap, family)) return; - - const fontFamilyCustomProperty = fontFamilyMap[family]; - - targets[targets.length - 1]!.replaced = true; - - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: fontFamilyCustomProperty, - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: fontFamilyCustomProperty.length, - }, - ]; - } - - return StopWalkingFunctionNodes; - } - }); - } - function handleFontSize() { parsedValue.walk((node) => { if (isNumericOperator(node)) { @@ -152,45 +104,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { } if (node.type === 'function') { - if (isSassFunction(namespacedFontSize, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 1 || args.length === 2)) return; - - // `font-size()` args reference: - // https://github.com/Shopify/polaris/blob/1738f17c739e06dcde4653a9783ca367e38b4e32/documentation/guides/legacy-polaris-v8-public-api.scss#L977 - const styleArg = args[0]; - const variantArg = args[1] ?? 'base'; - - if (!isKeyOf(fontSizeFunctionMap, styleArg)) return; - - const fontSizeStyle = fontSizeFunctionMap[styleArg]; - - if (!isKeyOf(fontSizeStyle, variantArg)) return; - - const fontSizeVariant = fontSizeStyle[variantArg]; - - targets[targets.length - 1]!.replaced = true; - - if (fontSizeVariant.startsWith('--')) { - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: fontSizeVariant, - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: fontSizeVariant.length, - }, - ]; - } else { - // @ts-expect-error: We are intentionally changing the node type - node.type = 'word'; - node.value = fontSizeVariant; - } - } - if (isSassFunction(namespacedRem, node)) { targets.push({replaced: false}); @@ -269,45 +182,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { } if (node.type === 'function') { - if (isSassFunction(namespacedLineHeight, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 1 || args.length === 2)) return; - - // `line-height()` args reference: - // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L961 - const styleArg = args[0]; - const variantArg = args[1] ?? 'base'; - - if (!isKeyOf(lineHeightFunctionMap, styleArg)) return; - - const lineHeightStyle = lineHeightFunctionMap[styleArg]; - - if (!isKeyOf(lineHeightStyle, variantArg)) return; - - const lineHeightVariant = lineHeightStyle[variantArg]; - - targets[targets.length - 1]!.replaced = true; - - if (lineHeightVariant.startsWith('--')) { - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: lineHeightVariant, - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: lineHeightVariant.length, - }, - ]; - } else { - // @ts-expect-error: We are intentionally changing the node type - node.type = 'word'; - node.value = lineHeightVariant; - } - } - if (isSassFunction(namespacedRem, node)) { targets.push({replaced: false}); @@ -345,11 +219,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { const globalValues = new Set(['inherit', 'initial', 'unset']); -const fontFamilyMap = { - base: '--p-font-family-sans', - monospace: '--p-font-family-mono', -}; - const fontSizeMap = { '12px': '--p-font-size-75', '14px': '--p-font-size-100', @@ -361,53 +230,6 @@ const fontSizeMap = { '40px': '--p-font-size-700', }; -const fontSizeFunctionMap = { - caption: { - base: '0.8125rem', // 13px - 'large-screen': '--p-font-size-75', - }, - heading: { - base: '1.0625rem', // 17px - 'large-screen': '--p-font-size-200', - }, - subheading: { - base: '0.8125rem', // 13px - 'large-screen': '--p-font-size-75', - }, - input: { - base: '--p-font-size-200', - 'large-screen': '--p-font-size-100', - }, - body: { - base: '0.9375rem', // 15px - 'large-screen': '--p-font-size-100', - }, - button: { - base: '0.9375rem', // 15px - 'large-screen': '--p-font-size-100', - }, - 'button-large': { - base: '1.0625rem', // 17px - 'large-screen': '--p-font-size-200', - }, - 'display-x-large': { - base: '1.6875rem', // 27px - 'large-screen': '2.625rem', // 42px - }, - 'display-large': { - base: '--p-font-size-400', - 'large-screen': '--p-font-size-500', - }, - 'display-medium': { - base: '1.3125rem', // 21px - 'large-screen': '1.625rem', // 26px - }, - 'display-small': { - base: '--p-font-size-200', - 'large-screen': '--p-font-size-300', - }, -}; - const fontLineHeightMap = { '16px': '--p-font-line-height-1', '20px': '--p-font-line-height-2', @@ -418,47 +240,6 @@ const fontLineHeightMap = { '48px': '--p-font-line-height-7', }; -const lineHeightFunctionMap = { - caption: { - base: '--p-font-line-height-2', - 'large-screen': '--p-font-line-height-1', - }, - heading: { - base: '--p-font-line-height-3', - }, - subheading: { - base: '--p-font-line-height-1', - }, - input: { - base: '--p-font-line-height-3', - }, - body: { - base: '--p-font-line-height-2', - }, - button: { - base: '--p-font-line-height-1', - }, - 'button-large': { - base: '--p-font-line-height-2', - }, - 'display-x-large': { - base: '2.25rem', // 36px - 'large-screen': '2.75rem', // 44px - }, - 'display-large': { - base: '--p-font-line-height-4', - 'large-screen': '--p-font-line-height-5', - }, - 'display-medium': { - base: '--p-font-line-height-4', - 'large-screen': '--p-font-line-height-5', - }, - 'display-small': { - base: '--p-font-line-height-3', - 'large-screen': '--p-font-line-height-4', - }, -}; - const fontWeightMap = { 400: '--p-font-weight-regular', 500: '--p-font-weight-medium', @@ -477,9 +258,3 @@ const fontWeightMap = { // 800 - Extra Bold (Ultra Bold) // 900 - Black (Heavy) }; - -/** - * Exit early and stop traversing descendant nodes: - * https://www.npmjs.com/package/postcss-value-parser:~:text=Returning%20false%20in%20the%20callback%20will%20prevent%20traversal%20of%20descendent%20nodes - */ -const StopWalkingFunctionNodes = false; diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.input.scss b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.input.scss similarity index 59% rename from polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.input.scss rename to polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.input.scss index c2607285db7..ab4445c3e34 100644 --- a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.input.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.input.scss @@ -1,10 +1,3 @@ -.font-family { - font-family: sans-serif; - font-family: font-family(); - font-family: font-family(base); - font-family: font-family(monospace); -} - .font-size { // LENGTHS font-size: 12px; @@ -16,16 +9,6 @@ font-size: 10px; font-size: 12px + 1px; - // FONT-SIZE FUNCTION - font-size: font-size(caption); - font-size: font-size(caption, base); - font-size: font-size(caption, large-screen); - // Comment - font-size: font-size($invalid); - font-size: font-size(caption, $invalid); - font-size: font-size(); - font-size: font-size(caption, base, $too-many-args); - // REM FUNCTION font-size: rem(12px); font-size: rem(1rem); @@ -65,17 +48,6 @@ // Comment line-height: 10px; - // LINE-HEIGHT FUNCTION - line-height: line-height(caption); - line-height: line-height(caption, base); - line-height: line-height(caption, large-screen); - line-height: line-height(display-x-large, base); - // Comment - line-height: line-height($invalid); - line-height: line-height(caption, $invalid); - line-height: line-height(); - line-height: line-height(caption, base, $too-many-args); - // REM FUNCTION line-height: rem(16px); line-height: rem(1rem); diff --git a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.output.scss b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.output.scss similarity index 71% rename from polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.output.scss rename to polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.output.scss index dcf4ccd14da..fb71fa6bd60 100644 --- a/polaris-migrator/src/migrations/replace-typography-declarations/tests/replace-typography-declarations.output.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.output.scss @@ -1,10 +1,3 @@ -.font-family { - font-family: sans-serif; - font-family: var(--p-font-family-sans); - font-family: var(--p-font-family-sans); - font-family: var(--p-font-family-mono); -} - .font-size { // LENGTHS font-size: var(--p-font-size-75); @@ -20,24 +13,6 @@ // font-size: var(--p-font-size-75) + 1px; font-size: 12px + 1px; - // FONT-SIZE FUNCTION - font-size: 0.8125rem; - font-size: 0.8125rem; - font-size: var(--p-font-size-75); - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: font-size($invalid); - font-size: font-size($invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: font-size(caption, $invalid); - font-size: font-size(caption, $invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: font-size(); - font-size: font-size(); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // font-size: font-size(caption, base, $too-many-args); - font-size: font-size(caption, base, $too-many-args); - // REM FUNCTION font-size: var(--p-font-size-75); font-size: var(--p-font-size-200); @@ -103,25 +78,6 @@ // line-height: 10px; line-height: 10px; - // LINE-HEIGHT FUNCTION - line-height: var(--p-font-line-height-2); - line-height: var(--p-font-line-height-2); - line-height: var(--p-font-line-height-1); - line-height: 2.25rem; - // Comment - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: line-height($invalid); - line-height: line-height($invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: line-height(caption, $invalid); - line-height: line-height(caption, $invalid); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: line-height(); - line-height: line-height(); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // line-height: line-height(caption, base, $too-many-args); - line-height: line-height(caption, base, $too-many-args); - // REM FUNCTION line-height: var(--p-font-line-height-1); line-height: var(--p-font-line-height-1); diff --git a/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.test.ts b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.test.ts new file mode 100644 index 00000000000..d3d171d9eca --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-font/tests/styles-tokenize-font.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'styles-tokenize-font'; +const fixtures = ['styles-tokenize-font', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.input.scss new file mode 100644 index 00000000000..2af110f3593 --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.input.scss @@ -0,0 +1,17 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-size { + // REM FUNCTION + font-size: legacy-polaris-v8.rem(12px); + font-size: legacy-polaris-v8.rem(1rem); + // Comment + font-size: legacy-polaris-v8.rem(1em); + font-size: legacy-polaris-v8.rem(10px); + font-size: legacy-polaris-v8.rem($invalid); + font-size: legacy-polaris-v8.rem(); + font-size: legacy-polaris-v8.rem(12px, $too-many-args); + font-size: legacy-polaris-v8.rem(12px) 1px; + font-size: legacy-polaris-v8.rem(1px) 12px; + font-size: legacy-polaris-v8.rem(#{10px + 2px}) 12px; + font-size: legacy-polaris-v8.rem(12px) + #{10px + 2px}; +} diff --git a/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.output.scss new file mode 100644 index 00000000000..9b8e72e6715 --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-font/tests/with-namespace.output.scss @@ -0,0 +1,35 @@ +@use 'global-styles/legacy-polaris-v8'; + +.font-size { + // REM FUNCTION + font-size: var(--p-font-size-75); + font-size: var(--p-font-size-200); + // Comment + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(1em); + font-size: legacy-polaris-v8.rem(1em); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(10px); + font-size: legacy-polaris-v8.rem(10px); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem($invalid); + font-size: legacy-polaris-v8.rem($invalid); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(); + font-size: legacy-polaris-v8.rem(); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(var(--p-font-size-75), $too-many-args); + font-size: legacy-polaris-v8.rem(12px, $too-many-args); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: var(--p-font-size-75) 1px; + font-size: legacy-polaris-v8.rem(12px) 1px; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(1px) var(--p-font-size-75); + font-size: legacy-polaris-v8.rem(1px) 12px; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: legacy-polaris-v8.rem(#{10px + 2px}) var(--p-font-size-75); + font-size: legacy-polaris-v8.rem(#{10px + 2px}) 12px; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // font-size: var(--p-font-size-75) + #{10px + 2px}; + font-size: legacy-polaris-v8.rem(12px) + #{10px + 2px}; +} diff --git a/polaris-migrator/src/migrations/replace-sass-transition/replace-sass-transition.ts b/polaris-migrator/src/migrations/styles-tokenize-motion/styles-tokenize-motion.ts similarity index 69% rename from polaris-migrator/src/migrations/replace-sass-transition/replace-sass-transition.ts rename to polaris-migrator/src/migrations/styles-tokenize-motion/styles-tokenize-motion.ts index e14cbc2166a..d19126665e8 100644 --- a/polaris-migrator/src/migrations/replace-sass-transition/replace-sass-transition.ts +++ b/polaris-migrator/src/migrations/styles-tokenize-motion/styles-tokenize-motion.ts @@ -1,33 +1,16 @@ import {Declaration} from 'postcss'; -import valueParser, { - ParsedValue, - Node, - FunctionNode, -} from 'postcss-value-parser'; +import valueParser, {ParsedValue, Node} from 'postcss-value-parser'; import { - namespace, - isSassFunction, isSassVariable, hasNumericOperator, isTransformableDuration, isPolarisVar, createSassMigrator, + setNodeValue, } from '../../utilities/sass'; import {isKeyOf} from '../../utilities/type-guards'; -const DEFAULT_DURATION = 'base'; -const DEFAULT_FUNCTION = 'base'; - -const durationFuncMap = { - none: '--p-duration-0', - fast: '--p-duration-100', - base: '--p-duration-200', - slow: '--p-duration-300', - slower: '--p-duration-400', - slowest: '--p-duration-500', -}; - const durationConstantsMap = { '0': '--p-duration-0', '0s': '--p-duration-0', @@ -55,12 +38,6 @@ const durationConstantsMap = { '5s': '--p-duration-5000', }; -const easingFuncMap = { - base: '--p-ease', - in: '--p-ease-in', - out: '--p-ease-out', -}; - const easingFuncConstantsMap = { linear: '--p-linear', ease: '--p-ease', @@ -69,8 +46,6 @@ const easingFuncConstantsMap = { 'ease-in-out': '--p-ease-in-out', }; -const deprecatedEasingFuncs = ['anticipate', 'excite', 'overshoot']; - // Per the spec for transition easing functions: // https://w3c.github.io/csswg-drafts/css-easing/#easing-functions const cssEasingBuiltinFuncs = [ @@ -85,60 +60,13 @@ const cssEasingBuiltinFuncs = [ 'steps', ]; -function normaliseStringifiedNumber(number: string): string { +function normalizeStringifiedNumber(number: string): string { return Number(number).toString(); } -function setNodeValue(node: Node, value: string): void { - const {sourceIndex} = node; - const parsedValue = valueParser(value).nodes[0]; - Object.assign(node, parsedValue); - // The node we're replacing might be mid-way through a higher-level value - // string. Eg; 'border: 1px solid', the 'solid' node is 5 characters into the - // higher-level value, so we need to correct the index here. - node.sourceIndex += sourceIndex; - node.sourceEndIndex += sourceIndex; -} - export default createSassMigrator( 'replace-sass-transition', - (_, {methods, options}, context) => { - const durationFunc = namespace('duration', options); - - function migrateLegacySassEasingFunction( - node: FunctionNode, - decl: Declaration, - ) { - const easingFunc = node.nodes[0]?.value ?? DEFAULT_FUNCTION; - - if (!isKeyOf(easingFuncMap, easingFunc)) { - const comment = deprecatedEasingFuncs.includes(easingFunc) - ? `The ${easingFunc} easing function is no longer available in Polaris. See https://polaris.shopify.com/tokens/motion for possible values.` - : `Unexpected easing function '${easingFunc}'.`; - - methods.report({ - severity: 'warning', - node: decl, - message: comment, - }); - - return; - } - - const easingCustomProperty = easingFuncMap[easingFunc]; - const targetValue = `var(${easingCustomProperty})`; - - if (context.fix) { - setNodeValue(node, targetValue); - } else { - methods.report({ - severity: 'error', - node: decl, - message: `Replace easing function with token: ${targetValue}`, - }); - } - } - + (_, {methods}, context) => { function insertUnexpectedEasingFunctionComment( node: Node, decl: Declaration, @@ -162,42 +90,14 @@ export default createSassMigrator( methods.report({ severity: 'warning', node: decl, - message: `Cannot statically analyse SASS variable ${node.value}.`, + message: `Cannot statically analyze SCSS variable ${node.value}.`, }); return; } - if (isSassFunction(durationFunc, node)) { - const duration = node.nodes[0]?.value ?? DEFAULT_DURATION; - - if (!isKeyOf(durationFuncMap, duration)) { - methods.report({ - severity: 'warning', - node: decl, - message: `Unknown duration key '${duration}'.`, - }); - return; - } - - const durationCustomProperty = durationFuncMap[duration]; - const targetValue = `var(${durationCustomProperty})`; - - if (context.fix) { - setNodeValue(node, targetValue); - } else { - methods.report({ - severity: 'error', - node: decl, - message: `Replace duration with token: ${targetValue}`, - }); - } - - return; - } - const unit = valueParser.unit(node.value); if (unit) { - const constantDuration = `${normaliseStringifiedNumber(unit.number)}${ + const constantDuration = `${normalizeStringifiedNumber(unit.number)}${ unit.unit }`; @@ -238,14 +138,13 @@ export default createSassMigrator( methods.report({ severity: 'warning', node: decl, - message: `Cannot statically analyse SASS variable ${node.value}.`, + message: `Cannot statically analyze SCSS variable ${node.value}.`, }); return; } if (node.type === 'function') { const easingFuncHandlers = { - [namespace('easing', options)]: migrateLegacySassEasingFunction, // Per the spec, these can all be functions: // https://w3c.github.io/csswg-drafts/css-easing/#easing-functions linear: insertUnexpectedEasingFunctionComment, @@ -318,10 +217,7 @@ export default createSassMigrator( nodes.forEach((node) => { const unit = valueParser.unit(node.value); - if ( - isTransformableDuration(unit) || - isSassFunction(durationFunc, node) - ) { + if (isTransformableDuration(unit)) { timings.push(node); } else { // This node could be either the property to animate, or an easing diff --git a/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.input.scss b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.input.scss new file mode 100644 index 00000000000..82493cffef3 --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.input.scss @@ -0,0 +1,140 @@ +.easing { + transition-timing-function: linear; + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + transition-timing-function: linear(1); + transition-timing-function: ease; + transition-timing-function: ease-in; + transition-timing-function: ease-out; + transition-timing-function: ease-in-out; + transition-timing-function: cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + transition-timing-function: step-start; + transition-timing-function: step-end; + transition-timing-function: steps(1, jump-end); +} + +.easing-shorthand { + transition: opacity 300ms linear; + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + transition: opacity 300ms linear(1); + transition: opacity 300ms ease; + transition: opacity 300ms ease-in; + transition: opacity 300ms ease-out; + transition: opacity 300ms ease-in-out; + transition: opacity 300ms cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + transition: opacity 300ms step-start; + transition: opacity 300ms step-end; + transition: opacity 300ms steps(1, jump-end); +} + +.easing-multiple { + transition: opacity 300ms linear, left 300ms linear; + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + transition: opacity 300ms linear(1), left 300ms linear(1); + transition: opacity 300ms ease, left 300ms ease; + transition: opacity 300ms ease-in, left 300ms ease-in; + transition: opacity 300ms ease-out, left 300ms ease-out; + transition: opacity 300ms ease-in-out, left 300ms ease-in-out; + transition: opacity 300ms cubic-bezier(0, 0, 1, 1), + left 300ms cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + transition: opacity 300ms step-start, left 300ms step-start; + transition: opacity 300ms step-end, left 300ms step-start; + transition: opacity 300ms steps(1, jump-end), left 300ms steps(1, jump-end); +} + +.duration { + transition-duration: 0; + transition-duration: 0ms; + transition-duration: 0s; + transition-duration: 50ms; + transition-duration: 0.05s; + transition-duration: 100ms; + transition-duration: 0.1s; + transition-duration: 150ms; + transition-duration: 0.15s; + transition-duration: 200ms; + transition-duration: 0.2s; + transition-duration: 250ms; + transition-duration: 0.25s; + transition-duration: 300ms; + transition-duration: 0.3s; + transition-duration: 350ms; + transition-duration: 0.35s; + transition-duration: 400ms; + transition-duration: 0.4s; + transition-duration: 450ms; + transition-duration: 0.45s; + transition-duration: 500ms; + transition-duration: 0.5s; + transition-duration: 5s; +} + +.duration-shorthand { + transition: opacity 0 linear; + transition: opacity 0ms linear; + transition: opacity 0s linear; + transition: opacity 50ms linear; + transition: opacity 0.05s linear; + transition: opacity 100ms linear; + transition: opacity 0.1s linear; + transition: opacity 150ms linear; + transition: opacity 0.15s linear; + transition: opacity 200ms linear; + transition: opacity 0.2s linear; + transition: opacity 250ms linear; + transition: opacity 0.25s linear; + transition: opacity 300ms linear; + transition: opacity 0.3s linear; + transition: opacity 350ms linear; + transition: opacity 0.35s linear; + transition: opacity 400ms linear; + transition: opacity 0.4s linear; + transition: opacity 450ms linear; + transition: opacity 0.45s linear; + transition: opacity 500ms linear; + transition: opacity 0.5s linear; + transition: opacity 5s linear; +} + +.duration-multiple { + transition: opacity 0 linear, left 0 linear; + transition: opacity 0ms linear, left 0ms linear; + transition: opacity 0s linear, left 0s linear; + transition: opacity 50ms linear, left 50ms linear; + transition: opacity 0.05s linear, left 0.05s linear; + transition: opacity 100ms linear, left 100ms linear; + transition: opacity 0.1s linear, left 0.1s linear; + transition: opacity 150ms linear, left 150ms linear; + transition: opacity 0.15s linear, left 0.15s linear; + transition: opacity 200ms linear, left 200ms linear; + transition: opacity 0.2s linear, left 0.2s linear; + transition: opacity 250ms linear, left 250ms linear; + transition: opacity 0.25s linear, left 0.25s linear; + transition: opacity 300ms linear, left 300ms linear; + transition: opacity 0.3s linear, left 0.3s linear; + transition: opacity 350ms linear, left 350ms linear; + transition: opacity 0.35s linear, left 0.35s linear; + transition: opacity 400ms linear, left 400ms linear; + transition: opacity 0.4s linear, left 0.4s linear; + transition: opacity 450ms linear, left 450ms linear; + transition: opacity 0.45s linear, left 0.45s linear; + transition: opacity 500ms linear, left 500ms linear; + transition: opacity 0.5s linear, left 0.5s linear; + transition: opacity 5s linear, left 5s linear; +} + +.edges { + // Without an easing function + transition: fill 300ms; + // Duration comes after easing func + transition: opacity linear 0.5s; + // Duration + Delay + transition: opacity 400ms linear 300ms; + // Duration + Delay after easing func + transition: opacity linear 400ms 100ms; + // can't process variables + transition-timing-function: $foo; + transition: opacity $foo 0.5s; +} diff --git a/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.output.scss b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.output.scss new file mode 100644 index 00000000000..5b9d974921d --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.output.scss @@ -0,0 +1,217 @@ +.easing { + transition-timing-function: var(--p-linear); + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: linear(1); + transition-timing-function: var(--p-ease); + transition-timing-function: var(--p-ease-in); + transition-timing-function: var(--p-ease-out); + transition-timing-function: var(--p-ease-in-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: step-start; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: step-end; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. + transition-timing-function: steps(1, jump-end); +} + +.easing-shorthand { + transition: opacity var(--p-duration-300) var(--p-linear); + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) linear(1); + transition: opacity 300ms linear(1); + transition: opacity var(--p-duration-300) var(--p-ease); + transition: opacity var(--p-duration-300) var(--p-ease-in); + transition: opacity var(--p-duration-300) var(--p-ease-out); + transition: opacity var(--p-duration-300) var(--p-ease-in-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) cubic-bezier(0, 0, 1, 1); + transition: opacity 300ms cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) step-start; + transition: opacity 300ms step-start; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) step-end; + transition: opacity 300ms step-end; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) steps(1, jump-end); + transition: opacity 300ms steps(1, jump-end); +} + +.easing-multiple { + transition: opacity var(--p-duration-300) var(--p-linear), + left var(--p-duration-300) var(--p-linear); + // See: https://w3c.github.io/csswg-drafts/css-easing/#typedef-linear-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'linear'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) linear(1), left var(--p-duration-300) linear(1); + transition: opacity 300ms linear(1), left 300ms linear(1); + transition: opacity var(--p-duration-300) var(--p-ease), + left var(--p-duration-300) var(--p-ease); + transition: opacity var(--p-duration-300) var(--p-ease-in), + left var(--p-duration-300) var(--p-ease-in); + transition: opacity var(--p-duration-300) var(--p-ease-out), + left var(--p-duration-300) var(--p-ease-out); + transition: opacity var(--p-duration-300) var(--p-ease-in-out), + left var(--p-duration-300) var(--p-ease-in-out); + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'cubic-bezier'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) cubic-bezier(0, 0, 1, 1), left var(--p-duration-300) cubic-bezier(0, 0, 1, 1); + transition: opacity 300ms cubic-bezier(0, 0, 1, 1), + left 300ms cubic-bezier(0, 0, 1, 1); + // See:https://w3c.github.io/csswg-drafts/css-easing/#typedef-step-easing-function + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) step-start, left var(--p-duration-300) step-start; + transition: opacity 300ms step-start, left 300ms step-start; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'step-end'. See https://polaris.shopify.com/tokens/motion for possible values. + // warning: Unexpected easing function 'step-start'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) step-end, left var(--p-duration-300) step-start; + transition: opacity 300ms step-end, left 300ms step-start; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Unexpected easing function 'steps'. See https://polaris.shopify.com/tokens/motion for possible values. + // transition: opacity var(--p-duration-300) steps(1, jump-end), left var(--p-duration-300) steps(1, jump-end); + transition: opacity 300ms steps(1, jump-end), left 300ms steps(1, jump-end); +} + +.duration { + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-0); + transition-duration: var(--p-duration-50); + transition-duration: var(--p-duration-50); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-100); + transition-duration: var(--p-duration-150); + transition-duration: var(--p-duration-150); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-200); + transition-duration: var(--p-duration-250); + transition-duration: var(--p-duration-250); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-300); + transition-duration: var(--p-duration-350); + transition-duration: var(--p-duration-350); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-400); + transition-duration: var(--p-duration-450); + transition-duration: var(--p-duration-450); + transition-duration: var(--p-duration-500); + transition-duration: var(--p-duration-500); + transition-duration: var(--p-duration-5000); +} + +.duration-shorthand { + transition: opacity var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-50) var(--p-linear); + transition: opacity var(--p-duration-50) var(--p-linear); + transition: opacity var(--p-duration-100) var(--p-linear); + transition: opacity var(--p-duration-100) var(--p-linear); + transition: opacity var(--p-duration-150) var(--p-linear); + transition: opacity var(--p-duration-150) var(--p-linear); + transition: opacity var(--p-duration-200) var(--p-linear); + transition: opacity var(--p-duration-200) var(--p-linear); + transition: opacity var(--p-duration-250) var(--p-linear); + transition: opacity var(--p-duration-250) var(--p-linear); + transition: opacity var(--p-duration-300) var(--p-linear); + transition: opacity var(--p-duration-300) var(--p-linear); + transition: opacity var(--p-duration-350) var(--p-linear); + transition: opacity var(--p-duration-350) var(--p-linear); + transition: opacity var(--p-duration-400) var(--p-linear); + transition: opacity var(--p-duration-400) var(--p-linear); + transition: opacity var(--p-duration-450) var(--p-linear); + transition: opacity var(--p-duration-450) var(--p-linear); + transition: opacity var(--p-duration-500) var(--p-linear); + transition: opacity var(--p-duration-500) var(--p-linear); + transition: opacity var(--p-duration-5000) var(--p-linear); +} + +.duration-multiple { + transition: opacity var(--p-duration-0) var(--p-linear), + left var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-0) var(--p-linear), + left var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-0) var(--p-linear), + left var(--p-duration-0) var(--p-linear); + transition: opacity var(--p-duration-50) var(--p-linear), + left var(--p-duration-50) var(--p-linear); + transition: opacity var(--p-duration-50) var(--p-linear), + left var(--p-duration-50) var(--p-linear); + transition: opacity var(--p-duration-100) var(--p-linear), + left var(--p-duration-100) var(--p-linear); + transition: opacity var(--p-duration-100) var(--p-linear), + left var(--p-duration-100) var(--p-linear); + transition: opacity var(--p-duration-150) var(--p-linear), + left var(--p-duration-150) var(--p-linear); + transition: opacity var(--p-duration-150) var(--p-linear), + left var(--p-duration-150) var(--p-linear); + transition: opacity var(--p-duration-200) var(--p-linear), + left var(--p-duration-200) var(--p-linear); + transition: opacity var(--p-duration-200) var(--p-linear), + left var(--p-duration-200) var(--p-linear); + transition: opacity var(--p-duration-250) var(--p-linear), + left var(--p-duration-250) var(--p-linear); + transition: opacity var(--p-duration-250) var(--p-linear), + left var(--p-duration-250) var(--p-linear); + transition: opacity var(--p-duration-300) var(--p-linear), + left var(--p-duration-300) var(--p-linear); + transition: opacity var(--p-duration-300) var(--p-linear), + left var(--p-duration-300) var(--p-linear); + transition: opacity var(--p-duration-350) var(--p-linear), + left var(--p-duration-350) var(--p-linear); + transition: opacity var(--p-duration-350) var(--p-linear), + left var(--p-duration-350) var(--p-linear); + transition: opacity var(--p-duration-400) var(--p-linear), + left var(--p-duration-400) var(--p-linear); + transition: opacity var(--p-duration-400) var(--p-linear), + left var(--p-duration-400) var(--p-linear); + transition: opacity var(--p-duration-450) var(--p-linear), + left var(--p-duration-450) var(--p-linear); + transition: opacity var(--p-duration-450) var(--p-linear), + left var(--p-duration-450) var(--p-linear); + transition: opacity var(--p-duration-500) var(--p-linear), + left var(--p-duration-500) var(--p-linear); + transition: opacity var(--p-duration-500) var(--p-linear), + left var(--p-duration-500) var(--p-linear); + transition: opacity var(--p-duration-5000) var(--p-linear), + left var(--p-duration-5000) var(--p-linear); +} + +.edges { + // Without an easing function + transition: fill var(--p-duration-300); + // Duration comes after easing func + transition: opacity var(--p-linear) var(--p-duration-500); + // Duration + Delay + transition: opacity var(--p-duration-400) var(--p-linear) + var(--p-duration-300); + // Duration + Delay after easing func + transition: opacity var(--p-linear) var(--p-duration-400) + var(--p-duration-100); + // can't process variables + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Cannot statically analyze SCSS variable $foo. + transition-timing-function: $foo; + // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. + // warning: Cannot statically analyze SCSS variable $foo. + // transition: opacity $foo var(--p-duration-500); + transition: opacity $foo 0.5s; +} diff --git a/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.test.ts b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.test.ts new file mode 100644 index 00000000000..932b5897d58 --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-motion/tests/styles-tokenize-motion.test.ts @@ -0,0 +1,12 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'styles-tokenize-motion'; +const fixtures = ['styles-tokenize-motion']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + }); +} diff --git a/polaris-migrator/src/migrations/replace-border-declarations/replace-border-declarations.ts b/polaris-migrator/src/migrations/styles-tokenize-shape/styles-tokenize-shape.ts similarity index 60% rename from polaris-migrator/src/migrations/replace-border-declarations/replace-border-declarations.ts rename to polaris-migrator/src/migrations/styles-tokenize-shape/styles-tokenize-shape.ts index 5dcf73b8ede..c4162b67192 100644 --- a/polaris-migrator/src/migrations/replace-border-declarations/replace-border-declarations.ts +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/styles-tokenize-shape.ts @@ -16,7 +16,7 @@ import { } from '../../utilities/sass'; import {isKeyOf} from '../../utilities/type-guards'; -export default function replaceBorderDeclarations( +export default function stylesTokenizeShape( fileInfo: FileInfo, _: API, options: Options, @@ -32,12 +32,9 @@ interface PluginOptions extends Options, NamespaceOptions {} const plugin = (options: PluginOptions = {}): Plugin => { const namespacedRem = namespace('rem', options); - const namespacedBorder = namespace('border', options); - const namespacedBorderWidth = namespace('border-width', options); - const namespacedBorderRadius = namespace('border-radius', options); return { - postcssPlugin: 'replace-border-declarations', + postcssPlugin: 'styles-tokenize-shape', Declaration(decl) { // @ts-expect-error - Skip if processed so we don't process it again if (decl[processed]) return; @@ -63,9 +60,7 @@ const plugin = (options: PluginOptions = {}): Plugin => { if (targets.some(({replaced}) => !replaced || hasNumericOperator)) { // Insert comment if the declaration value contains calculations - decl.before( - createInlineComment(POLARIS_MIGRATOR_COMMENT, {prose: true}), - ); + decl.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); decl.before( createInlineComment(`${decl.prop}: ${parsedValue.toString()};`), ); @@ -129,58 +124,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { targets[targets.length - 1]!.replaced = true; } - if (isSassFunction(namespacedBorder, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 0 || args.length === 1)) return; - - // `border()` args reference: - // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L641 - const value = args[0] ?? 'base'; - - if (!isKeyOf(borderFunctionMap, value)) return; - - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: borderFunctionMap[value], - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: borderFunctionMap[value].length, - }, - ]; - - targets[targets.length - 1]!.replaced = true; - } - - if (isSassFunction(namespacedBorderWidth, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 0 || args.length === 1)) return; - - // `border-width()` args reference: - // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L616 - const value = args[0] ?? 'base'; - - if (!isKeyOf(borderWidthFunctionMap, value)) return; - - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: borderWidthFunctionMap[value], - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: borderWidthFunctionMap[value].length, - }, - ]; - - targets[targets.length - 1]!.replaced = true; - } - return StopWalkingFunctionNodes; } }); @@ -238,32 +181,6 @@ const plugin = (options: PluginOptions = {}): Plugin => { targets[targets.length - 1]!.replaced = true; } - if (isSassFunction(namespacedBorderRadius, node)) { - targets.push({replaced: false}); - - const args = getFunctionArgs(node); - - if (!(args.length === 0 || args.length === 1)) return; - - // `border-radius()` args reference: - // https://github.com/shopify/polaris/blob/2b14c0b60097f75d21df7eaa744dfaf84f8f53f7/documentation/guides/legacy-polaris-v8-public-api.scss#L655 - const value = args[0] ?? 'base'; - - if (!isKeyOf(borderRadiusFunctionMap, value)) return; - - node.value = 'var'; - node.nodes = [ - { - type: 'word', - value: borderRadiusFunctionMap[value], - sourceIndex: node.nodes[0]?.sourceIndex ?? 0, - sourceEndIndex: borderRadiusFunctionMap[value].length, - }, - ]; - - targets[targets.length - 1]!.replaced = true; - } - return StopWalkingFunctionNodes; } }); @@ -305,43 +222,12 @@ const borderWidthLengthMap = { const borderRadiusLengthMap = { '2px': '--p-border-radius-05', - '3px': '--p-border-radius-base', '4px': '--p-border-radius-1', - '6px': '--p-border-radius-large', '8px': '--p-border-radius-2', '12px': '--p-border-radius-3', '16px': '--p-border-radius-4', '20px': '--p-border-radius-5', '30px': '--p-border-radius-6', - '50%': '--p- border-radius-half', -} as const; - -const borderFunctionMap = { - '': '--p-border-base', - base: '--p-border-base', - "'base'": '--p-border-base', - dark: '--p-border-dark', - "'dark'": '--p-border-dark', - transparent: '--p-border-transparent', - "'transparent'": '--p-border-transparent', - divider: ' --p-border-divider', - "'divider'": ' --p-border-divider', -} as const; - -const borderWidthFunctionMap = { - '': '--p-border-width-1', - base: '--p-border-width-1', - "'base'": '--p-border-width-1', - thick: '--p-border-width-2', - "'thick'": '--p-border-width-2', - thicker: '--p-border-width-3', - "'thicker'": '--p-border-width-3', -} as const; - -const borderRadiusFunctionMap = { - '': '--p-border-radius-base', - base: '--p-border-radius-base', - "'base'": '--p-border-radius-base', - large: '--p-border-radius-large', - "'large'": '--p-border-radius-large', + '3px': '--p-border-radius-base', + '6px': '--p-border-radius-large', } as const; diff --git a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.input.scss b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.input.scss similarity index 65% rename from polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.input.scss rename to polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.input.scss index 535e4e39989..f6a88c5d3e4 100644 --- a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.input.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.input.scss @@ -55,32 +55,6 @@ border-width: rem(10px) -1px; border-width: rem(10px) + 1px; border-width: rem($var * 1px); - - /* --- BORDER FUNCTION --- */ - - /* Migrate */ - border: border(); - border: border(base); - border: border(dark); - border: border(transparent); - border: border(divider); - border: border('divider'); - - /* --- BORDER WIDTH FUNCTION --- */ - - /* Migrate */ - border: border-width() solid var(--p-border-subdued); - border: border-width(base) solid var(--p-border-subdued); - border: border-width(thick) solid var(--p-border-subdued); - border: border-width(thicker) solid var(--p-border-subdued); - border-width: border-width('thicker'); - - /* Ignore */ - border-width: calc(-1 * border-width()); - border-width: calc($var * border-width()); - - /* Comment */ - border-width: rem(1px) rem(10px - border-width()); } .border-radius { @@ -111,21 +85,4 @@ /* Comment */ border-radius: rem(10px) rem(4px); border-radius: rem(1px) * 5; - - /* --- BORDER-RADIUS FUNCTION --- */ - - /* Migrate */ - border-radius: border-radius(); - border-radius: border-radius(base); - border-radius: border-radius(large); - - /* Ignore */ - border-radius: calc(border-radius(base) * 2); - border-radius: calc(border-radius() * rem(1px)); - - /* Comment */ - border-radius: border-radius(base) * 2; - border-radius: border-radius() * rem(1px); - border-radius: 10px; - border-top-right-radius: border-radius() * rem(4px); } diff --git a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.output.scss b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.output.scss similarity index 69% rename from polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.output.scss rename to polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.output.scss index 313b0d45519..40cbf4d90a3 100644 --- a/polaris-migrator/src/migrations/replace-border-declarations/tests/replace-border-declarations.output.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.output.scss @@ -77,34 +77,6 @@ // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. // border-width: rem($var * var(--p-border-width-1)); border-width: rem($var * 1px); - - /* --- BORDER FUNCTION --- */ - - /* Migrate */ - border: var(--p-border-base); - border: var(--p-border-base); - border: var(--p-border-dark); - border: var(--p-border-transparent); - border: var(--p-border-divider); - border: var(--p-border-divider); - - /* --- BORDER WIDTH FUNCTION --- */ - - /* Migrate */ - border: var(--p-border-width-1) solid var(--p-border-subdued); - border: var(--p-border-width-1) solid var(--p-border-subdued); - border: var(--p-border-width-2) solid var(--p-border-subdued); - border: var(--p-border-width-3) solid var(--p-border-subdued); - border-width: var(--p-border-width-3); - - /* Ignore */ - border-width: calc(-1 * border-width()); - border-width: calc($var * border-width()); - - /* Comment */ - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-width: var(--p-border-width-1) rem(10px - var(--p-border-width-1)); - border-width: rem(1px) rem(10px - border-width()); } .border-radius { @@ -143,29 +115,4 @@ // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. // border-radius: rem(1px) * 5; border-radius: rem(1px) * 5; - - /* --- BORDER-RADIUS FUNCTION --- */ - - /* Migrate */ - border-radius: var(--p-border-radius-base); - border-radius: var(--p-border-radius-base); - border-radius: var(--p-border-radius-large); - - /* Ignore */ - border-radius: calc(border-radius(base) * 2); - border-radius: calc(border-radius() * rem(1px)); - - /* Comment */ - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: var(--p-border-radius-base) * 2; - border-radius: border-radius(base) * 2; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: var(--p-border-radius-base) * rem(1px); - border-radius: border-radius() * rem(1px); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: 10px; - border-radius: 10px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-top-right-radius: var(--p-border-radius-base) * var(--p-border-radius-1); - border-top-right-radius: border-radius() * rem(4px); } diff --git a/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.test.ts b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.test.ts new file mode 100644 index 00000000000..152be82d18c --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/styles-tokenize-shape.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'styles-tokenize-shape'; +const fixtures = ['styles-tokenize-shape', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.input.scss similarity index 61% rename from polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.input.scss index ccff4ab2033..8111f61de2c 100644 --- a/polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.input.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.input.scss @@ -58,33 +58,6 @@ border-width: legacy-polaris-v8.rem(10px) -1px; border-width: legacy-polaris-v8.rem(10px) + 1px; border-width: legacy-polaris-v8.rem($var * 1px); - - /* --- BORDER FUNCTION --- */ - - /* Migrate */ - border: legacy-polaris-v8.border(); - border: legacy-polaris-v8.border(base); - border: legacy-polaris-v8.border(dark); - border: legacy-polaris-v8.border(transparent); - border: legacy-polaris-v8.border(divider); - border: legacy-polaris-v8.border('divider'); - - /* --- BORDER WIDTH FUNCTION --- */ - - /* Migrate */ - border: legacy-polaris-v8.border-width() solid var(--p-border-subdued); - border: legacy-polaris-v8.border-width(base) solid var(--p-border-subdued); - border: legacy-polaris-v8.border-width(thick) solid var(--p-border-subdued); - border: legacy-polaris-v8.border-width(thicker) solid var(--p-border-subdued); - border-width: legacy-polaris-v8.border-width('thicker'); - - /* Ignore */ - border-width: calc(-1 * legacy-polaris-v8.border-width()); - border-width: calc($var * legacy-polaris-v8.border-width()); - - /* Comment */ - border-width: legacy-polaris-v8.rem(1px) - legacy-polaris-v8.rem(10px - legacy-polaris-v8.border-width()); } .border-radius { @@ -115,24 +88,4 @@ /* Comment */ border-radius: legacy-polaris-v8.rem(10px) legacy-polaris-v8.rem(4px); border-radius: legacy-polaris-v8.rem(1px) * 5; - - /* --- BORDER-RADIUS FUNCTION --- */ - - /* Migrate */ - border-radius: legacy-polaris-v8.border-radius(); - border-radius: legacy-polaris-v8.border-radius(base); - border-radius: legacy-polaris-v8.border-radius(large); - - /* Ignore */ - border-radius: calc(legacy-polaris-v8.border-radius(base) * 2); - border-radius: calc( - legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px) - ); - - /* Comment */ - border-radius: legacy-polaris-v8.border-radius(base) * 2; - border-radius: legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px); - border-radius: 10px; - border-top-right-radius: legacy-polaris-v8.border-radius() * - legacy-polaris-v8.rem(4px); } diff --git a/polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.output.scss similarity index 68% rename from polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.output.scss index 591b63510ab..f0427a089ed 100644 --- a/polaris-migrator/src/migrations/replace-border-declarations/tests/with-namespace.output.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-shape/tests/with-namespace.output.scss @@ -80,35 +80,6 @@ // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. // border-width: legacy-polaris-v8.rem($var * var(--p-border-width-1)); border-width: legacy-polaris-v8.rem($var * 1px); - - /* --- BORDER FUNCTION --- */ - - /* Migrate */ - border: var(--p-border-base); - border: var(--p-border-base); - border: var(--p-border-dark); - border: var(--p-border-transparent); - border: var(--p-border-divider); - border: var(--p-border-divider); - - /* --- BORDER WIDTH FUNCTION --- */ - - /* Migrate */ - border: var(--p-border-width-1) solid var(--p-border-subdued); - border: var(--p-border-width-1) solid var(--p-border-subdued); - border: var(--p-border-width-2) solid var(--p-border-subdued); - border: var(--p-border-width-3) solid var(--p-border-subdued); - border-width: var(--p-border-width-3); - - /* Ignore */ - border-width: calc(-1 * legacy-polaris-v8.border-width()); - border-width: calc($var * legacy-polaris-v8.border-width()); - - /* Comment */ - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-width: var(--p-border-width-1) legacy-polaris-v8.rem(10px - var(--p-border-width-1)); - border-width: legacy-polaris-v8.rem(1px) - legacy-polaris-v8.rem(10px - legacy-polaris-v8.border-width()); } .border-radius { @@ -147,32 +118,4 @@ // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. // border-radius: legacy-polaris-v8.rem(1px) * 5; border-radius: legacy-polaris-v8.rem(1px) * 5; - - /* --- BORDER-RADIUS FUNCTION --- */ - - /* Migrate */ - border-radius: var(--p-border-radius-base); - border-radius: var(--p-border-radius-base); - border-radius: var(--p-border-radius-large); - - /* Ignore */ - border-radius: calc(legacy-polaris-v8.border-radius(base) * 2); - border-radius: calc( - legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px) - ); - - /* Comment */ - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: var(--p-border-radius-base) * 2; - border-radius: legacy-polaris-v8.border-radius(base) * 2; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: var(--p-border-radius-base) * legacy-polaris-v8.rem(1px); - border-radius: legacy-polaris-v8.border-radius() * legacy-polaris-v8.rem(1px); - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-radius: 10px; - border-radius: 10px; - // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // border-top-right-radius: var(--p-border-radius-base) * var(--p-border-radius-1); - border-top-right-radius: legacy-polaris-v8.border-radius() * - legacy-polaris-v8.rem(4px); } diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts b/polaris-migrator/src/migrations/styles-tokenize-space/styles-tokenize-space.ts similarity index 99% rename from polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts rename to polaris-migrator/src/migrations/styles-tokenize-space/styles-tokenize-space.ts index 088f09cf8b1..c5e7c163797 100644 --- a/polaris-migrator/src/migrations/replace-spacing-lengths/replace-spacing-lengths.ts +++ b/polaris-migrator/src/migrations/styles-tokenize-space/styles-tokenize-space.ts @@ -13,7 +13,7 @@ import { import {isKeyOf} from '../../utilities/type-guards'; export default createSassMigrator( - 'replace-sass-space', + 'styles-tokenize-space', (_, {methods, options}, context) => { const namespacedRem = namespace('rem', options); diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.input.scss b/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.input.scss rename to polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.input.scss diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.output.scss b/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.output.scss similarity index 99% rename from polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.output.scss rename to polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.output.scss index becc4078125..017cf3eb5cd 100644 --- a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/replace-spacing-lengths.output.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.output.scss @@ -116,7 +116,7 @@ // padding: var(--p-space-4) + var(--p-space-4); padding: rem(16px) + 16px; // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // error: Non-tokenizable value '$var \* 16px' + // error: Non-tokenizable value '$var * 16px' // warning: Numeric operator detected. // padding: rem($var * var(--p-space-4)); padding: rem($var * 16px); diff --git a/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.test.ts b/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.test.ts new file mode 100644 index 00000000000..b25af1e92a7 --- /dev/null +++ b/polaris-migrator/src/migrations/styles-tokenize-space/tests/styles-tokenize-space.test.ts @@ -0,0 +1,17 @@ +import {check} from '../../../utilities/testUtils'; + +const migration = 'styles-tokenize-space'; +const fixtures = ['styles-tokenize-space', 'with-namespace']; + +for (const fixture of fixtures) { + check(__dirname, { + fixture, + migration, + extension: 'scss', + options: { + namespace: fixture.includes('with-namespace') + ? 'legacy-polaris-v8' + : undefined, + }, + }); +} diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/with-namespace.input.scss b/polaris-migrator/src/migrations/styles-tokenize-space/tests/with-namespace.input.scss similarity index 100% rename from polaris-migrator/src/migrations/replace-spacing-lengths/tests/with-namespace.input.scss rename to polaris-migrator/src/migrations/styles-tokenize-space/tests/with-namespace.input.scss diff --git a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/with-namespace.output.scss b/polaris-migrator/src/migrations/styles-tokenize-space/tests/with-namespace.output.scss similarity index 99% rename from polaris-migrator/src/migrations/replace-spacing-lengths/tests/with-namespace.output.scss rename to polaris-migrator/src/migrations/styles-tokenize-space/tests/with-namespace.output.scss index 2b9be603f01..f881894d4f3 100644 --- a/polaris-migrator/src/migrations/replace-spacing-lengths/tests/with-namespace.output.scss +++ b/polaris-migrator/src/migrations/styles-tokenize-space/tests/with-namespace.output.scss @@ -118,7 +118,7 @@ // padding: var(--p-space-4) + var(--p-space-4); padding: legacy-polaris-v8.rem(16px) + 16px; // polaris-migrator: Unable to migrate the following expression. Please upgrade manually. - // error: Non-tokenizable value '$var \* 16px' + // error: Non-tokenizable value '$var * 16px' // warning: Numeric operator detected. // padding: legacy-polaris-v8.rem($var * var(--p-space-4)); padding: legacy-polaris-v8.rem($var * 16px); diff --git a/polaris-migrator/src/utilities/sass.ts b/polaris-migrator/src/utilities/sass.ts index 9ed1177638c..f97e72ba989 100644 --- a/polaris-migrator/src/utilities/sass.ts +++ b/polaris-migrator/src/utilities/sass.ts @@ -17,7 +17,6 @@ import valueParser, { Dimension, } from 'postcss-value-parser'; import {toPx, getCustomPropertyNames, tokens} from '@shopify/polaris-tokens'; -import prettier from 'prettier'; import {POLARIS_MIGRATOR_COMMENT} from '../constants'; @@ -328,15 +327,8 @@ export function isPolarisVar(node: Node): boolean { ); } -export function createInlineComment(text: string, options?: {prose?: boolean}) { - const formatted = prettier - .format(text, { - parser: options?.prose ? 'markdown' : 'scss', - proseWrap: 'never', - printWidth: 9999, - }) - .trim(); - const comment = postcss.comment({text: formatted}); +export function createInlineComment(text: string) { + const comment = postcss.comment({text: text.replace(/\s+/gm, ' ').trim()}); comment.raws.left = ' '; comment.raws.inline = true; @@ -477,15 +469,11 @@ export function createSassMigrator(name: string, ruleFn: PolarisMigrator) { const flushReportsAsComments = () => { // @ts-expect-error No idea why TS is complaining here for (const [node, reportsForNode] of reports) { - node.before( - createInlineComment(POLARIS_MIGRATOR_COMMENT, {prose: true}), - ); + node.before(createInlineComment(POLARIS_MIGRATOR_COMMENT)); for (const report of reportsForNode) { node.before( - createInlineComment(`${report.severity}: ${report.message}`, { - prose: true, - }), + createInlineComment(`${report.severity}: ${report.message}`), ); } } @@ -573,7 +561,7 @@ export function createSassMigrator(name: string, ruleFn: PolarisMigrator) { root.walkDecls( createWalker({ walker, - serialiseSuggestion: (node) => `${node.prop}: ${node.value}`, + serialiseSuggestion: (node) => `${node.prop}: ${node.value};`, }), ); }, @@ -600,3 +588,14 @@ export function createSassMigrator(name: string, ruleFn: PolarisMigrator) { return convertStylelintRuleToPostcssProcessor(wrappedRule); } + +export function setNodeValue(node: Node, value: string): void { + const {sourceIndex} = node; + const parsedValue = valueParser(value).nodes[0]; + Object.assign(node, parsedValue); + // The node we're replacing might be mid-way through a higher-level value + // string. Eg; 'border: 1px solid', the 'solid' node is 5 characters into the + // higher-level value, so we need to correct the index here. + node.sourceIndex += sourceIndex; + node.sourceEndIndex += sourceIndex; +} diff --git a/polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.input.scss.hbs b/polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.input.scss.hbs similarity index 100% rename from polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.input.scss.hbs rename to polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.input.scss.hbs diff --git a/polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.output.scss.hbs b/polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.output.scss.hbs similarity index 100% rename from polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.output.scss.hbs rename to polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.output.scss.hbs diff --git a/polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.test.ts.hbs b/polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.test.ts.hbs similarity index 100% rename from polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.test.ts.hbs rename to polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/tests/{{kebabCase migrationName}}.test.ts.hbs diff --git a/polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/{{kebabCase migrationName}}.ts.hbs b/polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/{{kebabCase migrationName}}.ts.hbs similarity index 100% rename from polaris-migrator/templates/sass-migration/{{kebabCase migrationName}}/{{kebabCase migrationName}}.ts.hbs rename to polaris-migrator/templates/scss-migration/{{kebabCase migrationName}}/{{kebabCase migrationName}}.ts.hbs