@atlaskit/eslint-plugin-design-system 9.2.5 → 9.3.1
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 +17 -0
- package/README.md +1 -0
- package/constellation/index/usage.mdx +1 -0
- package/constellation/use-heading/usage.mdx +28 -0
- package/dist/cjs/ast-nodes/root.js +32 -0
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/use-heading/config/index.js +15 -0
- package/dist/cjs/rules/use-heading/index.js +39 -0
- package/dist/cjs/rules/use-heading/transformers/common.js +19 -0
- package/dist/cjs/rules/use-heading/transformers/index.js +12 -0
- package/dist/cjs/rules/use-heading/transformers/native-elements.js +99 -0
- package/dist/cjs/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
- package/dist/cjs/rules/use-primitives/transformers/emotion-css/index.js +1 -2
- package/dist/cjs/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
- package/dist/cjs/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
- package/dist/cjs/rules/use-primitives-text/transformers/span-elements.js +1 -2
- package/dist/cjs/rules/use-primitives-text/transformers/strong-elements.js +1 -2
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/index.js +1 -2
- package/dist/cjs/rules/utils/create-no-tagged-template-expression-rule/index.js +5 -7
- package/dist/cjs/rules/utils/create-rule.js +4 -7
- package/dist/es2019/ast-nodes/root.js +34 -0
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/use-heading/config/index.js +9 -0
- package/dist/es2019/rules/use-heading/index.js +33 -0
- package/dist/es2019/rules/use-heading/transformers/common.js +9 -0
- package/dist/es2019/rules/use-heading/transformers/index.js +1 -0
- package/dist/es2019/rules/use-heading/transformers/native-elements.js +89 -0
- package/dist/es2019/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
- package/dist/es2019/rules/use-primitives/transformers/emotion-css/index.js +1 -2
- package/dist/es2019/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
- package/dist/es2019/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
- package/dist/es2019/rules/use-primitives-text/transformers/span-elements.js +1 -2
- package/dist/es2019/rules/use-primitives-text/transformers/strong-elements.js +1 -2
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/index.js +1 -2
- package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/index.js +21 -9
- package/dist/es2019/rules/utils/create-rule.js +4 -6
- package/dist/esm/ast-nodes/root.js +32 -0
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/use-heading/config/index.js +9 -0
- package/dist/esm/rules/use-heading/index.js +33 -0
- package/dist/esm/rules/use-heading/transformers/common.js +9 -0
- package/dist/esm/rules/use-heading/transformers/index.js +1 -0
- package/dist/esm/rules/use-heading/transformers/native-elements.js +89 -0
- package/dist/esm/rules/use-primitives/transformers/compiled-styled/index.js +1 -2
- package/dist/esm/rules/use-primitives/transformers/emotion-css/index.js +1 -2
- package/dist/esm/rules/use-primitives-text/transformers/emphasis-elements.js +1 -2
- package/dist/esm/rules/use-primitives-text/transformers/paragraph-elements.js +2 -3
- package/dist/esm/rules/use-primitives-text/transformers/span-elements.js +1 -2
- package/dist/esm/rules/use-primitives-text/transformers/strong-elements.js +1 -2
- package/dist/esm/rules/use-tokens-space/transformers/style-property/index.js +1 -2
- package/dist/esm/rules/utils/create-no-tagged-template-expression-rule/index.js +6 -8
- package/dist/esm/rules/utils/create-rule.js +4 -6
- package/dist/types/ast-nodes/jsx-element.d.ts +2 -2
- package/dist/types/ast-nodes/root.d.ts +8 -0
- package/dist/types/index.codegen.d.ts +1 -0
- package/dist/types/presets/all.codegen.d.ts +2 -1
- package/dist/types/rules/ensure-design-token-usage/rule-meta.d.ts +1 -1
- package/dist/types/rules/index.codegen.d.ts +1 -0
- package/dist/types/rules/use-heading/config/index.d.ts +6 -0
- package/dist/types/rules/use-heading/index.d.ts +3 -0
- package/dist/types/rules/use-heading/transformers/common.d.ts +9 -0
- package/dist/types/rules/use-heading/transformers/index.d.ts +1 -0
- package/dist/types/rules/use-heading/transformers/native-elements.d.ts +18 -0
- package/dist/types/rules/utils/create-rule.d.ts +1 -37
- package/dist/types-ts4.5/ast-nodes/jsx-element.d.ts +2 -2
- package/dist/types-ts4.5/ast-nodes/root.d.ts +8 -0
- package/dist/types-ts4.5/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
- package/dist/types-ts4.5/rules/ensure-design-token-usage/rule-meta.d.ts +1 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-heading/config/index.d.ts +6 -0
- package/dist/types-ts4.5/rules/use-heading/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/use-heading/transformers/common.d.ts +9 -0
- package/dist/types-ts4.5/rules/use-heading/transformers/index.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-heading/transformers/native-elements.d.ts +18 -0
- package/dist/types-ts4.5/rules/utils/create-rule.d.ts +1 -37
- package/package.json +2 -2
- package/dist/cjs/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -37
- package/dist/cjs/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -37
- package/dist/cjs/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -37
- package/dist/es2019/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -30
- package/dist/es2019/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -30
- package/dist/es2019/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -30
- package/dist/esm/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.js +0 -29
- package/dist/esm/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.js +0 -29
- package/dist/esm/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.js +0 -29
- package/dist/types/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +0 -14
- package/dist/types/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +0 -14
- package/dist/types/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +0 -14
- package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/upsert-import-declaration.d.ts +0 -14
- package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/upsert-import-declaration.d.ts +0 -14
- package/dist/types-ts4.5/rules/use-tokens-space/transformers/style-property/upsert-import-declaration.d.ts +0 -14
|
@@ -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::
|
|
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
|
+
const defaults = {
|
|
2
|
+
patterns: ['native-elements']
|
|
3
|
+
};
|
|
4
|
+
export const 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
|
+
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
111
|
+
const importFix = ast.Root.upsertNamedImportDeclaration({
|
|
113
112
|
module: '@atlaskit/tokens',
|
|
114
113
|
specifiers: ['token']
|
|
115
114
|
}, context, fixer);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
3
|
|
|
4
4
|
import esquery from 'esquery';
|
|
5
|
-
import { getImportSources, isEmotion
|
|
5
|
+
import { getImportSources, isEmotion } from '@atlaskit/eslint-utils/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';
|
|
@@ -60,11 +60,23 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
|
|
|
60
60
|
return;
|
|
61
61
|
}
|
|
62
62
|
const args = toArguments(source, quasi);
|
|
63
|
-
if (
|
|
63
|
+
if (args.some(hasNestedSelectorWithMultipleArguments)) {
|
|
64
64
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
65
|
+
* We don't want to autofix if we would produce an array value, for example:
|
|
66
|
+
* ```
|
|
67
|
+
* styled.div({
|
|
68
|
+
* ':hover': [
|
|
69
|
+
* mixin,
|
|
70
|
+
* {
|
|
71
|
+
* color: 'red'
|
|
72
|
+
* }
|
|
73
|
+
* ]
|
|
74
|
+
* })
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* This should only occur if there is a mixin in a nested selector.
|
|
78
|
+
*
|
|
79
|
+
* The array syntax is only supported by emotion.
|
|
68
80
|
*/
|
|
69
81
|
return;
|
|
70
82
|
}
|
|
@@ -136,17 +148,17 @@ export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => cont
|
|
|
136
148
|
}
|
|
137
149
|
};
|
|
138
150
|
};
|
|
139
|
-
function
|
|
151
|
+
function hasNestedSelectorWithMultipleArguments(arg) {
|
|
140
152
|
if (arg.type === 'literal' || arg.type === 'expression' || arg.type === 'declaration') {
|
|
141
153
|
return false;
|
|
142
154
|
}
|
|
143
|
-
if (arg.type === 'rule' && arg.declarations.length > 1
|
|
155
|
+
if (arg.type === 'rule' && arg.declarations.length > 1) {
|
|
144
156
|
return true;
|
|
145
157
|
}
|
|
146
158
|
if (arg.type === 'block') {
|
|
147
|
-
return arg.blocks.some(
|
|
159
|
+
return arg.blocks.some(hasNestedSelectorWithMultipleArguments);
|
|
148
160
|
}
|
|
149
161
|
if (arg.type === 'rule') {
|
|
150
|
-
return arg.declarations.some(
|
|
162
|
+
return arg.declarations.some(hasNestedSelectorWithMultipleArguments);
|
|
151
163
|
}
|
|
152
164
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
|
|
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 =
|
|
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
|
|
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::
|
|
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::
|
|
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 =
|
|
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 =
|
|
100
|
+
var importFix = ast.Root.upsertNamedImportDeclaration({
|
|
102
101
|
module: '@atlaskit/primitives',
|
|
103
102
|
specifiers: ['Box', 'xcss']
|
|
104
103
|
}, context, fixer);
|