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