@atlaskit/eslint-plugin-design-system 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/cjs/rules/ensure-design-token-usage-spacing/index.js +31 -14
- package/dist/cjs/rules/ensure-design-token-usage-spacing/utils.js +30 -7
- package/dist/cjs/rules/use-primitives/index.js +3 -3
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/rules/ensure-design-token-usage-spacing/index.js +31 -16
- package/dist/es2019/rules/ensure-design-token-usage-spacing/utils.js +25 -4
- package/dist/es2019/rules/use-primitives/index.js +3 -3
- package/dist/es2019/version.json +1 -1
- package/dist/esm/rules/ensure-design-token-usage-spacing/index.js +32 -15
- package/dist/esm/rules/ensure-design-token-usage-spacing/utils.js +25 -4
- package/dist/esm/rules/use-primitives/index.js +3 -3
- package/dist/esm/version.json +1 -1
- package/dist/types/rules/ensure-design-token-usage-spacing/utils.d.ts +2 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 5.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`a5f1c4fa284`](https://bitbucket.org/atlassian/atlassian-frontend/commits/a5f1c4fa284) - Update links in the `use-primitives` rule to point to the right docs URL.
|
|
8
|
+
|
|
9
|
+
## 5.0.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`31ebca384fa`](https://bitbucket.org/atlassian/atlassian-frontend/commits/31ebca384fa) - Improved behaviour of `ensure-design-token-usage-spacing` rule to not report on or replace 0, auto, and calc within spacing properties.
|
|
14
|
+
|
|
3
15
|
## 5.0.0
|
|
4
16
|
|
|
5
17
|
### Major Changes
|
|
@@ -118,6 +118,11 @@ var rule = (0, _createRule.createRule)({
|
|
|
118
118
|
});
|
|
119
119
|
return;
|
|
120
120
|
}
|
|
121
|
+
|
|
122
|
+
// Don't report on CSS calc function
|
|
123
|
+
if (node.value.type === 'Literal' && (0, _utils.isCalc)(node.value.value)) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
121
126
|
var propertyName = node.key.name;
|
|
122
127
|
var isFontFamily = /fontFamily/.test(propertyName);
|
|
123
128
|
var value = (0, _utils.getValue)(node.value, context);
|
|
@@ -139,6 +144,11 @@ var rule = (0, _createRule.createRule)({
|
|
|
139
144
|
if (values.length === 1 || isFontFamily) {
|
|
140
145
|
var _values = (0, _slicedToArray2.default)(values, 1),
|
|
141
146
|
_value = _values[0];
|
|
147
|
+
|
|
148
|
+
// Do not report or suggest a token to replace `0`
|
|
149
|
+
if ((0, _utils.isZero)(_value)) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
142
152
|
var pixelValue = isFontFamily ? _value : (0, _utils.emToPixels)(_value, fontSize);
|
|
143
153
|
return context.report({
|
|
144
154
|
node: node,
|
|
@@ -170,17 +180,22 @@ var rule = (0, _createRule.createRule)({
|
|
|
170
180
|
* estree node.
|
|
171
181
|
*
|
|
172
182
|
* @example
|
|
173
|
-
* { padding: '8px 0px' }
|
|
183
|
+
* { padding: '8px 0px' }
|
|
174
184
|
*/
|
|
175
185
|
values.forEach(function (val, index) {
|
|
176
186
|
var pixelValue = (0, _utils.emToPixels)(val, fontSize);
|
|
187
|
+
|
|
188
|
+
// Do not report or suggest a token to replace `0`
|
|
189
|
+
if ((0, _utils.isZero)(val) || val === 'auto') {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
177
192
|
context.report({
|
|
178
193
|
node: node,
|
|
179
194
|
messageId: 'noRawSpacingValues',
|
|
180
195
|
data: {
|
|
181
196
|
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
182
197
|
},
|
|
183
|
-
fix:
|
|
198
|
+
fix: function fix(fixer) {
|
|
184
199
|
var allResolvableValues = values.every(function (value) {
|
|
185
200
|
return !Number.isNaN((0, _utils.emToPixels)(value, fontSize));
|
|
186
201
|
});
|
|
@@ -189,6 +204,8 @@ var rule = (0, _createRule.createRule)({
|
|
|
189
204
|
}
|
|
190
205
|
var valuesWithTokenReplacement = values.filter(function (value) {
|
|
191
206
|
return (0, _utils.findTokenNameByPropertyValue)(propertyName, value);
|
|
207
|
+
}).filter(function (value) {
|
|
208
|
+
return value !== 0;
|
|
192
209
|
});
|
|
193
210
|
if (valuesWithTokenReplacement.length === 0) {
|
|
194
211
|
// all values could be replaceable but that just means they're numeric
|
|
@@ -211,12 +228,16 @@ var rule = (0, _createRule.createRule)({
|
|
|
211
228
|
return null;
|
|
212
229
|
}
|
|
213
230
|
return (!tokenNode && ruleConfig.applyImport ? [(0, _utils.insertTokensImport)(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(values.map(function (value, index) {
|
|
231
|
+
if ((0, _utils.isZero)(value)) {
|
|
232
|
+
return originalValues[index];
|
|
233
|
+
}
|
|
214
234
|
var pixelValue = (0, _utils.emToPixels)(value, fontSize);
|
|
215
235
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
216
236
|
// if there is a token we take it, otherwise we go with the original value
|
|
237
|
+
|
|
217
238
|
return (0, _utils.findTokenNameByPropertyValue)(propertyName, value) ? "${".concat((0, _utils.getTokenNodeForValue)(propertyName, pixelValueString), "}") : originalValues[index];
|
|
218
239
|
}).join(' '), "`"))]);
|
|
219
|
-
}
|
|
240
|
+
}
|
|
220
241
|
});
|
|
221
242
|
});
|
|
222
243
|
}
|
|
@@ -225,7 +246,7 @@ var rule = (0, _createRule.createRule)({
|
|
|
225
246
|
// CSSTemplateLiteral and StyledTemplateLiteral
|
|
226
247
|
// const cssTemplateLiteral = css`color: red; padding: 12px`;
|
|
227
248
|
// const styledTemplateLiteral = styled.p`color: red; padding: 8px`;
|
|
228
|
-
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': function
|
|
249
|
+
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"],TaggedTemplateExpression[tag.callee.name="styled"]': function TaggedTemplateExpressionTagNameCssTaggedTemplateExpressionTagObjectNameStyledTaggedTemplateExpressionTagCalleeNameStyled(node) {
|
|
229
250
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
230
251
|
return;
|
|
231
252
|
}
|
|
@@ -282,17 +303,13 @@ var rule = (0, _createRule.createRule)({
|
|
|
282
303
|
// if the value is already valid, nothing to report or replace
|
|
283
304
|
return originalValue;
|
|
284
305
|
}
|
|
285
|
-
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
286
|
-
// this can be either a weird expression or a fontsize declaration
|
|
287
306
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
});
|
|
307
|
+
// do not replace 0 with tokens
|
|
308
|
+
if ((0, _utils.isZero)(pxValue) || pxValue === 'auto') {
|
|
309
|
+
return originalValue;
|
|
310
|
+
}
|
|
311
|
+
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
312
|
+
// do not report if we have nothing to replace with
|
|
296
313
|
return originalValue;
|
|
297
314
|
}
|
|
298
315
|
|
|
@@ -15,9 +15,9 @@ exports.getTokenNodeForValue = getTokenNodeForValue;
|
|
|
15
15
|
exports.getTokenReplacement = getTokenReplacement;
|
|
16
16
|
exports.getValueFromShorthand = exports.getValue = void 0;
|
|
17
17
|
exports.insertTokensImport = insertTokensImport;
|
|
18
|
-
exports.isSpacingProperty = void 0;
|
|
18
|
+
exports.isSpacingProperty = exports.isCalc = void 0;
|
|
19
19
|
exports.isTokenValueString = isTokenValueString;
|
|
20
|
-
exports.onlyScaleTokens = exports.isValidSpacingValue = exports.isTypographyProperty = void 0;
|
|
20
|
+
exports.onlyScaleTokens = exports.isZero = exports.isValidSpacingValue = exports.isTypographyProperty = void 0;
|
|
21
21
|
exports.processCssNode = processCssNode;
|
|
22
22
|
exports.removePixelSuffix = void 0;
|
|
23
23
|
exports.shouldAnalyzeProperty = shouldAnalyzeProperty;
|
|
@@ -292,12 +292,11 @@ var emToPixels = function emToPixels(value, fontSize) {
|
|
|
292
292
|
return value;
|
|
293
293
|
};
|
|
294
294
|
exports.emToPixels = emToPixels;
|
|
295
|
-
var
|
|
295
|
+
var percentageOrEmOrAuto = /(%$)|(\d+em$)|(auto$)/;
|
|
296
296
|
var removePixelSuffix = function removePixelSuffix(value) {
|
|
297
297
|
var isString = typeof value === 'string';
|
|
298
|
-
|
|
299
298
|
// @ts-ignore This shouldn't be a type error but CI is complaining
|
|
300
|
-
if (isString &&
|
|
299
|
+
if (isString && percentageOrEmOrAuto.test(value)) {
|
|
301
300
|
return value;
|
|
302
301
|
}
|
|
303
302
|
|
|
@@ -305,7 +304,7 @@ var removePixelSuffix = function removePixelSuffix(value) {
|
|
|
305
304
|
return Number(isString ? value.replace('px', '') : value);
|
|
306
305
|
};
|
|
307
306
|
exports.removePixelSuffix = removePixelSuffix;
|
|
308
|
-
var invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(
|
|
307
|
+
var invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(vw$)|(vh$)/;
|
|
309
308
|
var isValidSpacingValue = function isValidSpacingValue(value, fontSize) {
|
|
310
309
|
if (typeof value === 'string') {
|
|
311
310
|
if (invalidSpacingUnitRegex.test(value)) {
|
|
@@ -324,9 +323,33 @@ var isValidSpacingValue = function isValidSpacingValue(value, fontSize) {
|
|
|
324
323
|
}
|
|
325
324
|
return true;
|
|
326
325
|
};
|
|
326
|
+
exports.isValidSpacingValue = isValidSpacingValue;
|
|
327
|
+
var calcRegex = /(^calc)/;
|
|
328
|
+
var isCalc = function isCalc(value) {
|
|
329
|
+
if (typeof value === 'string') {
|
|
330
|
+
if (calcRegex.test(value)) {
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return false;
|
|
335
|
+
};
|
|
336
|
+
exports.isCalc = isCalc;
|
|
337
|
+
var isZero = function isZero(value) {
|
|
338
|
+
if (typeof value === 'string') {
|
|
339
|
+
if (value === '0px' || value === '0') {
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (typeof value === 'number') {
|
|
344
|
+
if (value === 0) {
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return false;
|
|
349
|
+
};
|
|
327
350
|
|
|
328
351
|
// convert line-height to lineHeight
|
|
329
|
-
exports.
|
|
352
|
+
exports.isZero = isZero;
|
|
330
353
|
var convertHyphenatedNameToCamelCase = function convertHyphenatedNameToCamelCase(prop) {
|
|
331
354
|
return prop.replace(/-./g, function (m) {
|
|
332
355
|
return m[1].toUpperCase();
|
|
@@ -7,9 +7,9 @@ exports.default = void 0;
|
|
|
7
7
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
8
|
var _createRule = require("../utils/create-rule");
|
|
9
9
|
var _utils = require("./utils");
|
|
10
|
-
var boxDocsUrl = 'https://atlassian.design/components/
|
|
11
|
-
var inlineDocsUrl = 'https://atlassian.design/components/
|
|
12
|
-
var stackDocsUrl = 'https://atlassian.design/components/
|
|
10
|
+
var boxDocsUrl = 'https://staging.atlassian.design/components/primitives/box';
|
|
11
|
+
var inlineDocsUrl = 'https://staging.atlassian.design/components/primitives/inline';
|
|
12
|
+
var stackDocsUrl = 'https://staging.atlassian.design/components/primitives/stack';
|
|
13
13
|
var rule = (0, _createRule.createLintRule)({
|
|
14
14
|
meta: {
|
|
15
15
|
name: 'use-primitives',
|
package/dist/cjs/version.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { isNodeOfType, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
4
4
|
import { createRule } from '../utils/create-rule';
|
|
5
5
|
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
6
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isTokenValueString, isTypographyProperty, isValidSpacingValue, processCssNode, shouldAnalyzeProperty, spacingValueToToken, splitShorthandValues, typographyValueToToken } from './utils';
|
|
6
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isCalc, isTokenValueString, isTypographyProperty, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, spacingValueToToken, splitShorthandValues, typographyValueToToken } from './utils';
|
|
7
7
|
const rule = createRule({
|
|
8
8
|
defaultOptions: [{
|
|
9
9
|
addons: ['spacing'],
|
|
@@ -109,6 +109,11 @@ const rule = createRule({
|
|
|
109
109
|
});
|
|
110
110
|
return;
|
|
111
111
|
}
|
|
112
|
+
|
|
113
|
+
// Don't report on CSS calc function
|
|
114
|
+
if (node.value.type === 'Literal' && isCalc(node.value.value)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
112
117
|
const propertyName = node.key.name;
|
|
113
118
|
const isFontFamily = /fontFamily/.test(propertyName);
|
|
114
119
|
const value = getValue(node.value, context);
|
|
@@ -129,6 +134,11 @@ const rule = createRule({
|
|
|
129
134
|
// treat fontFamily as having one value
|
|
130
135
|
if (values.length === 1 || isFontFamily) {
|
|
131
136
|
const [value] = values;
|
|
137
|
+
|
|
138
|
+
// Do not report or suggest a token to replace `0`
|
|
139
|
+
if (isZero(value)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
132
142
|
const pixelValue = isFontFamily ? value : emToPixels(value, fontSize);
|
|
133
143
|
return context.report({
|
|
134
144
|
node,
|
|
@@ -161,22 +171,27 @@ const rule = createRule({
|
|
|
161
171
|
* estree node.
|
|
162
172
|
*
|
|
163
173
|
* @example
|
|
164
|
-
* { padding: '8px 0px' }
|
|
174
|
+
* { padding: '8px 0px' }
|
|
165
175
|
*/
|
|
166
176
|
values.forEach((val, index) => {
|
|
167
177
|
const pixelValue = emToPixels(val, fontSize);
|
|
178
|
+
|
|
179
|
+
// Do not report or suggest a token to replace `0`
|
|
180
|
+
if (isZero(val) || val === 'auto') {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
168
183
|
context.report({
|
|
169
184
|
node,
|
|
170
185
|
messageId: 'noRawSpacingValues',
|
|
171
186
|
data: {
|
|
172
187
|
payload: `${propertyName}:${pixelValue}`
|
|
173
188
|
},
|
|
174
|
-
fix:
|
|
189
|
+
fix: fixer => {
|
|
175
190
|
const allResolvableValues = values.every(value => !Number.isNaN(emToPixels(value, fontSize)));
|
|
176
191
|
if (!allResolvableValues) {
|
|
177
192
|
return null;
|
|
178
193
|
}
|
|
179
|
-
const valuesWithTokenReplacement = values.filter(value => findTokenNameByPropertyValue(propertyName, value));
|
|
194
|
+
const valuesWithTokenReplacement = values.filter(value => findTokenNameByPropertyValue(propertyName, value)).filter(value => value !== 0);
|
|
180
195
|
if (valuesWithTokenReplacement.length === 0) {
|
|
181
196
|
// all values could be replaceable but that just means they're numeric
|
|
182
197
|
// if none of the values have token replacement we bail
|
|
@@ -198,12 +213,16 @@ const rule = createRule({
|
|
|
198
213
|
return null;
|
|
199
214
|
}
|
|
200
215
|
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, `\`${values.map((value, index) => {
|
|
216
|
+
if (isZero(value)) {
|
|
217
|
+
return originalValues[index];
|
|
218
|
+
}
|
|
201
219
|
const pixelValue = emToPixels(value, fontSize);
|
|
202
220
|
const pixelValueString = `${pixelValue}px`;
|
|
203
221
|
// if there is a token we take it, otherwise we go with the original value
|
|
222
|
+
|
|
204
223
|
return findTokenNameByPropertyValue(propertyName, value) ? `\${${getTokenNodeForValue(propertyName, pixelValueString)}}` : originalValues[index];
|
|
205
224
|
}).join(' ')}\``)]);
|
|
206
|
-
}
|
|
225
|
+
}
|
|
207
226
|
});
|
|
208
227
|
});
|
|
209
228
|
}
|
|
@@ -212,7 +231,7 @@ const rule = createRule({
|
|
|
212
231
|
// CSSTemplateLiteral and StyledTemplateLiteral
|
|
213
232
|
// const cssTemplateLiteral = css`color: red; padding: 12px`;
|
|
214
233
|
// const styledTemplateLiteral = styled.p`color: red; padding: 8px`;
|
|
215
|
-
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': node => {
|
|
234
|
+
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"],TaggedTemplateExpression[tag.callee.name="styled"]': node => {
|
|
216
235
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
217
236
|
return;
|
|
218
237
|
}
|
|
@@ -254,17 +273,13 @@ const rule = createRule({
|
|
|
254
273
|
// if the value is already valid, nothing to report or replace
|
|
255
274
|
return originalValue;
|
|
256
275
|
}
|
|
257
|
-
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
258
|
-
// this can be either a weird expression or a fontsize declaration
|
|
259
276
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
});
|
|
277
|
+
// do not replace 0 with tokens
|
|
278
|
+
if (isZero(pxValue) || pxValue === 'auto') {
|
|
279
|
+
return originalValue;
|
|
280
|
+
}
|
|
281
|
+
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
282
|
+
// do not report if we have nothing to replace with
|
|
268
283
|
return originalValue;
|
|
269
284
|
}
|
|
270
285
|
|
|
@@ -234,19 +234,18 @@ export const emToPixels = (value, fontSize) => {
|
|
|
234
234
|
}
|
|
235
235
|
return value;
|
|
236
236
|
};
|
|
237
|
-
const
|
|
237
|
+
const percentageOrEmOrAuto = /(%$)|(\d+em$)|(auto$)/;
|
|
238
238
|
export const removePixelSuffix = value => {
|
|
239
239
|
const isString = typeof value === 'string';
|
|
240
|
-
|
|
241
240
|
// @ts-ignore This shouldn't be a type error but CI is complaining
|
|
242
|
-
if (isString &&
|
|
241
|
+
if (isString && percentageOrEmOrAuto.test(value)) {
|
|
243
242
|
return value;
|
|
244
243
|
}
|
|
245
244
|
|
|
246
245
|
// @ts-ignore This shouldn't be a type error but CI is complaining
|
|
247
246
|
return Number(isString ? value.replace('px', '') : value);
|
|
248
247
|
};
|
|
249
|
-
const invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(
|
|
248
|
+
const invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(vw$)|(vh$)/;
|
|
250
249
|
export const isValidSpacingValue = (value, fontSize) => {
|
|
251
250
|
if (typeof value === 'string') {
|
|
252
251
|
if (invalidSpacingUnitRegex.test(value)) {
|
|
@@ -265,6 +264,28 @@ export const isValidSpacingValue = (value, fontSize) => {
|
|
|
265
264
|
}
|
|
266
265
|
return true;
|
|
267
266
|
};
|
|
267
|
+
const calcRegex = /(^calc)/;
|
|
268
|
+
export const isCalc = value => {
|
|
269
|
+
if (typeof value === 'string') {
|
|
270
|
+
if (calcRegex.test(value)) {
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return false;
|
|
275
|
+
};
|
|
276
|
+
export const isZero = value => {
|
|
277
|
+
if (typeof value === 'string') {
|
|
278
|
+
if (value === '0px' || value === '0') {
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (typeof value === 'number') {
|
|
283
|
+
if (value === 0) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return false;
|
|
288
|
+
};
|
|
268
289
|
|
|
269
290
|
// convert line-height to lineHeight
|
|
270
291
|
export const convertHyphenatedNameToCamelCase = prop => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
2
|
import { createLintRule } from '../utils/create-rule';
|
|
3
3
|
import { primitiveFixer, shouldSuggestBox, shouldSuggestInline, shouldSuggestStack } from './utils';
|
|
4
|
-
const boxDocsUrl = 'https://atlassian.design/components/
|
|
5
|
-
const inlineDocsUrl = 'https://atlassian.design/components/
|
|
6
|
-
const stackDocsUrl = 'https://atlassian.design/components/
|
|
4
|
+
const boxDocsUrl = 'https://staging.atlassian.design/components/primitives/box';
|
|
5
|
+
const inlineDocsUrl = 'https://staging.atlassian.design/components/primitives/inline';
|
|
6
|
+
const stackDocsUrl = 'https://staging.atlassian.design/components/primitives/stack';
|
|
7
7
|
const rule = createLintRule({
|
|
8
8
|
meta: {
|
|
9
9
|
name: 'use-primitives',
|
package/dist/es2019/version.json
CHANGED
|
@@ -8,7 +8,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
8
8
|
import { isNodeOfType, node as nodeFn, property } from 'eslint-codemod-utils';
|
|
9
9
|
import { createRule } from '../utils/create-rule';
|
|
10
10
|
import { isDecendantOfGlobalToken } from '../utils/is-node';
|
|
11
|
-
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isTokenValueString, isTypographyProperty, isValidSpacingValue, processCssNode, shouldAnalyzeProperty, spacingValueToToken, splitShorthandValues, typographyValueToToken } from './utils';
|
|
11
|
+
import { convertHyphenatedNameToCamelCase, emToPixels, findParentNodeForLine, findTokenNameByPropertyValue, getFontSizeValueInScope, getRawExpression, getTokenNodeForValue, getTokenReplacement, getValue, getValueFromShorthand, insertTokensImport, isCalc, isTokenValueString, isTypographyProperty, isValidSpacingValue, isZero, processCssNode, shouldAnalyzeProperty, spacingValueToToken, splitShorthandValues, typographyValueToToken } from './utils';
|
|
12
12
|
var rule = createRule({
|
|
13
13
|
defaultOptions: [{
|
|
14
14
|
addons: ['spacing'],
|
|
@@ -113,6 +113,11 @@ var rule = createRule({
|
|
|
113
113
|
});
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
|
+
|
|
117
|
+
// Don't report on CSS calc function
|
|
118
|
+
if (node.value.type === 'Literal' && isCalc(node.value.value)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
116
121
|
var propertyName = node.key.name;
|
|
117
122
|
var isFontFamily = /fontFamily/.test(propertyName);
|
|
118
123
|
var value = getValue(node.value, context);
|
|
@@ -134,6 +139,11 @@ var rule = createRule({
|
|
|
134
139
|
if (values.length === 1 || isFontFamily) {
|
|
135
140
|
var _values = _slicedToArray(values, 1),
|
|
136
141
|
_value = _values[0];
|
|
142
|
+
|
|
143
|
+
// Do not report or suggest a token to replace `0`
|
|
144
|
+
if (isZero(_value)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
137
147
|
var pixelValue = isFontFamily ? _value : emToPixels(_value, fontSize);
|
|
138
148
|
return context.report({
|
|
139
149
|
node: node,
|
|
@@ -165,17 +175,22 @@ var rule = createRule({
|
|
|
165
175
|
* estree node.
|
|
166
176
|
*
|
|
167
177
|
* @example
|
|
168
|
-
* { padding: '8px 0px' }
|
|
178
|
+
* { padding: '8px 0px' }
|
|
169
179
|
*/
|
|
170
180
|
values.forEach(function (val, index) {
|
|
171
181
|
var pixelValue = emToPixels(val, fontSize);
|
|
182
|
+
|
|
183
|
+
// Do not report or suggest a token to replace `0`
|
|
184
|
+
if (isZero(val) || val === 'auto') {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
172
187
|
context.report({
|
|
173
188
|
node: node,
|
|
174
189
|
messageId: 'noRawSpacingValues',
|
|
175
190
|
data: {
|
|
176
191
|
payload: "".concat(propertyName, ":").concat(pixelValue)
|
|
177
192
|
},
|
|
178
|
-
fix:
|
|
193
|
+
fix: function fix(fixer) {
|
|
179
194
|
var allResolvableValues = values.every(function (value) {
|
|
180
195
|
return !Number.isNaN(emToPixels(value, fontSize));
|
|
181
196
|
});
|
|
@@ -184,6 +199,8 @@ var rule = createRule({
|
|
|
184
199
|
}
|
|
185
200
|
var valuesWithTokenReplacement = values.filter(function (value) {
|
|
186
201
|
return findTokenNameByPropertyValue(propertyName, value);
|
|
202
|
+
}).filter(function (value) {
|
|
203
|
+
return value !== 0;
|
|
187
204
|
});
|
|
188
205
|
if (valuesWithTokenReplacement.length === 0) {
|
|
189
206
|
// all values could be replaceable but that just means they're numeric
|
|
@@ -206,12 +223,16 @@ var rule = createRule({
|
|
|
206
223
|
return null;
|
|
207
224
|
}
|
|
208
225
|
return (!tokenNode && ruleConfig.applyImport ? [insertTokensImport(fixer)] : []).concat([fixer.replaceText(node.value, "`".concat(values.map(function (value, index) {
|
|
226
|
+
if (isZero(value)) {
|
|
227
|
+
return originalValues[index];
|
|
228
|
+
}
|
|
209
229
|
var pixelValue = emToPixels(value, fontSize);
|
|
210
230
|
var pixelValueString = "".concat(pixelValue, "px");
|
|
211
231
|
// if there is a token we take it, otherwise we go with the original value
|
|
232
|
+
|
|
212
233
|
return findTokenNameByPropertyValue(propertyName, value) ? "${".concat(getTokenNodeForValue(propertyName, pixelValueString), "}") : originalValues[index];
|
|
213
234
|
}).join(' '), "`"))]);
|
|
214
|
-
}
|
|
235
|
+
}
|
|
215
236
|
});
|
|
216
237
|
});
|
|
217
238
|
}
|
|
@@ -220,7 +241,7 @@ var rule = createRule({
|
|
|
220
241
|
// CSSTemplateLiteral and StyledTemplateLiteral
|
|
221
242
|
// const cssTemplateLiteral = css`color: red; padding: 12px`;
|
|
222
243
|
// const styledTemplateLiteral = styled.p`color: red; padding: 8px`;
|
|
223
|
-
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"]': function
|
|
244
|
+
'TaggedTemplateExpression[tag.name="css"],TaggedTemplateExpression[tag.object.name="styled"],TaggedTemplateExpression[tag.callee.name="styled"]': function TaggedTemplateExpressionTagNameCssTaggedTemplateExpressionTagObjectNameStyledTaggedTemplateExpressionTagCalleeNameStyled(node) {
|
|
224
245
|
if (node.type !== 'TaggedTemplateExpression') {
|
|
225
246
|
return;
|
|
226
247
|
}
|
|
@@ -277,17 +298,13 @@ var rule = createRule({
|
|
|
277
298
|
// if the value is already valid, nothing to report or replace
|
|
278
299
|
return originalValue;
|
|
279
300
|
}
|
|
280
|
-
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
281
|
-
// this can be either a weird expression or a fontsize declaration
|
|
282
301
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
290
|
-
});
|
|
302
|
+
// do not replace 0 with tokens
|
|
303
|
+
if (isZero(pxValue) || pxValue === 'auto') {
|
|
304
|
+
return originalValue;
|
|
305
|
+
}
|
|
306
|
+
if (isNaN(numericOrNanValue) && !isFontFamily) {
|
|
307
|
+
// do not report if we have nothing to replace with
|
|
291
308
|
return originalValue;
|
|
292
309
|
}
|
|
293
310
|
|
|
@@ -256,19 +256,18 @@ export var emToPixels = function emToPixels(value, fontSize) {
|
|
|
256
256
|
}
|
|
257
257
|
return value;
|
|
258
258
|
};
|
|
259
|
-
var
|
|
259
|
+
var percentageOrEmOrAuto = /(%$)|(\d+em$)|(auto$)/;
|
|
260
260
|
export var removePixelSuffix = function removePixelSuffix(value) {
|
|
261
261
|
var isString = typeof value === 'string';
|
|
262
|
-
|
|
263
262
|
// @ts-ignore This shouldn't be a type error but CI is complaining
|
|
264
|
-
if (isString &&
|
|
263
|
+
if (isString && percentageOrEmOrAuto.test(value)) {
|
|
265
264
|
return value;
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
// @ts-ignore This shouldn't be a type error but CI is complaining
|
|
269
268
|
return Number(isString ? value.replace('px', '') : value);
|
|
270
269
|
};
|
|
271
|
-
var invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(
|
|
270
|
+
var invalidSpacingUnitRegex = /(%$)|(\d+rem$)|(vw$)|(vh$)/;
|
|
272
271
|
export var isValidSpacingValue = function isValidSpacingValue(value, fontSize) {
|
|
273
272
|
if (typeof value === 'string') {
|
|
274
273
|
if (invalidSpacingUnitRegex.test(value)) {
|
|
@@ -287,6 +286,28 @@ export var isValidSpacingValue = function isValidSpacingValue(value, fontSize) {
|
|
|
287
286
|
}
|
|
288
287
|
return true;
|
|
289
288
|
};
|
|
289
|
+
var calcRegex = /(^calc)/;
|
|
290
|
+
export var isCalc = function isCalc(value) {
|
|
291
|
+
if (typeof value === 'string') {
|
|
292
|
+
if (calcRegex.test(value)) {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return false;
|
|
297
|
+
};
|
|
298
|
+
export var isZero = function isZero(value) {
|
|
299
|
+
if (typeof value === 'string') {
|
|
300
|
+
if (value === '0px' || value === '0') {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (typeof value === 'number') {
|
|
305
|
+
if (value === 0) {
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return false;
|
|
310
|
+
};
|
|
290
311
|
|
|
291
312
|
// convert line-height to lineHeight
|
|
292
313
|
export var convertHyphenatedNameToCamelCase = function convertHyphenatedNameToCamelCase(prop) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
2
|
import { createLintRule } from '../utils/create-rule';
|
|
3
3
|
import { primitiveFixer, shouldSuggestBox, shouldSuggestInline, shouldSuggestStack } from './utils';
|
|
4
|
-
var boxDocsUrl = 'https://atlassian.design/components/
|
|
5
|
-
var inlineDocsUrl = 'https://atlassian.design/components/
|
|
6
|
-
var stackDocsUrl = 'https://atlassian.design/components/
|
|
4
|
+
var boxDocsUrl = 'https://staging.atlassian.design/components/primitives/box';
|
|
5
|
+
var inlineDocsUrl = 'https://staging.atlassian.design/components/primitives/inline';
|
|
6
|
+
var stackDocsUrl = 'https://staging.atlassian.design/components/primitives/stack';
|
|
7
7
|
var rule = createLintRule({
|
|
8
8
|
meta: {
|
|
9
9
|
name: 'use-primitives',
|
package/dist/esm/version.json
CHANGED
|
@@ -91,6 +91,8 @@ export declare const getRawExpression: (node: EslintNode, context: Rule.RuleCont
|
|
|
91
91
|
export declare const emToPixels: <T extends unknown>(value: T, fontSize: number | null | undefined) => number | T | null;
|
|
92
92
|
export declare const removePixelSuffix: (value: string | number) => string | number;
|
|
93
93
|
export declare const isValidSpacingValue: (value: string | number | boolean | RegExp | null | undefined | any[] | bigint, fontSize?: number | null | undefined) => boolean;
|
|
94
|
+
export declare const isCalc: (value: string | number | boolean | RegExp | null | undefined | any[] | bigint) => boolean;
|
|
95
|
+
export declare const isZero: (value: string | number | boolean | RegExp | null | undefined | any[] | bigint) => boolean;
|
|
94
96
|
export declare const convertHyphenatedNameToCamelCase: (prop: string) => string;
|
|
95
97
|
/**
|
|
96
98
|
* @param node
|
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": "5.0.
|
|
4
|
+
"version": "5.0.2",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|