@atlaskit/eslint-plugin-design-system 8.19.0 → 8.19.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/use-primitives/config/index.js +15 -0
- package/dist/cjs/rules/use-primitives/index.js +10 -11
- package/dist/cjs/rules/use-primitives/transformers/css-to-xcss.js +21 -7
- package/dist/cjs/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +30 -9
- package/dist/cjs/rules/use-primitives/utils/find-valid-styled-component-call.js +1 -0
- package/dist/cjs/rules/use-primitives/utils/get-variable-usage-count.js +1 -0
- package/dist/cjs/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +25 -5
- package/dist/es2019/rules/use-primitives/config/index.js +9 -0
- package/dist/es2019/rules/use-primitives/index.js +10 -10
- package/dist/es2019/rules/use-primitives/transformers/css-to-xcss.js +21 -7
- package/dist/es2019/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +30 -9
- package/dist/es2019/rules/use-primitives/utils/find-valid-styled-component-call.js +1 -0
- package/dist/es2019/rules/use-primitives/utils/get-variable-usage-count.js +1 -0
- package/dist/es2019/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +21 -5
- package/dist/esm/rules/use-primitives/config/index.js +9 -0
- package/dist/esm/rules/use-primitives/index.js +10 -10
- package/dist/esm/rules/use-primitives/transformers/css-to-xcss.js +21 -7
- package/dist/esm/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +30 -9
- package/dist/esm/rules/use-primitives/utils/find-valid-styled-component-call.js +1 -0
- package/dist/esm/rules/use-primitives/utils/get-variable-usage-count.js +1 -0
- package/dist/esm/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +24 -5
- package/dist/types/rules/use-primitives/config/index.d.ts +6 -0
- package/dist/types/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts +6 -1
- package/dist/types/rules/use-primitives/utils/get-variable-usage-count.d.ts +1 -0
- package/dist/types/rules/use-primitives/utils/is-valid-css-properties-to-transform.d.ts +2 -1
- package/dist/types-ts4.5/rules/use-primitives/config/index.d.ts +6 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts +6 -1
- package/dist/types-ts4.5/rules/use-primitives/utils/get-variable-usage-count.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/is-valid-css-properties-to-transform.d.ts +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 8.19.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#66118](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/66118) [`93988e6fd035`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/93988e6fd035) - `use-primitives` now handles tokenised padding/margin properties. This change is guarded by a config flag and not enabled by default.
|
|
8
|
+
|
|
9
|
+
## 8.19.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#65221](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/65221) [`a2ba22904ca0`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a2ba22904ca0) - Allow for @atlaskit/design-system/use-primitives lint rule to take a configuration object.
|
|
14
|
+
|
|
3
15
|
## 8.19.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getConfig = void 0;
|
|
7
|
+
var defaults = {
|
|
8
|
+
patterns: ['compiled-css-function']
|
|
9
|
+
};
|
|
10
|
+
var getConfig = exports.getConfig = function getConfig(overrides) {
|
|
11
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
12
|
+
// start with an empty object, then merge in the defaults, then merge in overrides.
|
|
13
|
+
// The empty object is returned, as well as modified in place
|
|
14
|
+
return Object.assign({}, defaults, overrides);
|
|
15
|
+
};
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
3
|
Object.defineProperty(exports, "__esModule", {
|
|
5
4
|
value: true
|
|
6
5
|
});
|
|
7
6
|
exports.default = void 0;
|
|
8
7
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
9
|
-
var _assign = _interopRequireDefault(require("lodash/assign"));
|
|
10
8
|
var _createRule = require("../utils/create-rule");
|
|
9
|
+
var _config = require("./config");
|
|
11
10
|
var _transformers = require("./transformers");
|
|
12
11
|
var _utils = require("./utils");
|
|
13
12
|
var boxDocsUrl = 'https://atlassian.design/components/primitives/box';
|
|
14
|
-
var defaultConfig = {
|
|
15
|
-
preview: false
|
|
16
|
-
};
|
|
17
13
|
var rule = (0, _createRule.createLintRule)({
|
|
18
14
|
meta: {
|
|
19
15
|
name: 'use-primitives',
|
|
@@ -30,18 +26,18 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
30
26
|
}
|
|
31
27
|
},
|
|
32
28
|
create: function create(context) {
|
|
33
|
-
var
|
|
29
|
+
var config = (0, _config.getConfig)(context.options[0]);
|
|
34
30
|
return {
|
|
35
31
|
// transforms styled.<html>(...) usages
|
|
36
32
|
CallExpression: function CallExpression(node) {
|
|
37
|
-
if (!
|
|
33
|
+
if (!config.patterns.includes('compiled-styled-object')) {
|
|
38
34
|
return;
|
|
39
35
|
}
|
|
40
36
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression')) {
|
|
41
37
|
return;
|
|
42
38
|
}
|
|
43
39
|
var styledComponentVariableRef = (0, _utils.findValidStyledComponentCall)(node);
|
|
44
|
-
if (!styledComponentVariableRef || !(0, _eslintCodemodUtils.isNodeOfType)(styledComponentVariableRef.id, 'Identifier') || !(0, _utils.isValidCssPropertiesToTransform)(node)) {
|
|
40
|
+
if (!styledComponentVariableRef || !(0, _eslintCodemodUtils.isNodeOfType)(styledComponentVariableRef.id, 'Identifier') || !(0, _utils.isValidCssPropertiesToTransform)(node, config)) {
|
|
45
41
|
return;
|
|
46
42
|
}
|
|
47
43
|
var styledComponentJsxRef = (0, _utils.findValidJsxUsageToTransform)(styledComponentVariableRef.id.name, context.getScope());
|
|
@@ -64,6 +60,9 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
64
60
|
},
|
|
65
61
|
// transforms <div css={...}> usages
|
|
66
62
|
JSXOpeningElement: function JSXOpeningElement(node) {
|
|
63
|
+
if (!config.patterns.includes('compiled-css-function')) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
67
66
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXOpeningElement')) {
|
|
68
67
|
return;
|
|
69
68
|
}
|
|
@@ -73,7 +72,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
73
72
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.parent, 'JSXElement')) {
|
|
74
73
|
return;
|
|
75
74
|
}
|
|
76
|
-
var suggestBox = shouldSuggestBox(node.parent, context);
|
|
75
|
+
var suggestBox = shouldSuggestBox(node.parent, context, config);
|
|
77
76
|
if (suggestBox) {
|
|
78
77
|
context.report({
|
|
79
78
|
node: node,
|
|
@@ -91,7 +90,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
91
90
|
};
|
|
92
91
|
}
|
|
93
92
|
});
|
|
94
|
-
var shouldSuggestBox = function shouldSuggestBox(node, context
|
|
93
|
+
var shouldSuggestBox = function shouldSuggestBox(node, context, config
|
|
95
94
|
// scope: Scope.Scope,
|
|
96
95
|
) {
|
|
97
96
|
if (!node) {
|
|
@@ -138,6 +137,6 @@ var shouldSuggestBox = function shouldSuggestBox(node, context
|
|
|
138
137
|
if (!cssVariableValue || !(0, _utils.isFunctionNamed)(cssVariableValue, 'css')) {
|
|
139
138
|
return false;
|
|
140
139
|
}
|
|
141
|
-
return (0, _utils.isValidCssPropertiesToTransform)(cssVariableValue.node.init);
|
|
140
|
+
return (0, _utils.isValidCssPropertiesToTransform)(cssVariableValue.node.init, config);
|
|
142
141
|
};
|
|
143
142
|
var _default = exports.default = rule;
|
|
@@ -39,7 +39,7 @@ var cssToXcssTransformer = exports.cssToXcssTransformer = function cssToXcssTran
|
|
|
39
39
|
fixer.replaceText(cssVariableValue.node.init.callee, (0, _eslintCodemodUtils.identifier)('xcss').toString())].concat((0, _toConsumableArray2.default)(styledObjectToXcssTokens(cssObjectExpression, fixer)));
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
// Update css object values to xcss values
|
|
42
|
+
// Update css object values to xcss values
|
|
43
43
|
// Note: `properties` in this context is a group of AST nodes that make up a key/value pair in an object.
|
|
44
44
|
// e.g. `padding: '8px'`. For clarity, it's renamed to `entry` inside the `.map()`.
|
|
45
45
|
var styledObjectToXcssTokens = exports.styledObjectToXcssTokens = function styledObjectToXcssTokens(styles, fixer) {
|
|
@@ -50,16 +50,30 @@ var styledObjectToXcssTokens = exports.styledObjectToXcssTokens = function style
|
|
|
50
50
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(entry.key, 'Identifier')) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
|
|
54
|
+
// maps literal values like: 8px to 'space.100'
|
|
55
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(entry.value, 'Literal')) {
|
|
56
|
+
var value = entry.value.value;
|
|
57
|
+
if (typeof value !== 'string') {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
return fixer.replaceText(entry.value, (0, _eslintCodemodUtils.literal)("'".concat(supportedStylesMap[entry.key.name][value], "'")).toString());
|
|
55
61
|
}
|
|
56
|
-
|
|
57
|
-
if (
|
|
58
|
-
|
|
62
|
+
// maps token calls like: token('space.100') to 'space.100'
|
|
63
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(entry.value, 'CallExpression')) {
|
|
64
|
+
var callExpression = entry.value;
|
|
65
|
+
// skip if not a call to `token`
|
|
66
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token' || !(0, _eslintCodemodUtils.isNodeOfType)(callExpression.arguments[0], 'Literal')) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// the first argument of `token` is the token name and
|
|
70
|
+
// can be given directly to `xcss` as it has been validated already.
|
|
71
|
+
return fixer.replaceText(entry.value, (0, _eslintCodemodUtils.literal)("'".concat(callExpression.arguments[0].value, "'")).toString());
|
|
59
72
|
}
|
|
60
|
-
return fixer.replaceText(entry.value, (0, _eslintCodemodUtils.literal)("'".concat(supportedStylesMap[entry.key.name][value], "'")).toString());
|
|
61
73
|
});
|
|
62
74
|
};
|
|
75
|
+
|
|
76
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16054
|
|
63
77
|
var spaceTokenMap = exports.spaceTokenMap = {
|
|
64
78
|
'0px': 'space.0',
|
|
65
79
|
'2px': 'space.025',
|
|
@@ -20,28 +20,49 @@ var convertASTObjectExpressionToJSObject = exports.convertASTObjectExpressionToJ
|
|
|
20
20
|
return false;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
// TODO:
|
|
23
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16055
|
|
24
|
+
// We need to harden this logic asap.
|
|
24
25
|
// It currently generates a false positive for:
|
|
25
26
|
// styled.div({
|
|
26
27
|
// marginTop: "0px",
|
|
27
|
-
// marginBottom:
|
|
28
|
+
// marginBottom: blah(...),
|
|
28
29
|
// })
|
|
29
|
-
// as the value for `marginBottom` is not a string,
|
|
30
|
-
// from the resulting map and this
|
|
30
|
+
// as the value for `marginBottom` is not a string nor a `token` call, it is just skipped
|
|
31
|
+
// from the resulting map and this is inaccurate.
|
|
31
32
|
styles.properties.forEach(function (prop) {
|
|
33
|
+
// cases we want to skip (see note above)
|
|
32
34
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(prop, 'Property')) {
|
|
33
35
|
return;
|
|
34
36
|
}
|
|
35
37
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(prop.key, 'Identifier')) {
|
|
36
38
|
return;
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
// a literal string value, the base case
|
|
42
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'Literal') && typeof prop.value.value === 'string') {
|
|
43
|
+
styleObj[prop.key.name] = prop.value.value;
|
|
40
44
|
}
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
|
|
46
|
+
// try to handle a direct call to `token`
|
|
47
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'CallExpression')) {
|
|
48
|
+
var _callExpression$argum;
|
|
49
|
+
var callExpression = prop.value;
|
|
50
|
+
// skip if not a call to `token`
|
|
51
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token') {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// only two valid cases are supported
|
|
56
|
+
// one argument => token('space.100')
|
|
57
|
+
// two arguments => token('space.100', '8px')
|
|
58
|
+
if (callExpression.arguments.length !== 1 && callExpression.arguments.length !== 2 || !(0, _eslintCodemodUtils.isNodeOfType)(callExpression.arguments[0], 'Literal') || callExpression.arguments[1] && !(0, _eslintCodemodUtils.isNodeOfType)(callExpression.arguments[1], 'Literal')) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
styleObj[prop.key.name] = {
|
|
62
|
+
tokenName: String(callExpression.arguments[0].value),
|
|
63
|
+
fallbackValue: (_callExpression$argum = callExpression.arguments[1]) !== null && _callExpression$argum !== void 0 && _callExpression$argum.value ? String(callExpression.arguments[1].value) : undefined
|
|
64
|
+
};
|
|
43
65
|
}
|
|
44
|
-
styleObj[prop.key.name] = prop.value.value;
|
|
45
66
|
});
|
|
46
67
|
return styleObj;
|
|
47
68
|
};
|
|
@@ -34,6 +34,7 @@ var findValidStyledComponentCall = exports.findValidStyledComponentCall = functi
|
|
|
34
34
|
*
|
|
35
35
|
* In the future it could be enhanced to double check `styled` and `styled2`
|
|
36
36
|
* are Compiled imports but as is should work for the majority of use cases
|
|
37
|
+
* https://product-fabric.atlassian.net/browse/DSP-16058
|
|
37
38
|
*/
|
|
38
39
|
var isStyledCallExpression = function isStyledCallExpression(call) {
|
|
39
40
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(call, 'CallExpression')) {
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.getVariableUsagesCount = void 0;
|
|
7
7
|
/**
|
|
8
|
+
* TODO: Update this logic: https://product-fabric.atlassian.net/browse/DSP-16059
|
|
8
9
|
* Using Regex here because otherwise we'd need to traverse the entire AST
|
|
9
10
|
* We should harden this logic as we go.
|
|
10
11
|
*/
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.isValidCssPropertiesToTransform = void 0;
|
|
8
|
+
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
|
|
7
9
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
10
|
var _cssToXcss = require("../transformers/css-to-xcss");
|
|
9
11
|
var _convertAstObjectExpressionToJsObject = require("./convert-ast-object-expression-to-js-object");
|
|
10
|
-
var isValidCssPropertiesToTransform = exports.isValidCssPropertiesToTransform = function isValidCssPropertiesToTransform(node) {
|
|
12
|
+
var isValidCssPropertiesToTransform = exports.isValidCssPropertiesToTransform = function isValidCssPropertiesToTransform(node, config) {
|
|
11
13
|
var cssObjectExpression = node.arguments[0];
|
|
12
14
|
// Bail on empty object calls
|
|
13
15
|
if (!cssObjectExpression || !(0, _eslintCodemodUtils.isNodeOfType)(cssObjectExpression, 'ObjectExpression')) {
|
|
@@ -18,6 +20,12 @@ var isValidCssPropertiesToTransform = exports.isValidCssPropertiesToTransform =
|
|
|
18
20
|
if (!cssObject || Object.keys(cssObject).length !== 1) {
|
|
19
21
|
return false;
|
|
20
22
|
}
|
|
23
|
+
// Short-circuit when token calls are found but pattern is not enabled in config
|
|
24
|
+
if (!config.patterns.includes('css-property-with-tokens') && Object.values(cssObject).some(function (value) {
|
|
25
|
+
return (0, _typeof2.default)(value) === 'object' && value.tokenName;
|
|
26
|
+
})) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
21
29
|
|
|
22
30
|
// NOTE: Our approach with this lint rule is to strictly whitelist css properties we can map.
|
|
23
31
|
// It means we have to provide mappings for everything (e.g. `display: block`).
|
|
@@ -25,10 +33,22 @@ var isValidCssPropertiesToTransform = exports.isValidCssPropertiesToTransform =
|
|
|
25
33
|
// than the rule reporting on things that can't be mapped.
|
|
26
34
|
var containsOnlyValidStyles = Object.keys(cssObject).every(function (styleProperty) {
|
|
27
35
|
var styleValue = cssObject[styleProperty];
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
|
|
37
|
+
// token function call
|
|
38
|
+
if ((0, _typeof2.default)(styleValue) === 'object') {
|
|
39
|
+
// if there is no fallback value, we just map to the token name, if one is found
|
|
40
|
+
if (!styleValue.fallbackValue) {
|
|
41
|
+
return _cssToXcss.supportedStylesMap[styleProperty] && Object.values(_cssToXcss.supportedStylesMap[styleProperty]).includes(styleValue.tokenName);
|
|
42
|
+
}
|
|
43
|
+
// token with fallback
|
|
44
|
+
return _cssToXcss.supportedStylesMap[styleProperty] && _cssToXcss.supportedStylesMap[styleProperty][styleValue.fallbackValue] === styleValue.tokenName;
|
|
45
|
+
} else {
|
|
46
|
+
// direct value used
|
|
47
|
+
return _cssToXcss.supportedStylesMap[styleProperty] &&
|
|
48
|
+
// Is the key something we can map
|
|
49
|
+
_cssToXcss.supportedStylesMap[styleProperty][styleValue] // Is the value something we can map
|
|
50
|
+
;
|
|
51
|
+
}
|
|
32
52
|
});
|
|
33
53
|
|
|
34
54
|
if (!containsOnlyValidStyles) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const defaults = {
|
|
2
|
+
patterns: ['compiled-css-function']
|
|
3
|
+
};
|
|
4
|
+
export const getConfig = overrides => {
|
|
5
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
6
|
+
// start with an empty object, then merge in the defaults, then merge in overrides.
|
|
7
|
+
// The empty object is returned, as well as modified in place
|
|
8
|
+
return Object.assign({}, defaults, overrides);
|
|
9
|
+
};
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { getIdentifierInParentScope, isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
import assign from 'lodash/assign';
|
|
3
2
|
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { getConfig } from './config';
|
|
4
4
|
import { jsxElementToBoxTransformer, styledComponentToPrimitive } from './transformers';
|
|
5
5
|
import { containsOnlySupportedAttrs, findValidJsxUsageToTransform, findValidStyledComponentCall, getAttributeValueIdentifier, getJSXAttributeByName, getVariableDefinitionValue, getVariableUsagesCount, isFunctionNamed, isValidCssPropertiesToTransform, isValidTagName } from './utils';
|
|
6
6
|
const boxDocsUrl = 'https://atlassian.design/components/primitives/box';
|
|
7
|
-
const defaultConfig = {
|
|
8
|
-
preview: false
|
|
9
|
-
};
|
|
10
7
|
const rule = createLintRule({
|
|
11
8
|
meta: {
|
|
12
9
|
name: 'use-primitives',
|
|
@@ -23,18 +20,18 @@ const rule = createLintRule({
|
|
|
23
20
|
}
|
|
24
21
|
},
|
|
25
22
|
create(context) {
|
|
26
|
-
const
|
|
23
|
+
const config = getConfig(context.options[0]);
|
|
27
24
|
return {
|
|
28
25
|
// transforms styled.<html>(...) usages
|
|
29
26
|
CallExpression(node) {
|
|
30
|
-
if (!
|
|
27
|
+
if (!config.patterns.includes('compiled-styled-object')) {
|
|
31
28
|
return;
|
|
32
29
|
}
|
|
33
30
|
if (!isNodeOfType(node, 'CallExpression')) {
|
|
34
31
|
return;
|
|
35
32
|
}
|
|
36
33
|
const styledComponentVariableRef = findValidStyledComponentCall(node);
|
|
37
|
-
if (!styledComponentVariableRef || !isNodeOfType(styledComponentVariableRef.id, 'Identifier') || !isValidCssPropertiesToTransform(node)) {
|
|
34
|
+
if (!styledComponentVariableRef || !isNodeOfType(styledComponentVariableRef.id, 'Identifier') || !isValidCssPropertiesToTransform(node, config)) {
|
|
38
35
|
return;
|
|
39
36
|
}
|
|
40
37
|
const styledComponentJsxRef = findValidJsxUsageToTransform(styledComponentVariableRef.id.name, context.getScope());
|
|
@@ -57,6 +54,9 @@ const rule = createLintRule({
|
|
|
57
54
|
},
|
|
58
55
|
// transforms <div css={...}> usages
|
|
59
56
|
JSXOpeningElement(node) {
|
|
57
|
+
if (!config.patterns.includes('compiled-css-function')) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
60
|
if (!isNodeOfType(node, 'JSXOpeningElement')) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
@@ -66,7 +66,7 @@ const rule = createLintRule({
|
|
|
66
66
|
if (!isNodeOfType(node.parent, 'JSXElement')) {
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
const suggestBox = shouldSuggestBox(node.parent, context);
|
|
69
|
+
const suggestBox = shouldSuggestBox(node.parent, context, config);
|
|
70
70
|
if (suggestBox) {
|
|
71
71
|
context.report({
|
|
72
72
|
node: node,
|
|
@@ -84,7 +84,7 @@ const rule = createLintRule({
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
|
-
const shouldSuggestBox = (node, context
|
|
87
|
+
const shouldSuggestBox = (node, context, config
|
|
88
88
|
// scope: Scope.Scope,
|
|
89
89
|
) => {
|
|
90
90
|
if (!node) {
|
|
@@ -131,6 +131,6 @@ const shouldSuggestBox = (node, context
|
|
|
131
131
|
if (!cssVariableValue || !isFunctionNamed(cssVariableValue, 'css')) {
|
|
132
132
|
return false;
|
|
133
133
|
}
|
|
134
|
-
return isValidCssPropertiesToTransform(cssVariableValue.node.init);
|
|
134
|
+
return isValidCssPropertiesToTransform(cssVariableValue.node.init, config);
|
|
135
135
|
};
|
|
136
136
|
export default rule;
|
|
@@ -31,7 +31,7 @@ export const cssToXcssTransformer = (node, context, fixer) => {
|
|
|
31
31
|
fixer.replaceText(cssVariableValue.node.init.callee, identifier('xcss').toString()), ...styledObjectToXcssTokens(cssObjectExpression, fixer)];
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
// Update css object values to xcss values
|
|
34
|
+
// Update css object values to xcss values
|
|
35
35
|
// Note: `properties` in this context is a group of AST nodes that make up a key/value pair in an object.
|
|
36
36
|
// e.g. `padding: '8px'`. For clarity, it's renamed to `entry` inside the `.map()`.
|
|
37
37
|
export const styledObjectToXcssTokens = (styles, fixer) => {
|
|
@@ -42,16 +42,30 @@ export const styledObjectToXcssTokens = (styles, fixer) => {
|
|
|
42
42
|
if (!isNodeOfType(entry.key, 'Identifier')) {
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
|
|
46
|
+
// maps literal values like: 8px to 'space.100'
|
|
47
|
+
if (isNodeOfType(entry.value, 'Literal')) {
|
|
48
|
+
const value = entry.value.value;
|
|
49
|
+
if (typeof value !== 'string') {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
return fixer.replaceText(entry.value, literal(`'${supportedStylesMap[entry.key.name][value]}'`).toString());
|
|
47
53
|
}
|
|
48
|
-
|
|
49
|
-
if (
|
|
50
|
-
|
|
54
|
+
// maps token calls like: token('space.100') to 'space.100'
|
|
55
|
+
if (isNodeOfType(entry.value, 'CallExpression')) {
|
|
56
|
+
const callExpression = entry.value;
|
|
57
|
+
// skip if not a call to `token`
|
|
58
|
+
if (!isNodeOfType(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token' || !isNodeOfType(callExpression.arguments[0], 'Literal')) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// the first argument of `token` is the token name and
|
|
62
|
+
// can be given directly to `xcss` as it has been validated already.
|
|
63
|
+
return fixer.replaceText(entry.value, literal(`'${callExpression.arguments[0].value}'`).toString());
|
|
51
64
|
}
|
|
52
|
-
return fixer.replaceText(entry.value, literal(`'${supportedStylesMap[entry.key.name][value]}'`).toString());
|
|
53
65
|
});
|
|
54
66
|
};
|
|
67
|
+
|
|
68
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16054
|
|
55
69
|
export const spaceTokenMap = {
|
|
56
70
|
'0px': 'space.0',
|
|
57
71
|
'2px': 'space.025',
|
package/dist/es2019/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js
CHANGED
|
@@ -13,28 +13,49 @@ export const convertASTObjectExpressionToJSObject = styles => {
|
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
// TODO:
|
|
16
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16055
|
|
17
|
+
// We need to harden this logic asap.
|
|
17
18
|
// It currently generates a false positive for:
|
|
18
19
|
// styled.div({
|
|
19
20
|
// marginTop: "0px",
|
|
20
|
-
// marginBottom:
|
|
21
|
+
// marginBottom: blah(...),
|
|
21
22
|
// })
|
|
22
|
-
// as the value for `marginBottom` is not a string,
|
|
23
|
-
// from the resulting map and this
|
|
23
|
+
// as the value for `marginBottom` is not a string nor a `token` call, it is just skipped
|
|
24
|
+
// from the resulting map and this is inaccurate.
|
|
24
25
|
styles.properties.forEach(prop => {
|
|
26
|
+
// cases we want to skip (see note above)
|
|
25
27
|
if (!isNodeOfType(prop, 'Property')) {
|
|
26
28
|
return;
|
|
27
29
|
}
|
|
28
30
|
if (!isNodeOfType(prop.key, 'Identifier')) {
|
|
29
31
|
return;
|
|
30
32
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
|
|
34
|
+
// a literal string value, the base case
|
|
35
|
+
if (isNodeOfType(prop.value, 'Literal') && typeof prop.value.value === 'string') {
|
|
36
|
+
styleObj[prop.key.name] = prop.value.value;
|
|
33
37
|
}
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
|
|
39
|
+
// try to handle a direct call to `token`
|
|
40
|
+
if (isNodeOfType(prop.value, 'CallExpression')) {
|
|
41
|
+
var _callExpression$argum;
|
|
42
|
+
const callExpression = prop.value;
|
|
43
|
+
// skip if not a call to `token`
|
|
44
|
+
if (!isNodeOfType(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// only two valid cases are supported
|
|
49
|
+
// one argument => token('space.100')
|
|
50
|
+
// two arguments => token('space.100', '8px')
|
|
51
|
+
if (callExpression.arguments.length !== 1 && callExpression.arguments.length !== 2 || !isNodeOfType(callExpression.arguments[0], 'Literal') || callExpression.arguments[1] && !isNodeOfType(callExpression.arguments[1], 'Literal')) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
styleObj[prop.key.name] = {
|
|
55
|
+
tokenName: String(callExpression.arguments[0].value),
|
|
56
|
+
fallbackValue: (_callExpression$argum = callExpression.arguments[1]) !== null && _callExpression$argum !== void 0 && _callExpression$argum.value ? String(callExpression.arguments[1].value) : undefined
|
|
57
|
+
};
|
|
36
58
|
}
|
|
37
|
-
styleObj[prop.key.name] = prop.value.value;
|
|
38
59
|
});
|
|
39
60
|
return styleObj;
|
|
40
61
|
};
|
|
@@ -29,6 +29,7 @@ export const findValidStyledComponentCall = node => {
|
|
|
29
29
|
*
|
|
30
30
|
* In the future it could be enhanced to double check `styled` and `styled2`
|
|
31
31
|
* are Compiled imports but as is should work for the majority of use cases
|
|
32
|
+
* https://product-fabric.atlassian.net/browse/DSP-16058
|
|
32
33
|
*/
|
|
33
34
|
const isStyledCallExpression = call => {
|
|
34
35
|
if (!isNodeOfType(call, 'CallExpression')) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
2
|
import { supportedStylesMap } from '../transformers/css-to-xcss';
|
|
3
3
|
import { convertASTObjectExpressionToJSObject } from './convert-ast-object-expression-to-js-object';
|
|
4
|
-
export const isValidCssPropertiesToTransform = node => {
|
|
4
|
+
export const isValidCssPropertiesToTransform = (node, config) => {
|
|
5
5
|
const cssObjectExpression = node.arguments[0];
|
|
6
6
|
// Bail on empty object calls
|
|
7
7
|
if (!cssObjectExpression || !isNodeOfType(cssObjectExpression, 'ObjectExpression')) {
|
|
@@ -12,6 +12,10 @@ export const isValidCssPropertiesToTransform = node => {
|
|
|
12
12
|
if (!cssObject || Object.keys(cssObject).length !== 1) {
|
|
13
13
|
return false;
|
|
14
14
|
}
|
|
15
|
+
// Short-circuit when token calls are found but pattern is not enabled in config
|
|
16
|
+
if (!config.patterns.includes('css-property-with-tokens') && Object.values(cssObject).some(value => typeof value === 'object' && value.tokenName)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
15
19
|
|
|
16
20
|
// NOTE: Our approach with this lint rule is to strictly whitelist css properties we can map.
|
|
17
21
|
// It means we have to provide mappings for everything (e.g. `display: block`).
|
|
@@ -19,10 +23,22 @@ export const isValidCssPropertiesToTransform = node => {
|
|
|
19
23
|
// than the rule reporting on things that can't be mapped.
|
|
20
24
|
const containsOnlyValidStyles = Object.keys(cssObject).every(styleProperty => {
|
|
21
25
|
const styleValue = cssObject[styleProperty];
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
+
|
|
27
|
+
// token function call
|
|
28
|
+
if (typeof styleValue === 'object') {
|
|
29
|
+
// if there is no fallback value, we just map to the token name, if one is found
|
|
30
|
+
if (!styleValue.fallbackValue) {
|
|
31
|
+
return supportedStylesMap[styleProperty] && Object.values(supportedStylesMap[styleProperty]).includes(styleValue.tokenName);
|
|
32
|
+
}
|
|
33
|
+
// token with fallback
|
|
34
|
+
return supportedStylesMap[styleProperty] && supportedStylesMap[styleProperty][styleValue.fallbackValue] === styleValue.tokenName;
|
|
35
|
+
} else {
|
|
36
|
+
// direct value used
|
|
37
|
+
return supportedStylesMap[styleProperty] &&
|
|
38
|
+
// Is the key something we can map
|
|
39
|
+
supportedStylesMap[styleProperty][styleValue] // Is the value something we can map
|
|
40
|
+
;
|
|
41
|
+
}
|
|
26
42
|
});
|
|
27
43
|
|
|
28
44
|
if (!containsOnlyValidStyles) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var defaults = {
|
|
2
|
+
patterns: ['compiled-css-function']
|
|
3
|
+
};
|
|
4
|
+
export var getConfig = function getConfig(overrides) {
|
|
5
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
6
|
+
// start with an empty object, then merge in the defaults, then merge in overrides.
|
|
7
|
+
// The empty object is returned, as well as modified in place
|
|
8
|
+
return Object.assign({}, defaults, overrides);
|
|
9
|
+
};
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { getIdentifierInParentScope, isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
import assign from 'lodash/assign';
|
|
3
2
|
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { getConfig } from './config';
|
|
4
4
|
import { jsxElementToBoxTransformer, styledComponentToPrimitive } from './transformers';
|
|
5
5
|
import { containsOnlySupportedAttrs, findValidJsxUsageToTransform, findValidStyledComponentCall, getAttributeValueIdentifier, getJSXAttributeByName, getVariableDefinitionValue, getVariableUsagesCount, isFunctionNamed, isValidCssPropertiesToTransform, isValidTagName } from './utils';
|
|
6
6
|
var boxDocsUrl = 'https://atlassian.design/components/primitives/box';
|
|
7
|
-
var defaultConfig = {
|
|
8
|
-
preview: false
|
|
9
|
-
};
|
|
10
7
|
var rule = createLintRule({
|
|
11
8
|
meta: {
|
|
12
9
|
name: 'use-primitives',
|
|
@@ -23,18 +20,18 @@ var rule = createLintRule({
|
|
|
23
20
|
}
|
|
24
21
|
},
|
|
25
22
|
create: function create(context) {
|
|
26
|
-
var
|
|
23
|
+
var config = getConfig(context.options[0]);
|
|
27
24
|
return {
|
|
28
25
|
// transforms styled.<html>(...) usages
|
|
29
26
|
CallExpression: function CallExpression(node) {
|
|
30
|
-
if (!
|
|
27
|
+
if (!config.patterns.includes('compiled-styled-object')) {
|
|
31
28
|
return;
|
|
32
29
|
}
|
|
33
30
|
if (!isNodeOfType(node, 'CallExpression')) {
|
|
34
31
|
return;
|
|
35
32
|
}
|
|
36
33
|
var styledComponentVariableRef = findValidStyledComponentCall(node);
|
|
37
|
-
if (!styledComponentVariableRef || !isNodeOfType(styledComponentVariableRef.id, 'Identifier') || !isValidCssPropertiesToTransform(node)) {
|
|
34
|
+
if (!styledComponentVariableRef || !isNodeOfType(styledComponentVariableRef.id, 'Identifier') || !isValidCssPropertiesToTransform(node, config)) {
|
|
38
35
|
return;
|
|
39
36
|
}
|
|
40
37
|
var styledComponentJsxRef = findValidJsxUsageToTransform(styledComponentVariableRef.id.name, context.getScope());
|
|
@@ -57,6 +54,9 @@ var rule = createLintRule({
|
|
|
57
54
|
},
|
|
58
55
|
// transforms <div css={...}> usages
|
|
59
56
|
JSXOpeningElement: function JSXOpeningElement(node) {
|
|
57
|
+
if (!config.patterns.includes('compiled-css-function')) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
60
|
if (!isNodeOfType(node, 'JSXOpeningElement')) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
@@ -66,7 +66,7 @@ var rule = createLintRule({
|
|
|
66
66
|
if (!isNodeOfType(node.parent, 'JSXElement')) {
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
|
-
var suggestBox = shouldSuggestBox(node.parent, context);
|
|
69
|
+
var suggestBox = shouldSuggestBox(node.parent, context, config);
|
|
70
70
|
if (suggestBox) {
|
|
71
71
|
context.report({
|
|
72
72
|
node: node,
|
|
@@ -84,7 +84,7 @@ var rule = createLintRule({
|
|
|
84
84
|
};
|
|
85
85
|
}
|
|
86
86
|
});
|
|
87
|
-
var shouldSuggestBox = function shouldSuggestBox(node, context
|
|
87
|
+
var shouldSuggestBox = function shouldSuggestBox(node, context, config
|
|
88
88
|
// scope: Scope.Scope,
|
|
89
89
|
) {
|
|
90
90
|
if (!node) {
|
|
@@ -131,6 +131,6 @@ var shouldSuggestBox = function shouldSuggestBox(node, context
|
|
|
131
131
|
if (!cssVariableValue || !isFunctionNamed(cssVariableValue, 'css')) {
|
|
132
132
|
return false;
|
|
133
133
|
}
|
|
134
|
-
return isValidCssPropertiesToTransform(cssVariableValue.node.init);
|
|
134
|
+
return isValidCssPropertiesToTransform(cssVariableValue.node.init, config);
|
|
135
135
|
};
|
|
136
136
|
export default rule;
|
|
@@ -32,7 +32,7 @@ export var cssToXcssTransformer = function cssToXcssTransformer(node, context, f
|
|
|
32
32
|
fixer.replaceText(cssVariableValue.node.init.callee, identifier('xcss').toString())].concat(_toConsumableArray(styledObjectToXcssTokens(cssObjectExpression, fixer)));
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
// Update css object values to xcss values
|
|
35
|
+
// Update css object values to xcss values
|
|
36
36
|
// Note: `properties` in this context is a group of AST nodes that make up a key/value pair in an object.
|
|
37
37
|
// e.g. `padding: '8px'`. For clarity, it's renamed to `entry` inside the `.map()`.
|
|
38
38
|
export var styledObjectToXcssTokens = function styledObjectToXcssTokens(styles, fixer) {
|
|
@@ -43,16 +43,30 @@ export var styledObjectToXcssTokens = function styledObjectToXcssTokens(styles,
|
|
|
43
43
|
if (!isNodeOfType(entry.key, 'Identifier')) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
|
|
47
|
+
// maps literal values like: 8px to 'space.100'
|
|
48
|
+
if (isNodeOfType(entry.value, 'Literal')) {
|
|
49
|
+
var value = entry.value.value;
|
|
50
|
+
if (typeof value !== 'string') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return fixer.replaceText(entry.value, literal("'".concat(supportedStylesMap[entry.key.name][value], "'")).toString());
|
|
48
54
|
}
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
55
|
+
// maps token calls like: token('space.100') to 'space.100'
|
|
56
|
+
if (isNodeOfType(entry.value, 'CallExpression')) {
|
|
57
|
+
var callExpression = entry.value;
|
|
58
|
+
// skip if not a call to `token`
|
|
59
|
+
if (!isNodeOfType(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token' || !isNodeOfType(callExpression.arguments[0], 'Literal')) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// the first argument of `token` is the token name and
|
|
63
|
+
// can be given directly to `xcss` as it has been validated already.
|
|
64
|
+
return fixer.replaceText(entry.value, literal("'".concat(callExpression.arguments[0].value, "'")).toString());
|
|
52
65
|
}
|
|
53
|
-
return fixer.replaceText(entry.value, literal("'".concat(supportedStylesMap[entry.key.name][value], "'")).toString());
|
|
54
66
|
});
|
|
55
67
|
};
|
|
68
|
+
|
|
69
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16054
|
|
56
70
|
export var spaceTokenMap = {
|
|
57
71
|
'0px': 'space.0',
|
|
58
72
|
'2px': 'space.025',
|
|
@@ -15,28 +15,49 @@ export var convertASTObjectExpressionToJSObject = function convertASTObjectExpre
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
// TODO:
|
|
18
|
+
// TODO: https://product-fabric.atlassian.net/browse/DSP-16055
|
|
19
|
+
// We need to harden this logic asap.
|
|
19
20
|
// It currently generates a false positive for:
|
|
20
21
|
// styled.div({
|
|
21
22
|
// marginTop: "0px",
|
|
22
|
-
// marginBottom:
|
|
23
|
+
// marginBottom: blah(...),
|
|
23
24
|
// })
|
|
24
|
-
// as the value for `marginBottom` is not a string,
|
|
25
|
-
// from the resulting map and this
|
|
25
|
+
// as the value for `marginBottom` is not a string nor a `token` call, it is just skipped
|
|
26
|
+
// from the resulting map and this is inaccurate.
|
|
26
27
|
styles.properties.forEach(function (prop) {
|
|
28
|
+
// cases we want to skip (see note above)
|
|
27
29
|
if (!isNodeOfType(prop, 'Property')) {
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
32
|
if (!isNodeOfType(prop.key, 'Identifier')) {
|
|
31
33
|
return;
|
|
32
34
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
|
|
36
|
+
// a literal string value, the base case
|
|
37
|
+
if (isNodeOfType(prop.value, 'Literal') && typeof prop.value.value === 'string') {
|
|
38
|
+
styleObj[prop.key.name] = prop.value.value;
|
|
35
39
|
}
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
|
|
41
|
+
// try to handle a direct call to `token`
|
|
42
|
+
if (isNodeOfType(prop.value, 'CallExpression')) {
|
|
43
|
+
var _callExpression$argum;
|
|
44
|
+
var callExpression = prop.value;
|
|
45
|
+
// skip if not a call to `token`
|
|
46
|
+
if (!isNodeOfType(callExpression.callee, 'Identifier') || callExpression.callee.name !== 'token') {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// only two valid cases are supported
|
|
51
|
+
// one argument => token('space.100')
|
|
52
|
+
// two arguments => token('space.100', '8px')
|
|
53
|
+
if (callExpression.arguments.length !== 1 && callExpression.arguments.length !== 2 || !isNodeOfType(callExpression.arguments[0], 'Literal') || callExpression.arguments[1] && !isNodeOfType(callExpression.arguments[1], 'Literal')) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
styleObj[prop.key.name] = {
|
|
57
|
+
tokenName: String(callExpression.arguments[0].value),
|
|
58
|
+
fallbackValue: (_callExpression$argum = callExpression.arguments[1]) !== null && _callExpression$argum !== void 0 && _callExpression$argum.value ? String(callExpression.arguments[1].value) : undefined
|
|
59
|
+
};
|
|
38
60
|
}
|
|
39
|
-
styleObj[prop.key.name] = prop.value.value;
|
|
40
61
|
});
|
|
41
62
|
return styleObj;
|
|
42
63
|
};
|
|
@@ -29,6 +29,7 @@ export var findValidStyledComponentCall = function findValidStyledComponentCall(
|
|
|
29
29
|
*
|
|
30
30
|
* In the future it could be enhanced to double check `styled` and `styled2`
|
|
31
31
|
* are Compiled imports but as is should work for the majority of use cases
|
|
32
|
+
* https://product-fabric.atlassian.net/browse/DSP-16058
|
|
32
33
|
*/
|
|
33
34
|
var isStyledCallExpression = function isStyledCallExpression(call) {
|
|
34
35
|
if (!isNodeOfType(call, 'CallExpression')) {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import _typeof from "@babel/runtime/helpers/typeof";
|
|
1
2
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
3
|
import { supportedStylesMap } from '../transformers/css-to-xcss';
|
|
3
4
|
import { convertASTObjectExpressionToJSObject } from './convert-ast-object-expression-to-js-object';
|
|
4
|
-
export var isValidCssPropertiesToTransform = function isValidCssPropertiesToTransform(node) {
|
|
5
|
+
export var isValidCssPropertiesToTransform = function isValidCssPropertiesToTransform(node, config) {
|
|
5
6
|
var cssObjectExpression = node.arguments[0];
|
|
6
7
|
// Bail on empty object calls
|
|
7
8
|
if (!cssObjectExpression || !isNodeOfType(cssObjectExpression, 'ObjectExpression')) {
|
|
@@ -12,6 +13,12 @@ export var isValidCssPropertiesToTransform = function isValidCssPropertiesToTran
|
|
|
12
13
|
if (!cssObject || Object.keys(cssObject).length !== 1) {
|
|
13
14
|
return false;
|
|
14
15
|
}
|
|
16
|
+
// Short-circuit when token calls are found but pattern is not enabled in config
|
|
17
|
+
if (!config.patterns.includes('css-property-with-tokens') && Object.values(cssObject).some(function (value) {
|
|
18
|
+
return _typeof(value) === 'object' && value.tokenName;
|
|
19
|
+
})) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
15
22
|
|
|
16
23
|
// NOTE: Our approach with this lint rule is to strictly whitelist css properties we can map.
|
|
17
24
|
// It means we have to provide mappings for everything (e.g. `display: block`).
|
|
@@ -19,10 +26,22 @@ export var isValidCssPropertiesToTransform = function isValidCssPropertiesToTran
|
|
|
19
26
|
// than the rule reporting on things that can't be mapped.
|
|
20
27
|
var containsOnlyValidStyles = Object.keys(cssObject).every(function (styleProperty) {
|
|
21
28
|
var styleValue = cssObject[styleProperty];
|
|
22
|
-
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
|
|
30
|
+
// token function call
|
|
31
|
+
if (_typeof(styleValue) === 'object') {
|
|
32
|
+
// if there is no fallback value, we just map to the token name, if one is found
|
|
33
|
+
if (!styleValue.fallbackValue) {
|
|
34
|
+
return supportedStylesMap[styleProperty] && Object.values(supportedStylesMap[styleProperty]).includes(styleValue.tokenName);
|
|
35
|
+
}
|
|
36
|
+
// token with fallback
|
|
37
|
+
return supportedStylesMap[styleProperty] && supportedStylesMap[styleProperty][styleValue.fallbackValue] === styleValue.tokenName;
|
|
38
|
+
} else {
|
|
39
|
+
// direct value used
|
|
40
|
+
return supportedStylesMap[styleProperty] &&
|
|
41
|
+
// Is the key something we can map
|
|
42
|
+
supportedStylesMap[styleProperty][styleValue] // Is the value something we can map
|
|
43
|
+
;
|
|
44
|
+
}
|
|
26
45
|
});
|
|
27
46
|
|
|
28
47
|
if (!containsOnlyValidStyles) {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type Pattern = 'compiled-css-function' | 'compiled-styled-object' | 'css-template-literal' | 'css-property-with-tokens' | 'css-property-multiple-values';
|
|
2
|
+
export interface RuleConfig {
|
|
3
|
+
patterns: Pattern[];
|
|
4
|
+
}
|
|
5
|
+
export declare const getConfig: (overrides: Partial<RuleConfig>) => Required<RuleConfig>;
|
|
6
|
+
export {};
|
package/dist/types/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
2
|
import { ObjectExpression } from 'eslint-codemod-utils';
|
|
3
|
+
type Token = {
|
|
4
|
+
tokenName: string;
|
|
5
|
+
fallbackValue: string | undefined;
|
|
6
|
+
};
|
|
3
7
|
export type CSSPropStyleObject = {
|
|
4
|
-
[key: string]: string | number;
|
|
8
|
+
[key: string]: string | number | Token;
|
|
5
9
|
};
|
|
6
10
|
/**
|
|
7
11
|
* Note: Not recursive. Only handles top level key/value pairs
|
|
8
12
|
*/
|
|
9
13
|
export declare const convertASTObjectExpressionToJSObject: (styles: ObjectExpression & Partial<Rule.NodeParentExtension>) => CSSPropStyleObject | false;
|
|
14
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
2
|
import { SimpleCallExpression } from 'eslint-codemod-utils';
|
|
3
|
-
|
|
3
|
+
import { RuleConfig } from '../config';
|
|
4
|
+
export declare const isValidCssPropertiesToTransform: (node: SimpleCallExpression & Rule.NodeParentExtension, config: RuleConfig) => boolean;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type Pattern = 'compiled-css-function' | 'compiled-styled-object' | 'css-template-literal' | 'css-property-with-tokens' | 'css-property-multiple-values';
|
|
2
|
+
export interface RuleConfig {
|
|
3
|
+
patterns: Pattern[];
|
|
4
|
+
}
|
|
5
|
+
export declare const getConfig: (overrides: Partial<RuleConfig>) => Required<RuleConfig>;
|
|
6
|
+
export {};
|
package/dist/types-ts4.5/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
2
|
import { ObjectExpression } from 'eslint-codemod-utils';
|
|
3
|
+
type Token = {
|
|
4
|
+
tokenName: string;
|
|
5
|
+
fallbackValue: string | undefined;
|
|
6
|
+
};
|
|
3
7
|
export type CSSPropStyleObject = {
|
|
4
|
-
[key: string]: string | number;
|
|
8
|
+
[key: string]: string | number | Token;
|
|
5
9
|
};
|
|
6
10
|
/**
|
|
7
11
|
* Note: Not recursive. Only handles top level key/value pairs
|
|
8
12
|
*/
|
|
9
13
|
export declare const convertASTObjectExpressionToJSObject: (styles: ObjectExpression & Partial<Rule.NodeParentExtension>) => CSSPropStyleObject | false;
|
|
14
|
+
export {};
|
package/dist/types-ts4.5/rules/use-primitives/utils/is-valid-css-properties-to-transform.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { Rule } from 'eslint';
|
|
2
2
|
import { SimpleCallExpression } from 'eslint-codemod-utils';
|
|
3
|
-
|
|
3
|
+
import { RuleConfig } from '../config';
|
|
4
|
+
export declare const isValidCssPropertiesToTransform: (node: SimpleCallExpression & Rule.NodeParentExtension, config: RuleConfig) => 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": "8.19.
|
|
4
|
+
"version": "8.19.2",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|