@atlaskit/eslint-plugin-design-system 6.0.1 → 6.2.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.
- package/CHANGELOG.md +12 -0
- package/configs/deprecated.json +56 -0
- package/dist/cjs/rules/ensure-design-token-usage/index.js +8 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/index.js +28 -28
- package/dist/cjs/rules/ensure-design-token-usage-spacing/utils.js +19 -2
- package/dist/cjs/rules/use-visually-hidden/index.js +2 -2
- package/dist/cjs/rules/utils/is-node.js +12 -10
- package/dist/cjs/version.json +1 -1
- package/dist/configs/deprecated.json +56 -0
- package/dist/es2019/rules/ensure-design-token-usage/index.js +8 -0
- package/dist/es2019/rules/ensure-design-token-usage-spacing/index.js +29 -29
- package/dist/es2019/rules/ensure-design-token-usage-spacing/utils.js +16 -1
- package/dist/es2019/rules/use-visually-hidden/index.js +3 -3
- package/dist/es2019/rules/utils/is-node.js +5 -6
- package/dist/es2019/version.json +1 -1
- package/dist/esm/rules/ensure-design-token-usage/index.js +8 -0
- package/dist/esm/rules/ensure-design-token-usage-spacing/index.js +30 -30
- package/dist/esm/rules/ensure-design-token-usage-spacing/utils.js +16 -1
- package/dist/esm/rules/use-visually-hidden/index.js +3 -3
- package/dist/esm/rules/utils/is-node.js +8 -7
- package/dist/esm/version.json +1 -1
- package/dist/types/rules/ensure-design-token-usage-spacing/utils.d.ts +3 -1
- package/dist/types/rules/utils/is-node.d.ts +3 -2
- package/dist/types-ts4.5/rules/ensure-design-token-usage-spacing/utils.d.ts +3 -1
- package/dist/types-ts4.5/rules/utils/is-node.d.ts +3 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 6.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`373b6b701ca`](https://bitbucket.org/atlassian/atlassian-frontend/commits/373b6b701ca) - Linters will now error when deprecated theme color mixins are imported
|
|
8
|
+
|
|
9
|
+
## 6.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [`99d5309f42b`](https://bitbucket.org/atlassian/atlassian-frontend/commits/99d5309f42b) - The ensure-design-token-usage-spacing rule will now lint against inline style objects
|
|
14
|
+
|
|
3
15
|
## 6.0.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/configs/deprecated.json
CHANGED
|
@@ -93,6 +93,30 @@
|
|
|
93
93
|
"@atlaskit/item": {
|
|
94
94
|
"message": "item is deprecated. Please use '@atlaskit/menu' instead."
|
|
95
95
|
},
|
|
96
|
+
"@atlaskit/theme/elevation": {
|
|
97
|
+
"importSpecifiers": [
|
|
98
|
+
{
|
|
99
|
+
"importName": "e100",
|
|
100
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"importName": "e200",
|
|
104
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"importName": "e300",
|
|
108
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"importName": "e400",
|
|
112
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"importName": "e500",
|
|
116
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
96
120
|
"@atlaskit/theme/constants": {
|
|
97
121
|
"importSpecifiers": [
|
|
98
122
|
{
|
|
@@ -113,6 +137,34 @@
|
|
|
113
137
|
}
|
|
114
138
|
]
|
|
115
139
|
},
|
|
140
|
+
"@atlaskit/theme/colors": {
|
|
141
|
+
"importSpecifiers": [
|
|
142
|
+
{ "importName": "background", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
143
|
+
{ "importName": "backgroundActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
144
|
+
{ "importName": "backgroundHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
145
|
+
{ "importName": "backgroundOnLayer", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
146
|
+
{ "importName": "text", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
147
|
+
{ "importName": "textHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
148
|
+
{ "importName": "textActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
149
|
+
{ "importName": "subtleText", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
150
|
+
{ "importName": "placeholderText", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
151
|
+
{ "importName": "heading", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
152
|
+
{ "importName": "subtleHeading", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
153
|
+
{ "importName": "codeBlock", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
154
|
+
{ "importName": "link", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
155
|
+
{ "importName": "linkHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
156
|
+
{ "importName": "linkActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
157
|
+
{ "importName": "linkOutline", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
158
|
+
{ "importName": "primary", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
159
|
+
{ "importName": "blue", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
160
|
+
{ "importName": "teal", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
161
|
+
{ "importName": "purple", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
162
|
+
{ "importName": "red", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
163
|
+
{ "importName": "yellow", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
164
|
+
{ "importName": "green", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
165
|
+
{ "importName": "skeleton", "message": "Named color utils are deprecated in favor of design tokens." }
|
|
166
|
+
]
|
|
167
|
+
},
|
|
116
168
|
"@atlaskit/theme": {
|
|
117
169
|
"importSpecifiers": [
|
|
118
170
|
{
|
|
@@ -130,6 +182,10 @@
|
|
|
130
182
|
{
|
|
131
183
|
"importName": "gridSize",
|
|
132
184
|
"message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"importName": "elevation",
|
|
188
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
133
189
|
}
|
|
134
190
|
]
|
|
135
191
|
},
|
|
@@ -55,6 +55,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
55
55
|
var config = context.options[0] || defaultConfig;
|
|
56
56
|
var isException = (0, _getIsException.getIsException)(config.exceptions);
|
|
57
57
|
return {
|
|
58
|
+
// For expressions within template literals (e.g. `color: ${red}`)
|
|
58
59
|
'TemplateLiteral > Identifier': function TemplateLiteralIdentifier(node) {
|
|
59
60
|
if (node.type !== 'Identifier') {
|
|
60
61
|
return;
|
|
@@ -87,6 +88,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
87
88
|
return;
|
|
88
89
|
}
|
|
89
90
|
},
|
|
91
|
+
// For css/styled template literals (not handling expressions) (e.g. css`color: red`)
|
|
90
92
|
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': function TaggedTemplateExpressionTagNameCssTaggedTemplateExpressionTagObjectNameStyled(node) {
|
|
91
93
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
92
94
|
return;
|
|
@@ -113,6 +115,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
113
115
|
}
|
|
114
116
|
});
|
|
115
117
|
},
|
|
118
|
+
// For style objects with identifiers as values (expressions) (e.g. { color: red })
|
|
116
119
|
'ObjectExpression > Property > Identifier, ObjectExpression > Property > MemberExpression': function ObjectExpressionPropertyIdentifierObjectExpressionPropertyMemberExpression(node) {
|
|
117
120
|
if ((0, _isNode.isDecendantOfGlobalToken)(node)) {
|
|
118
121
|
return;
|
|
@@ -160,6 +163,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
160
163
|
return;
|
|
161
164
|
}
|
|
162
165
|
},
|
|
166
|
+
// For style objects with literals as values (strings/numbers) (e.g. { color: "red" })
|
|
163
167
|
'ObjectExpression > Property > Literal': function ObjectExpressionPropertyLiteral(node) {
|
|
164
168
|
var _node$value;
|
|
165
169
|
if (node.type !== 'Literal') {
|
|
@@ -180,6 +184,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
180
184
|
});
|
|
181
185
|
}
|
|
182
186
|
},
|
|
187
|
+
// For style objects with function calls as values (e.g. { color: red() })
|
|
183
188
|
'ObjectExpression > Property > CallExpression': function ObjectExpressionPropertyCallExpression(node) {
|
|
184
189
|
if (node.type !== 'CallExpression') {
|
|
185
190
|
return;
|
|
@@ -202,6 +207,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
202
207
|
suggest: getTokenSuggestion(node, "".concat(node.callee.name, "()"), config)
|
|
203
208
|
});
|
|
204
209
|
},
|
|
210
|
+
// For inline JSX styles - literals (e.g. <Test color="red"/>)
|
|
205
211
|
'JSXAttribute > Literal': function JSXAttributeLiteral(node) {
|
|
206
212
|
if (node.type !== 'Literal') {
|
|
207
213
|
return;
|
|
@@ -232,6 +238,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
232
238
|
return;
|
|
233
239
|
}
|
|
234
240
|
},
|
|
241
|
+
// For inline JSX styles - members (e.g. <Test color={color.red}/>)
|
|
235
242
|
'JSXExpressionContainer > MemberExpression': function JSXExpressionContainerMemberExpression(node) {
|
|
236
243
|
if (node.type !== 'MemberExpression') {
|
|
237
244
|
return;
|
|
@@ -247,6 +254,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
247
254
|
});
|
|
248
255
|
}
|
|
249
256
|
},
|
|
257
|
+
// For inline JSX styles - identifiers (e.g. <Test color={red}/>)
|
|
250
258
|
'JSXExpressionContainer > Identifier': function JSXExpressionContainerIdentifier(node) {
|
|
251
259
|
if (node.type !== 'Identifier') {
|
|
252
260
|
return;
|
|
@@ -69,25 +69,23 @@ var rule = (0, _createRule.createRule)({
|
|
|
69
69
|
},
|
|
70
70
|
// CSSObjectExpression
|
|
71
71
|
// const styles = css({ color: 'red', margin: '4px' }), styled.div({ color: 'red', margin: '4px' })
|
|
72
|
-
|
|
72
|
+
ObjectExpression: function ObjectExpression(parentNode) {
|
|
73
73
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(parentNode, 'ObjectExpression')) {
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// Return for nested objects - these get handled automatically so without returning we'd be doubling up
|
|
78
|
+
if (parentNode.parent.type === 'Property') {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (!(0, _isNode.isDecendantOfStyleBlock)(parentNode) && !(0, _isNode.isDecendantOfType)(parentNode, 'JSXExpressionContainer')) {
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
77
85
|
/**
|
|
78
86
|
* We do this in case the fontSize for a style object is declared alongside the `em` or `lineHeight` declaration
|
|
79
87
|
*/
|
|
80
|
-
var
|
|
81
|
-
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'Property')) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Identifier')) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
return node.key.name === 'fontSize';
|
|
88
|
-
});
|
|
89
|
-
var fontSizeValue = (0, _eslintCodemodUtils.isNodeOfType)(fontSizeNode, 'Property') ? (0, _utils.getValue)(fontSizeNode.value, context) : null;
|
|
90
|
-
var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
88
|
+
var fontSize = (0, _utils.getFontSizeFromNode)(parentNode, context);
|
|
91
89
|
function findObjectStyles(node) {
|
|
92
90
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'Property')) {
|
|
93
91
|
return;
|
|
@@ -126,7 +124,7 @@ var rule = (0, _createRule.createRule)({
|
|
|
126
124
|
var isFontFamily = /fontFamily/.test(propertyName);
|
|
127
125
|
var value = (0, _utils.getValue)(node.value, context);
|
|
128
126
|
|
|
129
|
-
// value is either NaN or it can't be resolved
|
|
127
|
+
// value is either NaN or it can't be resolved (e.g. em, 100% etc...)
|
|
130
128
|
if (!(value && (0, _utils.isValidSpacingValue)(value, fontSize))) {
|
|
131
129
|
return context.report({
|
|
132
130
|
node: node,
|
|
@@ -136,13 +134,15 @@ var rule = (0, _createRule.createRule)({
|
|
|
136
134
|
}
|
|
137
135
|
});
|
|
138
136
|
}
|
|
139
|
-
|
|
137
|
+
|
|
138
|
+
// The corresponding values for a single CSS property (e.g. padding: '8px 16px 2px' => [8, 16, 2])
|
|
139
|
+
var valuesForProperty = Array.isArray(value) ? value : [value];
|
|
140
140
|
|
|
141
141
|
// value is a single value so we can apply a more robust approach to our fix
|
|
142
142
|
// treat fontFamily as having one value
|
|
143
|
-
if (
|
|
144
|
-
var
|
|
145
|
-
_value =
|
|
143
|
+
if (valuesForProperty.length === 1 || isFontFamily) {
|
|
144
|
+
var _valuesForProperty = (0, _slicedToArray2.default)(valuesForProperty, 1),
|
|
145
|
+
_value = _valuesForProperty[0];
|
|
146
146
|
|
|
147
147
|
// Do not report or suggest a token to replace 0 or auto
|
|
148
148
|
if ((0, _utils.isZero)(_value) || (0, _utils.isAuto)(_value)) {
|
|
@@ -164,7 +164,7 @@ var rule = (0, _createRule.createRule)({
|
|
|
164
164
|
if (!replacementNode) {
|
|
165
165
|
return null;
|
|
166
166
|
}
|
|
167
|
-
return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.insertTextBefore(node, "
|
|
167
|
+
return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.insertTextBefore(node, "".concat(_utils.replacementComment, " `").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), {}, {
|
|
168
168
|
value: replacementNode
|
|
169
169
|
})).toString())]);
|
|
170
170
|
}
|
|
@@ -178,7 +178,7 @@ var rule = (0, _createRule.createRule)({
|
|
|
178
178
|
* @example
|
|
179
179
|
* { padding: '8px 0px' }
|
|
180
180
|
*/
|
|
181
|
-
|
|
181
|
+
valuesForProperty.forEach(function (val) {
|
|
182
182
|
var pixelValue = (0, _utils.emToPixels)(val, fontSize);
|
|
183
183
|
|
|
184
184
|
// Do not report or suggest a token to replace 0 or auto
|
|
@@ -192,13 +192,13 @@ var rule = (0, _createRule.createRule)({
|
|
|
192
192
|
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
193
193
|
},
|
|
194
194
|
fix: function fix(fixer) {
|
|
195
|
-
var allResolvableValues =
|
|
195
|
+
var allResolvableValues = valuesForProperty.every(function (value) {
|
|
196
196
|
return !Number.isNaN((0, _utils.emToPixels)(value, fontSize));
|
|
197
197
|
});
|
|
198
198
|
if (!allResolvableValues) {
|
|
199
199
|
return null;
|
|
200
200
|
}
|
|
201
|
-
var valuesWithTokenReplacement =
|
|
201
|
+
var valuesWithTokenReplacement = valuesForProperty.filter(function (value) {
|
|
202
202
|
return (0, _utils.findTokenNameByPropertyValue)(propertyName, value);
|
|
203
203
|
}).filter(function (value) {
|
|
204
204
|
return value !== 0;
|
|
@@ -219,11 +219,11 @@ var rule = (0, _createRule.createRule)({
|
|
|
219
219
|
* given they're part of the substring of the current node
|
|
220
220
|
*/
|
|
221
221
|
var originalValues = (0, _utils.splitShorthandValues)(originalCssString.replace(/`|'|"/g, ''));
|
|
222
|
-
if (originalValues.length !==
|
|
222
|
+
if (originalValues.length !== valuesForProperty.length) {
|
|
223
223
|
// we bail just in case original values don't correspond to the replaced values
|
|
224
224
|
return null;
|
|
225
225
|
}
|
|
226
|
-
return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(
|
|
226
|
+
return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(valuesForProperty.map(function (value, index) {
|
|
227
227
|
if ((0, _utils.isZero)(value)) {
|
|
228
228
|
return originalValues[index];
|
|
229
229
|
}
|
|
@@ -319,11 +319,11 @@ var rule = (0, _createRule.createRule)({
|
|
|
319
319
|
});
|
|
320
320
|
|
|
321
321
|
// from here on we know value is numeric or a font family, so it might or might not have a token equivalent
|
|
322
|
-
var
|
|
323
|
-
if (!
|
|
322
|
+
var replacementNode = (0, _utils.getTokenReplacement)(propertyName, numericOrNanValue);
|
|
323
|
+
if (!replacementNode) {
|
|
324
324
|
return originalValue;
|
|
325
325
|
}
|
|
326
|
-
var replacementToken = '${' +
|
|
326
|
+
var replacementToken = '${' + replacementNode.toString() + '}';
|
|
327
327
|
replacedValuesPerProperty.push(isFontFamily ? numericOrNanValue.trim() : pxValue);
|
|
328
328
|
return replacementToken;
|
|
329
329
|
}).join(' ');
|
|
@@ -341,13 +341,13 @@ var rule = (0, _createRule.createRule)({
|
|
|
341
341
|
return replacedCssLine;
|
|
342
342
|
}, textForSource);
|
|
343
343
|
if (completeSource !== textForSource) {
|
|
344
|
-
// means we found some replacement values,
|
|
344
|
+
// means we found some replacement values, we'll give the option to fix them
|
|
345
345
|
|
|
346
346
|
var replacementComments = "".concat(allReplacedValues.map(function (replacedProperties) {
|
|
347
347
|
var _replacedProperties = (0, _slicedToArray2.default)(replacedProperties, 1),
|
|
348
348
|
propertyName = _replacedProperties[0];
|
|
349
349
|
var replacedValues = replacedProperties.slice(1).join(' ');
|
|
350
|
-
return "
|
|
350
|
+
return "".concat(_utils.replacementComment, " `").concat(propertyName, ": ").concat(replacedValues, "`");
|
|
351
351
|
}).join('\n'), "\n");
|
|
352
352
|
context.report({
|
|
353
353
|
node: node,
|
|
@@ -9,6 +9,7 @@ exports.emToPixels = exports.convertHyphenatedNameToCamelCase = void 0;
|
|
|
9
9
|
exports.findIdentifierInParentScope = findIdentifierInParentScope;
|
|
10
10
|
exports.findParentNodeForLine = void 0;
|
|
11
11
|
exports.findTokenNameByPropertyValue = findTokenNameByPropertyValue;
|
|
12
|
+
exports.getFontSizeFromNode = getFontSizeFromNode;
|
|
12
13
|
exports.getFontSizeValueInScope = getFontSizeValueInScope;
|
|
13
14
|
exports.getRawExpression = void 0;
|
|
14
15
|
exports.getTokenNodeForValue = getTokenNodeForValue;
|
|
@@ -20,7 +21,7 @@ exports.isTokenValueString = isTokenValueString;
|
|
|
20
21
|
exports.isZero = exports.isValidSpacingValue = void 0;
|
|
21
22
|
exports.normaliseValue = normaliseValue;
|
|
22
23
|
exports.processCssNode = processCssNode;
|
|
23
|
-
exports.removePixelSuffix = void 0;
|
|
24
|
+
exports.replacementComment = exports.removePixelSuffix = void 0;
|
|
24
25
|
exports.shouldAnalyzeProperty = shouldAnalyzeProperty;
|
|
25
26
|
exports.splitCssProperties = splitCssProperties;
|
|
26
27
|
exports.splitShorthandValues = void 0;
|
|
@@ -29,6 +30,8 @@ var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
|
29
30
|
var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
|
|
30
31
|
var _shape = require("./shape");
|
|
31
32
|
var _typography = require("./typography");
|
|
33
|
+
var replacementComment = '// TODO Delete this comment after verifying space token -> previous value';
|
|
34
|
+
exports.replacementComment = replacementComment;
|
|
32
35
|
var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingInline', 'paddingInlineStart', 'paddingInlineEnd', 'paddingBlock', 'paddingBlockStart', 'paddingBlockEnd', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginInline', 'marginInlineStart', 'marginInlineEnd', 'marginBlock', 'marginBlockStart', 'marginBlockEnd', 'margin', 'gap', 'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap', 'top', 'left', 'right', 'bottom', 'inlineStart', 'inlineEnd', 'blockStart', 'blockEnd', 'outline-offset'];
|
|
33
36
|
var spacingValueToToken = Object.fromEntries(_tokensRaw.spacing.map(function (token) {
|
|
34
37
|
return [token.value, token.name];
|
|
@@ -398,7 +401,7 @@ function processCssNode(node, context) {
|
|
|
398
401
|
var cssProperties = splitCssProperties(cleanComments(combinedString));
|
|
399
402
|
var unalteredCssProperties = splitCssProperties(cleanComments(rawString));
|
|
400
403
|
if (cssProperties.length !== unalteredCssProperties.length) {
|
|
401
|
-
// this means something
|
|
404
|
+
// this means something went wrong with the parsing, the original lines can't be reconciled with the processed lines
|
|
402
405
|
return undefined;
|
|
403
406
|
}
|
|
404
407
|
return cssProperties.map(function (cssProperty, index) {
|
|
@@ -527,4 +530,18 @@ function getTokenReplacement(propertyName, value) {
|
|
|
527
530
|
}
|
|
528
531
|
var fallbackValue = normaliseValue(propertyName, value);
|
|
529
532
|
return getTokenNodeForValue(propertyName, fallbackValue);
|
|
533
|
+
}
|
|
534
|
+
function getFontSizeFromNode(parentNode, context) {
|
|
535
|
+
var fontSizeNode = parentNode.properties.find(function (node) {
|
|
536
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'Property')) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Identifier')) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
return node.key.name === 'fontSize';
|
|
543
|
+
});
|
|
544
|
+
var fontSizeValue = (0, _eslintCodemodUtils.isNodeOfType)(fontSizeNode, 'Property') ? getValue(fontSizeNode.value, context) : null;
|
|
545
|
+
var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
546
|
+
return fontSize;
|
|
530
547
|
}
|
|
@@ -62,7 +62,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
62
62
|
});
|
|
63
63
|
// this is either a styled usage OR mixin usage in a styled usage
|
|
64
64
|
} else if (idNode.parent.type === 'CallExpression') {
|
|
65
|
-
if ((0, _isNode.
|
|
65
|
+
if ((0, _isNode.isCssInJsObjectNode)(idNode.parent) || (0, _isNode.isCssInJsTemplateNode)(idNode.parent)) {
|
|
66
66
|
context.report({
|
|
67
67
|
node: idNode.parent,
|
|
68
68
|
messageId: 'noDeprecatedUsage',
|
|
@@ -104,7 +104,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
104
104
|
if (!(node.callee.type === 'MemberExpression' || node.callee.type === 'Identifier')) {
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
|
-
var isStyled = (0, _isNode.
|
|
107
|
+
var isStyled = (0, _isNode.isCssInJsObjectNode)(node);
|
|
108
108
|
if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name !== 'styled') {
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.isPropertyKey = exports.isDecendantOfType = exports.isDecendantOfStyleJsxAttribute = exports.isDecendantOfStyleBlock = exports.isDecendantOfGlobalToken = exports.isCssInJsTemplateNode = exports.isCssInJsObjectNode = exports.isCssInJsCallNode = exports.isChildOfType = void 0;
|
|
7
7
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
8
|
var isDecendantOfGlobalToken = function isDecendantOfGlobalToken(node) {
|
|
9
9
|
if ((0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'token' || node.callee.name === 'getTokenValue')) {
|
|
@@ -44,14 +44,19 @@ var isDecendantOfStyleJsxAttribute = function isDecendantOfStyleJsxAttribute(nod
|
|
|
44
44
|
return false;
|
|
45
45
|
};
|
|
46
46
|
exports.isDecendantOfStyleJsxAttribute = isDecendantOfStyleJsxAttribute;
|
|
47
|
-
var
|
|
47
|
+
var cssInJsCallees = ['css', 'styled', 'styled2'];
|
|
48
|
+
var isCssInJsTemplateNode = function isCssInJsTemplateNode(node) {
|
|
48
49
|
return (node === null || node === void 0 ? void 0 : node.type) === 'TaggedTemplateExpression' && node.tag.type === 'MemberExpression' && node.tag.object.type === 'Identifier' && node.tag.object.name === 'styled';
|
|
49
50
|
};
|
|
50
|
-
exports.
|
|
51
|
-
var
|
|
52
|
-
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === '
|
|
51
|
+
exports.isCssInJsTemplateNode = isCssInJsTemplateNode;
|
|
52
|
+
var isCssInJsCallNode = function isCssInJsCallNode(node) {
|
|
53
|
+
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'Identifier' && cssInJsCallees.includes(node.callee.name);
|
|
53
54
|
};
|
|
54
|
-
exports.
|
|
55
|
+
exports.isCssInJsCallNode = isCssInJsCallNode;
|
|
56
|
+
var isCssInJsObjectNode = function isCssInJsObjectNode(node) {
|
|
57
|
+
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && cssInJsCallees.includes(node.callee.object.name);
|
|
58
|
+
};
|
|
59
|
+
exports.isCssInJsObjectNode = isCssInJsObjectNode;
|
|
55
60
|
var isDecendantOfStyleBlock = function isDecendantOfStyleBlock(node) {
|
|
56
61
|
if (node.type === 'VariableDeclarator') {
|
|
57
62
|
if (node.id.type !== 'Identifier') {
|
|
@@ -80,10 +85,7 @@ var isDecendantOfStyleBlock = function isDecendantOfStyleBlock(node) {
|
|
|
80
85
|
return varName.includes(el);
|
|
81
86
|
});
|
|
82
87
|
}
|
|
83
|
-
if (node
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
if (isStyledTemplateNode(node)) {
|
|
88
|
+
if (isCssInJsCallNode(node) || isCssInJsObjectNode(node) || isCssInJsTemplateNode(node)) {
|
|
87
89
|
return true;
|
|
88
90
|
}
|
|
89
91
|
if (node.type === 'TaggedTemplateExpression' && node.tag.type === 'Identifier' && node.tag.name === 'css') {
|
package/dist/cjs/version.json
CHANGED
|
@@ -93,6 +93,30 @@
|
|
|
93
93
|
"@atlaskit/item": {
|
|
94
94
|
"message": "item is deprecated. Please use '@atlaskit/menu' instead."
|
|
95
95
|
},
|
|
96
|
+
"@atlaskit/theme/elevation": {
|
|
97
|
+
"importSpecifiers": [
|
|
98
|
+
{
|
|
99
|
+
"importName": "e100",
|
|
100
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"importName": "e200",
|
|
104
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"importName": "e300",
|
|
108
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"importName": "e400",
|
|
112
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"importName": "e500",
|
|
116
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
},
|
|
96
120
|
"@atlaskit/theme/constants": {
|
|
97
121
|
"importSpecifiers": [
|
|
98
122
|
{
|
|
@@ -113,6 +137,34 @@
|
|
|
113
137
|
}
|
|
114
138
|
]
|
|
115
139
|
},
|
|
140
|
+
"@atlaskit/theme/colors": {
|
|
141
|
+
"importSpecifiers": [
|
|
142
|
+
{ "importName": "background", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
143
|
+
{ "importName": "backgroundActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
144
|
+
{ "importName": "backgroundHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
145
|
+
{ "importName": "backgroundOnLayer", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
146
|
+
{ "importName": "text", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
147
|
+
{ "importName": "textHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
148
|
+
{ "importName": "textActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
149
|
+
{ "importName": "subtleText", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
150
|
+
{ "importName": "placeholderText", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
151
|
+
{ "importName": "heading", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
152
|
+
{ "importName": "subtleHeading", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
153
|
+
{ "importName": "codeBlock", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
154
|
+
{ "importName": "link", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
155
|
+
{ "importName": "linkHover", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
156
|
+
{ "importName": "linkActive", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
157
|
+
{ "importName": "linkOutline", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
158
|
+
{ "importName": "primary", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
159
|
+
{ "importName": "blue", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
160
|
+
{ "importName": "teal", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
161
|
+
{ "importName": "purple", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
162
|
+
{ "importName": "red", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
163
|
+
{ "importName": "yellow", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
164
|
+
{ "importName": "green", "message": "Named color utils are deprecated in favor of design tokens." },
|
|
165
|
+
{ "importName": "skeleton", "message": "Named color utils are deprecated in favor of design tokens." }
|
|
166
|
+
]
|
|
167
|
+
},
|
|
116
168
|
"@atlaskit/theme": {
|
|
117
169
|
"importSpecifiers": [
|
|
118
170
|
{
|
|
@@ -130,6 +182,10 @@
|
|
|
130
182
|
{
|
|
131
183
|
"importName": "gridSize",
|
|
132
184
|
"message": "The gridSize mixin is deprecated. Please use space tokens via `@atlaskit/tokens` instead."
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"importName": "elevation",
|
|
188
|
+
"message": "Elevation mixin is deprecated. Please use design tokens instead."
|
|
133
189
|
}
|
|
134
190
|
]
|
|
135
191
|
},
|
|
@@ -40,6 +40,7 @@ const rule = createLintRule({
|
|
|
40
40
|
const config = context.options[0] || defaultConfig;
|
|
41
41
|
const isException = getIsException(config.exceptions);
|
|
42
42
|
return {
|
|
43
|
+
// For expressions within template literals (e.g. `color: ${red}`)
|
|
43
44
|
'TemplateLiteral > Identifier': node => {
|
|
44
45
|
if (node.type !== 'Identifier') {
|
|
45
46
|
return;
|
|
@@ -80,6 +81,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
80
81
|
return;
|
|
81
82
|
}
|
|
82
83
|
},
|
|
84
|
+
// For css/styled template literals (not handling expressions) (e.g. css`color: red`)
|
|
83
85
|
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': node => {
|
|
84
86
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
85
87
|
return;
|
|
@@ -102,6 +104,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
102
104
|
}
|
|
103
105
|
});
|
|
104
106
|
},
|
|
107
|
+
// For style objects with identifiers as values (expressions) (e.g. { color: red })
|
|
105
108
|
'ObjectExpression > Property > Identifier, ObjectExpression > Property > MemberExpression': node => {
|
|
106
109
|
if (isDecendantOfGlobalToken(node)) {
|
|
107
110
|
return;
|
|
@@ -149,6 +152,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
149
152
|
return;
|
|
150
153
|
}
|
|
151
154
|
},
|
|
155
|
+
// For style objects with literals as values (strings/numbers) (e.g. { color: "red" })
|
|
152
156
|
'ObjectExpression > Property > Literal': node => {
|
|
153
157
|
var _node$value;
|
|
154
158
|
if (node.type !== 'Literal') {
|
|
@@ -169,6 +173,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
169
173
|
});
|
|
170
174
|
}
|
|
171
175
|
},
|
|
176
|
+
// For style objects with function calls as values (e.g. { color: red() })
|
|
172
177
|
'ObjectExpression > Property > CallExpression': node => {
|
|
173
178
|
if (node.type !== 'CallExpression') {
|
|
174
179
|
return;
|
|
@@ -191,6 +196,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
191
196
|
suggest: getTokenSuggestion(node, `${node.callee.name}()`, config)
|
|
192
197
|
});
|
|
193
198
|
},
|
|
199
|
+
// For inline JSX styles - literals (e.g. <Test color="red"/>)
|
|
194
200
|
'JSXAttribute > Literal': node => {
|
|
195
201
|
if (node.type !== 'Literal') {
|
|
196
202
|
return;
|
|
@@ -221,6 +227,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
221
227
|
return;
|
|
222
228
|
}
|
|
223
229
|
},
|
|
230
|
+
// For inline JSX styles - members (e.g. <Test color={color.red}/>)
|
|
224
231
|
'JSXExpressionContainer > MemberExpression': node => {
|
|
225
232
|
if (node.type !== 'MemberExpression') {
|
|
226
233
|
return;
|
|
@@ -236,6 +243,7 @@ ${' '.repeat(getNodeColumn(node) - 2)}box-shadow: \${token('${elevation.shadow}'
|
|
|
236
243
|
});
|
|
237
244
|
}
|
|
238
245
|
},
|
|
246
|
+
// For inline JSX styles - identifiers (e.g. <Test color={red}/>)
|
|
239
247
|
'JSXExpressionContainer > Identifier': node => {
|
|
240
248
|
if (node.type !== 'Identifier') {
|
|
241
249
|
return;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { isNodeOfType, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
4
4
|
import { createRule } from '../utils/create-rule';
|
|
5
|
-
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
6
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, splitShorthandValues } from './utils';
|
|
5
|
+
import { isDecendantOfGlobalToken, isDecendantOfStyleBlock, isDecendantOfType } from '../utils/is-node';
|
|
6
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeFromNode, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, replacementComment, shouldAnalyzeProperty, splitShorthandValues } from './utils';
|
|
7
7
|
const rule = createRule({
|
|
8
8
|
defaultOptions: [{
|
|
9
9
|
addons: ['spacing'],
|
|
@@ -60,25 +60,23 @@ const rule = createRule({
|
|
|
60
60
|
},
|
|
61
61
|
// CSSObjectExpression
|
|
62
62
|
// const styles = css({ color: 'red', margin: '4px' }), styled.div({ color: 'red', margin: '4px' })
|
|
63
|
-
|
|
63
|
+
ObjectExpression: parentNode => {
|
|
64
64
|
if (!isNodeOfType(parentNode, 'ObjectExpression')) {
|
|
65
65
|
return;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
// Return for nested objects - these get handled automatically so without returning we'd be doubling up
|
|
69
|
+
if (parentNode.parent.type === 'Property') {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!isDecendantOfStyleBlock(parentNode) && !isDecendantOfType(parentNode, 'JSXExpressionContainer')) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
68
76
|
/**
|
|
69
77
|
* We do this in case the fontSize for a style object is declared alongside the `em` or `lineHeight` declaration
|
|
70
78
|
*/
|
|
71
|
-
const
|
|
72
|
-
if (!isNodeOfType(node, 'Property')) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (!isNodeOfType(node.key, 'Identifier')) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
return node.key.name === 'fontSize';
|
|
79
|
-
});
|
|
80
|
-
const fontSizeValue = isNodeOfType(fontSizeNode, 'Property') ? getValue(fontSizeNode.value, context) : null;
|
|
81
|
-
const fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
79
|
+
const fontSize = getFontSizeFromNode(parentNode, context);
|
|
82
80
|
function findObjectStyles(node) {
|
|
83
81
|
if (!isNodeOfType(node, 'Property')) {
|
|
84
82
|
return;
|
|
@@ -117,7 +115,7 @@ const rule = createRule({
|
|
|
117
115
|
const isFontFamily = /fontFamily/.test(propertyName);
|
|
118
116
|
const value = getValue(node.value, context);
|
|
119
117
|
|
|
120
|
-
// value is either NaN or it can't be resolved
|
|
118
|
+
// value is either NaN or it can't be resolved (e.g. em, 100% etc...)
|
|
121
119
|
if (!(value && isValidSpacingValue(value, fontSize))) {
|
|
122
120
|
return context.report({
|
|
123
121
|
node,
|
|
@@ -127,12 +125,14 @@ const rule = createRule({
|
|
|
127
125
|
}
|
|
128
126
|
});
|
|
129
127
|
}
|
|
130
|
-
|
|
128
|
+
|
|
129
|
+
// The corresponding values for a single CSS property (e.g. padding: '8px 16px 2px' => [8, 16, 2])
|
|
130
|
+
const valuesForProperty = Array.isArray(value) ? value : [value];
|
|
131
131
|
|
|
132
132
|
// value is a single value so we can apply a more robust approach to our fix
|
|
133
133
|
// treat fontFamily as having one value
|
|
134
|
-
if (
|
|
135
|
-
const [value] =
|
|
134
|
+
if (valuesForProperty.length === 1 || isFontFamily) {
|
|
135
|
+
const [value] = valuesForProperty;
|
|
136
136
|
|
|
137
137
|
// Do not report or suggest a token to replace 0 or auto
|
|
138
138
|
if (isZero(value) || isAuto(value)) {
|
|
@@ -154,7 +154,7 @@ const rule = createRule({
|
|
|
154
154
|
if (!replacementNode) {
|
|
155
155
|
return null;
|
|
156
156
|
}
|
|
157
|
-
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.insertTextBefore(node,
|
|
157
|
+
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.insertTextBefore(node, `${replacementComment} \`${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({
|
|
158
158
|
...node,
|
|
159
159
|
value: replacementNode
|
|
160
160
|
}).toString())]);
|
|
@@ -169,7 +169,7 @@ const rule = createRule({
|
|
|
169
169
|
* @example
|
|
170
170
|
* { padding: '8px 0px' }
|
|
171
171
|
*/
|
|
172
|
-
|
|
172
|
+
valuesForProperty.forEach(val => {
|
|
173
173
|
const pixelValue = emToPixels(val, fontSize);
|
|
174
174
|
|
|
175
175
|
// Do not report or suggest a token to replace 0 or auto
|
|
@@ -183,11 +183,11 @@ const rule = createRule({
|
|
|
183
183
|
payload: `${propertyName}:${pixelValue}`
|
|
184
184
|
},
|
|
185
185
|
fix: fixer => {
|
|
186
|
-
const allResolvableValues =
|
|
186
|
+
const allResolvableValues = valuesForProperty.every(value => !Number.isNaN(emToPixels(value, fontSize)));
|
|
187
187
|
if (!allResolvableValues) {
|
|
188
188
|
return null;
|
|
189
189
|
}
|
|
190
|
-
const valuesWithTokenReplacement =
|
|
190
|
+
const valuesWithTokenReplacement = valuesForProperty.filter(value => findTokenNameByPropertyValue(propertyName, value)).filter(value => value !== 0);
|
|
191
191
|
if (valuesWithTokenReplacement.length === 0) {
|
|
192
192
|
// all values could be replaceable but that just means they're numeric
|
|
193
193
|
// if none of the values have token replacement we bail
|
|
@@ -204,11 +204,11 @@ const rule = createRule({
|
|
|
204
204
|
* given they're part of the substring of the current node
|
|
205
205
|
*/
|
|
206
206
|
const originalValues = splitShorthandValues(originalCssString.replace(/`|'|"/g, ''));
|
|
207
|
-
if (originalValues.length !==
|
|
207
|
+
if (originalValues.length !== valuesForProperty.length) {
|
|
208
208
|
// we bail just in case original values don't correspond to the replaced values
|
|
209
209
|
return null;
|
|
210
210
|
}
|
|
211
|
-
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, `\`${
|
|
211
|
+
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, `\`${valuesForProperty.map((value, index) => {
|
|
212
212
|
if (isZero(value)) {
|
|
213
213
|
return originalValues[index];
|
|
214
214
|
}
|
|
@@ -289,11 +289,11 @@ const rule = createRule({
|
|
|
289
289
|
});
|
|
290
290
|
|
|
291
291
|
// from here on we know value is numeric or a font family, so it might or might not have a token equivalent
|
|
292
|
-
const
|
|
293
|
-
if (!
|
|
292
|
+
const replacementNode = getTokenReplacement(propertyName, numericOrNanValue);
|
|
293
|
+
if (!replacementNode) {
|
|
294
294
|
return originalValue;
|
|
295
295
|
}
|
|
296
|
-
const replacementToken = '${' +
|
|
296
|
+
const replacementToken = '${' + replacementNode.toString() + '}';
|
|
297
297
|
replacedValuesPerProperty.push(isFontFamily ? numericOrNanValue.trim() : pxValue);
|
|
298
298
|
return replacementToken;
|
|
299
299
|
}).join(' ');
|
|
@@ -312,12 +312,12 @@ const rule = createRule({
|
|
|
312
312
|
return replacedCssLine;
|
|
313
313
|
}, textForSource);
|
|
314
314
|
if (completeSource !== textForSource) {
|
|
315
|
-
// means we found some replacement values,
|
|
315
|
+
// means we found some replacement values, we'll give the option to fix them
|
|
316
316
|
|
|
317
317
|
const replacementComments = `${allReplacedValues.map(replacedProperties => {
|
|
318
318
|
const [propertyName] = replacedProperties;
|
|
319
319
|
const replacedValues = replacedProperties.slice(1).join(' ');
|
|
320
|
-
return
|
|
320
|
+
return `${replacementComment} \`${propertyName}: ${replacedValues}\``;
|
|
321
321
|
}).join('\n')}\n`;
|
|
322
322
|
context.report({
|
|
323
323
|
node,
|
|
@@ -2,6 +2,7 @@ import { callExpression, identifier, insertAtStartOfFile, insertImportDeclaratio
|
|
|
2
2
|
import { spacing as spacingScale } from '@atlaskit/tokens/tokens-raw';
|
|
3
3
|
import { borderWidthValueToToken, isBorderRadius, isBorderSizeProperty, isShapeProperty, radiusValueToToken } from './shape';
|
|
4
4
|
import { isCodeFontFamily, isFontFamily, isFontSize, isFontSizeSmall, isTypographyProperty, typographyValueToToken } from './typography';
|
|
5
|
+
export const replacementComment = '// TODO Delete this comment after verifying space token -> previous value';
|
|
5
6
|
const properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingInline', 'paddingInlineStart', 'paddingInlineEnd', 'paddingBlock', 'paddingBlockStart', 'paddingBlockEnd', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginInline', 'marginInlineStart', 'marginInlineEnd', 'marginBlock', 'marginBlockStart', 'marginBlockEnd', 'margin', 'gap', 'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap', 'top', 'left', 'right', 'bottom', 'inlineStart', 'inlineEnd', 'blockStart', 'blockEnd', 'outline-offset'];
|
|
6
7
|
const spacingValueToToken = Object.fromEntries(spacingScale.map(token => [token.value, token.name]));
|
|
7
8
|
export function findIdentifierInParentScope({
|
|
@@ -349,7 +350,7 @@ export function processCssNode(node, context) {
|
|
|
349
350
|
const cssProperties = splitCssProperties(cleanComments(combinedString));
|
|
350
351
|
const unalteredCssProperties = splitCssProperties(cleanComments(rawString));
|
|
351
352
|
if (cssProperties.length !== unalteredCssProperties.length) {
|
|
352
|
-
// this means something
|
|
353
|
+
// this means something went wrong with the parsing, the original lines can't be reconciled with the processed lines
|
|
353
354
|
return undefined;
|
|
354
355
|
}
|
|
355
356
|
return cssProperties.map((cssProperty, index) => [cssProperty, unalteredCssProperties[index]]);
|
|
@@ -458,4 +459,18 @@ export function getTokenReplacement(propertyName, value) {
|
|
|
458
459
|
}
|
|
459
460
|
const fallbackValue = normaliseValue(propertyName, value);
|
|
460
461
|
return getTokenNodeForValue(propertyName, fallbackValue);
|
|
462
|
+
}
|
|
463
|
+
export function getFontSizeFromNode(parentNode, context) {
|
|
464
|
+
const fontSizeNode = parentNode.properties.find(node => {
|
|
465
|
+
if (!isNodeOfType(node, 'Property')) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (!isNodeOfType(node.key, 'Identifier')) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
return node.key.name === 'fontSize';
|
|
472
|
+
});
|
|
473
|
+
const fontSizeValue = isNodeOfType(fontSizeNode, 'Property') ? getValue(fontSizeNode.value, context) : null;
|
|
474
|
+
const fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
475
|
+
return fontSize;
|
|
461
476
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { closestOfType, hasImportDeclaration, isNodeOfType } from 'eslint-codemod-utils';
|
|
2
2
|
import { createLintRule } from '../utils/create-rule';
|
|
3
|
-
import {
|
|
3
|
+
import { isCssInJsObjectNode, isCssInJsTemplateNode } from '../utils/is-node';
|
|
4
4
|
import fixJsx from './fix-jsx';
|
|
5
5
|
import fixVanilla from './fix-vanilla';
|
|
6
6
|
import { countMatchingKeyValues, getObjectLikeness, makeTemplateLiteralIntoEntries } from './utils';
|
|
@@ -48,7 +48,7 @@ const rule = createLintRule({
|
|
|
48
48
|
});
|
|
49
49
|
// this is either a styled usage OR mixin usage in a styled usage
|
|
50
50
|
} else if (idNode.parent.type === 'CallExpression') {
|
|
51
|
-
if (
|
|
51
|
+
if (isCssInJsObjectNode(idNode.parent) || isCssInJsTemplateNode(idNode.parent)) {
|
|
52
52
|
context.report({
|
|
53
53
|
node: idNode.parent,
|
|
54
54
|
messageId: 'noDeprecatedUsage',
|
|
@@ -90,7 +90,7 @@ const rule = createLintRule({
|
|
|
90
90
|
if (!(node.callee.type === 'MemberExpression' || node.callee.type === 'Identifier')) {
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
const isStyled =
|
|
93
|
+
const isStyled = isCssInJsObjectNode(node);
|
|
94
94
|
if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name !== 'styled') {
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
@@ -33,8 +33,10 @@ export const isDecendantOfStyleJsxAttribute = node => {
|
|
|
33
33
|
}
|
|
34
34
|
return false;
|
|
35
35
|
};
|
|
36
|
-
|
|
37
|
-
export const
|
|
36
|
+
const cssInJsCallees = ['css', 'styled', 'styled2'];
|
|
37
|
+
export const isCssInJsTemplateNode = node => (node === null || node === void 0 ? void 0 : node.type) === 'TaggedTemplateExpression' && node.tag.type === 'MemberExpression' && node.tag.object.type === 'Identifier' && node.tag.object.name === 'styled';
|
|
38
|
+
export const isCssInJsCallNode = node => (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'Identifier' && cssInJsCallees.includes(node.callee.name);
|
|
39
|
+
export const isCssInJsObjectNode = node => (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && cssInJsCallees.includes(node.callee.object.name);
|
|
38
40
|
export const isDecendantOfStyleBlock = node => {
|
|
39
41
|
if (node.type === 'VariableDeclarator') {
|
|
40
42
|
if (node.id.type !== 'Identifier') {
|
|
@@ -59,10 +61,7 @@ export const isDecendantOfStyleBlock = node => {
|
|
|
59
61
|
const varName = node.id.name.toLowerCase();
|
|
60
62
|
return ['style', 'css', 'theme'].some(el => varName.includes(el));
|
|
61
63
|
}
|
|
62
|
-
if (node
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
if (isStyledTemplateNode(node)) {
|
|
64
|
+
if (isCssInJsCallNode(node) || isCssInJsObjectNode(node) || isCssInJsTemplateNode(node)) {
|
|
66
65
|
return true;
|
|
67
66
|
}
|
|
68
67
|
if (node.type === 'TaggedTemplateExpression' && node.tag.type === 'Identifier' && node.tag.name === 'css') {
|
package/dist/es2019/version.json
CHANGED
|
@@ -49,6 +49,7 @@ var rule = createLintRule({
|
|
|
49
49
|
var config = context.options[0] || defaultConfig;
|
|
50
50
|
var isException = getIsException(config.exceptions);
|
|
51
51
|
return {
|
|
52
|
+
// For expressions within template literals (e.g. `color: ${red}`)
|
|
52
53
|
'TemplateLiteral > Identifier': function TemplateLiteralIdentifier(node) {
|
|
53
54
|
if (node.type !== 'Identifier') {
|
|
54
55
|
return;
|
|
@@ -81,6 +82,7 @@ var rule = createLintRule({
|
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
84
|
},
|
|
85
|
+
// For css/styled template literals (not handling expressions) (e.g. css`color: red`)
|
|
84
86
|
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': function TaggedTemplateExpressionTagNameCssTaggedTemplateExpressionTagObjectNameStyled(node) {
|
|
85
87
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
86
88
|
return;
|
|
@@ -107,6 +109,7 @@ var rule = createLintRule({
|
|
|
107
109
|
}
|
|
108
110
|
});
|
|
109
111
|
},
|
|
112
|
+
// For style objects with identifiers as values (expressions) (e.g. { color: red })
|
|
110
113
|
'ObjectExpression > Property > Identifier, ObjectExpression > Property > MemberExpression': function ObjectExpressionPropertyIdentifierObjectExpressionPropertyMemberExpression(node) {
|
|
111
114
|
if (isDecendantOfGlobalToken(node)) {
|
|
112
115
|
return;
|
|
@@ -154,6 +157,7 @@ var rule = createLintRule({
|
|
|
154
157
|
return;
|
|
155
158
|
}
|
|
156
159
|
},
|
|
160
|
+
// For style objects with literals as values (strings/numbers) (e.g. { color: "red" })
|
|
157
161
|
'ObjectExpression > Property > Literal': function ObjectExpressionPropertyLiteral(node) {
|
|
158
162
|
var _node$value;
|
|
159
163
|
if (node.type !== 'Literal') {
|
|
@@ -174,6 +178,7 @@ var rule = createLintRule({
|
|
|
174
178
|
});
|
|
175
179
|
}
|
|
176
180
|
},
|
|
181
|
+
// For style objects with function calls as values (e.g. { color: red() })
|
|
177
182
|
'ObjectExpression > Property > CallExpression': function ObjectExpressionPropertyCallExpression(node) {
|
|
178
183
|
if (node.type !== 'CallExpression') {
|
|
179
184
|
return;
|
|
@@ -196,6 +201,7 @@ var rule = createLintRule({
|
|
|
196
201
|
suggest: getTokenSuggestion(node, "".concat(node.callee.name, "()"), config)
|
|
197
202
|
});
|
|
198
203
|
},
|
|
204
|
+
// For inline JSX styles - literals (e.g. <Test color="red"/>)
|
|
199
205
|
'JSXAttribute > Literal': function JSXAttributeLiteral(node) {
|
|
200
206
|
if (node.type !== 'Literal') {
|
|
201
207
|
return;
|
|
@@ -226,6 +232,7 @@ var rule = createLintRule({
|
|
|
226
232
|
return;
|
|
227
233
|
}
|
|
228
234
|
},
|
|
235
|
+
// For inline JSX styles - members (e.g. <Test color={color.red}/>)
|
|
229
236
|
'JSXExpressionContainer > MemberExpression': function JSXExpressionContainerMemberExpression(node) {
|
|
230
237
|
if (node.type !== 'MemberExpression') {
|
|
231
238
|
return;
|
|
@@ -241,6 +248,7 @@ var rule = createLintRule({
|
|
|
241
248
|
});
|
|
242
249
|
}
|
|
243
250
|
},
|
|
251
|
+
// For inline JSX styles - identifiers (e.g. <Test color={red}/>)
|
|
244
252
|
'JSXExpressionContainer > Identifier': function JSXExpressionContainerIdentifier(node) {
|
|
245
253
|
if (node.type !== 'Identifier') {
|
|
246
254
|
return;
|
|
@@ -7,8 +7,8 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
7
7
|
|
|
8
8
|
import { isNodeOfType, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
9
9
|
import { createRule } from '../utils/create-rule';
|
|
10
|
-
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
11
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, splitShorthandValues } from './utils';
|
|
10
|
+
import { isDecendantOfGlobalToken, isDecendantOfStyleBlock, isDecendantOfType } from '../utils/is-node';
|
|
11
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeFromNode, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isAuto, isCalc, isTokenValueString, isValidSpacingValue, isZero, processCssNode, replacementComment, shouldAnalyzeProperty, splitShorthandValues } from './utils';
|
|
12
12
|
var rule = createRule({
|
|
13
13
|
defaultOptions: [{
|
|
14
14
|
addons: ['spacing'],
|
|
@@ -64,25 +64,23 @@ var rule = createRule({
|
|
|
64
64
|
},
|
|
65
65
|
// CSSObjectExpression
|
|
66
66
|
// const styles = css({ color: 'red', margin: '4px' }), styled.div({ color: 'red', margin: '4px' })
|
|
67
|
-
|
|
67
|
+
ObjectExpression: function ObjectExpression(parentNode) {
|
|
68
68
|
if (!isNodeOfType(parentNode, 'ObjectExpression')) {
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Return for nested objects - these get handled automatically so without returning we'd be doubling up
|
|
73
|
+
if (parentNode.parent.type === 'Property') {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!isDecendantOfStyleBlock(parentNode) && !isDecendantOfType(parentNode, 'JSXExpressionContainer')) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
72
80
|
/**
|
|
73
81
|
* We do this in case the fontSize for a style object is declared alongside the `em` or `lineHeight` declaration
|
|
74
82
|
*/
|
|
75
|
-
var
|
|
76
|
-
if (!isNodeOfType(node, 'Property')) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (!isNodeOfType(node.key, 'Identifier')) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
return node.key.name === 'fontSize';
|
|
83
|
-
});
|
|
84
|
-
var fontSizeValue = isNodeOfType(fontSizeNode, 'Property') ? getValue(fontSizeNode.value, context) : null;
|
|
85
|
-
var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
83
|
+
var fontSize = getFontSizeFromNode(parentNode, context);
|
|
86
84
|
function findObjectStyles(node) {
|
|
87
85
|
if (!isNodeOfType(node, 'Property')) {
|
|
88
86
|
return;
|
|
@@ -121,7 +119,7 @@ var rule = createRule({
|
|
|
121
119
|
var isFontFamily = /fontFamily/.test(propertyName);
|
|
122
120
|
var value = getValue(node.value, context);
|
|
123
121
|
|
|
124
|
-
// value is either NaN or it can't be resolved
|
|
122
|
+
// value is either NaN or it can't be resolved (e.g. em, 100% etc...)
|
|
125
123
|
if (!(value && isValidSpacingValue(value, fontSize))) {
|
|
126
124
|
return context.report({
|
|
127
125
|
node: node,
|
|
@@ -131,13 +129,15 @@ var rule = createRule({
|
|
|
131
129
|
}
|
|
132
130
|
});
|
|
133
131
|
}
|
|
134
|
-
|
|
132
|
+
|
|
133
|
+
// The corresponding values for a single CSS property (e.g. padding: '8px 16px 2px' => [8, 16, 2])
|
|
134
|
+
var valuesForProperty = Array.isArray(value) ? value : [value];
|
|
135
135
|
|
|
136
136
|
// value is a single value so we can apply a more robust approach to our fix
|
|
137
137
|
// treat fontFamily as having one value
|
|
138
|
-
if (
|
|
139
|
-
var
|
|
140
|
-
_value =
|
|
138
|
+
if (valuesForProperty.length === 1 || isFontFamily) {
|
|
139
|
+
var _valuesForProperty = _slicedToArray(valuesForProperty, 1),
|
|
140
|
+
_value = _valuesForProperty[0];
|
|
141
141
|
|
|
142
142
|
// Do not report or suggest a token to replace 0 or auto
|
|
143
143
|
if (isZero(_value) || isAuto(_value)) {
|
|
@@ -159,7 +159,7 @@ var rule = createRule({
|
|
|
159
159
|
if (!replacementNode) {
|
|
160
160
|
return null;
|
|
161
161
|
}
|
|
162
|
-
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.insertTextBefore(node, "
|
|
162
|
+
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.insertTextBefore(node, "".concat(replacementComment, " `").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), {}, {
|
|
163
163
|
value: replacementNode
|
|
164
164
|
})).toString())]);
|
|
165
165
|
}
|
|
@@ -173,7 +173,7 @@ var rule = createRule({
|
|
|
173
173
|
* @example
|
|
174
174
|
* { padding: '8px 0px' }
|
|
175
175
|
*/
|
|
176
|
-
|
|
176
|
+
valuesForProperty.forEach(function (val) {
|
|
177
177
|
var pixelValue = emToPixels(val, fontSize);
|
|
178
178
|
|
|
179
179
|
// Do not report or suggest a token to replace 0 or auto
|
|
@@ -187,13 +187,13 @@ var rule = createRule({
|
|
|
187
187
|
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
188
188
|
},
|
|
189
189
|
fix: function fix(fixer) {
|
|
190
|
-
var allResolvableValues =
|
|
190
|
+
var allResolvableValues = valuesForProperty.every(function (value) {
|
|
191
191
|
return !Number.isNaN(emToPixels(value, fontSize));
|
|
192
192
|
});
|
|
193
193
|
if (!allResolvableValues) {
|
|
194
194
|
return null;
|
|
195
195
|
}
|
|
196
|
-
var valuesWithTokenReplacement =
|
|
196
|
+
var valuesWithTokenReplacement = valuesForProperty.filter(function (value) {
|
|
197
197
|
return findTokenNameByPropertyValue(propertyName, value);
|
|
198
198
|
}).filter(function (value) {
|
|
199
199
|
return value !== 0;
|
|
@@ -214,11 +214,11 @@ var rule = createRule({
|
|
|
214
214
|
* given they're part of the substring of the current node
|
|
215
215
|
*/
|
|
216
216
|
var originalValues = splitShorthandValues(originalCssString.replace(/`|'|"/g, ''));
|
|
217
|
-
if (originalValues.length !==
|
|
217
|
+
if (originalValues.length !== valuesForProperty.length) {
|
|
218
218
|
// we bail just in case original values don't correspond to the replaced values
|
|
219
219
|
return null;
|
|
220
220
|
}
|
|
221
|
-
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(
|
|
221
|
+
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(valuesForProperty.map(function (value, index) {
|
|
222
222
|
if (isZero(value)) {
|
|
223
223
|
return originalValues[index];
|
|
224
224
|
}
|
|
@@ -314,11 +314,11 @@ var rule = createRule({
|
|
|
314
314
|
});
|
|
315
315
|
|
|
316
316
|
// from here on we know value is numeric or a font family, so it might or might not have a token equivalent
|
|
317
|
-
var
|
|
318
|
-
if (!
|
|
317
|
+
var replacementNode = getTokenReplacement(propertyName, numericOrNanValue);
|
|
318
|
+
if (!replacementNode) {
|
|
319
319
|
return originalValue;
|
|
320
320
|
}
|
|
321
|
-
var replacementToken = '${' +
|
|
321
|
+
var replacementToken = '${' + replacementNode.toString() + '}';
|
|
322
322
|
replacedValuesPerProperty.push(isFontFamily ? numericOrNanValue.trim() : pxValue);
|
|
323
323
|
return replacementToken;
|
|
324
324
|
}).join(' ');
|
|
@@ -336,13 +336,13 @@ var rule = createRule({
|
|
|
336
336
|
return replacedCssLine;
|
|
337
337
|
}, textForSource);
|
|
338
338
|
if (completeSource !== textForSource) {
|
|
339
|
-
// means we found some replacement values,
|
|
339
|
+
// means we found some replacement values, we'll give the option to fix them
|
|
340
340
|
|
|
341
341
|
var replacementComments = "".concat(allReplacedValues.map(function (replacedProperties) {
|
|
342
342
|
var _replacedProperties = _slicedToArray(replacedProperties, 1),
|
|
343
343
|
propertyName = _replacedProperties[0];
|
|
344
344
|
var replacedValues = replacedProperties.slice(1).join(' ');
|
|
345
|
-
return "
|
|
345
|
+
return "".concat(replacementComment, " `").concat(propertyName, ": ").concat(replacedValues, "`");
|
|
346
346
|
}).join('\n'), "\n");
|
|
347
347
|
context.report({
|
|
348
348
|
node: node,
|
|
@@ -3,6 +3,7 @@ import { callExpression, identifier, insertAtStartOfFile, insertImportDeclaratio
|
|
|
3
3
|
import { spacing as spacingScale } from '@atlaskit/tokens/tokens-raw';
|
|
4
4
|
import { borderWidthValueToToken, isBorderRadius, isBorderSizeProperty, isShapeProperty, radiusValueToToken } from './shape';
|
|
5
5
|
import { isCodeFontFamily, isFontFamily, isFontSize, isFontSizeSmall, isTypographyProperty, typographyValueToToken } from './typography';
|
|
6
|
+
export var replacementComment = '// TODO Delete this comment after verifying space token -> previous value';
|
|
6
7
|
var properties = ['padding', 'paddingBlock', 'paddingInline', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingInline', 'paddingInlineStart', 'paddingInlineEnd', 'paddingBlock', 'paddingBlockStart', 'paddingBlockEnd', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'marginInline', 'marginInlineStart', 'marginInlineEnd', 'marginBlock', 'marginBlockStart', 'marginBlockEnd', 'margin', 'gap', 'rowGap', 'gridRowGap', 'columnGap', 'gridColumnGap', 'top', 'left', 'right', 'bottom', 'inlineStart', 'inlineEnd', 'blockStart', 'blockEnd', 'outline-offset'];
|
|
7
8
|
var spacingValueToToken = Object.fromEntries(spacingScale.map(function (token) {
|
|
8
9
|
return [token.value, token.name];
|
|
@@ -359,7 +360,7 @@ export function processCssNode(node, context) {
|
|
|
359
360
|
var cssProperties = splitCssProperties(cleanComments(combinedString));
|
|
360
361
|
var unalteredCssProperties = splitCssProperties(cleanComments(rawString));
|
|
361
362
|
if (cssProperties.length !== unalteredCssProperties.length) {
|
|
362
|
-
// this means something
|
|
363
|
+
// this means something went wrong with the parsing, the original lines can't be reconciled with the processed lines
|
|
363
364
|
return undefined;
|
|
364
365
|
}
|
|
365
366
|
return cssProperties.map(function (cssProperty, index) {
|
|
@@ -488,4 +489,18 @@ export function getTokenReplacement(propertyName, value) {
|
|
|
488
489
|
}
|
|
489
490
|
var fallbackValue = normaliseValue(propertyName, value);
|
|
490
491
|
return getTokenNodeForValue(propertyName, fallbackValue);
|
|
492
|
+
}
|
|
493
|
+
export function getFontSizeFromNode(parentNode, context) {
|
|
494
|
+
var fontSizeNode = parentNode.properties.find(function (node) {
|
|
495
|
+
if (!isNodeOfType(node, 'Property')) {
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
if (!isNodeOfType(node.key, 'Identifier')) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
return node.key.name === 'fontSize';
|
|
502
|
+
});
|
|
503
|
+
var fontSizeValue = isNodeOfType(fontSizeNode, 'Property') ? getValue(fontSizeNode.value, context) : null;
|
|
504
|
+
var fontSize = Array.isArray(fontSizeValue) ? fontSizeValue[0] : fontSizeValue;
|
|
505
|
+
return fontSize;
|
|
491
506
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
2
|
import { closestOfType, hasImportDeclaration, isNodeOfType } from 'eslint-codemod-utils';
|
|
3
3
|
import { createLintRule } from '../utils/create-rule';
|
|
4
|
-
import {
|
|
4
|
+
import { isCssInJsObjectNode, isCssInJsTemplateNode } from '../utils/is-node';
|
|
5
5
|
import fixJsx from './fix-jsx';
|
|
6
6
|
import fixVanilla from './fix-vanilla';
|
|
7
7
|
import { countMatchingKeyValues, getObjectLikeness, makeTemplateLiteralIntoEntries } from './utils';
|
|
@@ -55,7 +55,7 @@ var rule = createLintRule({
|
|
|
55
55
|
});
|
|
56
56
|
// this is either a styled usage OR mixin usage in a styled usage
|
|
57
57
|
} else if (idNode.parent.type === 'CallExpression') {
|
|
58
|
-
if (
|
|
58
|
+
if (isCssInJsObjectNode(idNode.parent) || isCssInJsTemplateNode(idNode.parent)) {
|
|
59
59
|
context.report({
|
|
60
60
|
node: idNode.parent,
|
|
61
61
|
messageId: 'noDeprecatedUsage',
|
|
@@ -97,7 +97,7 @@ var rule = createLintRule({
|
|
|
97
97
|
if (!(node.callee.type === 'MemberExpression' || node.callee.type === 'Identifier')) {
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
var isStyled =
|
|
100
|
+
var isStyled = isCssInJsObjectNode(node);
|
|
101
101
|
if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name !== 'styled') {
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
@@ -34,11 +34,15 @@ export var isDecendantOfStyleJsxAttribute = function isDecendantOfStyleJsxAttrib
|
|
|
34
34
|
}
|
|
35
35
|
return false;
|
|
36
36
|
};
|
|
37
|
-
|
|
37
|
+
var cssInJsCallees = ['css', 'styled', 'styled2'];
|
|
38
|
+
export var isCssInJsTemplateNode = function isCssInJsTemplateNode(node) {
|
|
38
39
|
return (node === null || node === void 0 ? void 0 : node.type) === 'TaggedTemplateExpression' && node.tag.type === 'MemberExpression' && node.tag.object.type === 'Identifier' && node.tag.object.name === 'styled';
|
|
39
40
|
};
|
|
40
|
-
export var
|
|
41
|
-
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === '
|
|
41
|
+
export var isCssInJsCallNode = function isCssInJsCallNode(node) {
|
|
42
|
+
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'Identifier' && cssInJsCallees.includes(node.callee.name);
|
|
43
|
+
};
|
|
44
|
+
export var isCssInJsObjectNode = function isCssInJsObjectNode(node) {
|
|
45
|
+
return (node === null || node === void 0 ? void 0 : node.type) === 'CallExpression' && node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && cssInJsCallees.includes(node.callee.object.name);
|
|
42
46
|
};
|
|
43
47
|
export var isDecendantOfStyleBlock = function isDecendantOfStyleBlock(node) {
|
|
44
48
|
if (node.type === 'VariableDeclarator') {
|
|
@@ -68,10 +72,7 @@ export var isDecendantOfStyleBlock = function isDecendantOfStyleBlock(node) {
|
|
|
68
72
|
return varName.includes(el);
|
|
69
73
|
});
|
|
70
74
|
}
|
|
71
|
-
if (node
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
if (isStyledTemplateNode(node)) {
|
|
75
|
+
if (isCssInJsCallNode(node) || isCssInJsObjectNode(node) || isCssInJsTemplateNode(node)) {
|
|
75
76
|
return true;
|
|
76
77
|
}
|
|
77
78
|
if (node.type === 'TaggedTemplateExpression' && node.tag.type === 'Identifier' && node.tag.name === 'css') {
|
package/dist/esm/version.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Rule, Scope } from 'eslint';
|
|
2
|
-
import { EslintNode, TaggedTemplateExpression } from 'eslint-codemod-utils';
|
|
2
|
+
import { EslintNode, ObjectExpression, TaggedTemplateExpression } from 'eslint-codemod-utils';
|
|
3
|
+
export declare const replacementComment = "// TODO Delete this comment after verifying space token -> previous value";
|
|
3
4
|
export type ProcessedCSSLines = [string, string][];
|
|
4
5
|
export type TargetOptions = ('spacing' | 'typography' | 'shape')[];
|
|
5
6
|
export declare function findIdentifierInParentScope({ scope, identifierName, }: {
|
|
@@ -106,3 +107,4 @@ export declare function findTokenNameByPropertyValue(propertyName: string, value
|
|
|
106
107
|
* @param value the computed value e.g '8px' -> '8'
|
|
107
108
|
*/
|
|
108
109
|
export declare function getTokenReplacement(propertyName: string, value: string): import("eslint-codemod-utils").StringableASTNode<import("estree").SimpleCallExpression> | undefined;
|
|
110
|
+
export declare function getFontSizeFromNode(parentNode: ObjectExpression & Rule.NodeParentExtension, context: Rule.RuleContext): any;
|
|
@@ -4,7 +4,8 @@ export declare const isDecendantOfGlobalToken: (node: EslintNode) => boolean;
|
|
|
4
4
|
export declare const isDecendantOfType: (node: Rule.Node, type: Rule.Node['type'], skipNode?: boolean) => boolean;
|
|
5
5
|
export declare const isPropertyKey: (node: Rule.Node) => boolean;
|
|
6
6
|
export declare const isDecendantOfStyleJsxAttribute: (node: Rule.Node) => boolean;
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
7
|
+
export declare const isCssInJsTemplateNode: (node?: Expression | null) => node is TaggedTemplateExpression;
|
|
8
|
+
export declare const isCssInJsCallNode: (node?: Expression | null) => node is CallExpression;
|
|
9
|
+
export declare const isCssInJsObjectNode: (node?: Expression | null) => node is CallExpression;
|
|
9
10
|
export declare const isDecendantOfStyleBlock: (node: Rule.Node) => boolean;
|
|
10
11
|
export declare const isChildOfType: (node: Rule.Node, type: Rule.Node['type']) => boolean;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Rule, Scope } from 'eslint';
|
|
2
|
-
import { EslintNode, TaggedTemplateExpression } from 'eslint-codemod-utils';
|
|
2
|
+
import { EslintNode, ObjectExpression, TaggedTemplateExpression } from 'eslint-codemod-utils';
|
|
3
|
+
export declare const replacementComment = "// TODO Delete this comment after verifying space token -> previous value";
|
|
3
4
|
export type ProcessedCSSLines = [
|
|
4
5
|
string,
|
|
5
6
|
string
|
|
@@ -109,3 +110,4 @@ export declare function findTokenNameByPropertyValue(propertyName: string, value
|
|
|
109
110
|
* @param value the computed value e.g '8px' -> '8'
|
|
110
111
|
*/
|
|
111
112
|
export declare function getTokenReplacement(propertyName: string, value: string): import("eslint-codemod-utils").StringableASTNode<import("estree").SimpleCallExpression> | undefined;
|
|
113
|
+
export declare function getFontSizeFromNode(parentNode: ObjectExpression & Rule.NodeParentExtension, context: Rule.RuleContext): any;
|
|
@@ -4,7 +4,8 @@ export declare const isDecendantOfGlobalToken: (node: EslintNode) => boolean;
|
|
|
4
4
|
export declare const isDecendantOfType: (node: Rule.Node, type: Rule.Node['type'], skipNode?: boolean) => boolean;
|
|
5
5
|
export declare const isPropertyKey: (node: Rule.Node) => boolean;
|
|
6
6
|
export declare const isDecendantOfStyleJsxAttribute: (node: Rule.Node) => boolean;
|
|
7
|
-
export declare const
|
|
8
|
-
export declare const
|
|
7
|
+
export declare const isCssInJsTemplateNode: (node?: Expression | null) => node is TaggedTemplateExpression;
|
|
8
|
+
export declare const isCssInJsCallNode: (node?: Expression | null) => node is CallExpression;
|
|
9
|
+
export declare const isCssInJsObjectNode: (node?: Expression | null) => node is CallExpression;
|
|
9
10
|
export declare const isDecendantOfStyleBlock: (node: Rule.Node) => boolean;
|
|
10
11
|
export declare const isChildOfType: (node: Rule.Node, type: Rule.Node['type']) => boolean;
|
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": "6.0
|
|
4
|
+
"version": "6.2.0",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
".": "./src/index.tsx"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@atlaskit/tokens": "^1.
|
|
36
|
+
"@atlaskit/tokens": "^1.8.0",
|
|
37
37
|
"@babel/runtime": "^7.0.0",
|
|
38
38
|
"@typescript-eslint/utils": "^5.48.1",
|
|
39
39
|
"ajv": "^6.12.6",
|