@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.
- package/CHANGELOG.md +18 -0
- package/configs/deprecated.json +13 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/index.js +11 -12
- package/dist/cjs/rules/ensure-design-token-usage-spacing/shape.js +40 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/typography.js +41 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/utils.js +40 -67
- package/dist/cjs/version.json +1 -1
- package/dist/configs/deprecated.json +13 -0
- package/dist/es2019/rules/ensure-design-token-usage-spacing/index.js +12 -13
- package/dist/es2019/rules/ensure-design-token-usage-spacing/shape.js +21 -0
- package/dist/es2019/rules/ensure-design-token-usage-spacing/typography.js +17 -0
- package/dist/es2019/rules/ensure-design-token-usage-spacing/utils.js +31 -40
- package/dist/es2019/version.json +1 -1
- package/dist/esm/rules/ensure-design-token-usage-spacing/index.js +12 -13
- package/dist/esm/rules/ensure-design-token-usage-spacing/shape.js +27 -0
- package/dist/esm/rules/ensure-design-token-usage-spacing/typography.js +29 -0
- package/dist/esm/rules/ensure-design-token-usage-spacing/utils.js +32 -55
- package/dist/esm/version.json +1 -1
- package/dist/types/rules/ensure-design-token-usage-spacing/index.d.ts +1 -1
- package/dist/types/rules/ensure-design-token-usage-spacing/shape.d.ts +11 -0
- package/dist/types/rules/ensure-design-token-usage-spacing/typography.d.ts +9 -0
- package/dist/types/rules/ensure-design-token-usage-spacing/utils.d.ts +12 -67
- package/dist/types/rules/index.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/index.d.ts +1 -1
- package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/shape.d.ts +11 -0
- package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/typography.d.ts +9 -0
- package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/utils.d.ts +12 -67
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
- 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
|
package/configs/deprecated.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
165
|
-
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
327
|
-
if (!
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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.
|
|
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 (
|
|
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 (
|
|
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 =
|
|
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
|
-
|
|
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
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
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
|
|
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
|
|
557
|
-
|
|
558
|
-
// ${token('...', '...')}
|
|
559
|
-
var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
|
|
560
|
-
return replacementSubValue;
|
|
532
|
+
var fallbackValue = normaliseValue(propertyName, value);
|
|
533
|
+
return getTokenNodeForValue(propertyName, fallbackValue);
|
|
561
534
|
}
|
package/dist/cjs/version.json
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
|
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
|
|
155
|
-
|
|
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:
|
|
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(
|
|
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
|
|
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
|
|
297
|
-
if (!
|
|
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
|
+
}));
|