@atlaskit/eslint-plugin-design-system 8.15.4 → 8.16.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 +13 -0
- package/constellation/index/usage.mdx +62 -16
- package/dist/cjs/rules/ensure-design-token-usage/typography.js +2 -2
- package/dist/cjs/rules/prefer-primitives/index.js +2 -3
- package/dist/cjs/rules/prefer-primitives/utils.js +16 -5
- package/dist/cjs/rules/use-primitives/index.js +89 -58
- package/dist/cjs/rules/use-primitives/transformers/css-to-xcss.js +95 -0
- package/dist/cjs/rules/use-primitives/transformers/index.js +31 -0
- package/dist/cjs/rules/use-primitives/transformers/jsx-element-to-box.js +26 -0
- package/dist/cjs/rules/use-primitives/utils/contains-only-supported-attrs.js +19 -0
- package/dist/cjs/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +31 -0
- package/dist/cjs/rules/use-primitives/utils/get-attribute-value-identifier.js +37 -0
- package/dist/cjs/rules/use-primitives/utils/get-function-argument-at-pos.js +10 -0
- package/dist/cjs/rules/use-primitives/utils/get-jsx-attribute-by-name.js +16 -0
- package/dist/cjs/rules/use-primitives/utils/get-variable-definition-value.js +29 -0
- package/dist/cjs/rules/use-primitives/utils/get-variable-usage-count.js +21 -0
- package/dist/cjs/rules/use-primitives/utils/index.js +89 -0
- package/dist/cjs/rules/use-primitives/utils/is-function-named.js +19 -0
- package/dist/cjs/rules/use-primitives/utils/is-valid-tag-name.js +13 -0
- package/dist/cjs/rules/use-primitives/utils/update-jsx-attribute-by-name.js +31 -0
- package/dist/cjs/rules/use-primitives/utils/update-jsx-element-name.js +16 -0
- package/dist/cjs/rules/use-primitives/utils/upsert-import-declaration.js +80 -0
- package/dist/es2019/rules/ensure-design-token-usage/typography.js +1 -1
- package/dist/es2019/rules/prefer-primitives/index.js +1 -2
- package/dist/es2019/rules/prefer-primitives/utils.js +11 -2
- package/dist/es2019/rules/use-primitives/index.js +91 -60
- package/dist/es2019/rules/use-primitives/transformers/css-to-xcss.js +91 -0
- package/dist/es2019/rules/use-primitives/transformers/index.js +2 -0
- package/dist/es2019/rules/use-primitives/transformers/jsx-element-to-box.js +16 -0
- package/dist/es2019/rules/use-primitives/utils/contains-only-supported-attrs.js +13 -0
- package/dist/es2019/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +26 -0
- package/dist/es2019/rules/use-primitives/utils/get-attribute-value-identifier.js +32 -0
- package/dist/es2019/rules/use-primitives/utils/get-function-argument-at-pos.js +4 -0
- package/dist/es2019/rules/use-primitives/utils/get-jsx-attribute-by-name.js +10 -0
- package/dist/es2019/rules/use-primitives/utils/get-variable-definition-value.js +23 -0
- package/dist/es2019/rules/use-primitives/utils/get-variable-usage-count.js +15 -0
- package/dist/es2019/rules/use-primitives/utils/index.js +12 -0
- package/dist/es2019/rules/use-primitives/utils/is-function-named.js +13 -0
- package/dist/es2019/rules/use-primitives/utils/is-valid-tag-name.js +7 -0
- package/dist/es2019/rules/use-primitives/utils/update-jsx-attribute-by-name.js +26 -0
- package/dist/es2019/rules/use-primitives/utils/update-jsx-element-name.js +12 -0
- package/dist/es2019/rules/use-primitives/utils/upsert-import-declaration.js +76 -0
- package/dist/esm/rules/ensure-design-token-usage/typography.js +1 -1
- package/dist/esm/rules/prefer-primitives/index.js +1 -2
- package/dist/esm/rules/prefer-primitives/utils.js +13 -2
- package/dist/esm/rules/use-primitives/index.js +91 -60
- package/dist/esm/rules/use-primitives/transformers/css-to-xcss.js +88 -0
- package/dist/esm/rules/use-primitives/transformers/index.js +2 -0
- package/dist/esm/rules/use-primitives/transformers/jsx-element-to-box.js +19 -0
- package/dist/esm/rules/use-primitives/utils/contains-only-supported-attrs.js +13 -0
- package/dist/esm/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.js +26 -0
- package/dist/esm/rules/use-primitives/utils/get-attribute-value-identifier.js +32 -0
- package/dist/esm/rules/use-primitives/utils/get-function-argument-at-pos.js +4 -0
- package/dist/esm/rules/use-primitives/utils/get-jsx-attribute-by-name.js +10 -0
- package/dist/esm/rules/use-primitives/utils/get-variable-definition-value.js +23 -0
- package/dist/esm/rules/use-primitives/utils/get-variable-usage-count.js +15 -0
- package/dist/esm/rules/use-primitives/utils/index.js +12 -0
- package/dist/esm/rules/use-primitives/utils/is-function-named.js +13 -0
- package/dist/esm/rules/use-primitives/utils/is-valid-tag-name.js +7 -0
- package/dist/esm/rules/use-primitives/utils/update-jsx-attribute-by-name.js +24 -0
- package/dist/esm/rules/use-primitives/utils/update-jsx-element-name.js +10 -0
- package/dist/esm/rules/use-primitives/utils/upsert-import-declaration.js +75 -0
- package/dist/types/rules/prefer-primitives/utils.d.ts +2 -1
- package/dist/types/rules/use-primitives/transformers/css-to-xcss.d.ts +9 -0
- package/dist/types/rules/use-primitives/transformers/index.d.ts +2 -0
- package/dist/types/rules/use-primitives/transformers/jsx-element-to-box.d.ts +3 -0
- package/dist/types/rules/use-primitives/utils/contains-only-supported-attrs.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts +9 -0
- package/dist/types/rules/use-primitives/utils/get-attribute-value-identifier.d.ts +14 -0
- package/dist/types/rules/use-primitives/utils/get-function-argument-at-pos.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/get-jsx-attribute-by-name.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/get-variable-definition-value.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/get-variable-usage-count.d.ts +6 -0
- package/dist/types/rules/use-primitives/utils/index.d.ts +12 -0
- package/dist/types/rules/use-primitives/utils/is-function-named.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/is-valid-tag-name.d.ts +2 -0
- package/dist/types/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +3 -0
- package/dist/types/rules/use-primitives/utils/update-jsx-element-name.d.ts +3 -0
- package/dist/types/rules/use-primitives/utils/upsert-import-declaration.d.ts +11 -0
- package/dist/types-ts4.5/rules/prefer-primitives/utils.d.ts +2 -1
- package/dist/types-ts4.5/rules/use-primitives/transformers/css-to-xcss.d.ts +9 -0
- package/dist/types-ts4.5/rules/use-primitives/transformers/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/transformers/jsx-element-to-box.d.ts +3 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/contains-only-supported-attrs.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/convert-ast-object-expression-to-js-object.d.ts +9 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/get-attribute-value-identifier.d.ts +14 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/get-function-argument-at-pos.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/get-jsx-attribute-by-name.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/get-variable-definition-value.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/get-variable-usage-count.d.ts +6 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/index.d.ts +12 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/is-function-named.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/is-valid-tag-name.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +3 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-element-name.d.ts +3 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/upsert-import-declaration.d.ts +11 -0
- package/package.json +3 -1
- package/dist/cjs/rules/use-primitives/utils.js +0 -364
- package/dist/es2019/rules/use-primitives/utils.js +0 -353
- package/dist/esm/rules/use-primitives/utils.js +0 -359
- package/dist/types/rules/use-primitives/utils.d.ts +0 -13
- package/dist/types-ts4.5/rules/use-primitives/utils.d.ts +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 8.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#58402](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/58402) [`2b1a12e5936f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2b1a12e5936f) - Re-work `use-primitives` lint rule to only suggest `Box`, and only trigger a violation styles contain one style property and the style value can be mapped to a token.
|
|
8
|
+
|
|
9
|
+
## 8.15.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#63526](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/63526) [`cae958047771`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/cae958047771) - Internal change to how typography tokens are imported. There is no expected behaviour change.
|
|
14
|
+
- Updated dependencies
|
|
15
|
+
|
|
3
16
|
## 8.15.4
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
|
@@ -798,27 +798,73 @@ This rule marks code as violations when it can be replaced 1:1 with a primitive
|
|
|
798
798
|
|
|
799
799
|
#### Incorrect
|
|
800
800
|
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
|
|
801
|
+
```jsx
|
|
802
|
+
const someStyles = css({
|
|
803
|
+
padding: '8px';
|
|
804
|
+
})
|
|
804
805
|
|
|
805
|
-
<
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
</
|
|
806
|
+
<div css={someStyles}>
|
|
807
|
+
^^^^^^^^^^^^^^^^^^^^^^
|
|
808
|
+
// ...
|
|
809
|
+
</div>
|
|
809
810
|
```
|
|
810
811
|
|
|
811
812
|
#### Correct
|
|
812
813
|
|
|
813
|
-
```
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
<
|
|
819
|
-
|
|
820
|
-
</
|
|
821
|
-
```
|
|
814
|
+
```jsx
|
|
815
|
+
const someStyles = xcss({
|
|
816
|
+
padding: 'space.100';
|
|
817
|
+
})
|
|
818
|
+
|
|
819
|
+
<Box xcss={someStyles}>
|
|
820
|
+
// ...
|
|
821
|
+
</Box>
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
Currently, the rule is extremely defensive, only reporting on `css` styles that contain:
|
|
825
|
+
|
|
826
|
+
- one, and only one, style property from this list:
|
|
827
|
+
|
|
828
|
+
- padding
|
|
829
|
+
- paddingBlock
|
|
830
|
+
- paddingBlockEnd
|
|
831
|
+
- paddingBlockStart
|
|
832
|
+
- paddingBottom
|
|
833
|
+
- paddingInline
|
|
834
|
+
- paddingInlineEnd
|
|
835
|
+
- paddingInlineStart
|
|
836
|
+
- paddingLeft
|
|
837
|
+
- paddingRight
|
|
838
|
+
- paddingTop
|
|
839
|
+
- margin
|
|
840
|
+
- marginBlock
|
|
841
|
+
- marginBlockEnd
|
|
842
|
+
- marginBlockStart
|
|
843
|
+
- marginBottom
|
|
844
|
+
- marginInline
|
|
845
|
+
- marginInlineEnd
|
|
846
|
+
- marginInlineStart
|
|
847
|
+
- marginLeft
|
|
848
|
+
- marginRight
|
|
849
|
+
- marginTop
|
|
850
|
+
|
|
851
|
+
- and where the style value is one of:
|
|
852
|
+
- 0px
|
|
853
|
+
- 2px
|
|
854
|
+
- 4px
|
|
855
|
+
- 6px
|
|
856
|
+
- 8px
|
|
857
|
+
- 12px
|
|
858
|
+
- 16px
|
|
859
|
+
- 20px
|
|
860
|
+
- 24px
|
|
861
|
+
- 32px
|
|
862
|
+
- 40px
|
|
863
|
+
- 48px
|
|
864
|
+
- 64px
|
|
865
|
+
- 80px
|
|
866
|
+
|
|
867
|
+
If these conditions are not met, then no violation will be reported.
|
|
822
868
|
|
|
823
869
|
## use-visually-hidden
|
|
824
870
|
|
|
@@ -22,7 +22,7 @@ var isFontFamily = exports.isFontFamily = function isFontFamily(node) {
|
|
|
22
22
|
var isCodeFontFamily = exports.isCodeFontFamily = function isCodeFontFamily(node) {
|
|
23
23
|
return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
|
|
24
24
|
};
|
|
25
|
-
var typographyValueToToken = exports.typographyValueToToken = Object.fromEntries(_tokensRaw.
|
|
25
|
+
var typographyValueToToken = exports.typographyValueToToken = Object.fromEntries(_tokensRaw.typographyAdg3
|
|
26
26
|
// we're filtering here to remove the `font` tokens.
|
|
27
27
|
.filter(function (t) {
|
|
28
28
|
return t.attributes.group !== 'typography';
|
|
@@ -31,7 +31,7 @@ var typographyValueToToken = exports.typographyValueToToken = Object.fromEntries
|
|
|
31
31
|
// This allows us to look up values specific to a property
|
|
32
32
|
// (so as not to mix tokens with overlapping values e.g. font size and line height both have tokens for 16px)
|
|
33
33
|
var tokenGroup = currentToken.attributes.group;
|
|
34
|
-
return [tokenGroup, Object.fromEntries(_tokensRaw.
|
|
34
|
+
return [tokenGroup, Object.fromEntries(_tokensRaw.typographyAdg3.map(function (token) {
|
|
35
35
|
return token.attributes.group === tokenGroup ? [token.value.replaceAll("\"", "'"), token.name] : [];
|
|
36
36
|
}).filter(function (token) {
|
|
37
37
|
return token.length;
|
|
@@ -5,9 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
-
var _utils = require("../use-primitives/utils");
|
|
9
8
|
var _createRule = require("../utils/create-rule");
|
|
10
|
-
var
|
|
9
|
+
var _utils = require("./utils");
|
|
11
10
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
12
11
|
|
|
13
12
|
var primitiveDocsUrl = 'https://go.atlassian.com/dst-prefer-primitives';
|
|
@@ -36,7 +35,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
36
35
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.name, 'JSXIdentifier')) {
|
|
37
36
|
return;
|
|
38
37
|
}
|
|
39
|
-
var suggest = (0,
|
|
38
|
+
var suggest = (0, _utils.shouldSuggest)(node === null || node === void 0 ? void 0 : node.parent);
|
|
40
39
|
if (suggest) {
|
|
41
40
|
context.report({
|
|
42
41
|
node: node,
|
|
@@ -3,13 +3,24 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.shouldSuggest = void 0;
|
|
7
|
-
var
|
|
6
|
+
exports.validPrimitiveElements = exports.shouldSuggest = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var validPrimitiveElements = exports.validPrimitiveElements = new Set(['div', 'span', 'article', 'aside', 'dialog', 'footer', 'header', 'li', 'main', 'nav', 'ol', 'section', 'ul']);
|
|
9
|
+
var getChildrenByType = function getChildrenByType(node, types) {
|
|
10
|
+
return node.children.filter(function (child) {
|
|
11
|
+
return types.find(function (type) {
|
|
12
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(child, type);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
var isValidPrimitiveElement = function isValidPrimitiveElement(node) {
|
|
17
|
+
return validPrimitiveElements.has(node.openingElement.name.name);
|
|
18
|
+
};
|
|
8
19
|
var shouldSuggest = exports.shouldSuggest = function shouldSuggest(node) {
|
|
9
20
|
if (!node) {
|
|
10
21
|
return false;
|
|
11
22
|
}
|
|
12
|
-
if (!
|
|
23
|
+
if (!isValidPrimitiveElement(node)) {
|
|
13
24
|
return false;
|
|
14
25
|
}
|
|
15
26
|
|
|
@@ -22,8 +33,8 @@ var shouldSuggest = exports.shouldSuggest = function shouldSuggest(node) {
|
|
|
22
33
|
* </div>
|
|
23
34
|
* ```
|
|
24
35
|
*/
|
|
25
|
-
var nonWhiteSpaceTextChildren =
|
|
26
|
-
return
|
|
36
|
+
var nonWhiteSpaceTextChildren = getChildrenByType(node, ['JSXText']).filter(function (child) {
|
|
37
|
+
return child.value.trim() !== '';
|
|
27
38
|
});
|
|
28
39
|
if (nonWhiteSpaceTextChildren.length > 0) {
|
|
29
40
|
return false;
|
|
@@ -6,12 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
8
|
var _createRule = require("../utils/create-rule");
|
|
9
|
+
var _transformers = require("./transformers");
|
|
9
10
|
var _utils = require("./utils");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var boxDocsUrl = 'https://staging.atlassian.design/components/primitives/box';
|
|
13
|
-
var inlineDocsUrl = 'https://staging.atlassian.design/components/primitives/inline';
|
|
14
|
-
var stackDocsUrl = 'https://staging.atlassian.design/components/primitives/stack';
|
|
11
|
+
var boxDocsUrl = 'https://atlassian.design/components/primitives/box';
|
|
15
12
|
var rule = (0, _createRule.createLintRule)({
|
|
16
13
|
meta: {
|
|
17
14
|
name: 'use-primitives',
|
|
@@ -24,21 +21,11 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
24
21
|
severity: 'warn'
|
|
25
22
|
},
|
|
26
23
|
messages: {
|
|
27
|
-
preferPrimitivesBox: "This \"{{element}}\" may be able to be replaced with a \"Box\". See ".concat(boxDocsUrl, " for guidance.")
|
|
28
|
-
preferPrimitivesInline: "This \"{{element}}\" may be able to be replaced with an \"Inline\". See ".concat(inlineDocsUrl, " for guidance."),
|
|
29
|
-
preferPrimitivesStack: "This \"{{element}}\" may be able to be replaced with a \"Stack\". See ".concat(stackDocsUrl, " for guidance.")
|
|
24
|
+
preferPrimitivesBox: "This \"{{element}}\" may be able to be replaced with a \"Box\". See ".concat(boxDocsUrl, " for guidance.")
|
|
30
25
|
}
|
|
31
26
|
},
|
|
32
27
|
create: function create(context) {
|
|
33
28
|
return {
|
|
34
|
-
/**
|
|
35
|
-
* Traverse file
|
|
36
|
-
* Look for any JSX opening element and check what it is
|
|
37
|
-
* a) it's already a component
|
|
38
|
-
* b) it's native HTML
|
|
39
|
-
*
|
|
40
|
-
* if b) suggest alternative use of primitives
|
|
41
|
-
*/
|
|
42
29
|
JSXOpeningElement: function JSXOpeningElement(node) {
|
|
43
30
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXOpeningElement')) {
|
|
44
31
|
return;
|
|
@@ -46,15 +33,10 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
46
33
|
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.name, 'JSXIdentifier')) {
|
|
47
34
|
return;
|
|
48
35
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
// const suggestText = shouldSuggestText(
|
|
54
|
-
// node?.parent as any,
|
|
55
|
-
// // context.getScope(),
|
|
56
|
-
// );
|
|
57
|
-
|
|
36
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.parent, 'JSXElement')) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
var suggestBox = shouldSuggestBox(node.parent, context);
|
|
58
40
|
if (suggestBox) {
|
|
59
41
|
context.report({
|
|
60
42
|
node: node,
|
|
@@ -64,39 +46,7 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
64
46
|
},
|
|
65
47
|
suggest: [{
|
|
66
48
|
desc: "Convert to Box",
|
|
67
|
-
fix: (0,
|
|
68
|
-
}]
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
if (suggestInline) {
|
|
72
|
-
context.report({
|
|
73
|
-
node: node,
|
|
74
|
-
messageId: 'preferPrimitivesInline',
|
|
75
|
-
data: {
|
|
76
|
-
element: node.name.name
|
|
77
|
-
},
|
|
78
|
-
suggest: [{
|
|
79
|
-
desc: "Convert to Inline",
|
|
80
|
-
fix: (0, _utils.primitiveFixer)(node, 'Inline', context)
|
|
81
|
-
}, {
|
|
82
|
-
desc: "Convert to Flex",
|
|
83
|
-
fix: (0, _utils.primitiveFixer)(node, 'Flex', context)
|
|
84
|
-
}]
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
if (suggestStack) {
|
|
88
|
-
context.report({
|
|
89
|
-
node: node,
|
|
90
|
-
messageId: 'preferPrimitivesStack',
|
|
91
|
-
data: {
|
|
92
|
-
element: node.name.name
|
|
93
|
-
},
|
|
94
|
-
suggest: [{
|
|
95
|
-
desc: "Convert to Stack",
|
|
96
|
-
fix: (0, _utils.primitiveFixer)(node, 'Stack', context)
|
|
97
|
-
}, {
|
|
98
|
-
desc: "Convert to Flex",
|
|
99
|
-
fix: (0, _utils.primitiveFixer)(node, 'Flex', context)
|
|
49
|
+
fix: (0, _transformers.jsxElementToBoxTransformer)(node.parent, context)
|
|
100
50
|
}]
|
|
101
51
|
});
|
|
102
52
|
}
|
|
@@ -104,4 +54,85 @@ var rule = (0, _createRule.createLintRule)({
|
|
|
104
54
|
};
|
|
105
55
|
}
|
|
106
56
|
});
|
|
57
|
+
var shouldSuggestBox = function shouldSuggestBox(node, context
|
|
58
|
+
// scope: Scope.Scope,
|
|
59
|
+
) {
|
|
60
|
+
if (!node) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Currently we only support `div`, but possibly more in future
|
|
65
|
+
if (!(0, _utils.isValidTagName)(node)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Currently we only support elements that contain only a `css` attr, possibly more in future
|
|
70
|
+
if (!(0, _utils.containsOnlySupportedAttrs)(node)) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Get the `css` attr
|
|
75
|
+
var cssAttr = (0, _utils.getJSXAttributeByName)(node.openingElement, 'css');
|
|
76
|
+
|
|
77
|
+
// Get the prop value, e.g. `myStyles` in `css={myStyles}`
|
|
78
|
+
var cssVariableName = (0, _utils.getAttributeValueIdentifier)(cssAttr);
|
|
79
|
+
|
|
80
|
+
// `cssVariableName` could be undefined if the maker has
|
|
81
|
+
// done something like `css={[styles1, styles2]}`, `css={...styles}`, etc
|
|
82
|
+
if (!cssVariableName) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Make sure the variable is not used in multiple JSX elements:
|
|
88
|
+
* ```
|
|
89
|
+
* <div css={paddingStyles}></div>
|
|
90
|
+
* <input css={paddingStyles}></input>
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
if ((0, _utils.getVariableUsagesCount)(cssVariableName, context) !== 1) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Find where `cssVariableName` is defined. We're looking for `const myStyles = css({...})`
|
|
98
|
+
var cssVariableDefinition = (0, _eslintCodemodUtils.getIdentifierInParentScope)(context.getScope(), cssVariableName);
|
|
99
|
+
var cssVariableValue = (0, _utils.getVariableDefinitionValue)(cssVariableDefinition);
|
|
100
|
+
|
|
101
|
+
// Check if `cssVariableValue` is a function called `css()`
|
|
102
|
+
if (!(0, _utils.isFunctionNamed)(cssVariableValue, 'css')) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// get the `{}` in `css({})`
|
|
107
|
+
// Zero indexed
|
|
108
|
+
var cssObjectExpression = (0, _utils.getFunctionArgumentAtPos)(cssVariableValue, 0);
|
|
109
|
+
|
|
110
|
+
// Bail on empty `css()` calls
|
|
111
|
+
if (!cssObjectExpression) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
var cssObject = (0, _utils.convertASTObjectExpressionToJSObject)(cssObjectExpression);
|
|
115
|
+
|
|
116
|
+
// Bail if there are less or more than 1 styles defined
|
|
117
|
+
if (Object.keys(cssObject).length !== 1) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// NOTE: Our approach with this lint rule is to strictly whitelist css properties we can map.
|
|
122
|
+
// It means we have to provide mappings for everything (e.g. `display: block`).
|
|
123
|
+
// However, from a maker's experience, it's much better that the rule doesn't report (if we miss a mapping)
|
|
124
|
+
// than the rule reporting on things that can't be mapped.
|
|
125
|
+
var containsOnlyValidStyles = Object.keys(cssObject).every(function (styleProperty) {
|
|
126
|
+
var styleValue = cssObject[styleProperty];
|
|
127
|
+
return _transformers.supportedStylesMap[styleProperty] &&
|
|
128
|
+
// Is the key something we can map
|
|
129
|
+
_transformers.supportedStylesMap[styleProperty][styleValue] // Is the value something we can map
|
|
130
|
+
;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
if (!containsOnlyValidStyles) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
return true;
|
|
137
|
+
};
|
|
107
138
|
var _default = exports.default = rule;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.supportedStylesMap = exports.spaceTokenMap = exports.cssToXcssTransformer = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
10
|
+
var _utils = require("../utils");
|
|
11
|
+
var cssToXcssTransformer = exports.cssToXcssTransformer = function cssToXcssTransformer(node, context, fixer) {
|
|
12
|
+
/**
|
|
13
|
+
* Note: The logic here is very similar to the logic in `shouldSuggestBox`. i.e.
|
|
14
|
+
* 1. Find the `css` attr
|
|
15
|
+
* 2. Find the variableName (`myStyles` in `css={myStyles}`)
|
|
16
|
+
* 3. Find the `const myStyles = css({ padding: '8px' })`
|
|
17
|
+
* 4. Find the style object `{ padding: '8px' }`
|
|
18
|
+
*
|
|
19
|
+
* The only difference is, we've already performed very defensive checks for these steps in `shouldSuggestBox`,
|
|
20
|
+
* so there's no need to do those checks here.
|
|
21
|
+
*
|
|
22
|
+
* The repetition could be avoided by combining the 'shouldSuggest' and 'fixCode' steps. However, there are tradeoffs
|
|
23
|
+
* to that approach (mainly poor separation of concerns). I'm un-opinionated about which strategy we use. I just opted
|
|
24
|
+
* for this because the original `use-primitives` rule did this.
|
|
25
|
+
*/
|
|
26
|
+
var cssAttr = (0, _utils.getJSXAttributeByName)(node.openingElement, 'css');
|
|
27
|
+
var cssVariableName = (0, _utils.getAttributeValueIdentifier)(cssAttr);
|
|
28
|
+
if (!cssVariableName) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
var cssVariableDefinition = (0, _eslintCodemodUtils.getIdentifierInParentScope)(context.getScope(), cssVariableName);
|
|
32
|
+
var cssVariableValue = (0, _utils.getVariableDefinitionValue)(cssVariableDefinition);
|
|
33
|
+
if (!cssVariableValue) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
var cssObjectExpression = (0, _utils.getFunctionArgumentAtPos)(cssVariableValue, 0);
|
|
37
|
+
return [
|
|
38
|
+
// Update `css` function name to `xcss`.
|
|
39
|
+
fixer.replaceText(cssVariableValue.node.init.callee, (0, _eslintCodemodUtils.identifier)('xcss').toString())].concat((0, _toConsumableArray2.default)(cssObjectExpression.properties.map(function (entry) {
|
|
40
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(entry, 'Property')) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(entry.key, 'Identifier')) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(entry.value, 'Literal')) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
var value = entry.value.value;
|
|
50
|
+
if (typeof value !== 'string') {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
return fixer.replaceText(entry.value, (0, _eslintCodemodUtils.literal)("'".concat(supportedStylesMap[entry.key.name][value], "'")).toString());
|
|
54
|
+
})));
|
|
55
|
+
};
|
|
56
|
+
var spaceTokenMap = exports.spaceTokenMap = {
|
|
57
|
+
'0px': 'space.0',
|
|
58
|
+
'2px': 'space.025',
|
|
59
|
+
'4px': 'space.050',
|
|
60
|
+
'6px': 'space.075',
|
|
61
|
+
'8px': 'space.100',
|
|
62
|
+
'12px': 'space.150',
|
|
63
|
+
'16px': 'space.200',
|
|
64
|
+
'20px': 'space.250',
|
|
65
|
+
'24px': 'space.300',
|
|
66
|
+
'32px': 'space.400',
|
|
67
|
+
'40px': 'space.500',
|
|
68
|
+
'48px': 'space.600',
|
|
69
|
+
'64px': 'space.800',
|
|
70
|
+
'80px': 'space.1000'
|
|
71
|
+
};
|
|
72
|
+
var supportedStylesMap = exports.supportedStylesMap = {
|
|
73
|
+
padding: spaceTokenMap,
|
|
74
|
+
paddingBlock: spaceTokenMap,
|
|
75
|
+
paddingBlockEnd: spaceTokenMap,
|
|
76
|
+
paddingBlockStart: spaceTokenMap,
|
|
77
|
+
paddingBottom: spaceTokenMap,
|
|
78
|
+
paddingInline: spaceTokenMap,
|
|
79
|
+
paddingInlineEnd: spaceTokenMap,
|
|
80
|
+
paddingInlineStart: spaceTokenMap,
|
|
81
|
+
paddingLeft: spaceTokenMap,
|
|
82
|
+
paddingRight: spaceTokenMap,
|
|
83
|
+
paddingTop: spaceTokenMap,
|
|
84
|
+
margin: spaceTokenMap,
|
|
85
|
+
marginBlock: spaceTokenMap,
|
|
86
|
+
marginBlockEnd: spaceTokenMap,
|
|
87
|
+
marginBlockStart: spaceTokenMap,
|
|
88
|
+
marginBottom: spaceTokenMap,
|
|
89
|
+
marginInline: spaceTokenMap,
|
|
90
|
+
marginInlineEnd: spaceTokenMap,
|
|
91
|
+
marginInlineStart: spaceTokenMap,
|
|
92
|
+
marginLeft: spaceTokenMap,
|
|
93
|
+
marginRight: spaceTokenMap,
|
|
94
|
+
marginTop: spaceTokenMap
|
|
95
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "cssToXcssTransformer", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _cssToXcss.cssToXcssTransformer;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "jsxElementToBoxTransformer", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function get() {
|
|
15
|
+
return _jsxElementToBox.jsxElementToBoxTransformer;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "spaceTokenMap", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function get() {
|
|
21
|
+
return _cssToXcss.spaceTokenMap;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "supportedStylesMap", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function get() {
|
|
27
|
+
return _cssToXcss.supportedStylesMap;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
var _cssToXcss = require("./css-to-xcss");
|
|
31
|
+
var _jsxElementToBox = require("./jsx-element-to-box");
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.jsxElementToBoxTransformer = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _utils = require("../utils");
|
|
10
|
+
var _cssToXcss = require("./css-to-xcss");
|
|
11
|
+
var jsxElementToBoxTransformer = exports.jsxElementToBoxTransformer = function jsxElementToBoxTransformer(node, context) {
|
|
12
|
+
return function (fixer) {
|
|
13
|
+
// Insert `import { Box, xcss } from '@atlaskit/primitives'`
|
|
14
|
+
// Or, if the import exists already, update it to include `Box`, and `xcss`
|
|
15
|
+
var importFixes = (0, _utils.upsertImportDeclaration)({
|
|
16
|
+
packageName: '@atlaskit/primitives',
|
|
17
|
+
specifiers: ['Box', 'xcss']
|
|
18
|
+
}, context, fixer);
|
|
19
|
+
var elementNameFixes = (0, _utils.updateJSXElementName)(node, 'Box', fixer);
|
|
20
|
+
var attributeFix = (0, _utils.updateJSXAttributeByName)('css', 'xcss', node, fixer);
|
|
21
|
+
var cssToXcssTransform = (0, _cssToXcss.cssToXcssTransformer)(node, context, fixer);
|
|
22
|
+
return [importFixes, attributeFix].concat((0, _toConsumableArray2.default)(elementNameFixes), (0, _toConsumableArray2.default)(cssToXcssTransform)).filter(function (fix) {
|
|
23
|
+
return Boolean(fix);
|
|
24
|
+
}); // Some of the transformers can return arrays with undefined, so filter them out
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.containsOnlySupportedAttrs = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var supportedAttributes = ['css'];
|
|
9
|
+
var containsOnlySupportedAttrs = exports.containsOnlySupportedAttrs = function containsOnlySupportedAttrs(node) {
|
|
10
|
+
return node.openingElement.attributes.every(function (attr) {
|
|
11
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr.name, 'JSXIdentifier')) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return supportedAttributes.includes(attr.name.name);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.convertASTObjectExpressionToJSObject = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
// FIXME: This is only loosely typed
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Note: Not recursive. Only handles top level key/value pairs
|
|
12
|
+
*/
|
|
13
|
+
var convertASTObjectExpressionToJSObject = exports.convertASTObjectExpressionToJSObject = function convertASTObjectExpressionToJSObject(styles) {
|
|
14
|
+
var styleObj = {};
|
|
15
|
+
styles.properties.forEach(function (prop) {
|
|
16
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(prop, 'Property')) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(prop.key, 'Identifier')) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'Literal')) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (typeof prop.value.value !== 'string') {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
styleObj[prop.key.name] = prop.value.value;
|
|
29
|
+
});
|
|
30
|
+
return styleObj;
|
|
31
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getAttributeValueIdentifier = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
/**
|
|
9
|
+
* Bit of a weird name, but the functionality is quite specific, so this is the best I could do.
|
|
10
|
+
* This function looks at a JSXAttribute, and returns the string representation
|
|
11
|
+
* of the value if it's an identifier, e.g. `css={someStyles}` would return `'someStyles'`
|
|
12
|
+
*
|
|
13
|
+
* It returns undefined if it finds anything else, like:
|
|
14
|
+
* - `css={[styles1, styles2]}`
|
|
15
|
+
* - `css={...styles}`
|
|
16
|
+
* - `css={styleMap[key]}`
|
|
17
|
+
* - `css='what even is this'`
|
|
18
|
+
* - etc
|
|
19
|
+
*/
|
|
20
|
+
var getAttributeValueIdentifier = exports.getAttributeValueIdentifier = function getAttributeValueIdentifier(attr) {
|
|
21
|
+
if (!attr) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute')) {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
if (!attr.value) {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr.value, 'JSXExpressionContainer')) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr.value.expression, 'Identifier')) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return attr.value.expression.name;
|
|
37
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getFunctionArgumentAtPos = void 0;
|
|
7
|
+
var getFunctionArgumentAtPos = exports.getFunctionArgumentAtPos = function getFunctionArgumentAtPos(node, pos) {
|
|
8
|
+
var _node$node;
|
|
9
|
+
return node === null || node === void 0 || (_node$node = node.node) === null || _node$node === void 0 || (_node$node = _node$node.init) === null || _node$node === void 0 || (_node$node = _node$node.arguments) === null || _node$node === void 0 ? void 0 : _node$node[pos];
|
|
10
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getJSXAttributeByName = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var getJSXAttributeByName = exports.getJSXAttributeByName = function getJSXAttributeByName(node, attrName) {
|
|
9
|
+
return node.attributes.find(function (attr) {
|
|
10
|
+
// Ignore anything other than JSXAttribute
|
|
11
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return attr.name.name === attrName;
|
|
15
|
+
});
|
|
16
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getVariableDefinitionValue = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var getVariableDefinitionValue = exports.getVariableDefinitionValue = function getVariableDefinitionValue(variableDefinition) {
|
|
9
|
+
if (!variableDefinition) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
if (variableDefinition.defs.length !== 1) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
var variableValue = variableDefinition.defs[0];
|
|
16
|
+
|
|
17
|
+
// Note: unable to use `isNodeOfType` here
|
|
18
|
+
// because `variableDefinition` is necessarily of type `Scope.Variable`,
|
|
19
|
+
// which doesn't overlap properly with the `eslint-codemod-utils` types
|
|
20
|
+
if (variableValue.type !== 'Variable') {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// TODO: is this necessary?
|
|
25
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(variableValue.node, 'VariableDeclarator')) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return variableValue;
|
|
29
|
+
};
|