@atlaskit/eslint-plugin-design-system 8.23.1 → 8.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/ast-nodes/function-call.js +48 -0
  3. package/dist/cjs/ast-nodes/import.js +49 -0
  4. package/dist/cjs/ast-nodes/index.js +40 -0
  5. package/dist/cjs/ast-nodes/jsx-attribute.js +64 -0
  6. package/dist/cjs/ast-nodes/jsx-element.js +55 -0
  7. package/dist/cjs/ast-nodes/root.js +34 -0
  8. package/dist/cjs/rules/consistent-css-prop-usage/index.js +25 -5
  9. package/dist/cjs/rules/use-primitives/index.js +8 -104
  10. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/convert-jsx-call-site.js +39 -0
  11. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/convert-styled-component-call-to-jsx.js +44 -0
  12. package/dist/cjs/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-styled-component-call.js +5 -2
  13. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/index.js +117 -0
  14. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/supported.js +10 -0
  15. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +37 -0
  16. package/dist/cjs/rules/use-primitives/transformers/emotion-css/contains-only-supported-attrs.js +27 -0
  17. package/dist/cjs/rules/use-primitives/transformers/emotion-css/index.js +125 -0
  18. package/dist/cjs/rules/use-primitives/transformers/emotion-css/supported.js +10 -0
  19. package/dist/cjs/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +37 -0
  20. package/dist/cjs/rules/use-primitives/transformers/index.js +10 -10
  21. package/dist/cjs/rules/use-primitives/utils/index.js +1 -43
  22. package/dist/cjs/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +3 -0
  23. package/dist/es2019/ast-nodes/function-call.js +42 -0
  24. package/dist/es2019/ast-nodes/import.js +42 -0
  25. package/dist/es2019/ast-nodes/index.js +5 -0
  26. package/dist/es2019/ast-nodes/jsx-attribute.js +59 -0
  27. package/dist/es2019/ast-nodes/jsx-element.js +50 -0
  28. package/dist/es2019/ast-nodes/root.js +28 -0
  29. package/dist/es2019/rules/consistent-css-prop-usage/index.js +23 -5
  30. package/dist/es2019/rules/use-primitives/index.js +9 -105
  31. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/convert-jsx-call-site.js +29 -0
  32. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/convert-styled-component-call-to-jsx.js +37 -0
  33. package/dist/es2019/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-styled-component-call.js +2 -2
  34. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/index.js +107 -0
  35. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/supported.js +4 -0
  36. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +30 -0
  37. package/dist/es2019/rules/use-primitives/transformers/emotion-css/contains-only-supported-attrs.js +19 -0
  38. package/dist/es2019/rules/use-primitives/transformers/emotion-css/index.js +115 -0
  39. package/dist/es2019/rules/use-primitives/transformers/emotion-css/supported.js +4 -0
  40. package/dist/es2019/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +30 -0
  41. package/dist/es2019/rules/use-primitives/transformers/index.js +2 -2
  42. package/dist/es2019/rules/use-primitives/utils/index.js +1 -7
  43. package/dist/es2019/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +3 -0
  44. package/dist/esm/ast-nodes/function-call.js +42 -0
  45. package/dist/esm/ast-nodes/import.js +43 -0
  46. package/dist/esm/ast-nodes/index.js +5 -0
  47. package/dist/esm/ast-nodes/jsx-attribute.js +59 -0
  48. package/dist/esm/ast-nodes/jsx-element.js +50 -0
  49. package/dist/esm/ast-nodes/root.js +28 -0
  50. package/dist/esm/rules/consistent-css-prop-usage/index.js +25 -5
  51. package/dist/esm/rules/use-primitives/index.js +9 -105
  52. package/dist/esm/rules/use-primitives/transformers/compiled-styled/convert-jsx-call-site.js +30 -0
  53. package/dist/esm/rules/use-primitives/transformers/compiled-styled/convert-styled-component-call-to-jsx.js +38 -0
  54. package/dist/esm/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-styled-component-call.js +2 -2
  55. package/dist/esm/rules/use-primitives/transformers/compiled-styled/index.js +107 -0
  56. package/dist/esm/rules/use-primitives/transformers/compiled-styled/supported.js +4 -0
  57. package/dist/esm/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +29 -0
  58. package/dist/esm/rules/use-primitives/transformers/emotion-css/contains-only-supported-attrs.js +19 -0
  59. package/dist/esm/rules/use-primitives/transformers/emotion-css/index.js +115 -0
  60. package/dist/esm/rules/use-primitives/transformers/emotion-css/supported.js +4 -0
  61. package/dist/esm/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +29 -0
  62. package/dist/esm/rules/use-primitives/transformers/index.js +2 -2
  63. package/dist/esm/rules/use-primitives/utils/index.js +1 -7
  64. package/dist/esm/rules/use-primitives/utils/is-valid-css-properties-to-transform.js +3 -0
  65. package/dist/types/ast-nodes/function-call.d.ts +21 -0
  66. package/dist/types/ast-nodes/import.d.ts +16 -0
  67. package/dist/types/ast-nodes/index.d.ts +5 -0
  68. package/dist/types/ast-nodes/jsx-attribute.d.ts +26 -0
  69. package/dist/types/ast-nodes/jsx-element.d.ts +21 -0
  70. package/dist/types/ast-nodes/root.d.ts +19 -0
  71. package/dist/types/rules/use-primitives/transformers/compiled-styled/convert-jsx-call-site.d.ts +17 -0
  72. package/dist/types/rules/use-primitives/transformers/compiled-styled/convert-styled-component-call-to-jsx.d.ts +17 -0
  73. package/dist/types/rules/use-primitives/transformers/compiled-styled/index.d.ts +25 -0
  74. package/dist/types/rules/use-primitives/transformers/compiled-styled/supported.d.ts +2 -0
  75. package/dist/types/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +14 -0
  76. package/dist/types/rules/use-primitives/transformers/emotion-css/contains-only-supported-attrs.d.ts +7 -0
  77. package/dist/types/rules/use-primitives/transformers/emotion-css/index.d.ts +16 -0
  78. package/dist/types/rules/use-primitives/transformers/emotion-css/supported.d.ts +2 -0
  79. package/dist/types/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +14 -0
  80. package/dist/types/rules/use-primitives/transformers/index.d.ts +2 -2
  81. package/dist/types/rules/use-primitives/utils/index.d.ts +0 -6
  82. package/dist/types-ts4.5/ast-nodes/function-call.d.ts +21 -0
  83. package/dist/types-ts4.5/ast-nodes/import.d.ts +16 -0
  84. package/dist/types-ts4.5/ast-nodes/index.d.ts +5 -0
  85. package/dist/types-ts4.5/ast-nodes/jsx-attribute.d.ts +26 -0
  86. package/dist/types-ts4.5/ast-nodes/jsx-element.d.ts +21 -0
  87. package/dist/types-ts4.5/ast-nodes/root.d.ts +19 -0
  88. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/convert-jsx-call-site.d.ts +17 -0
  89. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/convert-styled-component-call-to-jsx.d.ts +17 -0
  90. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/index.d.ts +25 -0
  91. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/supported.d.ts +2 -0
  92. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +14 -0
  93. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/contains-only-supported-attrs.d.ts +7 -0
  94. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/index.d.ts +16 -0
  95. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/supported.d.ts +2 -0
  96. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +14 -0
  97. package/dist/types-ts4.5/rules/use-primitives/transformers/index.d.ts +2 -2
  98. package/dist/types-ts4.5/rules/use-primitives/utils/index.d.ts +0 -6
  99. package/package.json +1 -1
  100. package/dist/cjs/rules/use-primitives/transformers/jsx-element-to-box.js +0 -26
  101. package/dist/cjs/rules/use-primitives/transformers/styled-component-to-primitive.js +0 -68
  102. package/dist/cjs/rules/use-primitives/utils/contains-only-supported-attrs.js +0 -19
  103. package/dist/cjs/rules/use-primitives/utils/is-valid-tag-name.js +0 -13
  104. package/dist/cjs/rules/use-primitives/utils/update-jsx-element-name.js +0 -16
  105. package/dist/cjs/rules/use-primitives/utils/upsert-import-declaration.js +0 -80
  106. package/dist/es2019/rules/use-primitives/transformers/jsx-element-to-box.js +0 -16
  107. package/dist/es2019/rules/use-primitives/transformers/styled-component-to-primitive.js +0 -59
  108. package/dist/es2019/rules/use-primitives/utils/contains-only-supported-attrs.js +0 -13
  109. package/dist/es2019/rules/use-primitives/utils/is-valid-tag-name.js +0 -7
  110. package/dist/es2019/rules/use-primitives/utils/update-jsx-element-name.js +0 -12
  111. package/dist/es2019/rules/use-primitives/utils/upsert-import-declaration.js +0 -76
  112. package/dist/esm/rules/use-primitives/transformers/jsx-element-to-box.js +0 -19
  113. package/dist/esm/rules/use-primitives/transformers/styled-component-to-primitive.js +0 -61
  114. package/dist/esm/rules/use-primitives/utils/contains-only-supported-attrs.js +0 -13
  115. package/dist/esm/rules/use-primitives/utils/is-valid-tag-name.js +0 -7
  116. package/dist/esm/rules/use-primitives/utils/update-jsx-element-name.js +0 -10
  117. package/dist/esm/rules/use-primitives/utils/upsert-import-declaration.js +0 -75
  118. package/dist/types/rules/use-primitives/transformers/jsx-element-to-box.d.ts +0 -3
  119. package/dist/types/rules/use-primitives/transformers/styled-component-to-primitive.d.ts +0 -13
  120. package/dist/types/rules/use-primitives/utils/contains-only-supported-attrs.d.ts +0 -2
  121. package/dist/types/rules/use-primitives/utils/is-valid-tag-name.d.ts +0 -3
  122. package/dist/types/rules/use-primitives/utils/update-jsx-element-name.d.ts +0 -3
  123. package/dist/types/rules/use-primitives/utils/upsert-import-declaration.d.ts +0 -11
  124. package/dist/types-ts4.5/rules/use-primitives/transformers/jsx-element-to-box.d.ts +0 -3
  125. package/dist/types-ts4.5/rules/use-primitives/transformers/styled-component-to-primitive.d.ts +0 -13
  126. package/dist/types-ts4.5/rules/use-primitives/utils/contains-only-supported-attrs.d.ts +0 -2
  127. package/dist/types-ts4.5/rules/use-primitives/utils/is-valid-tag-name.d.ts +0 -3
  128. package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-element-name.d.ts +0 -3
  129. package/dist/types-ts4.5/rules/use-primitives/utils/upsert-import-declaration.d.ts +0 -11
  130. /package/dist/cjs/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-jsx-usage-to-transform.js +0 -0
  131. /package/dist/es2019/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-jsx-usage-to-transform.js +0 -0
  132. /package/dist/esm/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-jsx-usage-to-transform.js +0 -0
  133. /package/dist/types/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-jsx-usage-to-transform.d.ts +0 -0
  134. /package/dist/types/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-styled-component-call.d.ts +0 -0
  135. /package/dist/types-ts4.5/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-jsx-usage-to-transform.d.ts +0 -0
  136. /package/dist/types-ts4.5/rules/use-primitives/{utils → transformers/compiled-styled}/find-valid-styled-component-call.d.ts +0 -0
@@ -0,0 +1,30 @@
1
+ import * as ast from '../../../../ast-nodes';
2
+
3
+ /**
4
+ * Currently this is defined here because it's not very general purpose.
5
+ * If we were to move this to `ast-nodes`, half the implementation would be in `Root`,
6
+ * and the other half would be in `Import`.
7
+ *
8
+ * TODO: Refactor and move to `ast-nodes`
9
+ *
10
+ * Note: It does not handle default imports, namespace imports, or aliased imports.
11
+ */
12
+ export const upsertImportDeclaration = ({
13
+ module,
14
+ specifiers
15
+ }, context, fixer) => {
16
+ // Find any imports that match the packageName
17
+ const root = context.getSourceCode().ast.body;
18
+ const importDeclarations = ast.Root.findImportsByModule(root, module);
19
+
20
+ // The import doesn't exist yet, we can just insert a whole new one
21
+ if (importDeclarations.length === 0) {
22
+ return ast.Root.insertImport(root, {
23
+ module,
24
+ specifiers
25
+ }, fixer);
26
+ }
27
+
28
+ // The import exists so, modify the existing one
29
+ return ast.Import.insertNamedSpecifiers(importDeclarations[0], specifiers, fixer);
30
+ };
@@ -1,3 +1,3 @@
1
1
  export { cssToXcssTransformer, supportedStylesMap, spaceTokenMap } from './css-to-xcss';
2
- export { jsxElementToBoxTransformer } from './jsx-element-to-box';
3
- export { styledComponentToPrimitive } from './styled-component-to-primitive';
2
+ export { CompiledStyled } from './compiled-styled';
3
+ export { EmotionCSS } from './emotion-css';
@@ -1,7 +1,4 @@
1
- export { containsOnlySupportedAttrs } from './contains-only-supported-attrs';
2
1
  export { convertASTObjectExpressionToJSObject } from './convert-ast-object-expression-to-js-object';
3
- export { findValidJsxUsageToTransform } from './find-valid-jsx-usage-to-transform';
4
- export { findValidStyledComponentCall } from './find-valid-styled-component-call';
5
2
  export { getAttributeValueIdentifier } from './get-attribute-value-identifier';
6
3
  export { getFunctionArgumentAtPos } from './get-function-argument-at-pos';
7
4
  export { getJSXAttributeByName } from './get-jsx-attribute-by-name';
@@ -9,7 +6,4 @@ export { getVariableDefinitionValue } from './get-variable-definition-value';
9
6
  export { getVariableUsagesCount } from './get-variable-usage-count';
10
7
  export { isFunctionNamed } from './is-function-named';
11
8
  export { isValidCssPropertiesToTransform } from './is-valid-css-properties-to-transform';
12
- export { isValidTagName } from './is-valid-tag-name';
13
- export { updateJSXAttributeByName } from './update-jsx-attribute-by-name';
14
- export { updateJSXElementName } from './update-jsx-element-name';
15
- export { upsertImportDeclaration } from './upsert-import-declaration';
9
+ export { updateJSXAttributeByName } from './update-jsx-attribute-by-name';
@@ -2,6 +2,9 @@ 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
4
  export const isValidCssPropertiesToTransform = (node, config) => {
5
+ if (!node) {
6
+ return false;
7
+ }
5
8
  const cssObjectExpression = node.arguments[0];
6
9
  // Bail on empty object calls
7
10
  if (!cssObjectExpression || !isNodeOfType(cssObjectExpression, 'ObjectExpression')) {
@@ -0,0 +1,42 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ export var FunctionCall = {
5
+ getName: function getName(node) {
6
+ if (!isNodeOfType(node, 'CallExpression')) {
7
+ return undefined;
8
+ }
9
+ if (!isNodeOfType(node.callee, 'Identifier')) {
10
+ return undefined;
11
+ }
12
+ return node.callee.name;
13
+ },
14
+ updateName: function updateName(node, newName, fixer) {
15
+ return fixer.replaceText(node.callee, newName);
16
+ },
17
+ /**
18
+ * Function arguments can be many things:
19
+ * `css(myStyles, () => {}, undefined, 'literal', ...rest) // etc`
20
+ * They all need slightly different treatment.
21
+ *
22
+ * Currently 'getArgumentAtPos' only implements strategies for Literals and ObjectExpressions.
23
+ * If you need to support another type of arg, add it, and update the type.
24
+ */
25
+ getArgumentAtPos: function getArgumentAtPos(node, pos) {
26
+ var argument = node.arguments[pos];
27
+ if (isNodeOfType(argument, 'Literal') && argument.value) {
28
+ var _argument$value;
29
+ return {
30
+ type: 'Literal',
31
+ value: (_argument$value = argument.value) === null || _argument$value === void 0 ? void 0 : _argument$value.toString()
32
+ };
33
+ }
34
+ if (isNodeOfType(argument, 'ObjectExpression')) {
35
+ argument;
36
+ return {
37
+ type: 'ObjectExpression',
38
+ value: argument
39
+ };
40
+ }
41
+ }
42
+ };
@@ -0,0 +1,43 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { insertImportSpecifier, isNodeOfType } from 'eslint-codemod-utils';
4
+ export var Import = {
5
+ /**
6
+ * Note: fixes can't overlap, which means this will fail:
7
+ * ```
8
+ * const importNode = Root.findImportByModule('@atlaskit/primitives')
9
+ * Import.insertNamedSpecifier(importNode, 'Box')
10
+ * Import.insertNamedSpecifier(importNode, 'xcss')
11
+ * ```
12
+ *
13
+ * For this reason `insertNamedSpecifiers` accepts a `specifiers` array, so you can group all inserts together.
14
+ */
15
+ insertNamedSpecifiers: function insertNamedSpecifiers(node, specifiers, fixer) {
16
+ var _this = this;
17
+ /**
18
+ * `insertImportSpecifier()` has the unfortunate implementation detail of naively adding duplicate specifiers.
19
+ * e.g. calling
20
+ * `insertImportSpecifier(importDecl, 'xcss')`
21
+ * on
22
+ * `import { Inline, xcss } from '@atlaskit/primitives'`
23
+ * will result in:
24
+ * `import { Inline, xcss, xcss } from '@atlaskit/primitives'`.
25
+ * So, we need to filter out specifiers that are already imported.
26
+ */
27
+ var uniqueSpecifiers = specifiers.filter(function (specifier) {
28
+ return !_this.containsNamedSpecifier(node, specifier);
29
+ });
30
+ if (uniqueSpecifiers.length === 0) {
31
+ return;
32
+ }
33
+ return fixer.replaceText(node, "".concat(insertImportSpecifier(node, uniqueSpecifiers.join(', ')), ";\n"));
34
+ },
35
+ containsNamedSpecifier: function containsNamedSpecifier(node, name) {
36
+ return node.specifiers.some(function (specifier) {
37
+ if (!isNodeOfType(specifier, 'ImportSpecifier')) {
38
+ return false;
39
+ }
40
+ return specifier.imported.name === name;
41
+ });
42
+ }
43
+ };
@@ -0,0 +1,5 @@
1
+ export { FunctionCall } from './function-call';
2
+ export { Import } from './import';
3
+ export { JSXAttribute } from './jsx-attribute';
4
+ export { JSXElement } from './jsx-element';
5
+ export { Root } from './root';
@@ -0,0 +1,59 @@
1
+ import { isNodeOfType, literal } from 'eslint-codemod-utils';
2
+ var HelperJSXAttribute = {
3
+ getName: function getName(node) {
4
+ if (!isNodeOfType(node, 'JSXAttribute')) {
5
+ throw new Error('Not a JSXAttribute');
6
+ }
7
+ if (!isNodeOfType(node.name, 'JSXIdentifier')) {
8
+ throw new Error('name is not a JSXIdentifier');
9
+ }
10
+ return node.name.name;
11
+ },
12
+ updateName: function updateName(node, name, fixer) {
13
+ if (!isNodeOfType(node, 'JSXAttribute')) {
14
+ throw new Error('Not a JSXAttribute');
15
+ }
16
+ if (!isNodeOfType(node.name, 'JSXIdentifier')) {
17
+ throw new Error('name is not a JSXIdentifier');
18
+ }
19
+ return fixer.replaceText(node.name, literal(name).toString());
20
+ },
21
+ /**
22
+ * A JSXAttribute value can be many things:
23
+ * - css='myStyles'
24
+ * - css={myStyles}
25
+ * - css={[styles1, styles2]}
26
+ * - header={<></>}
27
+ * - css={styleMap.header}
28
+ * - css={...styles}
29
+ *
30
+ * Currently, `getValue` has only implemented strategies for when the value is a string, or an ExpressionStatement
31
+ * If you need additional functionality add it, and set the correct `type` on the returned object
32
+ */
33
+ getValue: function getValue(node) {
34
+ if (!isNodeOfType(node, 'JSXAttribute')) {
35
+ return;
36
+ }
37
+ if (!node.value) {
38
+ return;
39
+ }
40
+
41
+ // handle `css={myStyles}`
42
+ if (isNodeOfType(node.value, 'JSXExpressionContainer') && isNodeOfType(node.value.expression, 'Identifier')) {
43
+ return {
44
+ type: 'ExpressionStatement',
45
+ value: node.value.expression.name
46
+ };
47
+ }
48
+
49
+ // handle `css='myStyles'`
50
+ if (isNodeOfType(node.value, 'Literal') && node.value.value) {
51
+ var _node$value$value;
52
+ return {
53
+ type: 'Literal',
54
+ value: (_node$value$value = node.value.value) === null || _node$value$value === void 0 ? void 0 : _node$value$value.toString()
55
+ };
56
+ }
57
+ }
58
+ };
59
+ export { HelperJSXAttribute as JSXAttribute };
@@ -0,0 +1,50 @@
1
+ import { isNodeOfType, jsxIdentifier } from 'eslint-codemod-utils';
2
+ export var JSXElementHelper = {
3
+ /**
4
+ * Names of JSXElements can be any of:
5
+ * `<Component></Component>` - (JSXIdentifier)
6
+ * `<MyComponents.Component></MyComponents.Component>` - `MyComponents` is a namespace (JSXNamespacedName)
7
+ * `<MyComponents.Component></MyComponents.Component>` - `MyComponents` is an object (JSXMemberExpression)
8
+ *
9
+ * Getting the name of a JSXMemberExpression is difficult, because object can contain objects, which is recursively defined in the AST.
10
+ * e.g. getting the name of `<MyComponents.PresentationLayer.LeftSideBar.Header />` would require `getName` to recursively resolve all parts of the name.
11
+ * `getName` does not currently have this functionality. Add it if you need it.
12
+ */
13
+ getName: function getName(node) {
14
+ if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
15
+ // TODO: We may want to log this
16
+ return '';
17
+ }
18
+ return node.openingElement.name.name;
19
+ },
20
+ updateName: function updateName(node, newName, fixer) {
21
+ var isSelfClosing = JSXElementHelper.isSelfClosing(node);
22
+ var openingElementFix = fixer.replaceText(node.openingElement.name, jsxIdentifier(newName).toString());
23
+ if (isSelfClosing || !node.closingElement) {
24
+ return [openingElementFix];
25
+ }
26
+ var closingElementFix = fixer.replaceText(node.closingElement.name, jsxIdentifier(newName).toString());
27
+ return [openingElementFix, closingElementFix];
28
+ },
29
+ isSelfClosing: function isSelfClosing(node) {
30
+ return node.openingElement.selfClosing;
31
+ },
32
+ getAttributes: function getAttributes(node) {
33
+ return node.openingElement.attributes;
34
+ },
35
+ getAttributeByName: function getAttributeByName(node, name) {
36
+ return node.openingElement.attributes.find(function (attr) {
37
+ // Ignore anything other than JSXAttribute
38
+ if (!isNodeOfType(attr, 'JSXAttribute')) {
39
+ return false;
40
+ }
41
+ return attr.name.name === name;
42
+ });
43
+ },
44
+ containsSpreadAttributes: function containsSpreadAttributes(node) {
45
+ return node.openingElement.attributes.some(function (attr) {
46
+ return isNodeOfType(attr, 'JSXSpreadAttribute');
47
+ });
48
+ }
49
+ };
50
+ export { JSXElementHelper as JSXElement };
@@ -0,0 +1,28 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { hasImportDeclaration, insertImportDeclaration, isNodeOfType } from 'eslint-codemod-utils';
4
+ // Little bit unreadable, but better than duplicating the type
5
+
6
+ export var Root = {
7
+ /**
8
+ * Note: This can return multiple ImportDeclarations for cases like:
9
+ * ```
10
+ * import { Stack } from '@atlaskit/primitives'
11
+ * import type { StackProps } from '@atlaskit/primitives'
12
+ * ```
13
+ */
14
+ findImportsByModule: function findImportsByModule(root, name) {
15
+ return root.filter(function (node) {
16
+ if (!isNodeOfType(node, 'ImportDeclaration')) {
17
+ return false;
18
+ }
19
+ if (!hasImportDeclaration(node, name)) {
20
+ return false;
21
+ }
22
+ return true;
23
+ });
24
+ },
25
+ insertImport: function insertImport(root, data, fixer) {
26
+ return fixer.insertTextBefore(root[0], "".concat(insertImportDeclaration(data.module, data.specifiers), ";\n"));
27
+ }
28
+ };
@@ -6,6 +6,8 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
6
6
  import { getIdentifierInParentScope, isNodeOfType } from 'eslint-codemod-utils';
7
7
  import assign from 'lodash/assign';
8
8
  import { createLintRule } from '../utils/create-rule';
9
+ // File-level tracking of styles hoisted from the cssOnTopOfModule/cssAtBottomOfModule fixers
10
+ var hoistedCss = [];
9
11
  function isCssCallExpression(node, cssFunctions) {
10
12
  cssFunctions = [].concat(_toConsumableArray(cssFunctions), ['cssMap']);
11
13
  return !!(isNodeOfType(node, 'CallExpression') && node.callee && node.callee.type === 'Identifier' && cssFunctions.includes(node.callee.name) && node.arguments.length && node.arguments[0].type === 'ObjectExpression');
@@ -18,11 +20,11 @@ function findSpreadProperties(node) {
18
20
  property.type === 'ExperimentalSpreadProperty';
19
21
  });
20
22
  }
21
- var getTopLevelNode = function getTopLevelNode(expression) {
23
+ var getProgramNode = function getProgramNode(expression) {
22
24
  while (expression.parent.type !== 'Program') {
23
25
  expression = expression.parent;
24
26
  }
25
- return expression;
27
+ return expression.parent;
26
28
  };
27
29
 
28
30
  // TODO: This can be optimised by implementing a fixer at the very end (Program:exit) and handling all validations at once
@@ -41,7 +43,7 @@ var getDeclaratorString = function getDeclaratorString(context) {
41
43
  }
42
44
  var variables = scope.variables.map(function (variable) {
43
45
  return variable.name;
44
- });
46
+ }).concat(hoistedCss);
45
47
  var count = 2;
46
48
  var declaratorName = 'styles';
47
49
 
@@ -54,6 +56,9 @@ var getDeclaratorString = function getDeclaratorString(context) {
54
56
  count++;
55
57
  }
56
58
  }
59
+
60
+ // Keep track of it by adding it to the hoistedCss global array
61
+ hoistedCss = [].concat(_toConsumableArray(hoistedCss), ["".concat(declaratorName).concat(count)]);
57
62
  return "".concat(declaratorName).concat(count);
58
63
  };
59
64
  function analyzeIdentifier(context, sourceIdentifier, configuration) {
@@ -116,7 +121,19 @@ function analyzeIdentifier(context, sourceIdentifier, configuration) {
116
121
  */
117
122
  var fixCssNotInModuleScope = function fixCssNotInModuleScope(fixer, context, configuration, node, cssAttributeName) {
118
123
  var sourceCode = context.getSourceCode();
119
- var topLevelNode = getTopLevelNode(node);
124
+
125
+ // Get the program node in order to properly position the hoisted styles
126
+ var programNode = getProgramNode(node);
127
+ var fixerNodePlacement = programNode;
128
+ if (configuration.stylesPlacement === 'bottom') {
129
+ // The last value is the bottom of the file
130
+ fixerNodePlacement = programNode.body[programNode.body.length - 1];
131
+ } else {
132
+ // Place after the last ImportDeclaration
133
+ fixerNodePlacement = programNode.body.length === 1 ? programNode.body[0] : programNode.body.find(function (node) {
134
+ return node.type !== 'ImportDeclaration';
135
+ });
136
+ }
120
137
  var moduleString;
121
138
  var implementFixer = [];
122
139
  if (node.type === 'Identifier') {
@@ -138,7 +155,7 @@ var fixCssNotInModuleScope = function fixCssNotInModuleScope(fixer, context, con
138
155
  }
139
156
  return [].concat(implementFixer, [
140
157
  // Insert the node either before or after
141
- configuration.stylesPlacement === 'bottom' ? fixer.insertTextAfter(topLevelNode, '\n' + moduleString) : fixer.insertTextBefore(topLevelNode, moduleString + '\n')]);
158
+ configuration.stylesPlacement === 'bottom' ? fixer.insertTextAfter(fixerNodePlacement, '\n' + moduleString) : fixer.insertTextBefore(fixerNodePlacement, moduleString + '\n')]);
142
159
  };
143
160
 
144
161
  /**
@@ -269,6 +286,9 @@ var rule = createLintRule({
269
286
  }), _defineProperty(_ref3, "JSXAttribute", function JSXAttribute(node) {
270
287
  var name = node.name,
271
288
  value = node.value;
289
+
290
+ // Always reset to empty array
291
+ hoistedCss = [];
272
292
  if (name.type === 'JSXIdentifier' && mergedConfig.cssFunctions.includes(name.name)) {
273
293
  // When not a jsx expression. For eg. css=""
274
294
  if ((value === null || value === void 0 ? void 0 : value.type) !== 'JSXExpressionContainer') {
@@ -1,8 +1,6 @@
1
- import { getIdentifierInParentScope, isNodeOfType } from 'eslint-codemod-utils';
2
1
  import { createLintRule } from '../utils/create-rule';
3
2
  import { getConfig } from './config';
4
- import { jsxElementToBoxTransformer, styledComponentToPrimitive } from './transformers';
5
- import { containsOnlySupportedAttrs, findValidJsxUsageToTransform, findValidStyledComponentCall, getAttributeValueIdentifier, getJSXAttributeByName, getVariableDefinitionValue, getVariableUsagesCount, isFunctionNamed, isValidCssPropertiesToTransform, isValidTagName } from './utils';
3
+ import { CompiledStyled, EmotionCSS } from './transformers';
6
4
  var boxDocsUrl = 'https://atlassian.design/components/primitives/box';
7
5
  var rule = createLintRule({
8
6
  meta: {
@@ -24,113 +22,19 @@ var rule = createLintRule({
24
22
  return {
25
23
  // transforms styled.<html>(...) usages
26
24
  CallExpression: function CallExpression(node) {
27
- if (!config.patterns.includes('compiled-styled-object')) {
28
- return;
29
- }
30
- if (!isNodeOfType(node, 'CallExpression')) {
31
- return;
32
- }
33
- var styledComponentVariableRef = findValidStyledComponentCall(node);
34
- if (!styledComponentVariableRef || !isNodeOfType(styledComponentVariableRef.id, 'Identifier') || !isValidCssPropertiesToTransform(node, config)) {
35
- return;
36
- }
37
- var styledComponentJsxRef = findValidJsxUsageToTransform(styledComponentVariableRef.id.name, context.getScope());
38
- if (!styledComponentJsxRef) {
39
- return;
40
- }
41
-
42
- // if we have both references at this point then we can offer a fix \o/
43
- context.report({
44
- node: styledComponentVariableRef,
45
- messageId: 'preferPrimitivesBox',
46
- suggest: [{
47
- desc: "Convert ".concat(styledComponentVariableRef.id.name, " to Box"),
48
- fix: styledComponentToPrimitive({
49
- stylesRef: styledComponentVariableRef,
50
- jsxRef: styledComponentJsxRef
51
- }, context)
52
- }]
25
+ CompiledStyled.lint(node, {
26
+ context: context,
27
+ config: config
53
28
  });
54
29
  },
55
30
  // transforms <div css={...}> usages
56
- JSXOpeningElement: function JSXOpeningElement(node) {
57
- if (!config.patterns.includes('compiled-css-function')) {
58
- return false;
59
- }
60
- if (!isNodeOfType(node, 'JSXOpeningElement')) {
61
- return;
62
- }
63
- if (!isNodeOfType(node.name, 'JSXIdentifier')) {
64
- return;
65
- }
66
- if (!isNodeOfType(node.parent, 'JSXElement')) {
67
- return;
68
- }
69
- var suggestBox = shouldSuggestBox(node.parent, context, config);
70
- if (suggestBox) {
71
- context.report({
72
- node: node,
73
- messageId: 'preferPrimitivesBox',
74
- data: {
75
- element: node.name.name
76
- },
77
- suggest: [{
78
- desc: "Convert to Box",
79
- fix: jsxElementToBoxTransformer(node.parent, context)
80
- }]
81
- });
82
- }
31
+ JSXElement: function JSXElement(node) {
32
+ EmotionCSS.lint(node, {
33
+ context: context,
34
+ config: config
35
+ });
83
36
  }
84
37
  };
85
38
  }
86
39
  });
87
- var shouldSuggestBox = function shouldSuggestBox(node, context, config
88
- // scope: Scope.Scope,
89
- ) {
90
- if (!node) {
91
- return false;
92
- }
93
-
94
- // Currently we only support `div`, but possibly more in future
95
- if (!isValidTagName(node)) {
96
- return false;
97
- }
98
-
99
- // Currently we only support elements that contain only a `css` attr, possibly more in future
100
- if (!containsOnlySupportedAttrs(node)) {
101
- return false;
102
- }
103
-
104
- // Get the `css` attr
105
- var cssAttr = getJSXAttributeByName(node.openingElement, 'css');
106
-
107
- // Get the prop value, e.g. `myStyles` in `css={myStyles}`
108
- var cssVariableName = getAttributeValueIdentifier(cssAttr);
109
-
110
- // `cssVariableName` could be undefined if the maker has
111
- // done something like `css={[styles1, styles2]}`, `css={...styles}`, etc
112
- if (!cssVariableName) {
113
- return false;
114
- }
115
-
116
- /**
117
- * Make sure the variable is not used in multiple JSX elements:
118
- * ```
119
- * <div css={paddingStyles}></div>
120
- * <input css={paddingStyles}></input>
121
- * ```
122
- */
123
- if (getVariableUsagesCount(cssVariableName, context) !== 1) {
124
- return false;
125
- }
126
-
127
- // Find where `cssVariableName` is defined. We're looking for `const myStyles = css({...})`
128
- var cssVariableDefinition = getIdentifierInParentScope(context.getScope(), cssVariableName);
129
- var cssVariableValue = getVariableDefinitionValue(cssVariableDefinition);
130
- // Check if `cssVariableValue` is a function called `css()`
131
- if (!cssVariableValue || !isFunctionNamed(cssVariableValue, 'css')) {
132
- return false;
133
- }
134
- return isValidCssPropertiesToTransform(cssVariableValue.node.init, config);
135
- };
136
40
  export default rule;
@@ -0,0 +1,30 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { isNodeOfType } from 'eslint-codemod-utils';
3
+ import * as ast from '../../../../ast-nodes';
4
+
5
+ /**
6
+ * Transforms a JSXElement from:
7
+ * ```
8
+ * <div>
9
+ * // ...
10
+ * </div>
11
+ * ```
12
+ * to
13
+ * ```
14
+ * <Box xcss={myStyles}>
15
+ * // ...
16
+ * </Box>
17
+ * ```
18
+ */
19
+ export var convertJsxCallSite = function convertJsxCallSite(jsxElement, newStylesVariableName, fixer) {
20
+ var fixes = [];
21
+
22
+ // renames the JSX call site
23
+ if (isNodeOfType(jsxElement, 'JSXElement')) {
24
+ fixes.push.apply(fixes, _toConsumableArray(ast.JSXElement.updateName(jsxElement, 'Box', fixer)));
25
+ }
26
+
27
+ // adds xcss prop
28
+ fixes.push(fixer.insertTextAfter(jsxElement.openingElement.name, " xcss={".concat(newStylesVariableName, "}")));
29
+ return fixes;
30
+ };
@@ -0,0 +1,38 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { isNodeOfType } from 'eslint-codemod-utils';
3
+ import { styledObjectToXcssTokens } from '../css-to-xcss';
4
+
5
+ /**
6
+ * Transforms a variable like:
7
+ * ```
8
+ * const MyComponent = styled.div({
9
+ * padding: '8px',
10
+ * })
11
+ * ```
12
+ * to
13
+ * ```
14
+ * const myComponentStyles = xcss({
15
+ * padding: 'space.100',
16
+ * })
17
+ * ```
18
+ */
19
+ export var convertStyledComponentToXcss = function convertStyledComponentToXcss(styles, newStylesVariableName, fixer) {
20
+ var fixes = [];
21
+
22
+ // renames the variable from MyComponent to myComponentStyles
23
+ fixes.push(fixer.replaceText(styles.id, newStylesVariableName));
24
+
25
+ // renames the function call from styled.<tag> to xcss
26
+ if (styles.init && isNodeOfType(styles.init, 'CallExpression')) {
27
+ fixes.push(fixer.replaceText(styles.init.callee, 'xcss'));
28
+ }
29
+
30
+ // converts CSS values to XCSS-compatible tokens
31
+ if (styles.init && isNodeOfType(styles.init, 'CallExpression')) {
32
+ var objectExpression = styles.init.arguments[0];
33
+ if (isNodeOfType(objectExpression, 'ObjectExpression')) {
34
+ fixes.push.apply(fixes, _toConsumableArray(styledObjectToXcssTokens(objectExpression, fixer)));
35
+ }
36
+ }
37
+ return fixes;
38
+ };
@@ -1,5 +1,5 @@
1
1
  import { closestOfType, isNodeOfType } from 'eslint-codemod-utils';
2
- import { validPrimitiveElements } from './is-valid-tag-name';
2
+ import * as supported from './supported';
3
3
 
4
4
  /**
5
5
  * returns a variable reference if preconditions are favourable for
@@ -41,7 +41,7 @@ var isStyledCallExpression = function isStyledCallExpression(call) {
41
41
  if (!isNodeOfType(call.callee.object, 'Identifier') || !isNodeOfType(call.callee.property, 'Identifier')) {
42
42
  return false;
43
43
  }
44
- if (/^styled2?$/.test(call.callee.object.name) && validPrimitiveElements.has(call.callee.property.name)) {
44
+ if (/^styled2?$/.test(call.callee.object.name) && supported.elements.includes(call.callee.property.name)) {
45
45
  return true;
46
46
  }
47
47
  return false;