@atlaskit/eslint-plugin-design-system 5.3.2 → 5.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/configs/deprecated.json +13 -0
  3. package/dist/cjs/rules/ensure-design-token-usage-spacing/index.js +11 -12
  4. package/dist/cjs/rules/ensure-design-token-usage-spacing/shape.js +40 -0
  5. package/dist/cjs/rules/ensure-design-token-usage-spacing/typography.js +41 -0
  6. package/dist/cjs/rules/ensure-design-token-usage-spacing/utils.js +40 -67
  7. package/dist/cjs/version.json +1 -1
  8. package/dist/configs/deprecated.json +13 -0
  9. package/dist/es2019/rules/ensure-design-token-usage-spacing/index.js +12 -13
  10. package/dist/es2019/rules/ensure-design-token-usage-spacing/shape.js +21 -0
  11. package/dist/es2019/rules/ensure-design-token-usage-spacing/typography.js +17 -0
  12. package/dist/es2019/rules/ensure-design-token-usage-spacing/utils.js +31 -40
  13. package/dist/es2019/version.json +1 -1
  14. package/dist/esm/rules/ensure-design-token-usage-spacing/index.js +12 -13
  15. package/dist/esm/rules/ensure-design-token-usage-spacing/shape.js +27 -0
  16. package/dist/esm/rules/ensure-design-token-usage-spacing/typography.js +29 -0
  17. package/dist/esm/rules/ensure-design-token-usage-spacing/utils.js +32 -55
  18. package/dist/esm/version.json +1 -1
  19. package/dist/types/rules/ensure-design-token-usage-spacing/index.d.ts +1 -1
  20. package/dist/types/rules/ensure-design-token-usage-spacing/shape.d.ts +11 -0
  21. package/dist/types/rules/ensure-design-token-usage-spacing/typography.d.ts +9 -0
  22. package/dist/types/rules/ensure-design-token-usage-spacing/utils.d.ts +12 -67
  23. package/dist/types/rules/index.codegen.d.ts +1 -1
  24. package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/index.d.ts +1 -1
  25. package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/shape.d.ts +11 -0
  26. package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/typography.d.ts +9 -0
  27. package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/utils.d.ts +12 -67
  28. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
  29. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 5.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [`432d4ce47ee`](https://bitbucket.org/atlassian/atlassian-frontend/commits/432d4ce47ee) - Account for additional border properties in spacing rule.
8
+
9
+ ## 5.4.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`eb75c962cfb`](https://bitbucket.org/atlassian/atlassian-frontend/commits/eb75c962cfb) - `gridSize` imports from `@atlaskit/theme` are now deprecated in favor of applying space tokens via `@atlaskit/tokens`.
14
+
15
+ ### Patch Changes
16
+
17
+ - [`019af32072d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/019af32072d) - Add shape token handling to the `ensure-design-token-usage-spacing` rule.
18
+ - [`7b017c0be76`](https://bitbucket.org/atlassian/atlassian-frontend/commits/7b017c0be76) - Internal tweaks to spacing rule fixers.
19
+ - Updated dependencies
20
+
3
21
  ## 5.3.2
4
22
 
5
23
  ### Patch Changes
@@ -43,6 +43,11 @@
43
43
  {
44
44
  "moduleSpecifier": "@atlaskit/logo"
45
45
  }
46
+ ],
47
+ "enableRemoteAdminLinks": [
48
+ {
49
+ "moduleSpecifier": "@atlassian/switcher"
50
+ }
46
51
  ]
47
52
  },
48
53
  "imports": {
@@ -101,6 +106,10 @@
101
106
  {
102
107
  "importName": "focusRing",
103
108
  "message": "The focusRing mixin is deprecated. Please use `@atlaskit/focus-ring` instead."
109
+ },
110
+ {
111
+ "importName": "gridSize",
112
+ "message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
104
113
  }
105
114
  ]
106
115
  },
@@ -117,6 +126,10 @@
117
126
  {
118
127
  "importName": "focusRing",
119
128
  "message": "The focusRing mixin is deprecated. Please use `@atlaskit/focus-ring` instead."
129
+ },
130
+ {
131
+ "importName": "gridSize",
132
+ "message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
120
133
  }
121
134
  ]
122
135
  },
@@ -45,6 +45,7 @@ var rule = (0, _createRule.createRule)({
45
45
  recommended: false
46
46
  },
47
47
  messages: {
48
+ noRawRadiusValues: 'The use of shape tokens is preferred over the direct application of border properties.\n\n@meta <<{{payload}}>>',
48
49
  noRawSpacingValues: 'The use of spacing primitives or tokens is preferred over the direct application of spacing properties.\n\n@meta <<{{payload}}>>',
49
50
  autofixesPossible: 'Automated corrections available for spacing values. Apply autofix to replace values with appropriate tokens'
50
51
  }
@@ -108,7 +109,7 @@ var rule = (0, _createRule.createRule)({
108
109
  if ((0, _eslintCodemodUtils.isNodeOfType)(node.value, 'TemplateLiteral') && node.value.expressions.some(_isNode.isDecendantOfGlobalToken)) {
109
110
  return;
110
111
  }
111
- if (node.value.type === 'Literal' && !(0, _utils.isValidSpacingValue)(node.value.value, fontSize)) {
112
+ if ((0, _eslintCodemodUtils.isNodeOfType)(node.value, 'Literal') && !(0, _utils.isValidSpacingValue)(node.value.value, fontSize)) {
112
113
  context.report({
113
114
  node: node,
114
115
  messageId: 'noRawSpacingValues',
@@ -120,7 +121,7 @@ var rule = (0, _createRule.createRule)({
120
121
  }
121
122
 
122
123
  // Don't report on CSS calc function
123
- if (node.value.type === 'Literal' && (0, _utils.isCalc)(node.value.value)) {
124
+ if ((0, _eslintCodemodUtils.isNodeOfType)(node.value, 'Literal') && (0, _utils.isCalc)(node.value.value)) {
124
125
  return;
125
126
  }
126
127
  var propertyName = node.key.name;
@@ -161,15 +162,12 @@ var rule = (0, _createRule.createRule)({
161
162
  if (!(0, _utils.shouldAnalyzeProperty)(propertyName, ruleConfig.addons)) {
162
163
  return null;
163
164
  }
164
- var pixelValueString = "".concat(pixelValue, "px");
165
- var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
166
- var tokenName = (0, _utils.isTypographyProperty)(propertyName) ? _utils.typographyValueToToken[propertyName][lookupValue] : _utils.spacingValueToToken[lookupValue];
167
- if (!tokenName) {
165
+ var replacementNode = (0, _utils.getTokenReplacement)(propertyName, pixelValue);
166
+ if (!replacementNode) {
168
167
  return null;
169
168
  }
170
- var replacementValue = (0, _utils.getTokenNodeForValue)(propertyName, lookupValue);
171
169
  return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.insertTextBefore(node, "// TODO Delete this comment after verifying spacing token -> previous value `".concat((0, _eslintCodemodUtils.node)(node.value), "`\n").concat(' '.padStart(((_node$loc = node.loc) === null || _node$loc === void 0 ? void 0 : _node$loc.start.column) || 0))), fixer.replaceText(node, (0, _eslintCodemodUtils.property)(_objectSpread(_objectSpread({}, node), {}, {
172
- value: replacementValue
170
+ value: replacementNode
173
171
  })).toString())]);
174
172
  }
175
173
  });
@@ -182,7 +180,7 @@ var rule = (0, _createRule.createRule)({
182
180
  * @example
183
181
  * { padding: '8px 0px' }
184
182
  */
185
- values.forEach(function (val, index) {
183
+ values.forEach(function (val) {
186
184
  var pixelValue = (0, _utils.emToPixels)(val, fontSize);
187
185
 
188
186
  // Do not report or suggest a token to replace 0 or auto
@@ -247,7 +245,7 @@ var rule = (0, _createRule.createRule)({
247
245
  // const cssTemplateLiteral = css`color: red; padding: 12px`;
248
246
  // const styledTemplateLiteral = styled.p`color: red; padding: 8px`;
249
247
  'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"],TaggedTemplateExpression[tag.callee.name="styled"]': function TaggedTemplateExpressionTagNameCssTaggedTemplateExpressionTagObjectNameStyledTaggedTemplateExpressionTagCalleeNameStyled(node) {
250
- if (node.type !== 'TaggedTemplateExpression') {
248
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'TaggedTemplateExpression')) {
251
249
  return;
252
250
  }
253
251
  var processedCssLines = (0, _utils.processCssNode)(node, context);
@@ -323,10 +321,11 @@ var rule = (0, _createRule.createRule)({
323
321
  });
324
322
 
325
323
  // from here on we know value is numeric or a font family, so it might or might not have a token equivalent
326
- var replacementToken = (0, _utils.getTokenReplacement)(propertyName, numericOrNanValue);
327
- if (!replacementToken) {
324
+ var replacementTokenNode = (0, _utils.getTokenReplacement)(propertyName, numericOrNanValue);
325
+ if (!replacementTokenNode) {
328
326
  return originalValue;
329
327
  }
328
+ var replacementToken = '${' + replacementTokenNode.toString() + '}';
330
329
  replacedValuesPerProperty.push(isFontFamily ? numericOrNanValue.trim() : pxValue);
331
330
  return replacementToken;
332
331
  }).join(' ');
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.borderWidthValueToToken = void 0;
7
+ exports.isBorderRadius = isBorderRadius;
8
+ exports.isBorderSizeProperty = isBorderSizeProperty;
9
+ exports.isRadiusProperty = isRadiusProperty;
10
+ exports.isShapeProperty = isShapeProperty;
11
+ exports.radiusValueToToken = void 0;
12
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
13
+ var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
14
+ var shapeProperties = ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius', 'borderRadius'];
15
+ var borderSizeProperties = ['borderWidth', 'outlineWidth', 'borderRightWidth', 'borderLeftWidth', 'borderTopWidth', 'borderBottomWidth', 'borderInlineWidth', 'borderBlockWidth'];
16
+ var radiusValueToToken = Object.fromEntries(_tokensRaw.shape.filter(function (t) {
17
+ return t.name.startsWith('border.radius');
18
+ }).map(function (t) {
19
+ var value = t.value === '4px' ? '3px' : t.value;
20
+ return [value, t.name];
21
+ }));
22
+ exports.radiusValueToToken = radiusValueToToken;
23
+ var borderWidthValueToToken = Object.fromEntries(_tokensRaw.shape.filter(function (t) {
24
+ return t.name.startsWith('border.width');
25
+ }).map(function (t) {
26
+ return [t.value, t.name];
27
+ }));
28
+ exports.borderWidthValueToToken = borderWidthValueToToken;
29
+ function isRadiusProperty(propertyName) {
30
+ return shapeProperties.includes(propertyName);
31
+ }
32
+ function isBorderSizeProperty(propertyName) {
33
+ return borderSizeProperties.includes(propertyName);
34
+ }
35
+ function isShapeProperty(propertyName) {
36
+ return isRadiusProperty(propertyName) || isBorderSizeProperty(propertyName);
37
+ }
38
+ function isBorderRadius(node) {
39
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'borderRadius' || node.callee.name === 'getBorderRadius');
40
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.typographyValueToToken = exports.isTypographyProperty = exports.isFontSizeSmall = exports.isFontSize = exports.isFontFamily = exports.isCodeFontFamily = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
9
+ var typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
10
+ var isTypographyProperty = function isTypographyProperty(propertyName) {
11
+ return typographyProperties.includes(propertyName);
12
+ };
13
+ exports.isTypographyProperty = isTypographyProperty;
14
+ var isFontSize = function isFontSize(node) {
15
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontSize' || node.callee.name === 'getFontSize');
16
+ };
17
+ exports.isFontSize = isFontSize;
18
+ var isFontSizeSmall = function isFontSizeSmall(node) {
19
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
20
+ };
21
+ exports.isFontSizeSmall = isFontSizeSmall;
22
+ var isFontFamily = function isFontFamily(node) {
23
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
24
+ };
25
+ exports.isFontFamily = isFontFamily;
26
+ var isCodeFontFamily = function isCodeFontFamily(node) {
27
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
28
+ };
29
+ exports.isCodeFontFamily = isCodeFontFamily;
30
+ var typographyValueToToken = Object.fromEntries(_tokensRaw.typography.map(function (currentToken) {
31
+ // Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
32
+ // This allows us to look up values specific to a property
33
+ // (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
34
+ var tokenGroup = currentToken.attributes.group;
35
+ return [tokenGroup, Object.fromEntries(_tokensRaw.typography.map(function (token) {
36
+ return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
37
+ }).filter(function (token) {
38
+ return token.length;
39
+ }))];
40
+ }));
41
+ exports.typographyValueToToken = typographyValueToToken;
@@ -17,43 +17,22 @@ exports.getValueFromShorthand = exports.getValue = void 0;
17
17
  exports.insertTokensImport = insertTokensImport;
18
18
  exports.isSpacingProperty = exports.isCalc = exports.isAuto = void 0;
19
19
  exports.isTokenValueString = isTokenValueString;
20
- exports.onlyScaleTokens = exports.isZero = exports.isValidSpacingValue = exports.isTypographyProperty = void 0;
20
+ exports.isZero = exports.isValidSpacingValue = void 0;
21
+ exports.normaliseValue = normaliseValue;
21
22
  exports.processCssNode = processCssNode;
22
23
  exports.removePixelSuffix = void 0;
23
24
  exports.shouldAnalyzeProperty = shouldAnalyzeProperty;
24
- exports.spacingValueToToken = void 0;
25
25
  exports.splitCssProperties = splitCssProperties;
26
- exports.typographyValueToToken = exports.splitShorthandValues = void 0;
26
+ exports.splitShorthandValues = void 0;
27
27
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
28
28
  var _eslintCodemodUtils = require("eslint-codemod-utils");
29
29
  var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
30
- var typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
30
+ var _shape = require("./shape");
31
+ var _typography = require("./typography");
31
32
  var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingInline', 'paddingInlineStart', 'paddingInlineEnd', 'paddingBlock', 'paddingBlockStart', 'paddingBlockEnd', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginInline', 'marginInlineStart', 'marginInlineEnd', 'marginBlock', 'marginBlockStart', 'marginBlockEnd', 'margin', 'gap', 'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap', 'top', 'left', 'right', 'bottom', 'inlineStart', 'inlineEnd', 'blockStart', 'blockEnd', 'outline-offset'];
32
- /**
33
- * Currently we have a wide range of experimental spacing tokens that we are testing.
34
- * We only want transforms to apply to the stable scale values, not the rest.
35
- * This could be removed in the future.
36
- */
37
- var onlyScaleTokens = _tokensRaw.spacing.filter(function (token) {
38
- return token.name.startsWith('space.');
39
- });
40
- exports.onlyScaleTokens = onlyScaleTokens;
41
- var spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(function (token) {
42
- return [token.attributes['pixelValue'], token.name];
43
- }));
44
- exports.spacingValueToToken = spacingValueToToken;
45
- var typographyValueToToken = Object.fromEntries(_tokensRaw.typography.map(function (currentToken) {
46
- // Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
47
- // This allows us to look up values specific to a property
48
- // (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
49
- var tokenGroup = currentToken.attributes.group;
50
- return [tokenGroup, Object.fromEntries(_tokensRaw.typography.map(function (token) {
51
- return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
52
- }).filter(function (token) {
53
- return token.length;
54
- }))];
33
+ var spacingValueToToken = Object.fromEntries(_tokensRaw.spacing.map(function (token) {
34
+ return [token.value, token.name];
55
35
  }));
56
- exports.typographyValueToToken = typographyValueToToken;
57
36
  function findIdentifierInParentScope(_ref) {
58
37
  var scope = _ref.scope,
59
38
  identifierName = _ref.identifierName;
@@ -75,10 +54,6 @@ function insertTokensImport(fixer) {
75
54
  var isSpacingProperty = function isSpacingProperty(propertyName) {
76
55
  return properties.includes(propertyName);
77
56
  };
78
- exports.isSpacingProperty = isSpacingProperty;
79
- var isTypographyProperty = function isTypographyProperty(propertyName) {
80
- return typographyProperties.includes(propertyName);
81
- };
82
57
 
83
58
  /**
84
59
  * Accomplishes split str by whitespace but preserves expressions in between ${...}
@@ -91,7 +66,7 @@ var isTypographyProperty = function isTypographyProperty(propertyName) {
91
66
  * second part is a white space delimiter
92
67
  * For input `-${gridSize / 2}px ${token(...)} 18px -> [`-${gridSize / 2}px`, `${token(...)}`, `18px`]
93
68
  */
94
- exports.isTypographyProperty = isTypographyProperty;
69
+ exports.isSpacingProperty = isSpacingProperty;
95
70
  var splitShorthandValues = function splitShorthandValues(str) {
96
71
  return str.split(/(\S*\$\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}\S*)|\s+/g).filter(Boolean);
97
72
  };
@@ -109,18 +84,6 @@ exports.getValueFromShorthand = getValueFromShorthand;
109
84
  var isGridSize = function isGridSize(node) {
110
85
  return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'gridSize' || node.callee.name === 'getGridSize');
111
86
  };
112
- var isFontSize = function isFontSize(node) {
113
- return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontSize' || node.callee.name === 'getFontSize');
114
- };
115
- var isFontSizeSmall = function isFontSizeSmall(node) {
116
- return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
117
- };
118
- var isFontFamily = function isFontFamily(node) {
119
- return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
120
- };
121
- var isCodeFontFamily = function isCodeFontFamily(node) {
122
- return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
123
- };
124
87
  var isToken = function isToken(node) {
125
88
  return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'token';
126
89
  };
@@ -146,16 +109,19 @@ var getValueFromCallExpression = function getValueFromCallExpression(node, conte
146
109
  if (isGridSize(node)) {
147
110
  return 8;
148
111
  }
149
- if (isFontSize(node)) {
112
+ if ((0, _shape.isBorderRadius)(node)) {
113
+ return 3;
114
+ }
115
+ if ((0, _typography.isFontSize)(node)) {
150
116
  return 14;
151
117
  }
152
- if (isFontSizeSmall(node)) {
118
+ if ((0, _typography.isFontSizeSmall)(node)) {
153
119
  return 11;
154
120
  }
155
- if (isFontFamily(node)) {
121
+ if ((0, _typography.isFontFamily)(node)) {
156
122
  return "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif";
157
123
  }
158
- if (isCodeFontFamily(node)) {
124
+ if ((0, _typography.isCodeFontFamily)(node)) {
159
125
  return "'SFMono-Medium', 'SF Mono', 'Segoe UI Mono', 'Roboto Mono', 'Ubuntu Mono', Menlo, Consolas, Courier, monospace";
160
126
  }
161
127
  if (isToken(node)) {
@@ -397,7 +363,10 @@ function shouldAnalyzeProperty(propertyName, targetOptions) {
397
363
  if (isSpacingProperty(propertyName) && targetOptions.includes('spacing')) {
398
364
  return true;
399
365
  }
400
- if (isTypographyProperty(propertyName) && targetOptions.includes('typography')) {
366
+ if ((0, _shape.isShapeProperty)(propertyName) && targetOptions.includes('shape')) {
367
+ return true;
368
+ }
369
+ if ((0, _typography.isTypographyProperty)(propertyName) && targetOptions.includes('typography')) {
401
370
  return true;
402
371
  }
403
372
  return false;
@@ -452,7 +421,7 @@ function processCssNode(node, context) {
452
421
  * ```
453
422
  */
454
423
  function getTokenNodeForValue(propertyName, value) {
455
- var token = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
424
+ var token = findTokenNameByPropertyValue(propertyName, value);
456
425
  var fallbackValue = propertyName === 'fontFamily' ? {
457
426
  value: "".concat(value),
458
427
  raw: "`".concat(value, "`")
@@ -524,13 +493,25 @@ function splitCssProperties(styleString) {
524
493
  function isTokenValueString(originalValue) {
525
494
  return originalValue.startsWith('${token(') && originalValue.endsWith('}');
526
495
  }
527
- function findTokenNameByPropertyValue(propertyName, value) {
496
+
497
+ /**
498
+ * Translate a raw value into the same value format for further parsing:
499
+ *
500
+ * -> for pixels this '8px'
501
+ * -> for weights '400'
502
+ * -> for family 'Arial'
503
+ *
504
+ * @internal
505
+ */
506
+ function normaliseValue(propertyName, value) {
528
507
  var isFontWeightOrFamily = /fontWeight|fontFamily/.test(propertyName);
529
508
  var propertyValue = typeof value === 'string' ? value.trim() : value;
530
- var pixelValue = propertyValue;
531
- var pixelValueString = "".concat(propertyValue, "px");
532
- var lookupValue = isFontWeightOrFamily ? pixelValue : pixelValueString;
533
- var tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
509
+ var lookupValue = isFontWeightOrFamily ? propertyValue : typeof propertyValue === 'string' ? propertyValue : "".concat(propertyValue, "px");
510
+ return lookupValue;
511
+ }
512
+ function findTokenNameByPropertyValue(propertyName, value) {
513
+ var lookupValue = normaliseValue(propertyName, value);
514
+ var tokenName = (0, _shape.isShapeProperty)(propertyName) ? (0, _shape.isBorderSizeProperty)(propertyName) ? _shape.borderWidthValueToToken[lookupValue] : _shape.radiusValueToToken[lookupValue] : (0, _typography.isTypographyProperty)(propertyName) ? _typography.typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
534
515
  if (!tokenName) {
535
516
  return undefined;
536
517
  }
@@ -538,24 +519,16 @@ function findTokenNameByPropertyValue(propertyName, value) {
538
519
  }
539
520
 
540
521
  /**
541
- * Returns a string with token expression corresponding to input parameters
522
+ * Returns a stringifiable node with the token expression corresponding to its matching token.
542
523
  * if no token found for the pair the function returns undefined
543
524
  * @param propertyName string camelCased css property
544
525
  * @param value the computed value e.g '8px' -> '8'
545
526
  */
546
527
  function getTokenReplacement(propertyName, value) {
547
- var isFontWeightOrFamily = /fontWeight|fontFamily/.test(propertyName);
548
- var propertyValue = typeof value === 'string' ? value.trim() : value;
549
- var pixelValue = propertyValue;
550
- var pixelValueString = "".concat(propertyValue, "px");
551
- var lookupValue = isFontWeightOrFamily ? pixelValue : pixelValueString;
552
528
  var tokenName = findTokenNameByPropertyValue(propertyName, value);
553
529
  if (!tokenName) {
554
530
  return undefined;
555
531
  }
556
- var replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue);
557
-
558
- // ${token('...', '...')}
559
- var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
560
- return replacementSubValue;
532
+ var fallbackValue = normaliseValue(propertyName, value);
533
+ return getTokenNodeForValue(propertyName, fallbackValue);
561
534
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
- "version": "5.3.2",
3
+ "version": "5.4.1",
4
4
  "sideEffects": false
5
5
  }
@@ -43,6 +43,11 @@
43
43
  {
44
44
  "moduleSpecifier": "@atlaskit/logo"
45
45
  }
46
+ ],
47
+ "enableRemoteAdminLinks": [
48
+ {
49
+ "moduleSpecifier": "@atlassian/switcher"
50
+ }
46
51
  ]
47
52
  },
48
53
  "imports": {
@@ -101,6 +106,10 @@
101
106
  {
102
107
  "importName": "focusRing",
103
108
  "message": "The focusRing mixin is deprecated. Please use `@atlaskit/focus-ring` instead."
109
+ },
110
+ {
111
+ "importName": "gridSize",
112
+ "message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
104
113
  }
105
114
  ]
106
115
  },
@@ -117,6 +126,10 @@
117
126
  {
118
127
  "importName": "focusRing",
119
128
  "message": "The focusRing mixin is deprecated. Please use `@atlaskit/focus-ring` instead."
129
+ },
130
+ {
131
+ "importName": "gridSize",
132
+ "message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
120
133
  }
121
134
  ]
122
135
  },
@@ -3,7 +3,7 @@
3
3
  import { isNodeOfType, node as nodeFn, property } from 'eslint-codemod-utils';
4
4
  import { createRule } from '../utils/create-rule';
5
5
  import { isDecendantOfGlobalToken } from '../utils/is-node';
6
- import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isTypographyProperty, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, spacingValueToToken, splitShorthandValues, typographyValueToToken } from './utils';
6
+ import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, splitShorthandValues } from './utils';
7
7
  const rule = createRule({
8
8
  defaultOptions: [{
9
9
  addons: ['spacing'],
@@ -35,6 +35,7 @@ const rule = createRule({
35
35
  recommended: false
36
36
  },
37
37
  messages: {
38
+ noRawRadiusValues: 'The use of shape tokens is preferred over the direct application of border properties.\n\n@meta <<{{payload}}>>',
38
39
  noRawSpacingValues: 'The use of spacing primitives or tokens is preferred over the direct application of spacing properties.\n\n@meta <<{{payload}}>>',
39
40
  autofixesPossible: 'Automated corrections available for spacing values. Apply autofix to replace values with appropriate tokens'
40
41
  }
@@ -99,7 +100,7 @@ const rule = createRule({
99
100
  if (isNodeOfType(node.value, 'TemplateLiteral') && node.value.expressions.some(isDecendantOfGlobalToken)) {
100
101
  return;
101
102
  }
102
- if (node.value.type === 'Literal' && !isValidSpacingValue(node.value.value, fontSize)) {
103
+ if (isNodeOfType(node.value, 'Literal') && !isValidSpacingValue(node.value.value, fontSize)) {
103
104
  context.report({
104
105
  node,
105
106
  messageId: 'noRawSpacingValues',
@@ -111,7 +112,7 @@ const rule = createRule({
111
112
  }
112
113
 
113
114
  // Don't report on CSS calc function
114
- if (node.value.type === 'Literal' && isCalc(node.value.value)) {
115
+ if (isNodeOfType(node.value, 'Literal') && isCalc(node.value.value)) {
115
116
  return;
116
117
  }
117
118
  const propertyName = node.key.name;
@@ -151,16 +152,13 @@ const rule = createRule({
151
152
  if (!shouldAnalyzeProperty(propertyName, ruleConfig.addons)) {
152
153
  return null;
153
154
  }
154
- const pixelValueString = `${pixelValue}px`;
155
- const lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
156
- const tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
157
- if (!tokenName) {
155
+ const replacementNode = getTokenReplacement(propertyName, pixelValue);
156
+ if (!replacementNode) {
158
157
  return null;
159
158
  }
160
- const replacementValue = getTokenNodeForValue(propertyName, lookupValue);
161
159
  return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.insertTextBefore(node, `// TODO Delete this comment after verifying spacing token -> previous value \`${nodeFn(node.value)}\`\n${' '.padStart(((_node$loc = node.loc) === null || _node$loc === void 0 ? void 0 : _node$loc.start.column) || 0)}`), fixer.replaceText(node, property({
162
160
  ...node,
163
- value: replacementValue
161
+ value: replacementNode
164
162
  }).toString())]);
165
163
  }
166
164
  });
@@ -173,7 +171,7 @@ const rule = createRule({
173
171
  * @example
174
172
  * { padding: '8px 0px' }
175
173
  */
176
- values.forEach((val, index) => {
174
+ values.forEach(val => {
177
175
  const pixelValue = emToPixels(val, fontSize);
178
176
 
179
177
  // Do not report or suggest a token to replace 0 or auto
@@ -232,7 +230,7 @@ const rule = createRule({
232
230
  // const cssTemplateLiteral = css`color: red; padding: 12px`;
233
231
  // const styledTemplateLiteral = styled.p`color: red; padding: 8px`;
234
232
  'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"],TaggedTemplateExpression[tag.callee.name="styled"]': node => {
235
- if (node.type !== 'TaggedTemplateExpression') {
233
+ if (!isNodeOfType(node, 'TaggedTemplateExpression')) {
236
234
  return;
237
235
  }
238
236
  const processedCssLines = processCssNode(node, context);
@@ -293,10 +291,11 @@ const rule = createRule({
293
291
  });
294
292
 
295
293
  // from here on we know value is numeric or a font family, so it might or might not have a token equivalent
296
- const replacementToken = getTokenReplacement(propertyName, numericOrNanValue);
297
- if (!replacementToken) {
294
+ const replacementTokenNode = getTokenReplacement(propertyName, numericOrNanValue);
295
+ if (!replacementTokenNode) {
298
296
  return originalValue;
299
297
  }
298
+ const replacementToken = '${' + replacementTokenNode.toString() + '}';
300
299
  replacedValuesPerProperty.push(isFontFamily ? numericOrNanValue.trim() : pxValue);
301
300
  return replacementToken;
302
301
  }).join(' ');
@@ -0,0 +1,21 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import { shape as shapeTokens } from '@atlaskit/tokens/tokens-raw';
3
+ const shapeProperties = ['borderTopLeftRadius', 'borderTopRightRadius', 'borderBottomRightRadius', 'borderBottomLeftRadius', 'borderRadius'];
4
+ const borderSizeProperties = ['borderWidth', 'outlineWidth', 'borderRightWidth', 'borderLeftWidth', 'borderTopWidth', 'borderBottomWidth', 'borderInlineWidth', 'borderBlockWidth'];
5
+ export const radiusValueToToken = Object.fromEntries(shapeTokens.filter(t => t.name.startsWith('border.radius')).map(t => {
6
+ const value = t.value === '4px' ? '3px' : t.value;
7
+ return [value, t.name];
8
+ }));
9
+ export const borderWidthValueToToken = Object.fromEntries(shapeTokens.filter(t => t.name.startsWith('border.width')).map(t => [t.value, t.name]));
10
+ export function isRadiusProperty(propertyName) {
11
+ return shapeProperties.includes(propertyName);
12
+ }
13
+ export function isBorderSizeProperty(propertyName) {
14
+ return borderSizeProperties.includes(propertyName);
15
+ }
16
+ export function isShapeProperty(propertyName) {
17
+ return isRadiusProperty(propertyName) || isBorderSizeProperty(propertyName);
18
+ }
19
+ export function isBorderRadius(node) {
20
+ return isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'borderRadius' || node.callee.name === 'getBorderRadius');
21
+ }
@@ -0,0 +1,17 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import { typography as typographyTokens } from '@atlaskit/tokens/tokens-raw';
3
+ const typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
4
+ export const isTypographyProperty = propertyName => {
5
+ return typographyProperties.includes(propertyName);
6
+ };
7
+ export const isFontSize = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'fontSize' || node.callee.name === 'getFontSize');
8
+ export const isFontSizeSmall = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
9
+ export const isFontFamily = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
10
+ export const isCodeFontFamily = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
11
+ export const typographyValueToToken = Object.fromEntries(typographyTokens.map(currentToken => {
12
+ // Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
13
+ // This allows us to look up values specific to a property
14
+ // (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
15
+ const tokenGroup = currentToken.attributes.group;
16
+ return [tokenGroup, Object.fromEntries(typographyTokens.map(token => token.attributes.group === tokenGroup ? [token.value.replaceAll(`"`, `'`), token.name] : []).filter(token => token.length))];
17
+ }));