@atlaskit/eslint-plugin-design-system 4.13.6 → 4.13.8

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 4.13.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f4c5d7db7aa`](https://bitbucket.org/atlassian/atlassian-frontend/commits/f4c5d7db7aa) - Updates fix for `ensure-design-token-usage-spacing` to ensure fixes are not applied erroneously.
8
+
9
+ ## 4.13.7
10
+
11
+ ### Patch Changes
12
+
13
+ - [`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
14
+
3
15
  ## 4.13.6
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");
@@ -35,22 +37,38 @@ var onlyScaleTokens = _spacingRaw.default.filter(function (token) {
35
37
  var spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(function (token) {
36
38
  return [token.attributes['pixelValue'], token.name];
37
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
+ }))];
50
+ }));
38
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
39
55
  * @example
40
56
  * ```
41
- * '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')
42
59
  * ```
43
60
  */
44
61
 
45
- function pixelValueToSpacingTokenNode(pixelValueString) {
46
- var token = spacingValueToToken[pixelValueString];
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, "'");
47
65
  return (0, _eslintCodemodUtils.callExpression)({
48
66
  callee: (0, _eslintCodemodUtils.identifier)({
49
67
  name: 'token'
50
68
  }),
51
69
  arguments: [(0, _eslintCodemodUtils.literal)({
52
70
  value: "'".concat(token !== null && token !== void 0 ? token : '', "'")
53
- }), (0, _eslintCodemodUtils.literal)("'".concat(pixelValueString, "'"))],
71
+ }), (0, _eslintCodemodUtils.literal)(fallbackValue)],
54
72
  optional: false
55
73
  });
56
74
  }
@@ -92,7 +110,7 @@ var rule = {
92
110
 
93
111
  return node.key.name === 'fontSize';
94
112
  });
95
- var fontSizeValue = (0, _utils.getValue)( // @ts-ignore
113
+ var fontSizeValue = (0, _utils.getValue)( // @ts-expect-error
96
114
  (0, _eslintCodemodUtils.isNodeOfType)(fontSizeNode, 'Property') && fontSizeNode.value, context);
97
115
  var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
98
116
 
@@ -132,6 +150,8 @@ var rule = {
132
150
  return;
133
151
  }
134
152
 
153
+ var propertyName = node.key.name;
154
+ var isFontFamily = /fontFamily/.test(propertyName);
135
155
  var value = (0, _utils.getValue)(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
136
156
 
137
157
  if (!(value && (0, _utils.isValidSpacingValue)(value, fontSize))) {
@@ -145,34 +165,37 @@ var rule = {
145
165
  }
146
166
 
147
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
148
169
 
149
- if (values.length === 1) {
170
+ if (values.length === 1 || isFontFamily) {
150
171
  var _values = (0, _slicedToArray2.default)(values, 1),
151
172
  _value = _values[0];
152
173
 
153
- var pixelValue = (0, _utils.emToPixels)(_value, fontSize);
174
+ var pixelValue = isFontFamily ? _value : (0, _utils.emToPixels)(_value, fontSize);
154
175
  return context.report({
155
176
  node: node,
156
177
  messageId: 'noRawSpacingValues',
157
178
  data: {
158
- payload: "".concat(node.key.name, ":").concat(pixelValue)
179
+ payload: "".concat(propertyName, ":").concat(pixelValue)
159
180
  },
160
181
  fix: function fix(fixer) {
161
182
  var _node$loc;
162
183
 
163
- if (!/padding|margin|gap/.test(node.key.name)) {
184
+ if (!(0, _utils.isSpacingProperty)(propertyName)) {
164
185
  return null;
165
186
  }
166
187
 
167
188
  var pixelValueString = "".concat(pixelValue, "px");
168
- var tokenName = spacingValueToToken[pixelValueString];
189
+ var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
190
+ var tokenName = (0, _utils.isTypographyProperty)(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
169
191
 
170
192
  if (!tokenName) {
171
193
  return null;
172
194
  }
173
195
 
196
+ var replacementValue = getTokenNodeForValue(propertyName, lookupValue);
174
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), {}, {
175
- value: pixelValueToSpacingTokenNode(pixelValueString)
198
+ value: replacementValue
176
199
  })).toString())];
177
200
  }
178
201
  });
@@ -192,7 +215,7 @@ var rule = {
192
215
  node: node,
193
216
  messageId: 'noRawSpacingValues',
194
217
  data: {
195
- payload: "".concat(node.key.name, ":").concat(pixelValue)
218
+ payload: "".concat(propertyName, ":").concat(pixelValue)
196
219
  },
197
220
  fix: index === 0 ? function (fixer) {
198
221
  var allResolvableValues = values.every(function (value) {
@@ -206,7 +229,7 @@ var rule = {
206
229
  return fixer.replaceText(node.value, "`".concat(values.map(function (value) {
207
230
  var pixelValue = (0, _utils.emToPixels)(value, fontSize);
208
231
  var pixelValueString = "".concat(pixelValue, "px");
209
- return "${".concat(pixelValueToSpacingTokenNode(pixelValueString), "}");
232
+ return "${".concat(getTokenNodeForValue(propertyName, pixelValueString), "}");
210
233
  }).join(' '), "`"));
211
234
  } : undefined
212
235
  });
@@ -255,9 +278,9 @@ var rule = {
255
278
  rawProperty = _style$split4[0],
256
279
  value = _style$split4[1];
257
280
 
258
- var property = (0, _utils.convertHyphenatedNameToCamelCase)(rawProperty);
281
+ var propertyName = (0, _utils.convertHyphenatedNameToCamelCase)(rawProperty);
259
282
 
260
- if (!(0, _utils.isSpacingProperty)(property)) {
283
+ if (!(0, _utils.isSpacingProperty)(propertyName)) {
261
284
  return;
262
285
  } // value is either NaN or it can't be resolved eg, em, 100% etc...
263
286
 
@@ -274,16 +297,17 @@ var rule = {
274
297
 
275
298
  var values = (0, _utils.getValueFromShorthand)(value);
276
299
  values.forEach(function (val, index) {
277
- if (!val && val !== 0 || !/padding|margin|gap/.test(rawProperty)) {
300
+ if (!val && val !== 0 || !(0, _utils.isSpacingProperty)(propertyName)) {
278
301
  return;
279
302
  }
280
303
 
281
- var pixelValue = (0, _utils.emToPixels)(val, fontSize);
304
+ var isFontFamily = /fontFamily/.test(propertyName);
305
+ var pixelValue = isFontFamily ? val : (0, _utils.emToPixels)(val, fontSize);
282
306
  context.report({
283
307
  node: node,
284
308
  messageId: 'noRawSpacingValues',
285
309
  data: {
286
- payload: "".concat(property, ":").concat(pixelValue)
310
+ payload: "".concat(propertyName, ":").concat(pixelValue)
287
311
  },
288
312
  fix: index === 0 ? function (fixer) {
289
313
  var allResolvableValues = values.every(function (value) {
@@ -295,24 +319,33 @@ var rule = {
295
319
  }
296
320
 
297
321
  var replacementValue = values.map(function (value) {
298
- var pixelValue = (0, _utils.emToPixels)(value, fontSize);
322
+ var propertyValue = typeof value === 'string' ? value.trim() : value;
323
+ var pixelValue = isFontFamily ? propertyValue : (0, _utils.emToPixels)(propertyValue, fontSize);
299
324
  var pixelValueString = "".concat(pixelValue, "px");
300
- var tokenName = spacingValueToToken[pixelValueString];
325
+ var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
326
+ var tokenName = (0, _utils.isTypographyProperty)(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
301
327
 
302
328
  if (!tokenName) {
303
329
  return pixelValueString;
304
- } // ${token('...', '...')}
330
+ }
305
331
 
332
+ var replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
306
333
 
307
- var replacementSubValue = '${' + pixelValueToSpacingTokenNode(pixelValueString).toString() + '}';
334
+ var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
308
335
  return replacementSubValue;
309
336
  }).join(' '); // get original source
310
337
 
311
338
  var textForSource = context.getSourceCode().getText(node.quasi); // find `<property>: ...;` in original
312
339
 
313
- var searchRegExp = new RegExp("".concat(rawProperty, ".+?;"), 'g'); // replace property:val with new property:val
340
+ var searchRegExp = new RegExp(style, 'g'); // replace property:val with new property:val
341
+
342
+ var replacement = textForSource.replace(searchRegExp, // padding: ${gridSize()}px;
343
+ "".concat(rawProperty, ": ").concat(replacementValue));
344
+
345
+ if (!replacement) {
346
+ return [];
347
+ }
314
348
 
315
- var replacement = textForSource.replace(searchRegExp, "".concat(rawProperty, ": ").concat(replacementValue, ";"));
316
349
  return [fixer.insertTextBefore(parentNode, "// TODO Delete this comment after verifying spacing token -> previous value `".concat(value.trim(), "`\n")), fixer.replaceText(node.quasi, replacement)];
317
350
  } : undefined
318
351
  });
@@ -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 properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap', 'fontSize', 'lineHeight', // 'width', re-enable later
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(prop) {
37
- return properties.includes(prop);
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
- // If we want to filter out NaN just add .filter(Boolean)
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) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
- "version": "4.13.6",
3
+ "version": "4.13.8",
4
4
  "sideEffects": false
5
5
  }
@@ -1,7 +1,9 @@
1
+ /* eslint-disable @atlassian/tangerine/import/entry-points */
1
2
  import { callExpression, identifier, isNodeOfType, literal, node as nodeFn, property } from 'eslint-codemod-utils';
2
3
  import spacingScale from '@atlaskit/tokens/spacing-raw';
4
+ import typographyTokens from '@atlaskit/tokens/typography-raw';
3
5
  import { isDecendantOfGlobalToken } from '../utils/is-node';
4
- import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isValidSpacingValue } from './utils';
6
+ import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isTypographyProperty, isValidSpacingValue } from './utils';
5
7
  /**
6
8
  * Currently we have a wide range of experimental spacing tokens that we are testing.
7
9
  * We only want transforms to apply to the stable scale values, not the rest.
@@ -10,22 +12,34 @@ import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, ge
10
12
 
11
13
  const onlyScaleTokens = spacingScale.filter(token => token.name.startsWith('space.'));
12
14
  const spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(token => [token.attributes['pixelValue'], token.name]));
15
+ const typographyValueToToken = Object.fromEntries(typographyTokens.map(currentToken => {
16
+ // Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
17
+ // This allows us to look up values specific to a property
18
+ // (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
19
+ const tokenGroup = currentToken.attributes.group;
20
+ return [tokenGroup, Object.fromEntries(typographyTokens.map(token => token.attributes.group === tokenGroup ? [token.value.replaceAll(`"`, `'`), token.name] : []).filter(token => token.length))];
21
+ }));
13
22
  /**
23
+ * Returns a token node for a given value including fallbacks.
24
+ * @param propertyName camelCase CSS property
25
+ * @param value string representing pixel value, or font family, or number representing font weight
14
26
  * @example
15
27
  * ```
16
- * '8px' => token('spacing.scale.100', '8px')
28
+ * propertyName: padding, value: '8px' => token('spacing.scale.100', '8px')
29
+ * propertyName: fontWeight, value: 400 => token('font.weight.regular', '400')
17
30
  * ```
18
31
  */
19
32
 
20
- function pixelValueToSpacingTokenNode(pixelValueString) {
21
- const token = spacingValueToToken[pixelValueString];
33
+ function getTokenNodeForValue(propertyName, value) {
34
+ const token = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
35
+ const fallbackValue = propertyName === 'fontFamily' ? `"${value}"` : `'${value}'`;
22
36
  return callExpression({
23
37
  callee: identifier({
24
38
  name: 'token'
25
39
  }),
26
40
  arguments: [literal({
27
41
  value: `'${token !== null && token !== void 0 ? token : ''}'`
28
- }), literal(`'${pixelValueString}'`)],
42
+ }), literal(fallbackValue)],
29
43
  optional: false
30
44
  });
31
45
  }
@@ -68,7 +82,7 @@ const rule = {
68
82
 
69
83
  return node.key.name === 'fontSize';
70
84
  });
71
- const fontSizeValue = getValue( // @ts-ignore
85
+ const fontSizeValue = getValue( // @ts-expect-error
72
86
  isNodeOfType(fontSizeNode, 'Property') && fontSizeNode.value, context);
73
87
  const fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
74
88
 
@@ -108,6 +122,8 @@ const rule = {
108
122
  return;
109
123
  }
110
124
 
125
+ const propertyName = node.key.name;
126
+ const isFontFamily = /fontFamily/.test(propertyName);
111
127
  const value = getValue(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
112
128
 
113
129
  if (!(value && isValidSpacingValue(value, fontSize))) {
@@ -121,32 +137,35 @@ const rule = {
121
137
  }
122
138
 
123
139
  const values = Array.isArray(value) ? value : [value]; // value is a single value so we can apply a more robust approach to our fix
140
+ // treat fontFamily as having one value
124
141
 
125
- if (values.length === 1) {
142
+ if (values.length === 1 || isFontFamily) {
126
143
  const [value] = values;
127
- const pixelValue = emToPixels(value, fontSize);
144
+ const pixelValue = isFontFamily ? value : emToPixels(value, fontSize);
128
145
  return context.report({
129
146
  node,
130
147
  messageId: 'noRawSpacingValues',
131
148
  data: {
132
- payload: `${node.key.name}:${pixelValue}`
149
+ payload: `${propertyName}:${pixelValue}`
133
150
  },
134
151
  fix: fixer => {
135
152
  var _node$loc;
136
153
 
137
- if (!/padding|margin|gap/.test(node.key.name)) {
154
+ if (!isSpacingProperty(propertyName)) {
138
155
  return null;
139
156
  }
140
157
 
141
158
  const pixelValueString = `${pixelValue}px`;
142
- const tokenName = spacingValueToToken[pixelValueString];
159
+ const lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
160
+ const tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
143
161
 
144
162
  if (!tokenName) {
145
163
  return null;
146
164
  }
147
165
 
166
+ const replacementValue = getTokenNodeForValue(propertyName, lookupValue);
148
167
  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,
149
- value: pixelValueToSpacingTokenNode(pixelValueString)
168
+ value: replacementValue
150
169
  }).toString())];
151
170
  }
152
171
  });
@@ -166,7 +185,7 @@ const rule = {
166
185
  node,
167
186
  messageId: 'noRawSpacingValues',
168
187
  data: {
169
- payload: `${node.key.name}:${pixelValue}`
188
+ payload: `${propertyName}:${pixelValue}`
170
189
  },
171
190
  fix: index === 0 ? fixer => {
172
191
  const allResolvableValues = values.every(value => !Number.isNaN(emToPixels(value, fontSize)));
@@ -178,7 +197,7 @@ const rule = {
178
197
  return fixer.replaceText(node.value, `\`${values.map(value => {
179
198
  const pixelValue = emToPixels(value, fontSize);
180
199
  const pixelValueString = `${pixelValue}px`;
181
- return `\${${pixelValueToSpacingTokenNode(pixelValueString)}}`;
200
+ return `\${${getTokenNodeForValue(propertyName, pixelValueString)}}`;
182
201
  }).join(' ')}\``);
183
202
  } : undefined
184
203
  });
@@ -215,9 +234,9 @@ const rule = {
215
234
  const fontSize = getValueFromShorthand(fontSizeNode)[0];
216
235
  cssProperties.forEach(style => {
217
236
  const [rawProperty, value] = style.split(':');
218
- const property = convertHyphenatedNameToCamelCase(rawProperty);
237
+ const propertyName = convertHyphenatedNameToCamelCase(rawProperty);
219
238
 
220
- if (!isSpacingProperty(property)) {
239
+ if (!isSpacingProperty(propertyName)) {
221
240
  return;
222
241
  } // value is either NaN or it can't be resolved eg, em, 100% etc...
223
242
 
@@ -234,16 +253,17 @@ const rule = {
234
253
 
235
254
  const values = getValueFromShorthand(value);
236
255
  values.forEach((val, index) => {
237
- if (!val && val !== 0 || !/padding|margin|gap/.test(rawProperty)) {
256
+ if (!val && val !== 0 || !isSpacingProperty(propertyName)) {
238
257
  return;
239
258
  }
240
259
 
241
- const pixelValue = emToPixels(val, fontSize);
260
+ const isFontFamily = /fontFamily/.test(propertyName);
261
+ const pixelValue = isFontFamily ? val : emToPixels(val, fontSize);
242
262
  context.report({
243
263
  node,
244
264
  messageId: 'noRawSpacingValues',
245
265
  data: {
246
- payload: `${property}:${pixelValue}`
266
+ payload: `${propertyName}:${pixelValue}`
247
267
  },
248
268
  fix: index === 0 ? fixer => {
249
269
  const allResolvableValues = values.every(value => !Number.isNaN(emToPixels(value, fontSize)));
@@ -253,24 +273,33 @@ const rule = {
253
273
  }
254
274
 
255
275
  const replacementValue = values.map(value => {
256
- const pixelValue = emToPixels(value, fontSize);
276
+ const propertyValue = typeof value === 'string' ? value.trim() : value;
277
+ const pixelValue = isFontFamily ? propertyValue : emToPixels(propertyValue, fontSize);
257
278
  const pixelValueString = `${pixelValue}px`;
258
- const tokenName = spacingValueToToken[pixelValueString];
279
+ const lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
280
+ const tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
259
281
 
260
282
  if (!tokenName) {
261
283
  return pixelValueString;
262
- } // ${token('...', '...')}
284
+ }
263
285
 
286
+ const replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
264
287
 
265
- const replacementSubValue = '${' + pixelValueToSpacingTokenNode(pixelValueString).toString() + '}';
288
+ const replacementSubValue = '${' + replacementTokenValue.toString() + '}';
266
289
  return replacementSubValue;
267
290
  }).join(' '); // get original source
268
291
 
269
292
  const textForSource = context.getSourceCode().getText(node.quasi); // find `<property>: ...;` in original
270
293
 
271
- const searchRegExp = new RegExp(`${rawProperty}.+?;`, 'g'); // replace property:val with new property:val
294
+ const searchRegExp = new RegExp(style, 'g'); // replace property:val with new property:val
295
+
296
+ const replacement = textForSource.replace(searchRegExp, // padding: ${gridSize()}px;
297
+ `${rawProperty}: ${replacementValue}`);
298
+
299
+ if (!replacement) {
300
+ return [];
301
+ }
272
302
 
273
- const replacement = textForSource.replace(searchRegExp, `${rawProperty}: ${replacementValue};`);
274
303
  return [fixer.insertTextBefore(parentNode, `// TODO Delete this comment after verifying spacing token -> previous value \`${value.trim()}\`\n`), fixer.replaceText(node.quasi, replacement)];
275
304
  } : undefined
276
305
  });
@@ -1,5 +1,6 @@
1
1
  import { isNodeOfType } from 'eslint-codemod-utils';
2
- const properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap', 'fontSize', 'lineHeight', // 'width', re-enable later
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 = prop => {
24
- return properties.includes(prop);
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
- // If we want to filter out NaN just add .filter(Boolean)
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 => {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
- "version": "4.13.6",
3
+ "version": "4.13.8",
4
4
  "sideEffects": false
5
5
  }
@@ -5,10 +5,12 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
5
5
 
6
6
  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) { _defineProperty(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; }
7
7
 
8
+ /* eslint-disable @atlassian/tangerine/import/entry-points */
8
9
  import { callExpression, identifier, isNodeOfType, literal, node as nodeFn, property } from 'eslint-codemod-utils';
9
10
  import spacingScale from '@atlaskit/tokens/spacing-raw';
11
+ import typographyTokens from '@atlaskit/tokens/typography-raw';
10
12
  import { isDecendantOfGlobalToken } from '../utils/is-node';
11
- import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isValidSpacingValue } from './utils';
13
+ import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, getValue, getValueFromShorthand, isSpacingProperty, isTypographyProperty, isValidSpacingValue } from './utils';
12
14
  /**
13
15
  * Currently we have a wide range of experimental spacing tokens that we are testing.
14
16
  * We only want transforms to apply to the stable scale values, not the rest.
@@ -21,22 +23,38 @@ var onlyScaleTokens = spacingScale.filter(function (token) {
21
23
  var spacingValueToToken = Object.fromEntries(onlyScaleTokens.map(function (token) {
22
24
  return [token.attributes['pixelValue'], token.name];
23
25
  }));
26
+ var typographyValueToToken = Object.fromEntries(typographyTokens.map(function (currentToken) {
27
+ // Group tokens by property name (e.g. fontSize, fontFamily, lineHeight)
28
+ // This allows us to look up values specific to a property
29
+ // (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
30
+ var tokenGroup = currentToken.attributes.group;
31
+ return [tokenGroup, Object.fromEntries(typographyTokens.map(function (token) {
32
+ return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
33
+ }).filter(function (token) {
34
+ return token.length;
35
+ }))];
36
+ }));
24
37
  /**
38
+ * Returns a token node for a given value including fallbacks.
39
+ * @param propertyName camelCase CSS property
40
+ * @param value string representing pixel value, or font family, or number representing font weight
25
41
  * @example
26
42
  * ```
27
- * '8px' => token('spacing.scale.100', '8px')
43
+ * propertyName: padding, value: '8px' => token('spacing.scale.100', '8px')
44
+ * propertyName: fontWeight, value: 400 => token('font.weight.regular', '400')
28
45
  * ```
29
46
  */
30
47
 
31
- function pixelValueToSpacingTokenNode(pixelValueString) {
32
- var token = spacingValueToToken[pixelValueString];
48
+ function getTokenNodeForValue(propertyName, value) {
49
+ var token = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][value] : spacingValueToToken[value];
50
+ var fallbackValue = propertyName === 'fontFamily' ? "\"".concat(value, "\"") : "'".concat(value, "'");
33
51
  return callExpression({
34
52
  callee: identifier({
35
53
  name: 'token'
36
54
  }),
37
55
  arguments: [literal({
38
56
  value: "'".concat(token !== null && token !== void 0 ? token : '', "'")
39
- }), literal("'".concat(pixelValueString, "'"))],
57
+ }), literal(fallbackValue)],
40
58
  optional: false
41
59
  });
42
60
  }
@@ -78,7 +96,7 @@ var rule = {
78
96
 
79
97
  return node.key.name === 'fontSize';
80
98
  });
81
- var fontSizeValue = getValue( // @ts-ignore
99
+ var fontSizeValue = getValue( // @ts-expect-error
82
100
  isNodeOfType(fontSizeNode, 'Property') && fontSizeNode.value, context);
83
101
  var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
84
102
 
@@ -118,6 +136,8 @@ var rule = {
118
136
  return;
119
137
  }
120
138
 
139
+ var propertyName = node.key.name;
140
+ var isFontFamily = /fontFamily/.test(propertyName);
121
141
  var value = getValue(node.value, context); // value is either NaN or it can't be resolved eg, em, 100% etc...
122
142
 
123
143
  if (!(value && isValidSpacingValue(value, fontSize))) {
@@ -131,34 +151,37 @@ var rule = {
131
151
  }
132
152
 
133
153
  var values = Array.isArray(value) ? value : [value]; // value is a single value so we can apply a more robust approach to our fix
154
+ // treat fontFamily as having one value
134
155
 
135
- if (values.length === 1) {
156
+ if (values.length === 1 || isFontFamily) {
136
157
  var _values = _slicedToArray(values, 1),
137
158
  _value = _values[0];
138
159
 
139
- var pixelValue = emToPixels(_value, fontSize);
160
+ var pixelValue = isFontFamily ? _value : emToPixels(_value, fontSize);
140
161
  return context.report({
141
162
  node: node,
142
163
  messageId: 'noRawSpacingValues',
143
164
  data: {
144
- payload: "".concat(node.key.name, ":").concat(pixelValue)
165
+ payload: "".concat(propertyName, ":").concat(pixelValue)
145
166
  },
146
167
  fix: function fix(fixer) {
147
168
  var _node$loc;
148
169
 
149
- if (!/padding|margin|gap/.test(node.key.name)) {
170
+ if (!isSpacingProperty(propertyName)) {
150
171
  return null;
151
172
  }
152
173
 
153
174
  var pixelValueString = "".concat(pixelValue, "px");
154
- var tokenName = spacingValueToToken[pixelValueString];
175
+ var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
176
+ var tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
155
177
 
156
178
  if (!tokenName) {
157
179
  return null;
158
180
  }
159
181
 
182
+ var replacementValue = getTokenNodeForValue(propertyName, lookupValue);
160
183
  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), {}, {
161
- value: pixelValueToSpacingTokenNode(pixelValueString)
184
+ value: replacementValue
162
185
  })).toString())];
163
186
  }
164
187
  });
@@ -178,7 +201,7 @@ var rule = {
178
201
  node: node,
179
202
  messageId: 'noRawSpacingValues',
180
203
  data: {
181
- payload: "".concat(node.key.name, ":").concat(pixelValue)
204
+ payload: "".concat(propertyName, ":").concat(pixelValue)
182
205
  },
183
206
  fix: index === 0 ? function (fixer) {
184
207
  var allResolvableValues = values.every(function (value) {
@@ -192,7 +215,7 @@ var rule = {
192
215
  return fixer.replaceText(node.value, "`".concat(values.map(function (value) {
193
216
  var pixelValue = emToPixels(value, fontSize);
194
217
  var pixelValueString = "".concat(pixelValue, "px");
195
- return "${".concat(pixelValueToSpacingTokenNode(pixelValueString), "}");
218
+ return "${".concat(getTokenNodeForValue(propertyName, pixelValueString), "}");
196
219
  }).join(' '), "`"));
197
220
  } : undefined
198
221
  });
@@ -241,9 +264,9 @@ var rule = {
241
264
  rawProperty = _style$split4[0],
242
265
  value = _style$split4[1];
243
266
 
244
- var property = convertHyphenatedNameToCamelCase(rawProperty);
267
+ var propertyName = convertHyphenatedNameToCamelCase(rawProperty);
245
268
 
246
- if (!isSpacingProperty(property)) {
269
+ if (!isSpacingProperty(propertyName)) {
247
270
  return;
248
271
  } // value is either NaN or it can't be resolved eg, em, 100% etc...
249
272
 
@@ -260,16 +283,17 @@ var rule = {
260
283
 
261
284
  var values = getValueFromShorthand(value);
262
285
  values.forEach(function (val, index) {
263
- if (!val && val !== 0 || !/padding|margin|gap/.test(rawProperty)) {
286
+ if (!val && val !== 0 || !isSpacingProperty(propertyName)) {
264
287
  return;
265
288
  }
266
289
 
267
- var pixelValue = emToPixels(val, fontSize);
290
+ var isFontFamily = /fontFamily/.test(propertyName);
291
+ var pixelValue = isFontFamily ? val : emToPixels(val, fontSize);
268
292
  context.report({
269
293
  node: node,
270
294
  messageId: 'noRawSpacingValues',
271
295
  data: {
272
- payload: "".concat(property, ":").concat(pixelValue)
296
+ payload: "".concat(propertyName, ":").concat(pixelValue)
273
297
  },
274
298
  fix: index === 0 ? function (fixer) {
275
299
  var allResolvableValues = values.every(function (value) {
@@ -281,24 +305,33 @@ var rule = {
281
305
  }
282
306
 
283
307
  var replacementValue = values.map(function (value) {
284
- var pixelValue = emToPixels(value, fontSize);
308
+ var propertyValue = typeof value === 'string' ? value.trim() : value;
309
+ var pixelValue = isFontFamily ? propertyValue : emToPixels(propertyValue, fontSize);
285
310
  var pixelValueString = "".concat(pixelValue, "px");
286
- var tokenName = spacingValueToToken[pixelValueString];
311
+ var lookupValue = /fontWeight|fontFamily/.test(propertyName) ? pixelValue : pixelValueString;
312
+ var tokenName = isTypographyProperty(propertyName) ? typographyValueToToken[propertyName][lookupValue] : spacingValueToToken[lookupValue];
287
313
 
288
314
  if (!tokenName) {
289
315
  return pixelValueString;
290
- } // ${token('...', '...')}
316
+ }
291
317
 
318
+ var replacementTokenValue = getTokenNodeForValue(propertyName, lookupValue); // ${token('...', '...')}
292
319
 
293
- var replacementSubValue = '${' + pixelValueToSpacingTokenNode(pixelValueString).toString() + '}';
320
+ var replacementSubValue = '${' + replacementTokenValue.toString() + '}';
294
321
  return replacementSubValue;
295
322
  }).join(' '); // get original source
296
323
 
297
324
  var textForSource = context.getSourceCode().getText(node.quasi); // find `<property>: ...;` in original
298
325
 
299
- var searchRegExp = new RegExp("".concat(rawProperty, ".+?;"), 'g'); // replace property:val with new property:val
326
+ var searchRegExp = new RegExp(style, 'g'); // replace property:val with new property:val
327
+
328
+ var replacement = textForSource.replace(searchRegExp, // padding: ${gridSize()}px;
329
+ "".concat(rawProperty, ": ").concat(replacementValue));
330
+
331
+ if (!replacement) {
332
+ return [];
333
+ }
300
334
 
301
- var replacement = textForSource.replace(searchRegExp, "".concat(rawProperty, ": ").concat(replacementValue, ";"));
302
335
  return [fixer.insertTextBefore(parentNode, "// TODO Delete this comment after verifying spacing token -> previous value `".concat(value.trim(), "`\n")), fixer.replaceText(node.quasi, replacement)];
303
336
  } : undefined
304
337
  });
@@ -1,7 +1,8 @@
1
1
  import { isNodeOfType } from 'eslint-codemod-utils';
2
- var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'margin', 'gap', 'fontSize', 'lineHeight', // 'width', re-enable later
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(prop) {
25
- return properties.includes(prop);
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
- // If we want to filter out NaN just add .filter(Boolean)
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) {
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
- "version": "4.13.6",
3
+ "version": "4.13.8",
4
4
  "sideEffects": false
5
5
  }
@@ -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: (prop: string) => boolean;
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.6",
4
+ "version": "4.13.8",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "publishConfig": {
7
7
  "registry": "https://registry.npmjs.org/"