@atlaskit/eslint-plugin-design-system 8.33.0 → 8.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -0
  3. package/constellation/ensure-design-token-usage/usage.mdx +2 -2
  4. package/constellation/index/usage.mdx +1 -0
  5. package/constellation/use-tokens-typography/usage.mdx +42 -0
  6. package/dist/cjs/ast-nodes/index.js +7 -0
  7. package/dist/cjs/ast-nodes/object-entry.js +27 -0
  8. package/dist/cjs/ast-nodes/object.js +1 -1
  9. package/dist/cjs/presets/all.codegen.js +2 -1
  10. package/dist/cjs/rules/ensure-design-token-usage/index.js +5 -4
  11. package/dist/cjs/rules/ensure-design-token-usage/rule-meta.js +1 -1
  12. package/dist/cjs/rules/ensure-design-token-usage/spacing.js +5 -1
  13. package/dist/cjs/rules/ensure-design-token-usage/utils.js +52 -42
  14. package/dist/cjs/rules/index.codegen.js +3 -1
  15. package/dist/cjs/rules/use-tokens-typography/config/index.js +26 -0
  16. package/dist/cjs/rules/use-tokens-typography/error-boundary.js +24 -0
  17. package/dist/cjs/rules/use-tokens-typography/index.js +44 -0
  18. package/dist/cjs/rules/use-tokens-typography/transformers/style-object.js +212 -0
  19. package/dist/cjs/rules/use-tokens-typography/utils.js +146 -0
  20. package/dist/es2019/ast-nodes/index.js +1 -0
  21. package/dist/es2019/ast-nodes/object-entry.js +22 -0
  22. package/dist/es2019/ast-nodes/object.js +1 -1
  23. package/dist/es2019/presets/all.codegen.js +2 -1
  24. package/dist/es2019/rules/ensure-design-token-usage/index.js +6 -5
  25. package/dist/es2019/rules/ensure-design-token-usage/rule-meta.js +1 -1
  26. package/dist/es2019/rules/ensure-design-token-usage/spacing.js +5 -1
  27. package/dist/es2019/rules/ensure-design-token-usage/utils.js +42 -38
  28. package/dist/es2019/rules/index.codegen.js +3 -1
  29. package/dist/es2019/rules/use-tokens-typography/config/index.js +20 -0
  30. package/dist/es2019/rules/use-tokens-typography/error-boundary.js +19 -0
  31. package/dist/es2019/rules/use-tokens-typography/index.js +36 -0
  32. package/dist/es2019/rules/use-tokens-typography/transformers/style-object.js +209 -0
  33. package/dist/es2019/rules/use-tokens-typography/utils.js +99 -0
  34. package/dist/esm/ast-nodes/index.js +1 -0
  35. package/dist/esm/ast-nodes/object-entry.js +22 -0
  36. package/dist/esm/ast-nodes/object.js +1 -1
  37. package/dist/esm/presets/all.codegen.js +2 -1
  38. package/dist/esm/rules/ensure-design-token-usage/index.js +6 -5
  39. package/dist/esm/rules/ensure-design-token-usage/rule-meta.js +1 -1
  40. package/dist/esm/rules/ensure-design-token-usage/spacing.js +5 -1
  41. package/dist/esm/rules/ensure-design-token-usage/utils.js +46 -38
  42. package/dist/esm/rules/index.codegen.js +3 -1
  43. package/dist/esm/rules/use-tokens-typography/config/index.js +20 -0
  44. package/dist/esm/rules/use-tokens-typography/error-boundary.js +18 -0
  45. package/dist/esm/rules/use-tokens-typography/index.js +38 -0
  46. package/dist/esm/rules/use-tokens-typography/transformers/style-object.js +206 -0
  47. package/dist/esm/rules/use-tokens-typography/utils.js +129 -0
  48. package/dist/types/ast-nodes/index.d.ts +1 -0
  49. package/dist/types/ast-nodes/object-entry.d.ts +6 -0
  50. package/dist/types/ast-nodes/object.d.ts +1 -1
  51. package/dist/types/index.codegen.d.ts +1 -0
  52. package/dist/types/presets/all.codegen.d.ts +2 -1
  53. package/dist/types/rules/ensure-design-token-usage/types.d.ts +1 -1
  54. package/dist/types/rules/ensure-design-token-usage/utils.d.ts +22 -22
  55. package/dist/types/rules/index.codegen.d.ts +1 -0
  56. package/dist/types/rules/use-tokens-typography/config/index.d.ts +6 -0
  57. package/dist/types/rules/use-tokens-typography/error-boundary.d.ts +11 -0
  58. package/dist/types/rules/use-tokens-typography/index.d.ts +3 -0
  59. package/dist/types/rules/use-tokens-typography/transformers/style-object.d.ts +31 -0
  60. package/dist/types/rules/use-tokens-typography/utils.d.ts +161 -0
  61. package/dist/types-ts4.5/ast-nodes/index.d.ts +1 -0
  62. package/dist/types-ts4.5/ast-nodes/object-entry.d.ts +6 -0
  63. package/dist/types-ts4.5/ast-nodes/object.d.ts +1 -1
  64. package/dist/types-ts4.5/index.codegen.d.ts +1 -0
  65. package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
  66. package/dist/types-ts4.5/rules/ensure-design-token-usage/types.d.ts +1 -1
  67. package/dist/types-ts4.5/rules/ensure-design-token-usage/utils.d.ts +22 -22
  68. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
  69. package/dist/types-ts4.5/rules/use-tokens-typography/config/index.d.ts +6 -0
  70. package/dist/types-ts4.5/rules/use-tokens-typography/error-boundary.d.ts +11 -0
  71. package/dist/types-ts4.5/rules/use-tokens-typography/index.d.ts +3 -0
  72. package/dist/types-ts4.5/rules/use-tokens-typography/transformers/style-object.d.ts +31 -0
  73. package/dist/types-ts4.5/rules/use-tokens-typography/utils.d.ts +161 -0
  74. package/package.json +1 -1
  75. package/dist/cjs/rules/ensure-design-token-usage/typography.js +0 -39
  76. package/dist/es2019/rules/ensure-design-token-usage/typography.js +0 -19
  77. package/dist/esm/rules/ensure-design-token-usage/typography.js +0 -33
  78. package/dist/types/rules/ensure-design-token-usage/typography.d.ts +0 -9
  79. package/dist/types-ts4.5/rules/ensure-design-token-usage/typography.d.ts +0 -9
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StyleObject = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ var _astNodes = require("../../../ast-nodes");
9
+ var _utils = require("../../ensure-design-token-usage/utils");
10
+ var _isNode = require("../../utils/is-node");
11
+ var _utils2 = require("../utils");
12
+ /* eslint-disable @repo/internal/react/require-jsdoc */
13
+
14
+ var StyleObject = exports.StyleObject = {
15
+ lint: function lint(node, _ref) {
16
+ var context = _ref.context;
17
+ // To force the correct node type
18
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'ObjectExpression')) {
19
+ return {
20
+ success: false
21
+ };
22
+ }
23
+
24
+ // Check whether all criteria needed to make a transformation are met
25
+ var _StyleObject$_check = StyleObject._check(node, {
26
+ context: context
27
+ }),
28
+ success = _StyleObject$_check.success,
29
+ refs = _StyleObject$_check.refs;
30
+ if (!success || !refs) {
31
+ return;
32
+ }
33
+ var fontSizeNode = refs.fontSizeNode,
34
+ fontSizeRaw = refs.fontSizeRaw,
35
+ tokensImportNode = refs.tokensImportNode;
36
+ var fontSizeValue = (0, _utils.normaliseValue)('fontSize', fontSizeRaw);
37
+
38
+ // -- Font weight --
39
+ var fontWeightNode = _astNodes.Object.getEntryByPropertyName(node, 'fontWeight');
40
+ var fontWeightRaw = fontWeightNode && (0, _utils.getValueForPropertyNode)(fontWeightNode, context);
41
+
42
+ // If no fontWeight value exists, default to 400 to avoid matching with a bolder token resulting in a visual change
43
+ var fontWeightValue = fontWeightRaw && (0, _utils.normaliseValue)('fontWeight', fontWeightRaw) || _utils2.defaultFontWeight;
44
+ fontWeightValue = fontWeightValue.length === 3 ? fontWeightValue : _utils2.fontWeightMap[fontWeightValue] || _utils2.defaultFontWeight;
45
+
46
+ // -- Line height --
47
+ var lineHeightNode = _astNodes.Object.getEntryByPropertyName(node, 'lineHeight');
48
+ var lineHeightRaw = lineHeightNode && (0, _utils.getValueForPropertyNode)(lineHeightNode, context);
49
+ var shouldAddFontWeight = false;
50
+ var lineHeightValue = lineHeightRaw && (0, _utils.normaliseValue)('lineHeight', lineHeightRaw) || undefined;
51
+ if (lineHeightValue === fontSizeValue) {
52
+ lineHeightValue = '1';
53
+ }
54
+
55
+ // -- Match tokens --
56
+ var matchingTokens = (0, _utils2.findTypographyTokenForValues)(fontSizeValue, lineHeightValue);
57
+ if (matchingTokens.length) {
58
+ // If we have multiple matching tokens, try matching fontWeight
59
+ var matchingTokensWithWeight = matchingTokens.filter(function (token) {
60
+ return fontWeightValue ? token.values.fontWeight === fontWeightValue : token;
61
+ });
62
+ if (matchingTokensWithWeight.length) {
63
+ // Possibly narrowed down tokens
64
+ matchingTokens = matchingTokensWithWeight;
65
+ } else {
66
+ // Ended up with 0 matches by matching fontWeight
67
+ // return body token and add fontWeight manually
68
+ matchingTokens = matchingTokens.filter(function (token) {
69
+ return token.tokenName.includes('.body');
70
+ });
71
+ shouldAddFontWeight = true;
72
+ }
73
+ }
74
+
75
+ // Get other font-* nodes that we can replace/remove.
76
+ // These aren't needed for token matching.
77
+
78
+ // -- Font family --
79
+ var fontFamilyNode = _astNodes.Object.getEntryByPropertyName(node, 'fontFamily');
80
+ var fontFamilyRaw = fontFamilyNode && (0, _utils.getValueForPropertyNode)(fontFamilyNode, context);
81
+ var fontFamilyValue = fontFamilyRaw && (0, _utils.normaliseValue)('fontFamily', fontFamilyRaw) || undefined;
82
+ var fontFamilyToAdd;
83
+ // If font family uses the Charlie font we can't replace; exit
84
+ if (fontFamilyValue) {
85
+ if (fontFamilyValue.toLowerCase().includes('charlie display')) {
86
+ fontFamilyToAdd = 'heading';
87
+ } else if (fontFamilyValue.toLowerCase().includes('charlie text')) {
88
+ fontFamilyToAdd = 'body';
89
+ }
90
+ } else {
91
+ // Font family node exists but we can't resolve its value
92
+ // Will need to re-add it below the font property to ensure it still applies
93
+ fontFamilyToAdd = fontFamilyNode ? 'original' : undefined;
94
+ }
95
+
96
+ // -- Font style --
97
+ var fontStyleNode = _astNodes.Object.getEntryByPropertyName(node, 'fontStyle');
98
+ var fontStyleRaw = fontStyleNode && (0, _utils.getValueForPropertyNode)(fontStyleNode, context);
99
+ var fontStyleValue = fontStyleRaw && (0, _utils.normaliseValue)('fontStyle', fontStyleRaw) || undefined;
100
+ var fontStyleToAdd;
101
+ if (fontStyleValue === 'italic') {
102
+ fontStyleToAdd = 'italic';
103
+ }
104
+
105
+ // -- Letter spacing --
106
+ var letterSpacingNode = _astNodes.Object.getEntryByPropertyName(node, 'letterSpacing');
107
+
108
+ // A single matching token
109
+ // TOOD: Maybe suggest options if > 1 matching token
110
+ if (matchingTokens.length === 1) {
111
+ var matchingToken = matchingTokens[0];
112
+
113
+ // fontSize node is always first
114
+ var nodesToReplace = [fontSizeNode, fontWeightNode, lineHeightNode, fontFamilyNode, fontStyleNode, letterSpacingNode].filter(_utils2.notUndefined);
115
+ var fontFamilyTokenName = fontFamilyToAdd ? "font.family.brand.".concat(fontFamilyToAdd) : '';
116
+ var fontWeightReplacementToken = shouldAddFontWeight ? (0, _utils2.findFontWeightTokenForValue)(fontWeightValue) : undefined;
117
+ var fontWeightReplacement = fontWeightReplacementToken && (0, _utils2.getTokenProperty)('fontWeight', fontWeightReplacementToken.tokenName, fontWeightValue);
118
+ var fontFamilyReplacement = fontFamilyToAdd && (fontFamilyToAdd === 'original' ? (0, _utils2.convertPropertyNodeToStringableNode)(
119
+ // This will always exist if fontFamilyToAdd === 'original', TS can't figure that out.
120
+ fontFamilyNode) : (0, _utils2.getTokenProperty)('fontFamily', fontFamilyTokenName, (0, _utils2.findFontFamilyValueForToken)(fontFamilyTokenName)));
121
+ var fontStyleReplacement = fontStyleToAdd && (0, _utils2.getLiteralProperty)('fontStyle', fontStyleToAdd);
122
+ var fixerRefs = {
123
+ matchingToken: matchingToken,
124
+ nodesToReplace: nodesToReplace,
125
+ tokensImportNode: tokensImportNode,
126
+ fontWeightReplacement: fontWeightReplacement,
127
+ fontFamilyReplacement: fontFamilyReplacement,
128
+ fontStyleReplacement: fontStyleReplacement
129
+ };
130
+ context.report({
131
+ node: fontSizeNode,
132
+ messageId: 'noRawTypographyValues',
133
+ data: {
134
+ payload: "fontSize:".concat(fontSizeRaw)
135
+ },
136
+ fix: StyleObject._fix(fixerRefs, context)
137
+ });
138
+ } else if (!matchingTokens.length) {
139
+ context.report({
140
+ node: fontSizeNode,
141
+ messageId: 'noRawTypographyValues',
142
+ data: {
143
+ payload: "fontSize:".concat(fontSizeRaw)
144
+ }
145
+ });
146
+ }
147
+ return;
148
+ },
149
+ _check: function _check(node, _ref2) {
150
+ var context = _ref2.context;
151
+ if (!(0, _isNode.isDecendantOfStyleBlock)(node) && !(0, _isNode.isDecendantOfType)(node, 'JSXExpressionContainer')) {
152
+ return {
153
+ success: false
154
+ };
155
+ }
156
+
157
+ // -- Font size --
158
+ var fontSizeNode = _astNodes.Object.getEntryByPropertyName(node, 'fontSize');
159
+ if (!fontSizeNode || !(0, _utils2.isValidPropertyNode)(fontSizeNode) || (0, _isNode.isDecendantOfGlobalToken)(fontSizeNode.value)) {
160
+ return {
161
+ success: false
162
+ };
163
+ }
164
+ var fontSizeRaw = (0, _utils.getValueForPropertyNode)(fontSizeNode, context);
165
+
166
+ // Without a valid fontSize value we can't be certain what token should be used; exit
167
+ if (!fontSizeRaw) {
168
+ return {
169
+ success: false
170
+ };
171
+ }
172
+ var importDeclaration = _astNodes.Root.findImportsByModule(context.getSourceCode().ast.body, '@atlaskit/tokens');
173
+
174
+ // If there is more than one `@atlaskit/tokens` import, then it becomes difficult to determine which import to transform
175
+ if (importDeclaration.length > 1) {
176
+ return {
177
+ success: false
178
+ };
179
+ }
180
+ return {
181
+ success: true,
182
+ refs: {
183
+ fontSizeNode: fontSizeNode,
184
+ fontSizeRaw: fontSizeRaw,
185
+ tokensImportNode: importDeclaration[0]
186
+ }
187
+ };
188
+ },
189
+ _fix: function _fix(refs, context) {
190
+ return function (fixer) {
191
+ var matchingToken = refs.matchingToken,
192
+ nodesToReplace = refs.nodesToReplace,
193
+ tokensImportNode = refs.tokensImportNode,
194
+ fontWeightReplacement = refs.fontWeightReplacement,
195
+ fontFamilyReplacement = refs.fontFamilyReplacement,
196
+ fontStyleReplacement = refs.fontStyleReplacement;
197
+ var fontSizeNode = nodesToReplace[0];
198
+ return (!tokensImportNode ? [(0, _utils.insertTokensImport)(fixer)] : []).concat(nodesToReplace.map(function (node, index) {
199
+ // Replace first node with token, delete remaining nodes. Guaranteed to be fontSize
200
+ if (index === 0) {
201
+ return fixer.replaceText(node, "".concat((0, _utils2.getTokenProperty)('font', matchingToken.tokenName, matchingToken.tokenValue)));
202
+ }
203
+
204
+ // We don't replace fontWeight/fontFamily/fontStyle here in case it occurs before the font property.
205
+ // Instead delete the original property and add below
206
+ return _astNodes.ObjectEntry.deleteEntry(node, context, fixer);
207
+ }),
208
+ // Make sure font weight/family/style properties are added AFTER font property to ensure they override corectly
209
+ fontWeightReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontWeightReplacement))] : [], fontFamilyReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontFamilyReplacement))] : [], fontStyleReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontStyleReplacement))] : []);
210
+ };
211
+ }
212
+ };
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.convertPropertyNodeToStringableNode = convertPropertyNodeToStringableNode;
7
+ exports.defaultFontWeight = void 0;
8
+ exports.findFontFamilyValueForToken = findFontFamilyValueForToken;
9
+ exports.findFontWeightTokenForValue = findFontWeightTokenForValue;
10
+ exports.findTypographyTokenForValues = findTypographyTokenForValues;
11
+ exports.fontWeightTokens = exports.fontWeightMap = exports.fontFamilyTokens = void 0;
12
+ exports.getLiteralProperty = getLiteralProperty;
13
+ exports.getTokenProperty = getTokenProperty;
14
+ exports.isTypographyProperty = exports.isFontSizeSmall = exports.isFontSize = exports.isFontFamily = exports.isCodeFontFamily = void 0;
15
+ exports.isValidPropertyNode = isValidPropertyNode;
16
+ exports.notUndefined = notUndefined;
17
+ exports.typographyValueToToken = exports.typographyProperties = void 0;
18
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
19
+ var _palettesRaw = require("@atlaskit/tokens/palettes-raw");
20
+ var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
21
+ var typographyProperties = exports.typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
22
+ var isTypographyProperty = exports.isTypographyProperty = function isTypographyProperty(propertyName) {
23
+ return typographyProperties.includes(propertyName);
24
+ };
25
+ var isFontSize = exports.isFontSize = function isFontSize(node) {
26
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontSize' || node.callee.name === 'getFontSize');
27
+ };
28
+ var isFontSizeSmall = exports.isFontSizeSmall = function isFontSizeSmall(node) {
29
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
30
+ };
31
+ var isFontFamily = exports.isFontFamily = function isFontFamily(node) {
32
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
33
+ };
34
+ var isCodeFontFamily = exports.isCodeFontFamily = function isCodeFontFamily(node) {
35
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
36
+ };
37
+ var typographyValueToToken = exports.typographyValueToToken = _tokensRaw.typographyAdg3
38
+ // we're filtering here to remove the `font` tokens.
39
+ .filter(function (t) {
40
+ return t.attributes.group === 'typography';
41
+ }).filter(function (t) {
42
+ return t.cleanName.includes('font.heading') || t.cleanName.includes('font.body');
43
+ }).map(function (currentToken) {
44
+ var _typographyPalette$fi, _typographyPalette$fi2, _typographyPalette$fi3;
45
+ var individualValues = {
46
+ fontSize: (_typographyPalette$fi = _palettesRaw.typographyPalette.find(function (baseToken) {
47
+ return baseToken.path.slice(-1)[0] ===
48
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
49
+ currentToken.original.value.fontSize;
50
+ })) === null || _typographyPalette$fi === void 0 ? void 0 : _typographyPalette$fi.value,
51
+ fontWeight: (_typographyPalette$fi2 = _palettesRaw.typographyPalette.find(function (baseToken) {
52
+ return baseToken.path.slice(-1)[0] ===
53
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
54
+ currentToken.original.value.fontWeight;
55
+ })) === null || _typographyPalette$fi2 === void 0 ? void 0 : _typographyPalette$fi2.value,
56
+ lineHeight: (_typographyPalette$fi3 = _palettesRaw.typographyPalette.find(function (baseToken) {
57
+ return baseToken.path.slice(-1)[0] ===
58
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
59
+ currentToken.original.value.lineHeight;
60
+ })) === null || _typographyPalette$fi3 === void 0 ? void 0 : _typographyPalette$fi3.value
61
+ };
62
+ return {
63
+ tokenName: currentToken.cleanName,
64
+ tokenValue: currentToken.value,
65
+ values: individualValues
66
+ };
67
+ });
68
+ function findTypographyTokenForValues(fontSize, lineHeight) {
69
+ var matchingTokens = typographyValueToToken.filter(function (token) {
70
+ return token.values.fontSize === fontSize;
71
+ })
72
+ // If lineHeight == 1, we don't match to a token
73
+ .filter(function () {
74
+ return lineHeight === '1' ? false : true;
75
+ });
76
+ return matchingTokens;
77
+ }
78
+ var fontWeightTokens = exports.fontWeightTokens = _tokensRaw.typographyAdg3.filter(function (token) {
79
+ return token.attributes.group === 'fontWeight';
80
+ }).map(function (token) {
81
+ return {
82
+ tokenName: token.cleanName,
83
+ tokenValue: token.value,
84
+ values: {}
85
+ };
86
+ });
87
+ function findFontWeightTokenForValue(fontWeight) {
88
+ return fontWeightTokens.find(function (token) {
89
+ return token.tokenValue === fontWeight;
90
+ });
91
+ }
92
+ var fontWeightMap = exports.fontWeightMap = {
93
+ regular: '400',
94
+ medium: '500',
95
+ semibold: '600',
96
+ bold: '700'
97
+ };
98
+ var defaultFontWeight = exports.defaultFontWeight = fontWeightMap.regular;
99
+ var fontFamilyTokens = exports.fontFamilyTokens = _tokensRaw.typographyAdg3.filter(function (token) {
100
+ return token.attributes.group === 'fontFamily';
101
+ });
102
+ function findFontFamilyValueForToken(tokenName) {
103
+ var _fontFamilyTokens$fin;
104
+ // Note this will only ever be undefined if the tokens get renamed, and should never happen.
105
+ return ((_fontFamilyTokens$fin = fontFamilyTokens.find(function (token) {
106
+ return token.cleanName === tokenName;
107
+ })) === null || _fontFamilyTokens$fin === void 0 ? void 0 : _fontFamilyTokens$fin.value) || '';
108
+ }
109
+ function notUndefined(value) {
110
+ return value !== undefined;
111
+ }
112
+ function isValidPropertyNode(node) {
113
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Identifier') && !(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Literal')) {
114
+ return false;
115
+ }
116
+ return true;
117
+ }
118
+ function getTokenNode(tokenName, tokenValue) {
119
+ return (0, _eslintCodemodUtils.callExpression)({
120
+ callee: (0, _eslintCodemodUtils.identifier)({
121
+ name: 'token'
122
+ }),
123
+ arguments: [(0, _eslintCodemodUtils.literal)({
124
+ value: "'".concat(tokenName, "'")
125
+ }), (0, _eslintCodemodUtils.literal)(tokenValue)],
126
+ optional: false
127
+ });
128
+ }
129
+ function getTokenProperty(propertyName, tokenName, tokenFallback) {
130
+ return (0, _eslintCodemodUtils.property)({
131
+ key: (0, _eslintCodemodUtils.identifier)(propertyName),
132
+ value: getTokenNode(tokenName, tokenFallback)
133
+ });
134
+ }
135
+ function getLiteralProperty(propertyName, propertyValue) {
136
+ return (0, _eslintCodemodUtils.property)({
137
+ key: (0, _eslintCodemodUtils.identifier)(propertyName),
138
+ value: (0, _eslintCodemodUtils.literal)(propertyValue)
139
+ });
140
+ }
141
+ function convertPropertyNodeToStringableNode(node) {
142
+ return (0, _eslintCodemodUtils.property)({
143
+ key: node.key,
144
+ value: node.value
145
+ });
146
+ }
@@ -3,4 +3,5 @@ export { Import } from './import';
3
3
  export { JSXAttribute } from './jsx-attribute';
4
4
  export { JSXElement } from './jsx-element';
5
5
  export { Object } from './object';
6
+ export { ObjectEntry } from './object-entry';
6
7
  export { Root } from './root';
@@ -0,0 +1,22 @@
1
+ const ObjectEntry = {
2
+ deleteEntry(node, context, fixer) {
3
+ var _lastToken;
4
+ // context.getSourceCode() is deprecated in favour of context.sourceCode, however this returns undefined for some reason
5
+ const sourceCode = context.getSourceCode();
6
+
7
+ // fixer.remove() doesn't account for things like commas or newlines within an ObjectExpression and will result in invalid output.
8
+ // This approach specifically removes the node and trailing comma, and should work for single- and multi-line objects.
9
+ // From https://github.com/eslint/eslint/issues/9576#issuecomment-341737453
10
+ let prevToken = sourceCode.getTokenBefore(node);
11
+ while (((_prevToken = prevToken) === null || _prevToken === void 0 ? void 0 : _prevToken.value) !== ',' && ((_prevToken2 = prevToken) === null || _prevToken2 === void 0 ? void 0 : _prevToken2.value) !== '{') {
12
+ var _prevToken, _prevToken2;
13
+ prevToken = sourceCode.getTokenBefore(node);
14
+ }
15
+ let lastToken = sourceCode.getTokenAfter(node);
16
+ if (((_lastToken = lastToken) === null || _lastToken === void 0 ? void 0 : _lastToken.value) !== ',') {
17
+ lastToken = sourceCode.getTokenBefore(lastToken);
18
+ }
19
+ return fixer.removeRange([prevToken.range[1], lastToken.range[1]]);
20
+ }
21
+ };
22
+ export { ObjectEntry };
@@ -27,7 +27,7 @@ const ASTObjectExpression = {
27
27
  });
28
28
  },
29
29
  /**
30
- * Returns a key-value pair like: `padding: '8px'` from: `{ padding: '8px' }`.
30
+ * Returns the first Property node from an Object that matches the provided name.
31
31
  */
32
32
  getEntryByPropertyName(node, name) {
33
33
  return node.properties.find(property => {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
- * @codegen <<SignedSource::bcb633b9d5c2def00d43b11139433c5c>>
3
+ * @codegen <<SignedSource::d90c2cf5e100daf98915f9467f2e5663>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  export default {
@@ -35,6 +35,7 @@ export default {
35
35
  '@atlaskit/design-system/use-href-in-link-item': 'warn',
36
36
  '@atlaskit/design-system/use-primitives': 'warn',
37
37
  '@atlaskit/design-system/use-primitives-text': 'warn',
38
+ '@atlaskit/design-system/use-tokens-typography': 'warn',
38
39
  '@atlaskit/design-system/use-visually-hidden': 'error'
39
40
  }
40
41
  };
@@ -8,7 +8,7 @@ import { lintJSXIdentifierForColor, lintJSXLiteralForColor, lintJSXMemberForColo
8
8
  import { errorBoundary } from './error-boundary';
9
9
  import ruleMeta from './rule-meta';
10
10
  import { lintObjectForSpacing } from './spacing';
11
- import { convertHyphenatedNameToCamelCase, emToPixels, getDomainsForProperty, getFontSizeFromNode, getFontSizeValueInScope, getTokenReplacement, getValueFromShorthand, getValueFromTemplateLiteralRaw, includesTokenString, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, splitShorthandValues } from './utils';
11
+ import { convertHyphenatedNameToCamelCase, emToPixels, getDomainsForProperty, getFontSizeValueInScope, getPropertyNodeFromParent, getTokenReplacement, getValueForPropertyNode, getValueFromShorthand, getValueFromTemplateLiteralRaw, includesTokenString, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, splitShorthandValues } from './utils';
12
12
  const defaultConfig = {
13
13
  domains: ['color', 'spacing'],
14
14
  applyImport: true,
@@ -89,11 +89,12 @@ const createWithConfig = initialConfig => context => {
89
89
  if (domains.includes('color')) {
90
90
  return lintObjectForColor(node, context, config);
91
91
  }
92
- if (domains.includes('spacing') || domains.includes('shape') || domains.includes('typography')) {
92
+ if (domains.includes('spacing') || domains.includes('shape')) {
93
93
  /**
94
- * We do this in case the fontSize for a style object is declared alongside the `em` or `lineHeight` declaration
94
+ * We do this in case the fontSize for a style object is declared alongside the `em` or `lineHeight` declaration.
95
95
  */
96
- const fontSize = getFontSizeFromNode(parentNode, context);
96
+ const fontSizeNode = getPropertyNodeFromParent('fontSize', parentNode);
97
+ const fontSize = fontSizeNode && getValueForPropertyNode(fontSizeNode, context);
97
98
  return lintObjectForSpacing(node, context, config, fontSize, tokenNode);
98
99
  }
99
100
  }
@@ -140,7 +141,7 @@ const createWithConfig = initialConfig => context => {
140
141
  return currentSource;
141
142
  }
142
143
  }
143
- if (domains.includes('spacing') || domains.includes('typography') || domains.includes('shape')) {
144
+ if (domains.includes('spacing') || domains.includes('shape')) {
144
145
  if (!isValidSpacingValue(resolvedCssValues, globalFontSize)) {
145
146
  // no changes should be made to the current property
146
147
  return currentSource;
@@ -1,4 +1,4 @@
1
- const domainsToLint = ['color', 'spacing', 'typography', 'shape'];
1
+ const domainsToLint = ['color', 'spacing', 'shape'];
2
2
  const ruleMeta = {
3
3
  name: 'ensure-design-token-usage',
4
4
  hasSuggestions: true,
@@ -64,7 +64,8 @@ export const lintObjectForSpacing = (node, context, ruleConfig, fontSize, tokenN
64
64
  payload: `${propertyName}:${pixelValue}`
65
65
  },
66
66
  fix: fixer => {
67
- const replacementNode = getTokenReplacement(propertyName, pixelValue);
67
+ // Casting due to possibility of pixelValue being string | number from emToPixels
68
+ const replacementNode = pixelValue && getTokenReplacement(propertyName, pixelValue);
68
69
  if (!replacementNode) {
69
70
  return null;
70
71
  }
@@ -110,6 +111,8 @@ export const lintObjectForSpacing = (node, context, ruleConfig, fontSize, tokenN
110
111
  if (!allResolvableValues) {
111
112
  return null;
112
113
  }
114
+
115
+ // Casting due to possibility of value being string | number
113
116
  const valuesWithTokenReplacement = valuesForProperty.filter(value => findTokenNameByPropertyValue(propertyName, value)).filter(value => value !== 0);
114
117
  if (valuesWithTokenReplacement.length === 0) {
115
118
  // all values could be replaceable but that just means they're numeric
@@ -139,6 +142,7 @@ export const lintObjectForSpacing = (node, context, ruleConfig, fontSize, tokenN
139
142
  const pixelValueString = `${pixelValue}px`;
140
143
  // if there is a token we take it, otherwise we go with the original value
141
144
 
145
+ // Casting due to possibility of value being string | number
142
146
  return findTokenNameByPropertyValue(propertyName, value) ? `\${${getTokenNodeForValue(propertyName, pixelValueString)}}` : originalValues[index];
143
147
  }).join(' ')}\``)]);
144
148
  }