@atlaskit/eslint-plugin-design-system 8.37.1 → 8.37.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 CHANGED
@@ -1,5 +1,16 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 8.37.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#80662](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/80662) [`4833299b00d4`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4833299b00d4) - For `no-css-tagged-template-expression` and `no-styled-tagged-template-expression`:
8
+
9
+ - When importing from Emotion, stop applying autofixer when the styles contain `!important`.
10
+ - When importing from any library, stop applying autofixer when a selector contains a tagged template interpolation (previously only styled-components).
11
+
12
+ - [#81697](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/81697) [`cf3483e7e87d`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/cf3483e7e87d) - Adding a missing `license` entry to the `package.json` for this package. This package was already licensed under `Apache-2.0` (see `LICENSE` file), so this change is not changing it's license.
13
+
3
14
  ## 8.37.1
4
15
 
5
16
  ### Patch Changes
@@ -43,12 +43,11 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
43
43
  if (!isUsage(node.tag, references, importSources)) {
44
44
  return;
45
45
  }
46
- var isSC = (0, _isSupportedImport.isStyledComponents)(node.tag, references, importSources);
47
46
  context.report({
48
47
  messageId: messageId,
49
48
  node: node,
50
49
  fix: /*#__PURE__*/_regenerator.default.mark(function fix(fixer) {
51
- var quasi, source, args, oldCode, withoutQuasi, newCode;
50
+ var quasi, source, args, oldCode, withoutQuasi, newCode, usesEmotion;
52
51
  return _regenerator.default.wrap(function fix$(_context) {
53
52
  while (1) switch (_context.prev = _context.next) {
54
53
  case 0:
@@ -95,18 +94,28 @@ var createNoTaggedTemplateExpressionRule = exports.createNoTaggedTemplateExpress
95
94
  }
96
95
  return _context.abrupt("return");
97
96
  case 16:
98
- if (!(isSC && /\$\{.*:[\s]*\{/.test(newCode) || /\$\{.*\(.*:[\s]*\{/.test(newCode))) {
99
- _context.next = 18;
97
+ // For styles like `position: initial !important`,
98
+ // Emotion can give typechecking errors when using object syntax
99
+ // due to csstype being overly strict
100
+ usesEmotion = (0, _isSupportedImport.isEmotion)(node.tag, references, importSources);
101
+ if (!(usesEmotion && !!newCode.match(/!\s*important/gm))) {
102
+ _context.next = 19;
100
103
  break;
101
104
  }
102
105
  return _context.abrupt("return");
103
- case 18:
104
- _context.next = 20;
106
+ case 19:
107
+ if (!/\$\{.*:[\s]*\{/.test(newCode)) {
108
+ _context.next = 21;
109
+ break;
110
+ }
111
+ return _context.abrupt("return");
112
+ case 21:
113
+ _context.next = 23;
105
114
  return fixer.insertTextBefore(node, newCode);
106
- case 20:
107
- _context.next = 22;
115
+ case 23:
116
+ _context.next = 25;
108
117
  return fixer.remove(node);
109
- case 22:
118
+ case 25:
110
119
  case "end":
111
120
  return _context.stop();
112
121
  }
@@ -121,7 +121,9 @@ var isStyled = exports.isStyled = isSupportedImportWrapper('styled', ['styled-co
121
121
  var isImportedFrom = exports.isImportedFrom = function isImportedFrom(moduleName) {
122
122
  var exactMatch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
123
123
  return function (nodeToCheck, referencesInScope, importSources) {
124
- if (!importSources.includes(moduleName)) {
124
+ if (!importSources.some(function (importSource) {
125
+ return importSource === moduleName || !exactMatch && importSource.startsWith(moduleName);
126
+ })) {
125
127
  // Don't go through the trouble of checking the import sources does not include this
126
128
  // We'll assume this is skipped elsewhere.
127
129
  return false;
@@ -1,7 +1,7 @@
1
1
  // Original source from Compiled https://github.com/atlassian-labs/compiled/blob/master/packages/eslint-plugin/src/utils/create-no-tagged-template-expression-rule/index.ts
2
2
  // eslint-disable-next-line import/no-extraneous-dependencies
3
3
 
4
- import { getImportSources, isStyledComponents } from '../is-supported-import';
4
+ import { getImportSources, isEmotion } from '../is-supported-import';
5
5
  import { generate } from './generate';
6
6
  import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
7
7
  import { toArguments } from './to-arguments';
@@ -35,7 +35,6 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
35
35
  if (!isUsage(node.tag, references, importSources)) {
36
36
  return;
37
37
  }
38
- const isSC = isStyledComponents(node.tag, references, importSources);
39
38
  context.report({
40
39
  messageId,
41
40
  node,
@@ -77,12 +76,22 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
77
76
  return;
78
77
  }
79
78
 
80
- // TODO: We might want to similarly disallow `styled.div({ color: props => props.color })` for SC as it's broken too (both type and functionality)
81
- // Alternatively, autofix it to `styled.div(props => ({ color: props.color }))`?
82
- if (isSC && /\$\{.*:[\s]*\{/.test(newCode) || /\$\{.*\(.*:[\s]*\{/.test(newCode)) {
79
+ // For styles like `position: initial !important`,
80
+ // Emotion can give typechecking errors when using object syntax
81
+ // due to csstype being overly strict
82
+ const usesEmotion = isEmotion(node.tag, references, importSources);
83
+ if (usesEmotion && !!newCode.match(/!\s*important/gm)) {
84
+ return;
85
+ }
86
+
87
+ // For styled-components, we might also want to similarly disallow or autofix `styled.div({ color: props => props.color })` as it's broken too (both type and functionality). This is tracked in https://product-fabric.atlassian.net/browse/USS-26.
88
+ if (/\$\{.*:[\s]*\{/.test(newCode)) {
83
89
  /**
84
- * If we find a variable in a selector when migrating `styled-components` code, we skip it.
85
- * This is because `styled-components@3.x` does not support the syntax.
90
+ * If we find a variable in a selector, we skip it. There are two reasons:
91
+ *
92
+ * - `styled-components@3.x` does not support variables in a selector (see the first example).
93
+ *
94
+ * - We cannot guarantee that the contents of an function call is actually a selector, and not a CSS block (see the third example).
86
95
  *
87
96
  * @examples
88
97
  * ```tsx
@@ -90,11 +99,21 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
90
99
  * & + ${Button} { color: red; }
91
100
  * `;
92
101
  * ```
93
- *```tsx
102
+ *
103
+ * ```tsx
94
104
  * const Component = styled.div`
95
105
  * ${mixin()} button { color: red; }
96
106
  * `;
97
107
  * ```
108
+ *
109
+ * ```tsx
110
+ * const styles = `&:active { color: blue; }`;
111
+ * const Component = styled.div`
112
+ * ${styles} &:hover {
113
+ * color: red;
114
+ * }
115
+ * `;
116
+ * ```
98
117
  */
99
118
  return;
100
119
  }
@@ -110,7 +110,7 @@ export const isKeyframes = isSupportedImportWrapper('keyframes');
110
110
  // `styled` is also the explicit default of `styled-components` and `@emotion/styled`, so we also match on default imports generally
111
111
  export const isStyled = isSupportedImportWrapper('styled', ['styled-components', '@emotion/styled']);
112
112
  export const isImportedFrom = (moduleName, exactMatch = true) => (nodeToCheck, referencesInScope, importSources) => {
113
- if (!importSources.includes(moduleName)) {
113
+ if (!importSources.some(importSource => importSource === moduleName || !exactMatch && importSource.startsWith(moduleName))) {
114
114
  // Don't go through the trouble of checking the import sources does not include this
115
115
  // We'll assume this is skipped elsewhere.
116
116
  return false;
@@ -2,7 +2,7 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
2
2
  // Original source from Compiled https://github.com/atlassian-labs/compiled/blob/master/packages/eslint-plugin/src/utils/create-no-tagged-template-expression-rule/index.ts
3
3
  // eslint-disable-next-line import/no-extraneous-dependencies
4
4
 
5
- import { getImportSources, isStyledComponents } from '../is-supported-import';
5
+ import { getImportSources, isEmotion } from '../is-supported-import';
6
6
  import { generate } from './generate';
7
7
  import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
8
8
  import { toArguments } from './to-arguments';
@@ -36,12 +36,11 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
36
36
  if (!isUsage(node.tag, references, importSources)) {
37
37
  return;
38
38
  }
39
- var isSC = isStyledComponents(node.tag, references, importSources);
40
39
  context.report({
41
40
  messageId: messageId,
42
41
  node: node,
43
42
  fix: /*#__PURE__*/_regeneratorRuntime.mark(function fix(fixer) {
44
- var quasi, source, args, oldCode, withoutQuasi, newCode;
43
+ var quasi, source, args, oldCode, withoutQuasi, newCode, usesEmotion;
45
44
  return _regeneratorRuntime.wrap(function fix$(_context) {
46
45
  while (1) switch (_context.prev = _context.next) {
47
46
  case 0:
@@ -88,18 +87,28 @@ export var createNoTaggedTemplateExpressionRule = function createNoTaggedTemplat
88
87
  }
89
88
  return _context.abrupt("return");
90
89
  case 16:
91
- if (!(isSC && /\$\{.*:[\s]*\{/.test(newCode) || /\$\{.*\(.*:[\s]*\{/.test(newCode))) {
92
- _context.next = 18;
90
+ // For styles like `position: initial !important`,
91
+ // Emotion can give typechecking errors when using object syntax
92
+ // due to csstype being overly strict
93
+ usesEmotion = isEmotion(node.tag, references, importSources);
94
+ if (!(usesEmotion && !!newCode.match(/!\s*important/gm))) {
95
+ _context.next = 19;
93
96
  break;
94
97
  }
95
98
  return _context.abrupt("return");
96
- case 18:
97
- _context.next = 20;
99
+ case 19:
100
+ if (!/\$\{.*:[\s]*\{/.test(newCode)) {
101
+ _context.next = 21;
102
+ break;
103
+ }
104
+ return _context.abrupt("return");
105
+ case 21:
106
+ _context.next = 23;
98
107
  return fixer.insertTextBefore(node, newCode);
99
- case 20:
100
- _context.next = 22;
108
+ case 23:
109
+ _context.next = 25;
101
110
  return fixer.remove(node);
102
- case 22:
111
+ case 25:
103
112
  case "end":
104
113
  return _context.stop();
105
114
  }
@@ -115,7 +115,9 @@ export var isStyled = isSupportedImportWrapper('styled', ['styled-components', '
115
115
  export var isImportedFrom = function isImportedFrom(moduleName) {
116
116
  var exactMatch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
117
117
  return function (nodeToCheck, referencesInScope, importSources) {
118
- if (!importSources.includes(moduleName)) {
118
+ if (!importSources.some(function (importSource) {
119
+ return importSource === moduleName || !exactMatch && importSource.startsWith(moduleName);
120
+ })) {
119
121
  // Don't go through the trouble of checking the import sources does not include this
120
122
  // We'll assume this is skipped elsewhere.
121
123
  return false;
package/package.json CHANGED
@@ -1,8 +1,9 @@
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.37.1",
4
+ "version": "8.37.2",
5
5
  "author": "Atlassian Pty Ltd",
6
+ "license": "Apache-2.0",
6
7
  "publishConfig": {
7
8
  "registry": "https://registry.npmjs.org/"
8
9
  },