@atlaskit/eslint-plugin-platform 0.13.1 → 1.0.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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/eslint-plugin-platform
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#168864](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/168864)
8
+ [`49e4510bd86d3`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/49e4510bd86d3) -
9
+ update eslint rule 'expand-border-properties' from warn to error
10
+
11
+ ## 0.14.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [#173404](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/173404)
16
+ [`7818ef3312ccd`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7818ef3312ccd) -
17
+ Eslint rule for expand-background-shorthand with token
18
+
3
19
  ## 0.13.1
4
20
 
5
21
  ### Patch Changes
@@ -16,5 +16,9 @@
16
16
  "../src/**/*.test.*",
17
17
  "../src/**/test.*"
18
18
  ],
19
- "references": []
19
+ "references": [
20
+ {
21
+ "path": "../../../design-system/eslint-utils/afm-cc/tsconfig.json"
22
+ }
23
+ ]
20
24
  }
package/dist/cjs/index.js CHANGED
@@ -30,6 +30,7 @@ var _preferFg = _interopRequireDefault(require("./rules/feature-gating/prefer-fg
30
30
  var _noAlias = _interopRequireDefault(require("./rules/feature-gating/no-alias"));
31
31
  var _useEntrypointsInExamples = _interopRequireDefault(require("./rules/use-entrypoints-in-examples"));
32
32
  var _useRecommendedUtils = _interopRequireDefault(require("./rules/feature-gating/use-recommended-utils"));
33
+ var _expandBackgroundShorthand = _interopRequireDefault(require("./rules/compiled/expand-background-shorthand"));
33
34
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
34
35
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // eslint-disable-next-line import/no-extraneous-dependencies
35
36
  var rules = exports.rules = {
@@ -42,6 +43,7 @@ var rules = exports.rules = {
42
43
  'ensure-valid-platform-yarn-protocol-usage': _ensureValidPlatformYarnProtocolUsage.default,
43
44
  'ensure-valid-bin-values': _ensureValidBinValues.default,
44
45
  'expand-border-shorthand': _expandBorderShorthand.default,
46
+ 'expand-background-shorthand': _expandBackgroundShorthand.default,
45
47
  'no-duplicate-dependencies': _noDuplicateDependencies.default,
46
48
  'no-invalid-feature-flag-usage': _noInvalidFeatureFlagUsage.default,
47
49
  'no-pre-post-install-scripts': _noPrePostInstalls.default,
@@ -66,7 +68,8 @@ var commonConfig = {
66
68
  '@atlaskit/platform/ensure-atlassian-team': 'error',
67
69
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
68
70
  // Compiled: rules that are not included via `@compiled/recommended
69
- '@atlaskit/platform/expand-border-shorthand': 'warn',
71
+ '@atlaskit/platform/expand-border-shorthand': 'error',
72
+ '@atlaskit/platform/expand-background-shorthand': 'warn',
70
73
  '@compiled/jsx-pragma': ['error', {
71
74
  importSources: ['@atlaskit/css'],
72
75
  onlyRunIfImportingCompiled: true,
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.expandBackgroundShorthand = exports.default = void 0;
7
+ var _isSupportedImport = require("@atlaskit/eslint-utils/is-supported-import");
8
+ // Checks if the function that holds the border property is using an import package that this rule is targeting
9
+ var isCompiledAPI = function isCompiledAPI(context) {
10
+ var importSources = (0, _isSupportedImport.getImportSources)(context);
11
+ var _context$getScope = context.getScope(),
12
+ references = _context$getScope.references;
13
+ var ancestors = context.getAncestors();
14
+ if (ancestors.some(function (ancestor) {
15
+ return ancestor.type === 'CallExpression' && ancestor.callee && ((0, _isSupportedImport.isCompiled)(ancestor.callee, references, importSources) || (0, _isSupportedImport.isAtlasKitCSS)(ancestor.callee, references, importSources));
16
+ })) {
17
+ return true;
18
+ }
19
+ return false;
20
+ };
21
+
22
+ // Checks if node is a call expression with identifier 'token'
23
+ var isTokenCallExpression = function isTokenCallExpression(node) {
24
+ if (node.type === 'CallExpression') {
25
+ if (node.callee.type === 'Identifier' && node.callee.name === 'token') {
26
+ return true;
27
+ }
28
+ }
29
+ return false;
30
+ };
31
+ var expandBackgroundShorthand = exports.expandBackgroundShorthand = {
32
+ meta: {
33
+ docs: {
34
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/compiled/expand-background-shorthand/'
35
+ },
36
+ messages: {
37
+ expandBackgroundShorthand: 'Use backgroundColor instead of background shorthand'
38
+ },
39
+ type: 'problem',
40
+ fixable: 'code'
41
+ },
42
+ create: function create(context) {
43
+ return {
44
+ 'Property[key.name="background"]': function PropertyKeyNameBackground(node) {
45
+ if (isCompiledAPI(context) && isTokenCallExpression(node.value)) {
46
+ context.report({
47
+ node: node,
48
+ messageId: 'expandBackgroundShorthand',
49
+ fix: function fix(fixer) {
50
+ return fixer.replaceText(node.key, "backgroundColor");
51
+ }
52
+ });
53
+ return;
54
+ }
55
+ }
56
+ };
57
+ }
58
+ };
59
+ var _default = exports.default = expandBackgroundShorthand;
@@ -19,6 +19,9 @@ var separateBorderProperties = function separateBorderProperties(borderString, p
19
19
  if (EXCLUDED_VALUES.includes(borderString)) {
20
20
  return;
21
21
  }
22
+ if (borderString.includes('var(--')) {
23
+ return;
24
+ }
22
25
  context.report({
23
26
  node: property,
24
27
  messageId: 'expandBorderShorthand'
@@ -39,7 +42,7 @@ var isCompiledAPI = function isCompiledAPI(importDeclaration, callExpression) {
39
42
  return;
40
43
  }
41
44
  return importDeclaration.specifiers.some(function (specifier) {
42
- return specifier.type === 'ImportSpecifier' && specifier.imported.name === functionName;
45
+ return specifier.type === 'ImportSpecifier' && specifier.local.name === functionName;
43
46
  });
44
47
  };
45
48
  var expandBorderShorthand = exports.expandBorderShorthand = {
@@ -66,21 +69,11 @@ var expandBorderShorthand = exports.expandBorderShorthand = {
66
69
  if (importDeclaration) {
67
70
  if (isCompiledAPI(importDeclaration, callExpression)) {
68
71
  if (node.value.type === 'Literal' && node.value.value !== null) {
69
- if (typeof node.value.value === 'string') {
70
- var borderString = node.value.value;
72
+ var borderString = typeof node.value.value === 'string' ? node.value.value : node.value.raw;
73
+ if (borderString) {
71
74
  separateBorderProperties(borderString, node, context);
72
- } else if (node.value.raw) {
73
- var _borderString = node.value.raw;
74
- separateBorderProperties(_borderString, node, context);
75
75
  }
76
76
  } else if (node.value.type === 'TemplateLiteral') {
77
- if (node.value.quasis.length > 1 || node.value.expressions.length > 0) {
78
- context.report({
79
- node: node,
80
- messageId: 'expandBorderShorthand'
81
- });
82
- return;
83
- }
84
77
  if (node.value.quasis.length === 1 && node.value.quasis[0].value.cooked) {
85
78
  var borderQuasis = node.value.quasis[0].value.cooked;
86
79
  separateBorderProperties(borderQuasis, node, context);
@@ -24,6 +24,7 @@ import preferFG from './rules/feature-gating/prefer-fg';
24
24
  import noAlias from './rules/feature-gating/no-alias';
25
25
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
26
26
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
27
+ import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
27
28
  export const rules = {
28
29
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
29
30
  'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
@@ -34,6 +35,7 @@ export const rules = {
34
35
  'ensure-valid-platform-yarn-protocol-usage': ensureValidPlatformYarnProtocolUsage,
35
36
  'ensure-valid-bin-values': ensureValidBinValues,
36
37
  'expand-border-shorthand': expandBorderShorthand,
38
+ 'expand-background-shorthand': expandBackgroundShorthand,
37
39
  'no-duplicate-dependencies': noDuplicateDependencies,
38
40
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
39
41
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -58,7 +60,8 @@ const commonConfig = {
58
60
  '@atlaskit/platform/ensure-atlassian-team': 'error',
59
61
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
60
62
  // Compiled: rules that are not included via `@compiled/recommended
61
- '@atlaskit/platform/expand-border-shorthand': 'warn',
63
+ '@atlaskit/platform/expand-border-shorthand': 'error',
64
+ '@atlaskit/platform/expand-background-shorthand': 'warn',
62
65
  '@compiled/jsx-pragma': ['error', {
63
66
  importSources: ['@atlaskit/css'],
64
67
  onlyRunIfImportingCompiled: true,
@@ -0,0 +1,53 @@
1
+ import { getImportSources, isCompiled, isAtlasKitCSS } from '@atlaskit/eslint-utils/is-supported-import';
2
+
3
+ // Checks if the function that holds the border property is using an import package that this rule is targeting
4
+ const isCompiledAPI = context => {
5
+ const importSources = getImportSources(context);
6
+ const {
7
+ references
8
+ } = context.getScope();
9
+ const ancestors = context.getAncestors();
10
+ if (ancestors.some(ancestor => ancestor.type === 'CallExpression' && ancestor.callee && (isCompiled(ancestor.callee, references, importSources) || isAtlasKitCSS(ancestor.callee, references, importSources)))) {
11
+ return true;
12
+ }
13
+ return false;
14
+ };
15
+
16
+ // Checks if node is a call expression with identifier 'token'
17
+ const isTokenCallExpression = node => {
18
+ if (node.type === 'CallExpression') {
19
+ if (node.callee.type === 'Identifier' && node.callee.name === 'token') {
20
+ return true;
21
+ }
22
+ }
23
+ return false;
24
+ };
25
+ export const expandBackgroundShorthand = {
26
+ meta: {
27
+ docs: {
28
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/compiled/expand-background-shorthand/'
29
+ },
30
+ messages: {
31
+ expandBackgroundShorthand: 'Use backgroundColor instead of background shorthand'
32
+ },
33
+ type: 'problem',
34
+ fixable: 'code'
35
+ },
36
+ create(context) {
37
+ return {
38
+ 'Property[key.name="background"]': function (node) {
39
+ if (isCompiledAPI(context) && isTokenCallExpression(node.value)) {
40
+ context.report({
41
+ node,
42
+ messageId: 'expandBackgroundShorthand',
43
+ fix(fixer) {
44
+ return fixer.replaceText(node.key, `backgroundColor`);
45
+ }
46
+ });
47
+ return;
48
+ }
49
+ }
50
+ };
51
+ }
52
+ };
53
+ export default expandBackgroundShorthand;
@@ -13,6 +13,9 @@ const separateBorderProperties = (borderString, property, context) => {
13
13
  if (EXCLUDED_VALUES.includes(borderString)) {
14
14
  return;
15
15
  }
16
+ if (borderString.includes('var(--')) {
17
+ return;
18
+ }
16
19
  context.report({
17
20
  node: property,
18
21
  messageId: 'expandBorderShorthand'
@@ -32,7 +35,7 @@ const isCompiledAPI = (importDeclaration, callExpression) => {
32
35
  if (!functionName) {
33
36
  return;
34
37
  }
35
- return importDeclaration.specifiers.some(specifier => specifier.type === 'ImportSpecifier' && specifier.imported.name === functionName);
38
+ return importDeclaration.specifiers.some(specifier => specifier.type === 'ImportSpecifier' && specifier.local.name === functionName);
36
39
  };
37
40
  export const expandBorderShorthand = {
38
41
  meta: {
@@ -58,21 +61,11 @@ export const expandBorderShorthand = {
58
61
  if (importDeclaration) {
59
62
  if (isCompiledAPI(importDeclaration, callExpression)) {
60
63
  if (node.value.type === 'Literal' && node.value.value !== null) {
61
- if (typeof node.value.value === 'string') {
62
- const borderString = node.value.value;
63
- separateBorderProperties(borderString, node, context);
64
- } else if (node.value.raw) {
65
- const borderString = node.value.raw;
64
+ const borderString = typeof node.value.value === 'string' ? node.value.value : node.value.raw;
65
+ if (borderString) {
66
66
  separateBorderProperties(borderString, node, context);
67
67
  }
68
68
  } else if (node.value.type === 'TemplateLiteral') {
69
- if (node.value.quasis.length > 1 || node.value.expressions.length > 0) {
70
- context.report({
71
- node,
72
- messageId: 'expandBorderShorthand'
73
- });
74
- return;
75
- }
76
69
  if (node.value.quasis.length === 1 && node.value.quasis[0].value.cooked) {
77
70
  const borderQuasis = node.value.quasis[0].value.cooked;
78
71
  separateBorderProperties(borderQuasis, node, context);
package/dist/esm/index.js CHANGED
@@ -27,6 +27,7 @@ import preferFG from './rules/feature-gating/prefer-fg';
27
27
  import noAlias from './rules/feature-gating/no-alias';
28
28
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
29
29
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
30
+ import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
30
31
  export var rules = {
31
32
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
32
33
  'ensure-feature-flag-prefix': ensureFeatureFlagPrefix,
@@ -37,6 +38,7 @@ export var rules = {
37
38
  'ensure-valid-platform-yarn-protocol-usage': ensureValidPlatformYarnProtocolUsage,
38
39
  'ensure-valid-bin-values': ensureValidBinValues,
39
40
  'expand-border-shorthand': expandBorderShorthand,
41
+ 'expand-background-shorthand': expandBackgroundShorthand,
40
42
  'no-duplicate-dependencies': noDuplicateDependencies,
41
43
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
42
44
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -61,7 +63,8 @@ var commonConfig = {
61
63
  '@atlaskit/platform/ensure-atlassian-team': 'error',
62
64
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
63
65
  // Compiled: rules that are not included via `@compiled/recommended
64
- '@atlaskit/platform/expand-border-shorthand': 'warn',
66
+ '@atlaskit/platform/expand-border-shorthand': 'error',
67
+ '@atlaskit/platform/expand-background-shorthand': 'warn',
65
68
  '@compiled/jsx-pragma': ['error', {
66
69
  importSources: ['@atlaskit/css'],
67
70
  onlyRunIfImportingCompiled: true,
@@ -0,0 +1,54 @@
1
+ import { getImportSources, isCompiled, isAtlasKitCSS } from '@atlaskit/eslint-utils/is-supported-import';
2
+
3
+ // Checks if the function that holds the border property is using an import package that this rule is targeting
4
+ var isCompiledAPI = function isCompiledAPI(context) {
5
+ var importSources = getImportSources(context);
6
+ var _context$getScope = context.getScope(),
7
+ references = _context$getScope.references;
8
+ var ancestors = context.getAncestors();
9
+ if (ancestors.some(function (ancestor) {
10
+ return ancestor.type === 'CallExpression' && ancestor.callee && (isCompiled(ancestor.callee, references, importSources) || isAtlasKitCSS(ancestor.callee, references, importSources));
11
+ })) {
12
+ return true;
13
+ }
14
+ return false;
15
+ };
16
+
17
+ // Checks if node is a call expression with identifier 'token'
18
+ var isTokenCallExpression = function isTokenCallExpression(node) {
19
+ if (node.type === 'CallExpression') {
20
+ if (node.callee.type === 'Identifier' && node.callee.name === 'token') {
21
+ return true;
22
+ }
23
+ }
24
+ return false;
25
+ };
26
+ export var expandBackgroundShorthand = {
27
+ meta: {
28
+ docs: {
29
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/compiled/expand-background-shorthand/'
30
+ },
31
+ messages: {
32
+ expandBackgroundShorthand: 'Use backgroundColor instead of background shorthand'
33
+ },
34
+ type: 'problem',
35
+ fixable: 'code'
36
+ },
37
+ create: function create(context) {
38
+ return {
39
+ 'Property[key.name="background"]': function PropertyKeyNameBackground(node) {
40
+ if (isCompiledAPI(context) && isTokenCallExpression(node.value)) {
41
+ context.report({
42
+ node: node,
43
+ messageId: 'expandBackgroundShorthand',
44
+ fix: function fix(fixer) {
45
+ return fixer.replaceText(node.key, "backgroundColor");
46
+ }
47
+ });
48
+ return;
49
+ }
50
+ }
51
+ };
52
+ }
53
+ };
54
+ export default expandBackgroundShorthand;
@@ -13,6 +13,9 @@ var separateBorderProperties = function separateBorderProperties(borderString, p
13
13
  if (EXCLUDED_VALUES.includes(borderString)) {
14
14
  return;
15
15
  }
16
+ if (borderString.includes('var(--')) {
17
+ return;
18
+ }
16
19
  context.report({
17
20
  node: property,
18
21
  messageId: 'expandBorderShorthand'
@@ -33,7 +36,7 @@ var isCompiledAPI = function isCompiledAPI(importDeclaration, callExpression) {
33
36
  return;
34
37
  }
35
38
  return importDeclaration.specifiers.some(function (specifier) {
36
- return specifier.type === 'ImportSpecifier' && specifier.imported.name === functionName;
39
+ return specifier.type === 'ImportSpecifier' && specifier.local.name === functionName;
37
40
  });
38
41
  };
39
42
  export var expandBorderShorthand = {
@@ -60,21 +63,11 @@ export var expandBorderShorthand = {
60
63
  if (importDeclaration) {
61
64
  if (isCompiledAPI(importDeclaration, callExpression)) {
62
65
  if (node.value.type === 'Literal' && node.value.value !== null) {
63
- if (typeof node.value.value === 'string') {
64
- var borderString = node.value.value;
66
+ var borderString = typeof node.value.value === 'string' ? node.value.value : node.value.raw;
67
+ if (borderString) {
65
68
  separateBorderProperties(borderString, node, context);
66
- } else if (node.value.raw) {
67
- var _borderString = node.value.raw;
68
- separateBorderProperties(_borderString, node, context);
69
69
  }
70
70
  } else if (node.value.type === 'TemplateLiteral') {
71
- if (node.value.quasis.length > 1 || node.value.expressions.length > 0) {
72
- context.report({
73
- node: node,
74
- messageId: 'expandBorderShorthand'
75
- });
76
- return;
77
- }
78
71
  if (node.value.quasis.length === 1 && node.value.quasis[0].value.cooked) {
79
72
  var borderQuasis = node.value.quasis[0].value.cooked;
80
73
  separateBorderProperties(borderQuasis, node, context);
@@ -9,6 +9,7 @@ export declare const rules: {
9
9
  'ensure-valid-platform-yarn-protocol-usage': import("eslint").Rule.RuleModule;
10
10
  'ensure-valid-bin-values': import("eslint").Rule.RuleModule;
11
11
  'expand-border-shorthand': import("eslint").Rule.RuleModule;
12
+ 'expand-background-shorthand': import("eslint").Rule.RuleModule;
12
13
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
13
14
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
14
15
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -46,6 +47,7 @@ export declare const configs: {
46
47
  '@atlaskit/platform/ensure-atlassian-team': string;
47
48
  '@atlaskit/platform/no-module-level-eval-nav4': string;
48
49
  '@atlaskit/platform/expand-border-shorthand': string;
50
+ '@atlaskit/platform/expand-background-shorthand': string;
49
51
  '@compiled/jsx-pragma': (string | {
50
52
  importSources: string[];
51
53
  onlyRunIfImportingCompiled: boolean;
@@ -63,6 +65,7 @@ export declare const configs: {
63
65
  '@atlaskit/platform/ensure-atlassian-team': string;
64
66
  '@atlaskit/platform/no-module-level-eval-nav4': string;
65
67
  '@atlaskit/platform/expand-border-shorthand': string;
68
+ '@atlaskit/platform/expand-background-shorthand': string;
66
69
  '@compiled/jsx-pragma': (string | {
67
70
  importSources: string[];
68
71
  onlyRunIfImportingCompiled: boolean;
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const expandBackgroundShorthand: Rule.RuleModule;
3
+ export default expandBackgroundShorthand;
@@ -9,6 +9,7 @@ export declare const rules: {
9
9
  'ensure-valid-platform-yarn-protocol-usage': import("eslint").Rule.RuleModule;
10
10
  'ensure-valid-bin-values': import("eslint").Rule.RuleModule;
11
11
  'expand-border-shorthand': import("eslint").Rule.RuleModule;
12
+ 'expand-background-shorthand': import("eslint").Rule.RuleModule;
12
13
  'no-duplicate-dependencies': import("eslint").Rule.RuleModule;
13
14
  'no-invalid-feature-flag-usage': import("eslint").Rule.RuleModule;
14
15
  'no-pre-post-install-scripts': import("eslint").Rule.RuleModule;
@@ -46,6 +47,7 @@ export declare const configs: {
46
47
  '@atlaskit/platform/ensure-atlassian-team': string;
47
48
  '@atlaskit/platform/no-module-level-eval-nav4': string;
48
49
  '@atlaskit/platform/expand-border-shorthand': string;
50
+ '@atlaskit/platform/expand-background-shorthand': string;
49
51
  '@compiled/jsx-pragma': (string | {
50
52
  importSources: string[];
51
53
  onlyRunIfImportingCompiled: boolean;
@@ -63,6 +65,7 @@ export declare const configs: {
63
65
  '@atlaskit/platform/ensure-atlassian-team': string;
64
66
  '@atlaskit/platform/no-module-level-eval-nav4': string;
65
67
  '@atlaskit/platform/expand-border-shorthand': string;
68
+ '@atlaskit/platform/expand-background-shorthand': string;
66
69
  '@compiled/jsx-pragma': (string | {
67
70
  importSources: string[];
68
71
  onlyRunIfImportingCompiled: boolean;
@@ -0,0 +1,3 @@
1
+ import type { Rule } from 'eslint';
2
+ export declare const expandBackgroundShorthand: Rule.RuleModule;
3
+ export default expandBackgroundShorthand;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-platform",
3
3
  "description": "The essential plugin for use with Atlassian frontend platform tools",
4
- "version": "0.13.1",
4
+ "version": "1.0.0",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "atlassian": {
7
7
  "team": "Build Infra",
@@ -31,6 +31,7 @@
31
31
  ".": "./src/index.tsx"
32
32
  },
33
33
  "dependencies": {
34
+ "@atlaskit/eslint-utils": "^1.7.0",
34
35
  "@babel/runtime": "^7.0.0",
35
36
  "@manypkg/find-root": "^1.1.0",
36
37
  "fuse.js": "^6.6.2",
package/src/index.tsx CHANGED
@@ -24,6 +24,7 @@ import preferFG from './rules/feature-gating/prefer-fg';
24
24
  import noAlias from './rules/feature-gating/no-alias';
25
25
  import useEntrypointsInExamples from './rules/use-entrypoints-in-examples';
26
26
  import useRecommendedUtils from './rules/feature-gating/use-recommended-utils';
27
+ import expandBackgroundShorthand from './rules/compiled/expand-background-shorthand';
27
28
 
28
29
  export const rules = {
29
30
  'ensure-feature-flag-registration': ensureFeatureFlagRegistration,
@@ -35,6 +36,7 @@ export const rules = {
35
36
  'ensure-valid-platform-yarn-protocol-usage': ensureValidPlatformYarnProtocolUsage,
36
37
  'ensure-valid-bin-values': ensureValidBinValues,
37
38
  'expand-border-shorthand': expandBorderShorthand,
39
+ 'expand-background-shorthand': expandBackgroundShorthand,
38
40
  'no-duplicate-dependencies': noDuplicateDependencies,
39
41
  'no-invalid-feature-flag-usage': noInvalidFeatureFlagUsage,
40
42
  'no-pre-post-install-scripts': noPreAndPostInstallScripts,
@@ -60,7 +62,8 @@ const commonConfig = {
60
62
  '@atlaskit/platform/ensure-atlassian-team': 'error',
61
63
  '@atlaskit/platform/no-module-level-eval-nav4': 'error',
62
64
  // Compiled: rules that are not included via `@compiled/recommended
63
- '@atlaskit/platform/expand-border-shorthand': 'warn',
65
+ '@atlaskit/platform/expand-border-shorthand': 'error',
66
+ '@atlaskit/platform/expand-background-shorthand': 'warn',
64
67
  '@compiled/jsx-pragma': [
65
68
  'error',
66
69
  {
@@ -0,0 +1,23 @@
1
+ # `expand-background-shorthand`
2
+
3
+ This ESLint rule enforces the expansion of the CSS `background` shorthand property into
4
+ its longhand equivalent `backgroundColor`, where the `background`'s value is an Atlassian
5
+ Design System color token and the function call originates from `@compiled/react` or `@atlaskit/css`.
6
+
7
+ ## Rule details
8
+
9
+ 👎 Examples of **incorrect** code for this rule:
10
+
11
+ ```js
12
+ const styles = css({
13
+ background: token('color.background.neutral.hovered'),
14
+ });
15
+ ```
16
+
17
+ 👍 Examples of **correct** code for this rule:
18
+
19
+ ```js
20
+ const styles = css({
21
+ backgroundColor: token('color.background.neutral.hovered'),
22
+ });
23
+ ```
@@ -0,0 +1,160 @@
1
+ import { outdent } from 'outdent';
2
+ import { tester } from '../../../../__tests__/utils/_tester';
3
+ import { expandBackgroundShorthand } from '../index';
4
+
5
+ const included_packages_calls_and_imports = [
6
+ ['css', 'css', '@atlaskit/css'],
7
+ ['css', 'css', '@compiled/react'],
8
+ ['styled', 'styled.div', '@compiled/react'],
9
+ ];
10
+ const exempt_packages_calls_and_imports = [
11
+ ['css', '@atlaskit/primitives'],
12
+ ['css', '@emotion'],
13
+ ['css', 'styled-components'],
14
+ ['xcss', '@atlaskit/primitives'],
15
+ ];
16
+ tester.run('expand-border-shorthand', expandBackgroundShorthand, {
17
+ valid: [
18
+ ...exempt_packages_calls_and_imports.map(([pkg, imp]) => ({
19
+ name: `do not have to handle non-Compiled packages (${pkg}, ${imp})`,
20
+ code: outdent`
21
+ import {${pkg}} from '${imp}';
22
+ const styles = ${pkg}({
23
+ background: token('color.background.accent.gray.subtlest')
24
+ });
25
+ `,
26
+ })),
27
+ {
28
+ name: 'no background shorthand',
29
+ code: outdent`
30
+ import {css} from '@compiled/react';
31
+ const styles = css({
32
+ backgroundColor: token('color.background.neutral.hovered'),
33
+ });
34
+ const styles2 = css({
35
+ backgroundColor: token('color.border', colors.N40),
36
+ });
37
+ const styles3 = css({
38
+ backgroundColor: token('color.background.inverse.subtle', '#00000029'),
39
+ });
40
+ const styles4 = css({
41
+ backgroundColor: token('color.background.brand.bold', 'lightblue'),
42
+ });
43
+ `,
44
+ },
45
+ // Other background shorthands that do not have token is out of scope for now
46
+ {
47
+ name: 'background shorthand without token',
48
+ code: outdent`
49
+ import {css} from '@compiled/react';
50
+ const styles = css({
51
+ background: 'transparent'
52
+ });
53
+ const styles2 = css({
54
+ background: url(image.png)
55
+ });
56
+ const styles3 = css({
57
+ background: 0
58
+ });
59
+ `,
60
+ },
61
+ // Usages of token within a template string are not used, so ESLint rule does not handle this case
62
+ {
63
+ name: 'background shorthand in a template literal as string text',
64
+ code: outdent`
65
+ import {css} from '@compiled/react';
66
+ const styles = css({
67
+ background: \`token('color.background.brand.bold', 'lightblue')\`,
68
+ });
69
+ `,
70
+ },
71
+ {
72
+ name: 'background as key in cssMap call (cssMap, @compiled/react)',
73
+ code: outdent`
74
+ import { cssMap } from '@compiled/react';
75
+ const colorMap = cssMap({
76
+ background: {
77
+ color: token('some.token')
78
+ },
79
+ foreground: {
80
+ color: token('some.other.token')
81
+ },
82
+ });
83
+ `,
84
+ },
85
+ ],
86
+ invalid: [
87
+ ...included_packages_calls_and_imports.map(([pkg, call, imp]) => ({
88
+ name: `simple case (${call}, ${imp})`,
89
+ code: outdent`
90
+ import {${pkg}} from '${imp}';
91
+ const styles = ${call}({
92
+ background: token('color.background.accent.gray.subtlest'),
93
+ });
94
+ `,
95
+ output: outdent`
96
+ import {${pkg}} from '${imp}';
97
+ const styles = ${call}({
98
+ backgroundColor: token('color.background.accent.gray.subtlest'),
99
+ });
100
+ `,
101
+ errors: [{ messageId: 'expandBackgroundShorthand' }],
102
+ })),
103
+ {
104
+ name: `simple case (styled, @compiled/react)`,
105
+ code: outdent`
106
+ import { styled } from '@compiled/react';
107
+ const Button = styled.div({
108
+ paddingTop: '10px',
109
+ });
110
+ const StyledButton = styled(Button)({
111
+ background: token('elevation.surface', colors.N0),
112
+ });
113
+ `,
114
+ output: outdent`
115
+ import { styled } from '@compiled/react';
116
+ const Button = styled.div({
117
+ paddingTop: '10px',
118
+ });
119
+ const StyledButton = styled(Button)({
120
+ backgroundColor: token('elevation.surface', colors.N0),
121
+ });
122
+ `,
123
+ errors: [{ messageId: 'expandBackgroundShorthand' }],
124
+ },
125
+ {
126
+ name: `simple case (cssMap, @compiled/react)`,
127
+ code: outdent`
128
+ import { cssMap } from '@compiled/react';
129
+ const backgroundMap = cssMap({
130
+ firstBackground: { background: token('some.token') },
131
+ secondBackground: { background: token('some.other.token') },
132
+ });
133
+ `,
134
+ output: outdent`
135
+ import { cssMap } from '@compiled/react';
136
+ const backgroundMap = cssMap({
137
+ firstBackground: { backgroundColor: token('some.token') },
138
+ secondBackground: { backgroundColor: token('some.other.token') },
139
+ });
140
+ `,
141
+ errors: Array.from(Array(2), () => ({ messageId: 'expandBackgroundShorthand' })),
142
+ },
143
+ {
144
+ name: `compiled import with alias`,
145
+ code: outdent`
146
+ import { styled as styled2 } from '@compiled/react';
147
+ const style = styled2.span({
148
+ background: token('color.background.neutral.subtle', '#fff'),
149
+ });
150
+ `,
151
+ output: outdent`
152
+ import { styled as styled2 } from '@compiled/react';
153
+ const style = styled2.span({
154
+ backgroundColor: token('color.background.neutral.subtle', '#fff'),
155
+ });
156
+ `,
157
+ errors: [{ messageId: 'expandBackgroundShorthand' }],
158
+ },
159
+ ],
160
+ });
@@ -0,0 +1,67 @@
1
+ import type { Rule } from 'eslint';
2
+ import type { Property, Node } from 'estree';
3
+ import {
4
+ getImportSources,
5
+ isCompiled,
6
+ isAtlasKitCSS,
7
+ } from '@atlaskit/eslint-utils/is-supported-import';
8
+
9
+ // Checks if the function that holds the border property is using an import package that this rule is targeting
10
+ const isCompiledAPI = (context: Rule.RuleContext): boolean => {
11
+ const importSources = getImportSources(context);
12
+ const { references } = context.getScope();
13
+ const ancestors = context.getAncestors();
14
+ if (
15
+ ancestors.some(
16
+ (ancestor) =>
17
+ ancestor.type === 'CallExpression' &&
18
+ ancestor.callee &&
19
+ (isCompiled(ancestor.callee, references, importSources) ||
20
+ isAtlasKitCSS(ancestor.callee, references, importSources)),
21
+ )
22
+ ) {
23
+ return true;
24
+ }
25
+ return false;
26
+ };
27
+
28
+ // Checks if node is a call expression with identifier 'token'
29
+ const isTokenCallExpression = (node: Node) => {
30
+ if (node.type === 'CallExpression') {
31
+ if (node.callee.type === 'Identifier' && node.callee.name === 'token') {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ };
37
+
38
+ export const expandBackgroundShorthand: Rule.RuleModule = {
39
+ meta: {
40
+ docs: {
41
+ url: 'https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/master/platform/packages/platform/eslint-plugin/src/rules/compiled/expand-background-shorthand/',
42
+ },
43
+ messages: {
44
+ expandBackgroundShorthand: 'Use backgroundColor instead of background shorthand',
45
+ },
46
+ type: 'problem',
47
+ fixable: 'code',
48
+ },
49
+ create(context) {
50
+ return {
51
+ 'Property[key.name="background"]': function (node: Property) {
52
+ if (isCompiledAPI(context) && isTokenCallExpression(node.value)) {
53
+ context.report({
54
+ node,
55
+ messageId: 'expandBackgroundShorthand',
56
+ fix(fixer) {
57
+ return fixer.replaceText(node.key, `backgroundColor`);
58
+ },
59
+ });
60
+ return;
61
+ }
62
+ },
63
+ };
64
+ },
65
+ };
66
+
67
+ export default expandBackgroundShorthand;
@@ -1,6 +1,6 @@
1
1
  # `shorthand-property-sorting`
2
2
 
3
- This ESLint rule enforces the expansion of CSS `border` shorthand property, into it's longhand
3
+ This ESLint rule enforces the expansion of CSS `border` shorthand property, into its longhand
4
4
  equivalents `borderStyle`, `borderWidth`, `borderColor`, for packages that originates from
5
5
  `@compiled/react`, and `@atlaskit/css`.
6
6
 
@@ -3,15 +3,13 @@ import { outdent } from 'outdent';
3
3
  import { tester } from '../../../../__tests__/utils/_tester';
4
4
  import { expandBorderShorthand } from '../index';
5
5
 
6
- const valid_packages_calls_and_imports = [
6
+ const included_packages_calls_and_imports = [
7
7
  ['css', 'css', '@atlaskit/css'],
8
8
  ['css', 'css', '@compiled/react'],
9
9
  ['styled', 'styled.div', '@compiled/react'],
10
- ['cssMap', 'cssMap', '@atlaskit/css'],
11
- ['cssMap', 'cssMap', '@compiled/react'],
12
10
  ];
13
11
 
14
- const invalid_packages_calls_and_imports = [
12
+ const exempt_packages_calls_and_imports = [
15
13
  ['css', '@atlaskit/primitives'],
16
14
  ['css', '@emotion'],
17
15
  ['css', 'styled-components'],
@@ -19,8 +17,8 @@ const invalid_packages_calls_and_imports = [
19
17
 
20
18
  tester.run('expand-border-shorthand', expandBorderShorthand, {
21
19
  valid: [
22
- ...invalid_packages_calls_and_imports.map(([pkg, imp]) => ({
23
- name: `incorrect packages (${pkg}, ${imp})`,
20
+ ...exempt_packages_calls_and_imports.map(([pkg, imp]) => ({
21
+ name: `handle only Compiled APIs (${pkg}, ${imp})`,
24
22
  code: outdent`
25
23
  import {${pkg}} from '${imp}';
26
24
 
@@ -30,13 +28,18 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
30
28
  `,
31
29
  })),
32
30
  {
33
- name: 'references correct package',
31
+ name: 'CallExpression matches with imported API',
34
32
  code: outdent`
35
- import {css} from '@compiled/react';
33
+ import { styled } from 'styled-components';
34
+ import { styled as styled2, css as compiledCSS, jsx } from '@compiled/react';
36
35
 
37
36
  const styles = xcss({
38
37
  border: '1px solid red',
39
38
  });
39
+
40
+ const styles2 = styled.div({
41
+ border: '1px solid red',
42
+ });
40
43
  `,
41
44
  },
42
45
  {
@@ -71,6 +74,17 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
71
74
  const styles9 = css({
72
75
  border: 0,
73
76
  });
77
+ const styles10 = css({
78
+ border: 'var(--icon-border)',
79
+ });
80
+ const styles11 = css({
81
+ border: \`\${(props: { border?: boolean }) =>
82
+ props.border ? \`1px solid \${token('color.border.disabled', colors.N30)}\` : 'none'}\`,
83
+ });
84
+ const styles12 = css({
85
+ border: (props: { border?: boolean }) =>
86
+ props.border ? token('color.border.disabled', colors.N30) : 'none',
87
+ });
74
88
  `,
75
89
  },
76
90
  {
@@ -91,9 +105,20 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
91
105
  });
92
106
  `,
93
107
  },
108
+ {
109
+ name: 'cssMap case where border is assigned an ObjectExpression',
110
+ code: outdent`
111
+ import { cssMap } from '@compiled/react';
112
+
113
+ const borderStyleMap = cssMap({
114
+ none: { borderStyle: 'none' },
115
+ border: { borderStyle: 'solid' },
116
+ });
117
+ `,
118
+ },
94
119
  ],
95
120
  invalid: [
96
- ...valid_packages_calls_and_imports.map(([pkg, call, imp]) => ({
121
+ ...included_packages_calls_and_imports.map(([pkg, call, imp]) => ({
97
122
  name: `simple case (${call}, ${imp})`,
98
123
  code: outdent`
99
124
  import {${pkg}} from '${imp}';
@@ -147,14 +172,6 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
147
172
  border: \`1px solid red\`,
148
173
  })
149
174
 
150
- const styles2 = css({
151
- border: \`1px solid \${token('red')}\`,
152
- })
153
-
154
- const styles3 = css({
155
- border: \`1px \${solid} red\`,
156
- })
157
-
158
175
  const styles4 = css({
159
176
  border: \`1px red\`,
160
177
  })
@@ -162,12 +179,8 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
162
179
  const styles5 = css({
163
180
  border: \`1px\`,
164
181
  })
165
-
166
- const styles6 = css({
167
- border: \` \${token('red')}\`,
168
- })
169
182
  `,
170
- errors: Array.from(Array(6), () => ({ messageId: 'expandBorderShorthand' })),
183
+ errors: Array.from(Array(3), () => ({ messageId: 'expandBorderShorthand' })),
171
184
  },
172
185
  {
173
186
  name: 'tokens',
@@ -182,5 +195,17 @@ tester.run('expand-border-shorthand', expandBorderShorthand, {
182
195
  `,
183
196
  errors: Array.from(Array(2), () => ({ messageId: 'expandBorderShorthand' })),
184
197
  },
198
+ {
199
+ name: 'cssMap case where border is assigned an a Literal',
200
+ code: outdent`
201
+ import { cssMap } from '@compiled/react';
202
+
203
+ const borderStyleMap = cssMap({
204
+ none: { border: 'none' },
205
+ solid: { border: '1px solid blue' },
206
+ });
207
+ `,
208
+ errors: [{ messageId: 'expandBorderShorthand' }],
209
+ },
185
210
  ],
186
211
  });
@@ -22,6 +22,9 @@ const separateBorderProperties = (
22
22
  if (EXCLUDED_VALUES.includes(borderString)) {
23
23
  return;
24
24
  }
25
+ if (borderString.includes('var(--')) {
26
+ return;
27
+ }
25
28
 
26
29
  context.report({
27
30
  node: property,
@@ -44,7 +47,7 @@ const isCompiledAPI = (importDeclaration: ImportDeclaration, callExpression: Cal
44
47
  }
45
48
 
46
49
  return importDeclaration.specifiers.some(
47
- (specifier) => specifier.type === 'ImportSpecifier' && specifier.imported.name === functionName,
50
+ (specifier) => specifier.type === 'ImportSpecifier' && specifier.local.name === functionName,
48
51
  );
49
52
  };
50
53
 
@@ -74,21 +77,12 @@ export const expandBorderShorthand: Rule.RuleModule = {
74
77
  if (importDeclaration) {
75
78
  if (isCompiledAPI(importDeclaration, callExpression)) {
76
79
  if (node.value.type === 'Literal' && node.value.value !== null) {
77
- if (typeof node.value.value === 'string') {
78
- const borderString = node.value.value;
79
- separateBorderProperties(borderString, node, context);
80
- } else if (node.value.raw) {
81
- const borderString = node.value.raw;
80
+ const borderString =
81
+ typeof node.value.value === 'string' ? node.value.value : node.value.raw;
82
+ if (borderString) {
82
83
  separateBorderProperties(borderString, node, context);
83
84
  }
84
85
  } else if (node.value.type === 'TemplateLiteral') {
85
- if (node.value.quasis.length > 1 || node.value.expressions.length > 0) {
86
- context.report({
87
- node,
88
- messageId: 'expandBorderShorthand',
89
- });
90
- return;
91
- }
92
86
  if (node.value.quasis.length === 1 && node.value.quasis[0].value.cooked) {
93
87
  const borderQuasis: string = node.value.quasis[0].value.cooked;
94
88
  separateBorderProperties(borderQuasis, node, context);
package/tsconfig.dev.json CHANGED
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "references": [
36
36
  {
37
- "path": "tsconfig.app.json"
37
+ "path": "./tsconfig.app.json"
38
38
  }
39
39
  ],
40
40
  "files": []