Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 44 additions & 5 deletions polaris-migrator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,32 +155,71 @@ Replace legacy Typography functions and hardcoded lengths with Polaris custom pr
npx @shopify/polaris-migrator styles-tokenize-fonts <path>
```

### `styles-tokenize-fonts`
### `styles-tokenize-shape`

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 usage of the legacy Sass `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 <path>
```

### `sass-replace-border`

Replace usage of the legacy Sass `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-width: 0.0625rem;
- border: border(divider);
+ border: var(--p-border-divider);
```

```sh
npx @shopify/polaris-migrator sass-replace-border <path>
```

### `sass-replace-border-width`

Replace usage of the legacy Sass `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);
```

- border-radius: 4px;
```sh
npx @shopify/polaris-migrator sass-replace-border-width <path>
```

### `sass-replace-border-radius`

Replace usage of the legacy Sass `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 styles-tokenize-fonts <path>
npx @shopify/polaris-migrator sass-replace-border-radius <path>
```

### `scss-replace-z-index`
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
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,
isTransformableLength,
namespace,
NamespaceOptions,
toTransformablePx,
StopWalkingFunctionNodes,
createInlineComment,
} from '../../utilities/sass';
import {isKeyOf} from '../../utilities/type-guards';

export default function sassReplaceBorderRadius(
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: 'sass-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, {prose: true}),
);
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;
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {check} from '../../../utilities/testUtils';

const migration = 'replace-border-declarations';
const fixtures = ['replace-border-declarations', 'with-namespace'];
const migration = 'sass-replace-border-radius';
const fixtures = ['sass-replace-border-radius', 'with-namespace'];

for (const fixture of fixtures) {
check(__dirname, {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Loading