@atlaskit/eslint-plugin-design-system 9.2.5 → 9.3.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +1 -0
  3. package/constellation/index/usage.mdx +1 -0
  4. package/constellation/use-heading/usage.mdx +28 -0
  5. package/dist/cjs/ast-nodes/root.js +32 -0
  6. package/dist/cjs/presets/all.codegen.js +2 -1
  7. package/dist/cjs/rules/index.codegen.js +3 -1
  8. package/dist/cjs/rules/use-heading/config/index.js +15 -0
  9. package/dist/cjs/rules/use-heading/index.js +39 -0
  10. package/dist/cjs/rules/use-heading/transformers/common.js +19 -0
  11. package/dist/cjs/rules/use-heading/transformers/index.js +12 -0
  12. package/dist/cjs/rules/use-heading/transformers/native-elements.js +99 -0
  13. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
  14. package/dist/cjs/rules/use-primitives/transformers/emotion-css/index.js +1 -2
  15. package/dist/cjs/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
  16. package/dist/cjs/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
  17. package/dist/cjs/rules/use-primitives-text/transformers/span-elements.js +1 -2
  18. package/dist/cjs/rules/use-primitives-text/transformers/strong-elements.js +1 -2
  19. package/dist/cjs/rules/use-tokens-space/transformers/style-property/index.js +1 -2
  20. package/dist/cjs/rules/utils/create-rule.js +4 -7
  21. package/dist/es2019/ast-nodes/root.js +34 -0
  22. package/dist/es2019/presets/all.codegen.js +2 -1
  23. package/dist/es2019/rules/index.codegen.js +3 -1
  24. package/dist/es2019/rules/use-heading/config/index.js +9 -0
  25. package/dist/es2019/rules/use-heading/index.js +33 -0
  26. package/dist/es2019/rules/use-heading/transformers/common.js +9 -0
  27. package/dist/es2019/rules/use-heading/transformers/index.js +1 -0
  28. package/dist/es2019/rules/use-heading/transformers/native-elements.js +89 -0
  29. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
  30. package/dist/es2019/rules/use-primitives/transformers/emotion-css/index.js +1 -2
  31. package/dist/es2019/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
  32. package/dist/es2019/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
  33. package/dist/es2019/rules/use-primitives-text/transformers/span-elements.js +1 -2
  34. package/dist/es2019/rules/use-primitives-text/transformers/strong-elements.js +1 -2
  35. package/dist/es2019/rules/use-tokens-space/transformers/style-property/index.js +1 -2
  36. package/dist/es2019/rules/utils/create-rule.js +4 -6
  37. package/dist/esm/ast-nodes/root.js +32 -0
  38. package/dist/esm/presets/all.codegen.js +2 -1
  39. package/dist/esm/rules/index.codegen.js +3 -1
  40. package/dist/esm/rules/use-heading/config/index.js +9 -0
  41. package/dist/esm/rules/use-heading/index.js +33 -0
  42. package/dist/esm/rules/use-heading/transformers/common.js +9 -0
  43. package/dist/esm/rules/use-heading/transformers/index.js +1 -0
  44. package/dist/esm/rules/use-heading/transformers/native-elements.js +89 -0
  45. package/dist/esm/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
  46. package/dist/esm/rules/use-primitives/transformers/emotion-css/index.js +1 -2
  47. package/dist/esm/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
  48. package/dist/esm/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
  49. package/dist/esm/rules/use-primitives-text/transformers/span-elements.js +1 -2
  50. package/dist/esm/rules/use-primitives-text/transformers/strong-elements.js +1 -2
  51. package/dist/esm/rules/use-tokens-space/transformers/style-property/index.js +1 -2
  52. package/dist/esm/rules/utils/create-rule.js +4 -6
  53. package/dist/types/ast-nodes/jsx-element.d.ts +2 -2
  54. package/dist/types/ast-nodes/root.d.ts +8 -0
  55. package/dist/types/index.codegen.d.ts +1 -0
  56. package/dist/types/presets/all.codegen.d.ts +2 -1
  57. package/dist/types/rules/ensure-design-token-usage/rule-meta.d.ts +1 -1
  58. package/dist/types/rules/index.codegen.d.ts +1 -0
  59. package/dist/types/rules/use-heading/config/index.d.ts +6 -0
  60. package/dist/types/rules/use-heading/index.d.ts +3 -0
  61. package/dist/types/rules/use-heading/transformers/common.d.ts +9 -0
  62. package/dist/types/rules/use-heading/transformers/index.d.ts +1 -0
  63. package/dist/types/rules/use-heading/transformers/native-elements.d.ts +18 -0
  64. package/dist/types/rules/utils/create-rule.d.ts +1 -37
  65. package/dist/types-ts4.5/ast-nodes/jsx-element.d.ts +2 -2
  66. package/dist/types-ts4.5/ast-nodes/root.d.ts +8 -0
  67. package/dist/types-ts4.5/index.codegen.d.ts +1 -0
  68. package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
  69. package/dist/types-ts4.5/rules/ensure-design-token-usage/rule-meta.d.ts +1 -1
  70. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
  71. package/dist/types-ts4.5/rules/use-heading/config/index.d.ts +6 -0
  72. package/dist/types-ts4.5/rules/use-heading/index.d.ts +3 -0
  73. package/dist/types-ts4.5/rules/use-heading/transformers/common.d.ts +9 -0
  74. package/dist/types-ts4.5/rules/use-heading/transformers/index.d.ts +1 -0
  75. package/dist/types-ts4.5/rules/use-heading/transformers/native-elements.d.ts +18 -0
  76. package/dist/types-ts4.5/rules/utils/create-rule.d.ts +1 -37
  77. package/package.json +2 -2
  78. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -37
  79. package/dist/cjs/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -37
  80. package/dist/cjs/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -37
  81. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -30
  82. package/dist/es2019/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -30
  83. package/dist/es2019/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -30
  84. package/dist/esm/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -29
  85. package/dist/esm/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -29
  86. package/dist/esm/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -29
  87. package/dist/types/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +0 -14
  88. package/dist/types/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +0 -14
  89. package/dist/types/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +0 -14
  90. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +0 -14
  91. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +0 -14
  92. package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +0 -14
@@ -0,0 +1,33 @@
1
+ import { createLintRule } from '../utils/create-rule';
2
+ import { getConfig } from './config';
3
+ import { NativeElements } from './transformers';
4
+ const docsUrl = 'https://atlassian.design/components/heading';
5
+ const rule = createLintRule({
6
+ meta: {
7
+ name: 'use-heading',
8
+ type: 'suggestion',
9
+ fixable: 'code',
10
+ hasSuggestions: true,
11
+ docs: {
12
+ description: 'Encourage the usage of heading components.',
13
+ recommended: false,
14
+ severity: 'warn'
15
+ },
16
+ messages: {
17
+ preferHeading: `This element can be replaced with a "Heading" component. See ${docsUrl} for additional guidance.`
18
+ }
19
+ },
20
+ create(context) {
21
+ const config = getConfig(context.options[0]);
22
+ return {
23
+ // transforms <h1>...</h1> usages
24
+ 'JSXElement[openingElement.name.name=/^h[0-6]$/]': node => {
25
+ return NativeElements.lint(node, {
26
+ context,
27
+ config
28
+ });
29
+ }
30
+ };
31
+ }
32
+ });
33
+ export default rule;
@@ -0,0 +1,9 @@
1
+ import * as ast from '../../../ast-nodes';
2
+ // Rename data-testid prop to testId if present
3
+ export function updateTestIdAttributeFix(node, fixer) {
4
+ const testIdAttr = ast.JSXElement.getAttributeByName(node, 'data-testid');
5
+ if (testIdAttr) {
6
+ return ast.JSXAttribute.updateName(testIdAttr, 'testId', fixer);
7
+ }
8
+ }
9
+ export const allowedAttrs = ['id', 'data-testid', 'key'];
@@ -0,0 +1 @@
1
+ export { NativeElements } from './native-elements';
@@ -0,0 +1,89 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ import * as ast from '../../../ast-nodes';
5
+ import { allowedAttrs, updateTestIdAttributeFix } from './common';
6
+ const tagSizeMap = {
7
+ h1: 'xlarge',
8
+ h2: 'large',
9
+ h3: 'medium',
10
+ h4: 'small',
11
+ h5: 'xsmall',
12
+ h6: 'xxsmall'
13
+ };
14
+ export const NativeElements = {
15
+ lint(node, {
16
+ context,
17
+ config
18
+ }) {
19
+ // Check whether all criteria needed to make a transformation are met
20
+ if (!NativeElements._check(node, {
21
+ context,
22
+ config
23
+ })) {
24
+ return;
25
+ }
26
+ context.report({
27
+ node,
28
+ messageId: 'preferHeading',
29
+ suggest: [{
30
+ desc: 'Convert to Heading',
31
+ fix: NativeElements._fix(node, {
32
+ context,
33
+ config
34
+ })
35
+ }]
36
+ });
37
+ },
38
+ _check(node, {
39
+ config
40
+ }) {
41
+ if (!config.patterns.includes('native-elements')) {
42
+ return false;
43
+ }
44
+ if (!isNodeOfType(node, 'JSXElement')) {
45
+ return false;
46
+ }
47
+ if (!node.parent) {
48
+ return false;
49
+ }
50
+ const elementName = ast.JSXElement.getName(node);
51
+ if (!Object.keys(tagSizeMap).includes(elementName)) {
52
+ return false;
53
+ }
54
+
55
+ // Element has to be first element of its siblings
56
+ if (!(isNodeOfType(node.parent, 'JSXElement') || isNodeOfType(node.parent, 'JSXFragment'))) {
57
+ return false;
58
+ }
59
+ const siblings = ast.JSXElement.getChildren(node.parent);
60
+ if (siblings.length > 1) {
61
+ var _siblings$0$range, _node$range, _siblings$0$range2, _node$range2;
62
+ // Only report if element is first child element
63
+ if (((_siblings$0$range = siblings[0].range) === null || _siblings$0$range === void 0 ? void 0 : _siblings$0$range[0]) !== ((_node$range = node.range) === null || _node$range === void 0 ? void 0 : _node$range[0]) || ((_siblings$0$range2 = siblings[0].range) === null || _siblings$0$range2 === void 0 ? void 0 : _siblings$0$range2[1]) !== ((_node$range2 = node.range) === null || _node$range2 === void 0 ? void 0 : _node$range2[1])) {
64
+ return false;
65
+ }
66
+ }
67
+ if (!ast.JSXElement.hasAllowedAttrsOnly(node, allowedAttrs)) {
68
+ return false;
69
+ }
70
+ return true;
71
+ },
72
+ _fix(node, {
73
+ context
74
+ }) {
75
+ return fixer => {
76
+ // change to default import
77
+ const importFix = ast.Root.upsertDefaultImportDeclaration({
78
+ module: '@atlaskit/heading',
79
+ localName: 'Heading'
80
+ }, context, fixer);
81
+ const elementName = ast.JSXElement.getName(node);
82
+ const elementNameFixes = ast.JSXElement.updateName(node, 'Heading', fixer);
83
+ const size = tagSizeMap[elementName];
84
+ const asAttributeFix = ast.JSXElement.addAttribute(node, 'size', size, fixer);
85
+ const testAttributeFix = updateTestIdAttributeFix(node, fixer);
86
+ return [importFix, ...elementNameFixes, asAttributeFix, testAttributeFix].filter(fix => Boolean(fix)); // Some of the transformers can return arrays with undefined, so filter them out
87
+ };
88
+ }
89
+ };
@@ -8,7 +8,6 @@ import { convertJsxCallSite } from './convert-jsx-call-site';
8
8
  import { convertStyledComponentToXcss } from './convert-styled-component-call-to-jsx';
9
9
  import { findValidJsxUsageToTransform } from './find-valid-jsx-usage-to-transform';
10
10
  import { findValidStyledComponentCall } from './find-valid-styled-component-call';
11
- import { upsertImportDeclaration } from './upsert-import-declaration';
12
11
  export const CompiledStyled = {
13
12
  lint(node, {
14
13
  context,
@@ -97,7 +96,7 @@ export const CompiledStyled = {
97
96
  if (!calculatedStylesVariableName) {
98
97
  return [];
99
98
  }
100
- const importFixes = upsertImportDeclaration({
99
+ const importFixes = ast.Root.upsertNamedImportDeclaration({
101
100
  module: '@atlaskit/primitives',
102
101
  specifiers: ['Box', 'xcss']
103
102
  }, context, fixer);
@@ -6,7 +6,6 @@ import { getVariableDefinitionValue, getVariableUsagesCount, isValidCssPropertie
6
6
  import { validateStyles } from '../../utils/validate-styles';
7
7
  import { cssToXcssTransformer } from '../css-to-xcss';
8
8
  import * as supported from './supported';
9
- import { upsertImportDeclaration } from './upsert-import-declaration';
10
9
  export const EmotionCSS = {
11
10
  lint(node, {
12
11
  context,
@@ -100,7 +99,7 @@ export const EmotionCSS = {
100
99
  context
101
100
  }) {
102
101
  return fixer => {
103
- const importFix = upsertImportDeclaration({
102
+ const importFix = ast.Root.upsertNamedImportDeclaration({
104
103
  module: '@atlaskit/primitives',
105
104
  specifiers: ['Box', 'xcss']
106
105
  }, context, fixer);
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { isNodeOfType } from 'eslint-codemod-utils';
4
4
  import * as ast from '../../../ast-nodes';
5
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
6
5
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
7
6
  export const EmphasisElements = {
8
7
  lint(node, {
@@ -61,7 +60,7 @@ export const EmphasisElements = {
61
60
  config
62
61
  }) {
63
62
  return fixer => {
64
- const importFix = upsertImportDeclaration({
63
+ const importFix = ast.Root.upsertNamedImportDeclaration({
65
64
  module: '@atlaskit/primitives',
66
65
  specifiers: ['Text']
67
66
  }, context, fixer);
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { isNodeOfType } from 'eslint-codemod-utils';
4
4
  import * as ast from '../../../ast-nodes';
5
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
6
5
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
7
6
  export const ParagraphElements = {
8
7
  lint(node, {
@@ -155,7 +154,7 @@ export const ParagraphElements = {
155
154
  config
156
155
  }) {
157
156
  return fixer => {
158
- const importFix = upsertImportDeclaration({
157
+ const importFix = ast.Root.upsertNamedImportDeclaration({
159
158
  module: '@atlaskit/primitives',
160
159
  specifiers: ['Text']
161
160
  }, context, fixer);
@@ -175,7 +174,7 @@ export const ParagraphElements = {
175
174
  if (!isNodeOfType(node.parent, 'JSXElement') || !node.parent.closingElement) {
176
175
  return [];
177
176
  }
178
- const importFix = upsertImportDeclaration({
177
+ const importFix = ast.Root.upsertNamedImportDeclaration({
179
178
  module: '@atlaskit/primitives',
180
179
  specifiers: ['Text', 'Stack']
181
180
  }, context, fixer);
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { isNodeOfType } from 'eslint-codemod-utils';
4
4
  import * as ast from '../../../ast-nodes';
5
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
6
5
  import { addColorInheritAttributeFix, allowedAttrs, hasTextChildrenOnly, updateTestIdAttributeFix } from './common';
7
6
  export const SpanElements = {
8
7
  lint(node, {
@@ -66,7 +65,7 @@ export const SpanElements = {
66
65
  config
67
66
  }) {
68
67
  return fixer => {
69
- const importFix = upsertImportDeclaration({
68
+ const importFix = ast.Root.upsertNamedImportDeclaration({
70
69
  module: '@atlaskit/primitives',
71
70
  specifiers: ['Text']
72
71
  }, context, fixer);
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { isNodeOfType } from 'eslint-codemod-utils';
4
4
  import * as ast from '../../../ast-nodes';
5
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
6
5
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
7
6
  export const StrongElements = {
8
7
  lint(node, {
@@ -61,7 +60,7 @@ export const StrongElements = {
61
60
  config
62
61
  }) {
63
62
  return fixer => {
64
- const importFix = upsertImportDeclaration({
63
+ const importFix = ast.Root.upsertNamedImportDeclaration({
65
64
  module: '@atlaskit/primitives',
66
65
  specifiers: ['Text']
67
66
  }, context, fixer);
@@ -5,7 +5,6 @@ import * as ast from '../../../../ast-nodes';
5
5
  import { isStringOrNumber } from '../../utils';
6
6
  import { styleMap } from './style-map';
7
7
  import supported from './supported';
8
- import { upsertImportDeclaration } from './upsert-import-declaration';
9
8
  const messageId = 'noRawSpacingValues';
10
9
  export const StyleProperty = {
11
10
  lint(node, {
@@ -109,7 +108,7 @@ export const StyleProperty = {
109
108
  */
110
109
  _fix(ref, context) {
111
110
  return fixer => {
112
- const importFix = upsertImportDeclaration({
111
+ const importFix = ast.Root.upsertNamedImportDeclaration({
113
112
  module: '@atlaskit/tokens',
114
113
  specifiers: ['token']
115
114
  }, context, fixer);
@@ -1,5 +1,5 @@
1
1
  import { ESLintUtils } from '@typescript-eslint/utils';
2
- // eslint-disable-next-line import/no-extraneous-dependencies
2
+ import { getCreateLintRule, getPathSafeName } from '@atlaskit/eslint-utils/create-rule';
3
3
 
4
4
  /**
5
5
  * We are moving to our own small abstraction to create a lint rule that we have the power
@@ -11,16 +11,14 @@ import { ESLintUtils } from '@typescript-eslint/utils';
11
11
  * @deprecated
12
12
  */
13
13
  export const createRule = ESLintUtils.RuleCreator(name => getRuleUrl(name));
14
+
14
15
  /**
15
16
  * Tiny wrapped over the ESLint rule module type that ensures
16
17
  * there is a docs link to our ESLint plugin documentation page,
17
18
  * as well as improving type support.
18
19
  */
19
- export const createLintRule = rule => {
20
- rule.meta.docs.url = getRuleUrl(rule.meta.name);
21
- return rule;
22
- };
20
+ export const createLintRule = getCreateLintRule(getRuleUrl);
23
21
  function getRuleUrl(ruleName) {
24
- const name = ruleName.replace('/', '-'); // If it's a nested rule, ensure the url is clean and matches codegen/gatsby
22
+ const name = getPathSafeName(ruleName);
25
23
  return `https://atlassian.design/components/eslint-plugin-design-system/${name}/usage`;
26
24
  }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable @repo/internal/react/require-jsdoc */
2
2
 
3
3
  import { hasImportDeclaration, insertImportDeclaration, isNodeOfType } from 'eslint-codemod-utils';
4
+ import { Import } from './import';
4
5
  // Little bit unreadable, but better than duplicating the type
5
6
 
6
7
  export var Root = {
@@ -24,5 +25,36 @@ export var Root = {
24
25
  },
25
26
  insertImport: function insertImport(root, data, fixer) {
26
27
  return fixer.insertTextBefore(root[0], "".concat(insertImportDeclaration(data.module, data.specifiers), ";\n"));
28
+ },
29
+ upsertNamedImportDeclaration: function upsertNamedImportDeclaration(_ref, context, fixer) {
30
+ var module = _ref.module,
31
+ specifiers = _ref.specifiers;
32
+ // Find any imports that match the packageName
33
+ var root = context.getSourceCode().ast.body;
34
+ var importDeclarations = this.findImportsByModule(root, module);
35
+
36
+ // The named import doesn't exist yet, we can just insert a whole new one
37
+ if (importDeclarations.length === 0) {
38
+ return this.insertImport(root, {
39
+ module: module,
40
+ specifiers: specifiers
41
+ }, fixer);
42
+ }
43
+
44
+ // The import exists so, modify the existing one
45
+ return Import.insertNamedSpecifiers(importDeclarations[0], specifiers, fixer);
46
+ },
47
+ upsertDefaultImportDeclaration: function upsertDefaultImportDeclaration(_ref2, context, fixer) {
48
+ var module = _ref2.module,
49
+ localName = _ref2.localName;
50
+ // Find any imports that match the packageName
51
+ var root = context.getSourceCode().ast.body;
52
+ var importDeclarations = this.findImportsByModule(root, module);
53
+
54
+ // The import already exist exist
55
+ if (importDeclarations.length > 0) {
56
+ return undefined;
57
+ }
58
+ return fixer.insertTextBefore(root[0], "import ".concat(localName, " from '").concat(module, "';\n"));
27
59
  }
28
60
  };
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
- * @codegen <<SignedSource::d95217b658f807294de3c81123068bf1>>
3
+ * @codegen <<SignedSource::2e2cf6c0ecfe1b01f3eb24caa223f09e>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  export default {
@@ -31,6 +31,7 @@ export default {
31
31
  '@atlaskit/design-system/prefer-primitives': 'warn',
32
32
  '@atlaskit/design-system/use-button-group-label': 'warn',
33
33
  '@atlaskit/design-system/use-drawer-label': 'warn',
34
+ '@atlaskit/design-system/use-heading': 'warn',
34
35
  '@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
35
36
  '@atlaskit/design-system/use-href-in-link-item': 'warn',
36
37
  '@atlaskit/design-system/use-primitives': 'warn',
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
3
- * @codegen <<SignedSource::d1c25758089a050334359276ede0ca3a>>
3
+ * @codegen <<SignedSource::eb5c94901f711e67446ba88f0630bf76>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import consistentCssPropUsage from './consistent-css-prop-usage';
@@ -28,6 +28,7 @@ import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-li
28
28
  import preferPrimitives from './prefer-primitives';
29
29
  import useButtonGroupLabel from './use-button-group-label';
30
30
  import useDrawerLabel from './use-drawer-label';
31
+ import useHeading from './use-heading';
31
32
  import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
32
33
  import useHrefInLinkItem from './use-href-in-link-item';
33
34
  import usePrimitives from './use-primitives';
@@ -61,6 +62,7 @@ export default {
61
62
  'prefer-primitives': preferPrimitives,
62
63
  'use-button-group-label': useButtonGroupLabel,
63
64
  'use-drawer-label': useDrawerLabel,
65
+ 'use-heading': useHeading,
64
66
  'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
65
67
  'use-href-in-link-item': useHrefInLinkItem,
66
68
  'use-primitives': usePrimitives,
@@ -0,0 +1,9 @@
1
+ var defaults = {
2
+ patterns: ['native-elements']
3
+ };
4
+ export var getConfig = function getConfig(overrides) {
5
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
6
+ // start with an empty object, then merge in the defaults, then merge in overrides.
7
+ // The empty object is returned, as well as modified in place
8
+ return Object.assign({}, defaults, overrides);
9
+ };
@@ -0,0 +1,33 @@
1
+ import { createLintRule } from '../utils/create-rule';
2
+ import { getConfig } from './config';
3
+ import { NativeElements } from './transformers';
4
+ var docsUrl = 'https://atlassian.design/components/heading';
5
+ var rule = createLintRule({
6
+ meta: {
7
+ name: 'use-heading',
8
+ type: 'suggestion',
9
+ fixable: 'code',
10
+ hasSuggestions: true,
11
+ docs: {
12
+ description: 'Encourage the usage of heading components.',
13
+ recommended: false,
14
+ severity: 'warn'
15
+ },
16
+ messages: {
17
+ preferHeading: "This element can be replaced with a \"Heading\" component. See ".concat(docsUrl, " for additional guidance.")
18
+ }
19
+ },
20
+ create: function create(context) {
21
+ var config = getConfig(context.options[0]);
22
+ return {
23
+ // transforms <h1>...</h1> usages
24
+ 'JSXElement[openingElement.name.name=/^h[0-6]$/]': function JSXElementOpeningElementNameNameH06$(node) {
25
+ return NativeElements.lint(node, {
26
+ context: context,
27
+ config: config
28
+ });
29
+ }
30
+ };
31
+ }
32
+ });
33
+ export default rule;
@@ -0,0 +1,9 @@
1
+ import * as ast from '../../../ast-nodes';
2
+ // Rename data-testid prop to testId if present
3
+ export function updateTestIdAttributeFix(node, fixer) {
4
+ var testIdAttr = ast.JSXElement.getAttributeByName(node, 'data-testid');
5
+ if (testIdAttr) {
6
+ return ast.JSXAttribute.updateName(testIdAttr, 'testId', fixer);
7
+ }
8
+ }
9
+ export var allowedAttrs = ['id', 'data-testid', 'key'];
@@ -0,0 +1 @@
1
+ export { NativeElements } from './native-elements';
@@ -0,0 +1,89 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ /* eslint-disable @repo/internal/react/require-jsdoc */
3
+
4
+ import { isNodeOfType } from 'eslint-codemod-utils';
5
+ import * as ast from '../../../ast-nodes';
6
+ import { allowedAttrs, updateTestIdAttributeFix } from './common';
7
+ var tagSizeMap = {
8
+ h1: 'xlarge',
9
+ h2: 'large',
10
+ h3: 'medium',
11
+ h4: 'small',
12
+ h5: 'xsmall',
13
+ h6: 'xxsmall'
14
+ };
15
+ export var NativeElements = {
16
+ lint: function lint(node, _ref) {
17
+ var context = _ref.context,
18
+ config = _ref.config;
19
+ // Check whether all criteria needed to make a transformation are met
20
+ if (!NativeElements._check(node, {
21
+ context: context,
22
+ config: config
23
+ })) {
24
+ return;
25
+ }
26
+ context.report({
27
+ node: node,
28
+ messageId: 'preferHeading',
29
+ suggest: [{
30
+ desc: 'Convert to Heading',
31
+ fix: NativeElements._fix(node, {
32
+ context: context,
33
+ config: config
34
+ })
35
+ }]
36
+ });
37
+ },
38
+ _check: function _check(node, _ref2) {
39
+ var config = _ref2.config;
40
+ if (!config.patterns.includes('native-elements')) {
41
+ return false;
42
+ }
43
+ if (!isNodeOfType(node, 'JSXElement')) {
44
+ return false;
45
+ }
46
+ if (!node.parent) {
47
+ return false;
48
+ }
49
+ var elementName = ast.JSXElement.getName(node);
50
+ if (!Object.keys(tagSizeMap).includes(elementName)) {
51
+ return false;
52
+ }
53
+
54
+ // Element has to be first element of its siblings
55
+ if (!(isNodeOfType(node.parent, 'JSXElement') || isNodeOfType(node.parent, 'JSXFragment'))) {
56
+ return false;
57
+ }
58
+ var siblings = ast.JSXElement.getChildren(node.parent);
59
+ if (siblings.length > 1) {
60
+ var _siblings$0$range, _node$range, _siblings$0$range2, _node$range2;
61
+ // Only report if element is first child element
62
+ if (((_siblings$0$range = siblings[0].range) === null || _siblings$0$range === void 0 ? void 0 : _siblings$0$range[0]) !== ((_node$range = node.range) === null || _node$range === void 0 ? void 0 : _node$range[0]) || ((_siblings$0$range2 = siblings[0].range) === null || _siblings$0$range2 === void 0 ? void 0 : _siblings$0$range2[1]) !== ((_node$range2 = node.range) === null || _node$range2 === void 0 ? void 0 : _node$range2[1])) {
63
+ return false;
64
+ }
65
+ }
66
+ if (!ast.JSXElement.hasAllowedAttrsOnly(node, allowedAttrs)) {
67
+ return false;
68
+ }
69
+ return true;
70
+ },
71
+ _fix: function _fix(node, _ref3) {
72
+ var context = _ref3.context;
73
+ return function (fixer) {
74
+ // change to default import
75
+ var importFix = ast.Root.upsertDefaultImportDeclaration({
76
+ module: '@atlaskit/heading',
77
+ localName: 'Heading'
78
+ }, context, fixer);
79
+ var elementName = ast.JSXElement.getName(node);
80
+ var elementNameFixes = ast.JSXElement.updateName(node, 'Heading', fixer);
81
+ var size = tagSizeMap[elementName];
82
+ var asAttributeFix = ast.JSXElement.addAttribute(node, 'size', size, fixer);
83
+ var testAttributeFix = updateTestIdAttributeFix(node, fixer);
84
+ return [importFix].concat(_toConsumableArray(elementNameFixes), [asAttributeFix, testAttributeFix]).filter(function (fix) {
85
+ return Boolean(fix);
86
+ }); // Some of the transformers can return arrays with undefined, so filter them out
87
+ };
88
+ }
89
+ };
@@ -9,7 +9,6 @@ import { convertJsxCallSite } from './convert-jsx-call-site';
9
9
  import { convertStyledComponentToXcss } from './convert-styled-component-call-to-jsx';
10
10
  import { findValidJsxUsageToTransform } from './find-valid-jsx-usage-to-transform';
11
11
  import { findValidStyledComponentCall } from './find-valid-styled-component-call';
12
- import { upsertImportDeclaration } from './upsert-import-declaration';
13
12
  export var CompiledStyled = {
14
13
  lint: function lint(node, _ref) {
15
14
  var context = _ref.context,
@@ -95,7 +94,7 @@ export var CompiledStyled = {
95
94
  if (!calculatedStylesVariableName) {
96
95
  return [];
97
96
  }
98
- var importFixes = upsertImportDeclaration({
97
+ var importFixes = ast.Root.upsertNamedImportDeclaration({
99
98
  module: '@atlaskit/primitives',
100
99
  specifiers: ['Box', 'xcss']
101
100
  }, context, fixer);
@@ -7,7 +7,6 @@ import { getVariableDefinitionValue, getVariableUsagesCount, isValidCssPropertie
7
7
  import { validateStyles } from '../../utils/validate-styles';
8
8
  import { cssToXcssTransformer } from '../css-to-xcss';
9
9
  import * as supported from './supported';
10
- import { upsertImportDeclaration } from './upsert-import-declaration';
11
10
  export var EmotionCSS = {
12
11
  lint: function lint(node, _ref) {
13
12
  var context = _ref.context,
@@ -98,7 +97,7 @@ export var EmotionCSS = {
98
97
  _fix: function _fix(node, _ref3) {
99
98
  var context = _ref3.context;
100
99
  return function (fixer) {
101
- var importFix = upsertImportDeclaration({
100
+ var importFix = ast.Root.upsertNamedImportDeclaration({
102
101
  module: '@atlaskit/primitives',
103
102
  specifiers: ['Box', 'xcss']
104
103
  }, context, fixer);
@@ -3,7 +3,6 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
 
4
4
  import { isNodeOfType } from 'eslint-codemod-utils';
5
5
  import * as ast from '../../../ast-nodes';
6
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
7
6
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
8
7
  export var EmphasisElements = {
9
8
  lint: function lint(node, _ref) {
@@ -59,7 +58,7 @@ export var EmphasisElements = {
59
58
  var context = _ref3.context,
60
59
  config = _ref3.config;
61
60
  return function (fixer) {
62
- var importFix = upsertImportDeclaration({
61
+ var importFix = ast.Root.upsertNamedImportDeclaration({
63
62
  module: '@atlaskit/primitives',
64
63
  specifiers: ['Text']
65
64
  }, context, fixer);
@@ -3,7 +3,6 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
 
4
4
  import { isNodeOfType } from 'eslint-codemod-utils';
5
5
  import * as ast from '../../../ast-nodes';
6
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
7
6
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
8
7
  export var ParagraphElements = {
9
8
  lint: function lint(node, _ref) {
@@ -152,7 +151,7 @@ export var ParagraphElements = {
152
151
  var context = _ref3.context,
153
152
  config = _ref3.config;
154
153
  return function (fixer) {
155
- var importFix = upsertImportDeclaration({
154
+ var importFix = ast.Root.upsertNamedImportDeclaration({
156
155
  module: '@atlaskit/primitives',
157
156
  specifiers: ['Text']
158
157
  }, context, fixer);
@@ -173,7 +172,7 @@ export var ParagraphElements = {
173
172
  if (!isNodeOfType(node.parent, 'JSXElement') || !node.parent.closingElement) {
174
173
  return [];
175
174
  }
176
- var importFix = upsertImportDeclaration({
175
+ var importFix = ast.Root.upsertNamedImportDeclaration({
177
176
  module: '@atlaskit/primitives',
178
177
  specifiers: ['Text', 'Stack']
179
178
  }, context, fixer);
@@ -3,7 +3,6 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
 
4
4
  import { isNodeOfType } from 'eslint-codemod-utils';
5
5
  import * as ast from '../../../ast-nodes';
6
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
7
6
  import { addColorInheritAttributeFix, allowedAttrs, hasTextChildrenOnly, updateTestIdAttributeFix } from './common';
8
7
  export var SpanElements = {
9
8
  lint: function lint(node, _ref) {
@@ -64,7 +63,7 @@ export var SpanElements = {
64
63
  var context = _ref3.context,
65
64
  config = _ref3.config;
66
65
  return function (fixer) {
67
- var importFix = upsertImportDeclaration({
66
+ var importFix = ast.Root.upsertNamedImportDeclaration({
68
67
  module: '@atlaskit/primitives',
69
68
  specifiers: ['Text']
70
69
  }, context, fixer);
@@ -3,7 +3,6 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
3
 
4
4
  import { isNodeOfType } from 'eslint-codemod-utils';
5
5
  import * as ast from '../../../ast-nodes';
6
- import { upsertImportDeclaration } from '../../use-primitives/transformers/emotion-css/upsert-import-declaration';
7
6
  import { addColorInheritAttributeFix, allowedAttrs, updateTestIdAttributeFix } from './common';
8
7
  export var StrongElements = {
9
8
  lint: function lint(node, _ref) {
@@ -59,7 +58,7 @@ export var StrongElements = {
59
58
  var context = _ref3.context,
60
59
  config = _ref3.config;
61
60
  return function (fixer) {
62
- var importFix = upsertImportDeclaration({
61
+ var importFix = ast.Root.upsertNamedImportDeclaration({
63
62
  module: '@atlaskit/primitives',
64
63
  specifiers: ['Text']
65
64
  }, context, fixer);