@atlaskit/eslint-plugin-design-system 4.13.5 → 4.13.7
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 +12 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/index.js +50 -37
- package/dist/cjs/rules/ensure-design-token-usage-spacing/utils.js +36 -6
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/rules/ensure-design-token-usage-spacing/index.js +46 -38
- package/dist/es2019/rules/ensure-design-token-usage-spacing/utils.js +27 -4
- package/dist/es2019/version.json +1 -1
- package/dist/esm/rules/ensure-design-token-usage-spacing/index.js +50 -38
- package/dist/esm/rules/ensure-design-token-usage-spacing/utils.js +32 -5
- package/dist/esm/version.json +1 -1
- package/dist/types/rules/ensure-design-token-usage-spacing/utils.d.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 4.13.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`41ac6cadd32`](https://bitbucket.org/atlassian/atlassian-frontend/commits/41ac6cadd32) - Adds support to the ensure-design-token-usage-spacing rule for replacing typography values with tokens
|
|
8
|
+
|
|
9
|
+
## 4.13.6
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`0518a6ab41d`](https://bitbucket.org/atlassian/atlassian-frontend/commits/0518a6ab41d) - Changes behavior of `ensure-design-token-usage-spacing` to fallback to px instead of rems when a fix is applied.
|
|
14
|
+
|
|
3
15
|
## 4.13.5
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -15,6 +15,8 @@ var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
|
15
15
|
|
|
16
16
|
var _spacingRaw = _interopRequireDefault(require("@atlaskit/tokens/spacing-raw"));
|
|
17
17
|
|
|
18
|
+
var _typographyRaw = _interopRequireDefault(require("@atlaskit/tokens/typography-raw"));
|
|
19
|
+
|
|
18
20
|
var _isNode = require("../utils/is-node");
|
|
19
21
|
|
|
20
22
|
var _utils = require("./utils");
|
|
@@ -23,46 +25,50 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
23
25
|
|
|
24
26
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
25
27
|
|
|
26
|
-
var pixelsToRems = function pixelsToRems(pixelValueString) {
|
|
27
|
-
var pixels = (0, _utils.removePixelSuffix)(pixelValueString);
|
|
28
|
-
|
|
29
|
-
if (pixels === '0' || pixels === 0) {
|
|
30
|
-
return pixels;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return "".concat(Number(pixels) / 16, "rem");
|
|
34
|
-
};
|
|
35
28
|
/**
|
|
36
29
|
* Currently we have a wide range of experimental spacing tokens that we are testing.
|
|
37
30
|
* We only want transforms to apply to the stable scale values, not the rest.
|
|
38
31
|
* This could be removed in the future.
|
|
39
32
|
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
33
|
var onlyScaleTokens = _spacingRaw.default.filter(function (token) {
|
|
43
|
-
return token.name.startsWith('
|
|
34
|
+
return token.name.startsWith('space.');
|
|
44
35
|
});
|
|
45
36
|
|
|
46
37
|
var spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(function (token) {
|
|
47
|
-
return [token.
|
|
38
|
+
return [token.attributes['pixelValue'], token.name];
|
|
39
|
+
}));
|
|
40
|
+
var typographyValueToToken = Object.fromEntries(_typographyRaw.default.map(function (currentToken) {
|
|
41
|
+
// Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
|
|
42
|
+
// This allows us to look up values specific to a property
|
|
43
|
+
// (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
|
|
44
|
+
var tokenGroup = currentToken.attributes.group;
|
|
45
|
+
return [tokenGroup, Object.fromEntries(_typographyRaw.default.map(function (token) {
|
|
46
|
+
return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
|
|
47
|
+
}).filter(function (token) {
|
|
48
|
+
return token.length;
|
|
49
|
+
}))];
|
|
48
50
|
}));
|
|
49
51
|
/**
|
|
52
|
+
* Returns a token node for a given value including fallbacks.
|
|
53
|
+
* @param propertyName camelCase CSS property
|
|
54
|
+
* @param value string representing pixel value, or font family, or number representing font weight
|
|
50
55
|
* @example
|
|
51
56
|
* ```
|
|
52
|
-
* '8px' => token('spacing.scale.100', '8px')
|
|
57
|
+
* propertyName: padding, value: '8px' => token('spacing.scale.100', '8px')
|
|
58
|
+
* propertyName: fontWeight, value: 400 => token('font.weight.regular', '400')
|
|
53
59
|
* ```
|
|
54
60
|
*/
|
|
55
61
|
|
|
56
|
-
function
|
|
57
|
-
var
|
|
58
|
-
var
|
|
62
|
+
function getTokenNodeForValue(propertyName, value) {
|
|
63
|
+
var token = (0, _utils.isTypographyProperty)(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
|
|
64
|
+
var fallbackValue = propertyName === 'fontFamily' ? "\"".concat(value, "\"") : "'".concat(value, "'");
|
|
59
65
|
return (0, _eslintCodemodUtils.callExpression)({
|
|
60
66
|
callee: (0, _eslintCodemodUtils.identifier)({
|
|
61
67
|
name: 'token'
|
|
62
68
|
}),
|
|
63
69
|
arguments: [(0, _eslintCodemodUtils.literal)({
|
|
64
70
|
value: "'".concat(token !== null && token !== void 0 ? token : '', "'")
|
|
65
|
-
}), (0, _eslintCodemodUtils.literal)(
|
|
71
|
+
}), (0, _eslintCodemodUtils.literal)(fallbackValue)],
|
|
66
72
|
optional: false
|
|
67
73
|
});
|
|
68
74
|
}
|
|
@@ -144,6 +150,8 @@ var rule = {
|
|
|
144
150
|
return;
|
|
145
151
|
}
|
|
146
152
|
|
|
153
|
+
var propertyName = node.key.name;
|
|
154
|
+
var isFontFamily = /fontFamily/.test(propertyName);
|
|
147
155
|
var value = (0, _utils.getValue)(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
148
156
|
|
|
149
157
|
if (!(value && (0, _utils.isValidSpacingValue)(value, fontSize))) {
|
|
@@ -157,35 +165,37 @@ var rule = {
|
|
|
157
165
|
}
|
|
158
166
|
|
|
159
167
|
var values = Array.isArray(value) ? value : [value]; // value is a single value so we can apply a more robust approach to our fix
|
|
168
|
+
// treat fontFamily as having one value
|
|
160
169
|
|
|
161
|
-
if (values.length === 1) {
|
|
170
|
+
if (values.length === 1 || isFontFamily) {
|
|
162
171
|
var _values = (0, _slicedToArray2.default)(values, 1),
|
|
163
172
|
_value = _values[0];
|
|
164
173
|
|
|
165
|
-
var pixelValue = (0, _utils.emToPixels)(_value, fontSize);
|
|
174
|
+
var pixelValue = isFontFamily ? _value : (0, _utils.emToPixels)(_value, fontSize);
|
|
166
175
|
return context.report({
|
|
167
176
|
node: node,
|
|
168
177
|
messageId: 'noRawSpacingValues',
|
|
169
178
|
data: {
|
|
170
|
-
payload: "".concat(
|
|
179
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
171
180
|
},
|
|
172
181
|
fix: function fix(fixer) {
|
|
173
182
|
var _node$loc;
|
|
174
183
|
|
|
175
|
-
if (
|
|
184
|
+
if (!(0, _utils.isSpacingProperty)(propertyName)) {
|
|
176
185
|
return null;
|
|
177
186
|
}
|
|
178
187
|
|
|
179
188
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
180
|
-
var
|
|
181
|
-
var tokenName = spacingValueToToken[
|
|
189
|
+
var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
190
|
+
var tokenName = (0, _utils.isTypographyProperty)(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
182
191
|
|
|
183
192
|
if (!tokenName) {
|
|
184
193
|
return null;
|
|
185
194
|
}
|
|
186
195
|
|
|
196
|
+
var replacementValue = getTokenNodeForValue(propertyName, lookupValue);
|
|
187
197
|
return [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), {}, {
|
|
188
|
-
value:
|
|
198
|
+
value: replacementValue
|
|
189
199
|
})).toString())];
|
|
190
200
|
}
|
|
191
201
|
});
|
|
@@ -205,7 +215,7 @@ var rule = {
|
|
|
205
215
|
node: node,
|
|
206
216
|
messageId: 'noRawSpacingValues',
|
|
207
217
|
data: {
|
|
208
|
-
payload: "".concat(
|
|
218
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
209
219
|
},
|
|
210
220
|
fix: index === 0 ? function (fixer) {
|
|
211
221
|
var allResolvableValues = values.every(function (value) {
|
|
@@ -219,7 +229,7 @@ var rule = {
|
|
|
219
229
|
return fixer.replaceText(node.value, "`".concat(values.map(function (value) {
|
|
220
230
|
var pixelValue = (0, _utils.emToPixels)(value, fontSize);
|
|
221
231
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
222
|
-
return "${".concat(
|
|
232
|
+
return "${".concat(getTokenNodeForValue(propertyName, pixelValueString), "}");
|
|
223
233
|
}).join(' '), "`"));
|
|
224
234
|
} : undefined
|
|
225
235
|
});
|
|
@@ -268,9 +278,9 @@ var rule = {
|
|
|
268
278
|
rawProperty = _style$split4[0],
|
|
269
279
|
value = _style$split4[1];
|
|
270
280
|
|
|
271
|
-
var
|
|
281
|
+
var propertyName = (0, _utils.convertHyphenatedNameToCamelCase)(rawProperty);
|
|
272
282
|
|
|
273
|
-
if (!(0, _utils.isSpacingProperty)(
|
|
283
|
+
if (!(0, _utils.isSpacingProperty)(propertyName)) {
|
|
274
284
|
return;
|
|
275
285
|
} // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
276
286
|
|
|
@@ -287,16 +297,17 @@ var rule = {
|
|
|
287
297
|
|
|
288
298
|
var values = (0, _utils.getValueFromShorthand)(value);
|
|
289
299
|
values.forEach(function (val, index) {
|
|
290
|
-
if (!val && val !== 0 ||
|
|
300
|
+
if (!val && val !== 0 || !(0, _utils.isSpacingProperty)(propertyName)) {
|
|
291
301
|
return;
|
|
292
302
|
}
|
|
293
303
|
|
|
294
|
-
var
|
|
304
|
+
var isFontFamily = /fontFamily/.test(propertyName);
|
|
305
|
+
var pixelValue = isFontFamily ? val : (0, _utils.emToPixels)(val, fontSize);
|
|
295
306
|
context.report({
|
|
296
307
|
node: node,
|
|
297
308
|
messageId: 'noRawSpacingValues',
|
|
298
309
|
data: {
|
|
299
|
-
payload: "".concat(
|
|
310
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
300
311
|
},
|
|
301
312
|
fix: index === 0 ? function (fixer) {
|
|
302
313
|
var allResolvableValues = values.every(function (value) {
|
|
@@ -308,17 +319,19 @@ var rule = {
|
|
|
308
319
|
}
|
|
309
320
|
|
|
310
321
|
var replacementValue = values.map(function (value) {
|
|
311
|
-
var
|
|
322
|
+
var propertyValue = typeof value === 'string' ? value.trim() : value;
|
|
323
|
+
var pixelValue = isFontFamily ? propertyValue : (0, _utils.emToPixels)(propertyValue, fontSize);
|
|
312
324
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
313
|
-
var
|
|
314
|
-
var tokenName = spacingValueToToken[
|
|
325
|
+
var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
326
|
+
var tokenName = (0, _utils.isTypographyProperty)(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
315
327
|
|
|
316
328
|
if (!tokenName) {
|
|
317
329
|
return pixelValueString;
|
|
318
|
-
}
|
|
330
|
+
}
|
|
319
331
|
|
|
332
|
+
var replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
|
|
320
333
|
|
|
321
|
-
var replacementSubValue = '${' +
|
|
334
|
+
var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
|
|
322
335
|
return replacementSubValue;
|
|
323
336
|
}).join(' '); // get original source
|
|
324
337
|
|
|
@@ -5,13 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.emToPixels = exports.convertHyphenatedNameToCamelCase = void 0;
|
|
7
7
|
exports.findIdentifierInParentScope = findIdentifierInParentScope;
|
|
8
|
-
exports.removePixelSuffix = exports.isValidSpacingValue = exports.isSpacingProperty = exports.getValueFromShorthand = exports.getValue = exports.findParentNodeForLine = void 0;
|
|
8
|
+
exports.removePixelSuffix = exports.isValidSpacingValue = exports.isTypographyProperty = exports.isSpacingProperty = exports.getValueFromShorthand = exports.getValue = exports.findParentNodeForLine = void 0;
|
|
9
9
|
|
|
10
10
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
11
11
|
|
|
12
|
-
var
|
|
12
|
+
var typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
|
|
13
|
+
var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap'].concat(typographyProperties, [// 'width', re-enable later
|
|
13
14
|
// 'height', re-enable later
|
|
14
|
-
'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap'];
|
|
15
|
+
'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap']);
|
|
15
16
|
|
|
16
17
|
function findIdentifierInParentScope(_ref) {
|
|
17
18
|
var scope = _ref.scope,
|
|
@@ -33,14 +34,27 @@ function findIdentifierInParentScope(_ref) {
|
|
|
33
34
|
return null;
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
var isSpacingProperty = function isSpacingProperty(
|
|
37
|
-
return properties.includes(
|
|
37
|
+
var isSpacingProperty = function isSpacingProperty(propertyName) {
|
|
38
|
+
return properties.includes(propertyName);
|
|
38
39
|
};
|
|
39
40
|
|
|
40
41
|
exports.isSpacingProperty = isSpacingProperty;
|
|
41
42
|
|
|
43
|
+
var isTypographyProperty = function isTypographyProperty(propertyName) {
|
|
44
|
+
return typographyProperties.includes(propertyName);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
exports.isTypographyProperty = isTypographyProperty;
|
|
48
|
+
|
|
42
49
|
var getValueFromShorthand = function getValueFromShorthand(str) {
|
|
43
|
-
|
|
50
|
+
var valueString = String(str);
|
|
51
|
+
var fontFamily = /(sans-serif$)|(monospace$)/;
|
|
52
|
+
|
|
53
|
+
if (fontFamily.test(valueString)) {
|
|
54
|
+
return [valueString];
|
|
55
|
+
} // If we want to filter out NaN just add .filter(Boolean)
|
|
56
|
+
|
|
57
|
+
|
|
44
58
|
return String(str).trim().split(' ').filter(function (val) {
|
|
45
59
|
return val !== '';
|
|
46
60
|
}).map(removePixelSuffix);
|
|
@@ -60,6 +74,14 @@ var isFontSizeSmall = function isFontSizeSmall(node) {
|
|
|
60
74
|
return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
|
|
61
75
|
};
|
|
62
76
|
|
|
77
|
+
var isFontFamily = function isFontFamily(node) {
|
|
78
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
var isCodeFontFamily = function isCodeFontFamily(node) {
|
|
82
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
|
|
83
|
+
};
|
|
84
|
+
|
|
63
85
|
var isToken = function isToken(node) {
|
|
64
86
|
return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'token';
|
|
65
87
|
};
|
|
@@ -81,6 +103,14 @@ var getValueFromCallExpression = function getValueFromCallExpression(node, conte
|
|
|
81
103
|
return 11;
|
|
82
104
|
}
|
|
83
105
|
|
|
106
|
+
if (isFontFamily(node)) {
|
|
107
|
+
return "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (isCodeFontFamily(node)) {
|
|
111
|
+
return "'SFMono-Medium', 'SF Mono', 'Segoe UI Mono', 'Roboto Mono', 'Ubuntu Mono', Menlo, Consolas, Courier, monospace";
|
|
112
|
+
}
|
|
113
|
+
|
|
84
114
|
if (isToken(node)) {
|
|
85
115
|
var args = node.arguments;
|
|
86
116
|
var call = "${token(".concat(args.map(function (argNode) {
|
package/dist/cjs/version.json
CHANGED
|
@@ -1,43 +1,44 @@
|
|
|
1
1
|
import { callExpression, identifier, isNodeOfType, literal, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
2
2
|
import spacingScale from '@atlaskit/tokens/spacing-raw';
|
|
3
|
+
import typographyTokens from '@atlaskit/tokens/typography-raw';
|
|
3
4
|
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
4
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty,
|
|
5
|
-
|
|
6
|
-
const pixelsToRems = pixelValueString => {
|
|
7
|
-
const pixels = removePixelSuffix(pixelValueString);
|
|
8
|
-
|
|
9
|
-
if (pixels === '0' || pixels === 0) {
|
|
10
|
-
return pixels;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return `${Number(pixels) / 16}rem`;
|
|
14
|
-
};
|
|
5
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isTypographyProperty, isValidSpacingValue } from './utils';
|
|
15
6
|
/**
|
|
16
7
|
* Currently we have a wide range of experimental spacing tokens that we are testing.
|
|
17
8
|
* We only want transforms to apply to the stable scale values, not the rest.
|
|
18
9
|
* This could be removed in the future.
|
|
19
10
|
*/
|
|
20
11
|
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
const
|
|
12
|
+
const onlyScaleTokens = spacingScale.filter(token => token.name.startsWith('space.'));
|
|
13
|
+
const spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(token => [token.attributes['pixelValue'], token.name]));
|
|
14
|
+
const typographyValueToToken = Object.fromEntries(typographyTokens.map(currentToken => {
|
|
15
|
+
// Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
|
|
16
|
+
// This allows us to look up values specific to a property
|
|
17
|
+
// (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
|
|
18
|
+
const tokenGroup = currentToken.attributes.group;
|
|
19
|
+
return [tokenGroup, Object.fromEntries(typographyTokens.map(token => token.attributes.group === tokenGroup ? [token.value.replaceAll(`"`, `'`), token.name] : []).filter(token => token.length))];
|
|
20
|
+
}));
|
|
24
21
|
/**
|
|
22
|
+
* Returns a token node for a given value including fallbacks.
|
|
23
|
+
* @param propertyName camelCase CSS property
|
|
24
|
+
* @param value string representing pixel value, or font family, or number representing font weight
|
|
25
25
|
* @example
|
|
26
26
|
* ```
|
|
27
|
-
* '8px' => token('spacing.scale.100', '8px')
|
|
27
|
+
* propertyName: padding, value: '8px' => token('spacing.scale.100', '8px')
|
|
28
|
+
* propertyName: fontWeight, value: 400 => token('font.weight.regular', '400')
|
|
28
29
|
* ```
|
|
29
30
|
*/
|
|
30
31
|
|
|
31
|
-
function
|
|
32
|
-
const
|
|
33
|
-
const
|
|
32
|
+
function getTokenNodeForValue(propertyName, value) {
|
|
33
|
+
const token = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
|
|
34
|
+
const fallbackValue = propertyName === 'fontFamily' ? `"${value}"` : `'${value}'`;
|
|
34
35
|
return callExpression({
|
|
35
36
|
callee: identifier({
|
|
36
37
|
name: 'token'
|
|
37
38
|
}),
|
|
38
39
|
arguments: [literal({
|
|
39
40
|
value: `'${token !== null && token !== void 0 ? token : ''}'`
|
|
40
|
-
}), literal(
|
|
41
|
+
}), literal(fallbackValue)],
|
|
41
42
|
optional: false
|
|
42
43
|
});
|
|
43
44
|
}
|
|
@@ -120,6 +121,8 @@ const rule = {
|
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
122
123
|
|
|
124
|
+
const propertyName = node.key.name;
|
|
125
|
+
const isFontFamily = /fontFamily/.test(propertyName);
|
|
123
126
|
const value = getValue(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
124
127
|
|
|
125
128
|
if (!(value && isValidSpacingValue(value, fontSize))) {
|
|
@@ -133,33 +136,35 @@ const rule = {
|
|
|
133
136
|
}
|
|
134
137
|
|
|
135
138
|
const values = Array.isArray(value) ? value : [value]; // value is a single value so we can apply a more robust approach to our fix
|
|
139
|
+
// treat fontFamily as having one value
|
|
136
140
|
|
|
137
|
-
if (values.length === 1) {
|
|
141
|
+
if (values.length === 1 || isFontFamily) {
|
|
138
142
|
const [value] = values;
|
|
139
|
-
const pixelValue = emToPixels(value, fontSize);
|
|
143
|
+
const pixelValue = isFontFamily ? value : emToPixels(value, fontSize);
|
|
140
144
|
return context.report({
|
|
141
145
|
node,
|
|
142
146
|
messageId: 'noRawSpacingValues',
|
|
143
147
|
data: {
|
|
144
|
-
payload: `${
|
|
148
|
+
payload: `${propertyName}:${pixelValue}`
|
|
145
149
|
},
|
|
146
150
|
fix: fixer => {
|
|
147
151
|
var _node$loc;
|
|
148
152
|
|
|
149
|
-
if (
|
|
153
|
+
if (!isSpacingProperty(propertyName)) {
|
|
150
154
|
return null;
|
|
151
155
|
}
|
|
152
156
|
|
|
153
157
|
const pixelValueString = `${pixelValue}px`;
|
|
154
|
-
const
|
|
155
|
-
const tokenName = spacingValueToToken[
|
|
158
|
+
const lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
159
|
+
const tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
156
160
|
|
|
157
161
|
if (!tokenName) {
|
|
158
162
|
return null;
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
const replacementValue = getTokenNodeForValue(propertyName, lookupValue);
|
|
161
166
|
return [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({ ...node,
|
|
162
|
-
value:
|
|
167
|
+
value: replacementValue
|
|
163
168
|
}).toString())];
|
|
164
169
|
}
|
|
165
170
|
});
|
|
@@ -179,7 +184,7 @@ const rule = {
|
|
|
179
184
|
node,
|
|
180
185
|
messageId: 'noRawSpacingValues',
|
|
181
186
|
data: {
|
|
182
|
-
payload: `${
|
|
187
|
+
payload: `${propertyName}:${pixelValue}`
|
|
183
188
|
},
|
|
184
189
|
fix: index === 0 ? fixer => {
|
|
185
190
|
const allResolvableValues = values.every(value => !Number.isNaN(emToPixels(value, fontSize)));
|
|
@@ -191,7 +196,7 @@ const rule = {
|
|
|
191
196
|
return fixer.replaceText(node.value, `\`${values.map(value => {
|
|
192
197
|
const pixelValue = emToPixels(value, fontSize);
|
|
193
198
|
const pixelValueString = `${pixelValue}px`;
|
|
194
|
-
return `\${${
|
|
199
|
+
return `\${${getTokenNodeForValue(propertyName, pixelValueString)}}`;
|
|
195
200
|
}).join(' ')}\``);
|
|
196
201
|
} : undefined
|
|
197
202
|
});
|
|
@@ -228,9 +233,9 @@ const rule = {
|
|
|
228
233
|
const fontSize = getValueFromShorthand(fontSizeNode)[0];
|
|
229
234
|
cssProperties.forEach(style => {
|
|
230
235
|
const [rawProperty, value] = style.split(':');
|
|
231
|
-
const
|
|
236
|
+
const propertyName = convertHyphenatedNameToCamelCase(rawProperty);
|
|
232
237
|
|
|
233
|
-
if (!isSpacingProperty(
|
|
238
|
+
if (!isSpacingProperty(propertyName)) {
|
|
234
239
|
return;
|
|
235
240
|
} // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
236
241
|
|
|
@@ -247,16 +252,17 @@ const rule = {
|
|
|
247
252
|
|
|
248
253
|
const values = getValueFromShorthand(value);
|
|
249
254
|
values.forEach((val, index) => {
|
|
250
|
-
if (!val && val !== 0 ||
|
|
255
|
+
if (!val && val !== 0 || !isSpacingProperty(propertyName)) {
|
|
251
256
|
return;
|
|
252
257
|
}
|
|
253
258
|
|
|
254
|
-
const
|
|
259
|
+
const isFontFamily = /fontFamily/.test(propertyName);
|
|
260
|
+
const pixelValue = isFontFamily ? val : emToPixels(val, fontSize);
|
|
255
261
|
context.report({
|
|
256
262
|
node,
|
|
257
263
|
messageId: 'noRawSpacingValues',
|
|
258
264
|
data: {
|
|
259
|
-
payload: `${
|
|
265
|
+
payload: `${propertyName}:${pixelValue}`
|
|
260
266
|
},
|
|
261
267
|
fix: index === 0 ? fixer => {
|
|
262
268
|
const allResolvableValues = values.every(value => !Number.isNaN(emToPixels(value, fontSize)));
|
|
@@ -266,17 +272,19 @@ const rule = {
|
|
|
266
272
|
}
|
|
267
273
|
|
|
268
274
|
const replacementValue = values.map(value => {
|
|
269
|
-
const
|
|
275
|
+
const propertyValue = typeof value === 'string' ? value.trim() : value;
|
|
276
|
+
const pixelValue = isFontFamily ? propertyValue : emToPixels(propertyValue, fontSize);
|
|
270
277
|
const pixelValueString = `${pixelValue}px`;
|
|
271
|
-
const
|
|
272
|
-
const tokenName = spacingValueToToken[
|
|
278
|
+
const lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
279
|
+
const tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
273
280
|
|
|
274
281
|
if (!tokenName) {
|
|
275
282
|
return pixelValueString;
|
|
276
|
-
}
|
|
283
|
+
}
|
|
277
284
|
|
|
285
|
+
const replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
|
|
278
286
|
|
|
279
|
-
const replacementSubValue = '${' +
|
|
287
|
+
const replacementSubValue = '${' + replacementTokenValue.toString() + '}';
|
|
280
288
|
return replacementSubValue;
|
|
281
289
|
}).join(' '); // get original source
|
|
282
290
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
const
|
|
2
|
+
const typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
|
|
3
|
+
const properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap', ...typographyProperties, // 'width', re-enable later
|
|
3
4
|
// 'height', re-enable later
|
|
4
5
|
'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap'];
|
|
5
6
|
export function findIdentifierInParentScope({
|
|
@@ -20,11 +21,21 @@ export function findIdentifierInParentScope({
|
|
|
20
21
|
|
|
21
22
|
return null;
|
|
22
23
|
}
|
|
23
|
-
export const isSpacingProperty =
|
|
24
|
-
return properties.includes(
|
|
24
|
+
export const isSpacingProperty = propertyName => {
|
|
25
|
+
return properties.includes(propertyName);
|
|
26
|
+
};
|
|
27
|
+
export const isTypographyProperty = propertyName => {
|
|
28
|
+
return typographyProperties.includes(propertyName);
|
|
25
29
|
};
|
|
26
30
|
export const getValueFromShorthand = str => {
|
|
27
|
-
|
|
31
|
+
const valueString = String(str);
|
|
32
|
+
const fontFamily = /(sans-serif$)|(monospace$)/;
|
|
33
|
+
|
|
34
|
+
if (fontFamily.test(valueString)) {
|
|
35
|
+
return [valueString];
|
|
36
|
+
} // If we want to filter out NaN just add .filter(Boolean)
|
|
37
|
+
|
|
38
|
+
|
|
28
39
|
return String(str).trim().split(' ').filter(val => val !== '').map(removePixelSuffix);
|
|
29
40
|
};
|
|
30
41
|
|
|
@@ -34,6 +45,10 @@ const isFontSize = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(
|
|
|
34
45
|
|
|
35
46
|
const isFontSizeSmall = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
|
|
36
47
|
|
|
48
|
+
const isFontFamily = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
|
|
49
|
+
|
|
50
|
+
const isCodeFontFamily = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
|
|
51
|
+
|
|
37
52
|
const isToken = node => isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && node.callee.name === 'token';
|
|
38
53
|
|
|
39
54
|
const getValueFromCallExpression = (node, context) => {
|
|
@@ -53,6 +68,14 @@ const getValueFromCallExpression = (node, context) => {
|
|
|
53
68
|
return 11;
|
|
54
69
|
}
|
|
55
70
|
|
|
71
|
+
if (isFontFamily(node)) {
|
|
72
|
+
return `-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (isCodeFontFamily(node)) {
|
|
76
|
+
return `'SFMono-Medium', 'SF Mono', 'Segoe UI Mono', 'Roboto Mono', 'Ubuntu Mono', Menlo, Consolas, Courier, monospace`;
|
|
77
|
+
}
|
|
78
|
+
|
|
56
79
|
if (isToken(node)) {
|
|
57
80
|
const args = node.arguments;
|
|
58
81
|
const call = `\${token(${args.map(argNode => {
|
package/dist/es2019/version.json
CHANGED
|
@@ -7,48 +7,53 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
7
7
|
|
|
8
8
|
import { callExpression, identifier, isNodeOfType, literal, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
9
9
|
import spacingScale from '@atlaskit/tokens/spacing-raw';
|
|
10
|
+
import typographyTokens from '@atlaskit/tokens/typography-raw';
|
|
10
11
|
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
11
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty,
|
|
12
|
-
|
|
13
|
-
var pixelsToRems = function pixelsToRems(pixelValueString) {
|
|
14
|
-
var pixels = removePixelSuffix(pixelValueString);
|
|
15
|
-
|
|
16
|
-
if (pixels === '0' || pixels === 0) {
|
|
17
|
-
return pixels;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return "".concat(Number(pixels) / 16, "rem");
|
|
21
|
-
};
|
|
12
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isTypographyProperty, isValidSpacingValue } from './utils';
|
|
22
13
|
/**
|
|
23
14
|
* Currently we have a wide range of experimental spacing tokens that we are testing.
|
|
24
15
|
* We only want transforms to apply to the stable scale values, not the rest.
|
|
25
16
|
* This could be removed in the future.
|
|
26
17
|
*/
|
|
27
18
|
|
|
28
|
-
|
|
29
19
|
var onlyScaleTokens = spacingScale.filter(function (token) {
|
|
30
|
-
return token.name.startsWith('
|
|
20
|
+
return token.name.startsWith('space.');
|
|
31
21
|
});
|
|
32
22
|
var spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(function (token) {
|
|
33
|
-
return [token.
|
|
23
|
+
return [token.attributes['pixelValue'], token.name];
|
|
24
|
+
}));
|
|
25
|
+
var typographyValueToToken = Object.fromEntries(typographyTokens.map(function (currentToken) {
|
|
26
|
+
// Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
|
|
27
|
+
// This allows us to look up values specific to a property
|
|
28
|
+
// (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
|
|
29
|
+
var tokenGroup = currentToken.attributes.group;
|
|
30
|
+
return [tokenGroup, Object.fromEntries(typographyTokens.map(function (token) {
|
|
31
|
+
return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
|
|
32
|
+
}).filter(function (token) {
|
|
33
|
+
return token.length;
|
|
34
|
+
}))];
|
|
34
35
|
}));
|
|
35
36
|
/**
|
|
37
|
+
* Returns a token node for a given value including fallbacks.
|
|
38
|
+
* @param propertyName camelCase CSS property
|
|
39
|
+
* @param value string representing pixel value, or font family, or number representing font weight
|
|
36
40
|
* @example
|
|
37
41
|
* ```
|
|
38
|
-
* '8px' => token('spacing.scale.100', '8px')
|
|
42
|
+
* propertyName: padding, value: '8px' => token('spacing.scale.100', '8px')
|
|
43
|
+
* propertyName: fontWeight, value: 400 => token('font.weight.regular', '400')
|
|
39
44
|
* ```
|
|
40
45
|
*/
|
|
41
46
|
|
|
42
|
-
function
|
|
43
|
-
var
|
|
44
|
-
var
|
|
47
|
+
function getTokenNodeForValue(propertyName, value) {
|
|
48
|
+
var token = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
|
|
49
|
+
var fallbackValue = propertyName === 'fontFamily' ? "\"".concat(value, "\"") : "'".concat(value, "'");
|
|
45
50
|
return callExpression({
|
|
46
51
|
callee: identifier({
|
|
47
52
|
name: 'token'
|
|
48
53
|
}),
|
|
49
54
|
arguments: [literal({
|
|
50
55
|
value: "'".concat(token !== null && token !== void 0 ? token : '', "'")
|
|
51
|
-
}), literal(
|
|
56
|
+
}), literal(fallbackValue)],
|
|
52
57
|
optional: false
|
|
53
58
|
});
|
|
54
59
|
}
|
|
@@ -130,6 +135,8 @@ var rule = {
|
|
|
130
135
|
return;
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
var propertyName = node.key.name;
|
|
139
|
+
var isFontFamily = /fontFamily/.test(propertyName);
|
|
133
140
|
var value = getValue(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
134
141
|
|
|
135
142
|
if (!(value && isValidSpacingValue(value, fontSize))) {
|
|
@@ -143,35 +150,37 @@ var rule = {
|
|
|
143
150
|
}
|
|
144
151
|
|
|
145
152
|
var values = Array.isArray(value) ? value : [value]; // value is a single value so we can apply a more robust approach to our fix
|
|
153
|
+
// treat fontFamily as having one value
|
|
146
154
|
|
|
147
|
-
if (values.length === 1) {
|
|
155
|
+
if (values.length === 1 || isFontFamily) {
|
|
148
156
|
var _values = _slicedToArray(values, 1),
|
|
149
157
|
_value = _values[0];
|
|
150
158
|
|
|
151
|
-
var pixelValue = emToPixels(_value, fontSize);
|
|
159
|
+
var pixelValue = isFontFamily ? _value : emToPixels(_value, fontSize);
|
|
152
160
|
return context.report({
|
|
153
161
|
node: node,
|
|
154
162
|
messageId: 'noRawSpacingValues',
|
|
155
163
|
data: {
|
|
156
|
-
payload: "".concat(
|
|
164
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
157
165
|
},
|
|
158
166
|
fix: function fix(fixer) {
|
|
159
167
|
var _node$loc;
|
|
160
168
|
|
|
161
|
-
if (
|
|
169
|
+
if (!isSpacingProperty(propertyName)) {
|
|
162
170
|
return null;
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
166
|
-
var
|
|
167
|
-
var tokenName = spacingValueToToken[
|
|
174
|
+
var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
175
|
+
var tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
168
176
|
|
|
169
177
|
if (!tokenName) {
|
|
170
178
|
return null;
|
|
171
179
|
}
|
|
172
180
|
|
|
181
|
+
var replacementValue = getTokenNodeForValue(propertyName, lookupValue);
|
|
173
182
|
return [fixer.insertTextBefore(node, "// TODO Delete this comment after verifying spacing token -> previous value `".concat(nodeFn(node.value), "`\n").concat(' '.padStart(((_node$loc = node.loc) === null || _node$loc === void 0 ? void 0 : _node$loc.start.column) || 0))), fixer.replaceText(node, property(_objectSpread(_objectSpread({}, node), {}, {
|
|
174
|
-
value:
|
|
183
|
+
value: replacementValue
|
|
175
184
|
})).toString())];
|
|
176
185
|
}
|
|
177
186
|
});
|
|
@@ -191,7 +200,7 @@ var rule = {
|
|
|
191
200
|
node: node,
|
|
192
201
|
messageId: 'noRawSpacingValues',
|
|
193
202
|
data: {
|
|
194
|
-
payload: "".concat(
|
|
203
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
195
204
|
},
|
|
196
205
|
fix: index === 0 ? function (fixer) {
|
|
197
206
|
var allResolvableValues = values.every(function (value) {
|
|
@@ -205,7 +214,7 @@ var rule = {
|
|
|
205
214
|
return fixer.replaceText(node.value, "`".concat(values.map(function (value) {
|
|
206
215
|
var pixelValue = emToPixels(value, fontSize);
|
|
207
216
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
208
|
-
return "${".concat(
|
|
217
|
+
return "${".concat(getTokenNodeForValue(propertyName, pixelValueString), "}");
|
|
209
218
|
}).join(' '), "`"));
|
|
210
219
|
} : undefined
|
|
211
220
|
});
|
|
@@ -254,9 +263,9 @@ var rule = {
|
|
|
254
263
|
rawProperty = _style$split4[0],
|
|
255
264
|
value = _style$split4[1];
|
|
256
265
|
|
|
257
|
-
var
|
|
266
|
+
var propertyName = convertHyphenatedNameToCamelCase(rawProperty);
|
|
258
267
|
|
|
259
|
-
if (!isSpacingProperty(
|
|
268
|
+
if (!isSpacingProperty(propertyName)) {
|
|
260
269
|
return;
|
|
261
270
|
} // value is either NaN or it can't be resolved eg, em, 100% etc...
|
|
262
271
|
|
|
@@ -273,16 +282,17 @@ var rule = {
|
|
|
273
282
|
|
|
274
283
|
var values = getValueFromShorthand(value);
|
|
275
284
|
values.forEach(function (val, index) {
|
|
276
|
-
if (!val && val !== 0 ||
|
|
285
|
+
if (!val && val !== 0 || !isSpacingProperty(propertyName)) {
|
|
277
286
|
return;
|
|
278
287
|
}
|
|
279
288
|
|
|
280
|
-
var
|
|
289
|
+
var isFontFamily = /fontFamily/.test(propertyName);
|
|
290
|
+
var pixelValue = isFontFamily ? val : emToPixels(val, fontSize);
|
|
281
291
|
context.report({
|
|
282
292
|
node: node,
|
|
283
293
|
messageId: 'noRawSpacingValues',
|
|
284
294
|
data: {
|
|
285
|
-
payload: "".concat(
|
|
295
|
+
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
286
296
|
},
|
|
287
297
|
fix: index === 0 ? function (fixer) {
|
|
288
298
|
var allResolvableValues = values.every(function (value) {
|
|
@@ -294,17 +304,19 @@ var rule = {
|
|
|
294
304
|
}
|
|
295
305
|
|
|
296
306
|
var replacementValue = values.map(function (value) {
|
|
297
|
-
var
|
|
307
|
+
var propertyValue = typeof value === 'string' ? value.trim() : value;
|
|
308
|
+
var pixelValue = isFontFamily ? propertyValue : emToPixels(propertyValue, fontSize);
|
|
298
309
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
299
|
-
var
|
|
300
|
-
var tokenName = spacingValueToToken[
|
|
310
|
+
var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
|
|
311
|
+
var tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
|
|
301
312
|
|
|
302
313
|
if (!tokenName) {
|
|
303
314
|
return pixelValueString;
|
|
304
|
-
}
|
|
315
|
+
}
|
|
305
316
|
|
|
317
|
+
var replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
|
|
306
318
|
|
|
307
|
-
var replacementSubValue = '${' +
|
|
319
|
+
var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
|
|
308
320
|
return replacementSubValue;
|
|
309
321
|
}).join(' '); // get original source
|
|
310
322
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
var
|
|
2
|
+
var typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
|
|
3
|
+
var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap'].concat(typographyProperties, [// 'width', re-enable later
|
|
3
4
|
// 'height', re-enable later
|
|
4
|
-
'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap'];
|
|
5
|
+
'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap']);
|
|
5
6
|
export function findIdentifierInParentScope(_ref) {
|
|
6
7
|
var scope = _ref.scope,
|
|
7
8
|
identifierName = _ref.identifierName;
|
|
@@ -21,11 +22,21 @@ export function findIdentifierInParentScope(_ref) {
|
|
|
21
22
|
|
|
22
23
|
return null;
|
|
23
24
|
}
|
|
24
|
-
export var isSpacingProperty = function isSpacingProperty(
|
|
25
|
-
return properties.includes(
|
|
25
|
+
export var isSpacingProperty = function isSpacingProperty(propertyName) {
|
|
26
|
+
return properties.includes(propertyName);
|
|
27
|
+
};
|
|
28
|
+
export var isTypographyProperty = function isTypographyProperty(propertyName) {
|
|
29
|
+
return typographyProperties.includes(propertyName);
|
|
26
30
|
};
|
|
27
31
|
export var getValueFromShorthand = function getValueFromShorthand(str) {
|
|
28
|
-
|
|
32
|
+
var valueString = String(str);
|
|
33
|
+
var fontFamily = /(sans-serif$)|(monospace$)/;
|
|
34
|
+
|
|
35
|
+
if (fontFamily.test(valueString)) {
|
|
36
|
+
return [valueString];
|
|
37
|
+
} // If we want to filter out NaN just add .filter(Boolean)
|
|
38
|
+
|
|
39
|
+
|
|
29
40
|
return String(str).trim().split(' ').filter(function (val) {
|
|
30
41
|
return val !== '';
|
|
31
42
|
}).map(removePixelSuffix);
|
|
@@ -43,6 +54,14 @@ var isFontSizeSmall = function isFontSizeSmall(node) {
|
|
|
43
54
|
return isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
|
|
44
55
|
};
|
|
45
56
|
|
|
57
|
+
var isFontFamily = function isFontFamily(node) {
|
|
58
|
+
return isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var isCodeFontFamily = function isCodeFontFamily(node) {
|
|
62
|
+
return isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
|
|
63
|
+
};
|
|
64
|
+
|
|
46
65
|
var isToken = function isToken(node) {
|
|
47
66
|
return isNodeOfType(node, 'CallExpression') && isNodeOfType(node.callee, 'Identifier') && node.callee.name === 'token';
|
|
48
67
|
};
|
|
@@ -64,6 +83,14 @@ var getValueFromCallExpression = function getValueFromCallExpression(node, conte
|
|
|
64
83
|
return 11;
|
|
65
84
|
}
|
|
66
85
|
|
|
86
|
+
if (isFontFamily(node)) {
|
|
87
|
+
return "-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif";
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (isCodeFontFamily(node)) {
|
|
91
|
+
return "'SFMono-Medium', 'SF Mono', 'Segoe UI Mono', 'Roboto Mono', 'Ubuntu Mono', Menlo, Consolas, Courier, monospace";
|
|
92
|
+
}
|
|
93
|
+
|
|
67
94
|
if (isToken(node)) {
|
|
68
95
|
var args = node.arguments;
|
|
69
96
|
var call = "${token(".concat(args.map(function (argNode) {
|
package/dist/esm/version.json
CHANGED
|
@@ -4,7 +4,8 @@ export declare function findIdentifierInParentScope({ scope, identifierName, }:
|
|
|
4
4
|
scope: Scope.Scope;
|
|
5
5
|
identifierName: string;
|
|
6
6
|
}): Scope.Variable | null;
|
|
7
|
-
export declare const isSpacingProperty: (
|
|
7
|
+
export declare const isSpacingProperty: (propertyName: string) => boolean;
|
|
8
|
+
export declare const isTypographyProperty: (propertyName: string) => boolean;
|
|
8
9
|
export declare const getValueFromShorthand: (str: unknown) => any[];
|
|
9
10
|
export declare const getValue: (node: EslintNode, context: Rule.RuleContext) => string | number | any[] | null | undefined;
|
|
10
11
|
export declare const emToPixels: <T extends unknown>(value: T, fontSize: number | null | undefined) => number | T | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/eslint-plugin-design-system",
|
|
3
3
|
"description": "The essential plugin for use with the Atlassian Design System.",
|
|
4
|
-
"version": "4.13.
|
|
4
|
+
"version": "4.13.7",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|