@atlaskit/eslint-plugin-design-system 8.26.0 → 8.28.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 +31 -0
- package/README.md +31 -29
- package/constellation/consistent-css-prop-usage/usage.mdx +193 -0
- package/constellation/ensure-design-token-usage/usage.mdx +72 -0
- package/constellation/ensure-design-token-usage-preview/usage.mdx +5 -0
- package/constellation/icon-label/usage.mdx +39 -0
- package/constellation/index/usage.mdx +31 -1474
- package/constellation/local-cx-xcss/usage.mdx +37 -0
- package/constellation/no-banned-imports/usage.mdx +17 -0
- package/constellation/no-css-tagged-template-expression/usage.mdx +66 -0
- package/constellation/no-deprecated-apis/usage.mdx +76 -0
- package/constellation/no-deprecated-design-token-usage/usage.mdx +27 -0
- package/constellation/no-deprecated-imports/usage.mdx +62 -0
- package/constellation/no-empty-styled-expression/usage.mdx +77 -0
- package/constellation/no-exported-css/usage.mdx +50 -0
- package/constellation/no-exported-keyframes/usage.mdx +50 -0
- package/constellation/no-invalid-css-map/usage.mdx +199 -0
- package/constellation/no-keyframes-tagged-template-expression/usage.mdx +76 -0
- package/constellation/no-margin/usage.mdx +20 -0
- package/constellation/no-nested-styles/usage.mdx +47 -0
- package/constellation/no-physical-properties/usage.mdx +53 -0
- package/constellation/no-styled-tagged-template-expression/usage.mdx +90 -0
- package/constellation/no-unsafe-design-token-usage/usage.mdx +49 -0
- package/constellation/no-unsafe-style-overrides/usage.mdx +49 -0
- package/constellation/no-unsupported-drag-and-drop-libraries/usage.mdx +17 -0
- package/constellation/prefer-primitives/usage.mdx +31 -0
- package/constellation/use-button-group-label/usage.mdx +58 -0
- package/constellation/use-drawer-label/usage.mdx +53 -0
- package/constellation/use-heading-level-in-spotlight-card/usage.mdx +20 -0
- package/constellation/use-href-in-link-item/usage.mdx +18 -0
- package/constellation/use-primitives/usage.mdx +77 -0
- package/constellation/use-visually-hidden/usage.mdx +34 -0
- package/dist/cjs/presets/all.codegen.js +3 -1
- package/dist/cjs/rules/consistent-css-prop-usage/index.js +254 -32
- package/dist/cjs/rules/index.codegen.js +5 -1
- package/dist/cjs/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/cjs/rules/no-keyframes-tagged-template-expression/index.js +27 -0
- package/dist/cjs/rules/no-styled-tagged-template-expression/index.js +27 -0
- package/dist/cjs/rules/no-styled-tagged-template-expression/is-styled.js +53 -0
- package/dist/cjs/rules/utils/create-no-exported-rule/is-styled-component.js +6 -10
- package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.js +26 -6
- package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/cjs/rules/utils/create-rule.js +7 -5
- package/dist/cjs/rules/utils/get-first-supported-import.js +28 -0
- package/dist/cjs/rules/utils/is-supported-import.js +9 -11
- package/dist/es2019/presets/all.codegen.js +3 -1
- package/dist/es2019/rules/consistent-css-prop-usage/index.js +251 -33
- package/dist/es2019/rules/index.codegen.js +5 -1
- package/dist/es2019/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/es2019/rules/no-keyframes-tagged-template-expression/index.js +21 -0
- package/dist/es2019/rules/no-styled-tagged-template-expression/index.js +21 -0
- package/dist/es2019/rules/no-styled-tagged-template-expression/is-styled.js +45 -0
- package/dist/es2019/rules/utils/create-no-exported-rule/is-styled-component.js +4 -8
- package/dist/es2019/rules/utils/create-no-tagged-template-expression-rule/index.js +84 -0
- package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/es2019/rules/utils/create-rule.js +7 -5
- package/dist/es2019/rules/utils/get-first-supported-import.js +22 -0
- package/dist/es2019/rules/utils/is-supported-import.js +9 -9
- package/dist/esm/presets/all.codegen.js +3 -1
- package/dist/esm/rules/consistent-css-prop-usage/index.js +255 -33
- package/dist/esm/rules/index.codegen.js +5 -1
- package/dist/esm/rules/no-css-tagged-template-expression/index.js +3 -2
- package/dist/esm/rules/no-keyframes-tagged-template-expression/index.js +21 -0
- package/dist/esm/rules/no-styled-tagged-template-expression/index.js +21 -0
- package/dist/esm/rules/no-styled-tagged-template-expression/is-styled.js +47 -0
- package/dist/esm/rules/utils/create-no-exported-rule/is-styled-component.js +6 -10
- package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.js +25 -5
- package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.js +28 -2
- package/dist/esm/rules/utils/create-rule.js +7 -5
- package/dist/esm/rules/utils/get-first-supported-import.js +22 -0
- package/dist/esm/rules/utils/is-supported-import.js +9 -10
- package/dist/types/index.codegen.d.ts +2 -0
- package/dist/types/presets/all.codegen.d.ts +3 -1
- package/dist/types/rules/consistent-css-prop-usage/types.d.ts +7 -2
- package/dist/types/rules/index.codegen.d.ts +2 -0
- package/dist/types/rules/no-keyframes-tagged-template-expression/index.d.ts +2 -0
- package/dist/types/rules/no-styled-tagged-template-expression/index.d.ts +2 -0
- package/dist/types/rules/no-styled-tagged-template-expression/is-styled.d.ts +7 -0
- package/dist/types/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
- package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.d.ts +3 -1
- package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.d.ts +3 -0
- package/dist/types/rules/utils/get-first-supported-import.d.ts +17 -0
- package/dist/types/rules/utils/is-supported-import.d.ts +6 -5
- package/dist/types-ts4.5/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +3 -1
- package/dist/types-ts4.5/rules/consistent-css-prop-usage/types.d.ts +7 -2
- package/dist/types-ts4.5/rules/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-keyframes-tagged-template-expression/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-styled-tagged-template-expression/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-styled-tagged-template-expression/is-styled.d.ts +7 -0
- package/dist/types-ts4.5/rules/use-primitives/utils/update-jsx-attribute-by-name.d.ts +1 -1
- package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/index.d.ts +3 -1
- package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.d.ts +3 -0
- package/dist/types-ts4.5/rules/utils/get-first-supported-import.d.ts +17 -0
- package/dist/types-ts4.5/rules/utils/is-supported-import.d.ts +6 -5
- package/package.json +3 -1
- package/dist/es2019/rules/no-css-tagged-template-expression/create-no-tagged-template-expression-rule/index.js +0 -62
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/cjs/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/es2019/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.js +0 -0
- /package/dist/esm/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/types.js +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.d.ts +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.d.ts +0 -0
- /package/dist/types/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/generate.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/get-tagged-template-expression-offset.d.ts +0 -0
- /package/dist/types-ts4.5/rules/{no-css-tagged-template-expression → utils}/create-no-tagged-template-expression-rule/to-arguments.d.ts +0 -0
|
@@ -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::0a2813f0b87e94d23e1f6fc388539c70>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -17,9 +17,11 @@ import noEmptyStyledExpression from './no-empty-styled-expression';
|
|
|
17
17
|
import noExportedCss from './no-exported-css';
|
|
18
18
|
import noExportedKeyframes from './no-exported-keyframes';
|
|
19
19
|
import noInvalidCssMap from './no-invalid-css-map';
|
|
20
|
+
import noKeyframesTaggedTemplateExpression from './no-keyframes-tagged-template-expression';
|
|
20
21
|
import noMargin from './no-margin';
|
|
21
22
|
import noNestedStyles from './no-nested-styles';
|
|
22
23
|
import noPhysicalProperties from './no-physical-properties';
|
|
24
|
+
import noStyledTaggedTemplateExpression from './no-styled-tagged-template-expression';
|
|
23
25
|
import noUnsafeDesignTokenUsage from './no-unsafe-design-token-usage';
|
|
24
26
|
import noUnsafeStyleOverrides from './no-unsafe-style-overrides';
|
|
25
27
|
import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-libraries';
|
|
@@ -45,9 +47,11 @@ export default {
|
|
|
45
47
|
'no-exported-css': noExportedCss,
|
|
46
48
|
'no-exported-keyframes': noExportedKeyframes,
|
|
47
49
|
'no-invalid-css-map': noInvalidCssMap,
|
|
50
|
+
'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpression,
|
|
48
51
|
'no-margin': noMargin,
|
|
49
52
|
'no-nested-styles': noNestedStyles,
|
|
50
53
|
'no-physical-properties': noPhysicalProperties,
|
|
54
|
+
'no-styled-tagged-template-expression': noStyledTaggedTemplateExpression,
|
|
51
55
|
'no-unsafe-design-token-usage': noUnsafeDesignTokenUsage,
|
|
52
56
|
'no-unsafe-style-overrides': noUnsafeStyleOverrides,
|
|
53
57
|
'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
1
2
|
import { createLintRule } from '../utils/create-rule';
|
|
2
3
|
import { isCss } from '../utils/is-supported-import';
|
|
3
|
-
import { createNoTaggedTemplateExpressionRule } from './create-no-tagged-template-expression-rule';
|
|
4
4
|
const rule = createLintRule({
|
|
5
5
|
meta: {
|
|
6
6
|
name: 'no-css-tagged-template-expression',
|
|
@@ -13,7 +13,8 @@ const rule = createLintRule({
|
|
|
13
13
|
},
|
|
14
14
|
messages: {
|
|
15
15
|
unexpectedTaggedTemplate: 'Unexpected `css` tagged template expression'
|
|
16
|
-
}
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
17
18
|
},
|
|
18
19
|
create: createNoTaggedTemplateExpressionRule(isCss, 'unexpectedTaggedTemplate')
|
|
19
20
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isKeyframes } from '../utils/is-supported-import';
|
|
4
|
+
const rule = createLintRule({
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'no-keyframes-tagged-template-expression',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Disallows any `keyframe` tagged template expressions that originate from Emotion, Styled Components or Compiled',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
unexpectedTaggedTemplate: 'Unexpected `keyframes` tagged template expression'
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
18
|
+
},
|
|
19
|
+
create: createNoTaggedTemplateExpressionRule(isKeyframes, 'unexpectedTaggedTemplate')
|
|
20
|
+
});
|
|
21
|
+
export default rule;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createNoTaggedTemplateExpressionRule, noTaggedTemplateExpressionRuleSchema } from '../utils/create-no-tagged-template-expression-rule';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isStyled } from './is-styled';
|
|
4
|
+
const rule = createLintRule({
|
|
5
|
+
meta: {
|
|
6
|
+
name: 'no-styled-tagged-template-expression',
|
|
7
|
+
fixable: 'code',
|
|
8
|
+
type: 'problem',
|
|
9
|
+
docs: {
|
|
10
|
+
description: 'Disallows any `styled` tagged template expressions that originate from Emotion, Styled Components or Compiled',
|
|
11
|
+
recommended: false,
|
|
12
|
+
severity: 'error'
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
unexpectedTaggedTemplate: 'Unexpected `styled` tagged template expression'
|
|
16
|
+
},
|
|
17
|
+
schema: noTaggedTemplateExpressionRuleSchema
|
|
18
|
+
},
|
|
19
|
+
create: createNoTaggedTemplateExpressionRule(isStyled, 'unexpectedTaggedTemplate')
|
|
20
|
+
});
|
|
21
|
+
export default rule;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { CSS_IN_JS_IMPORTS } from '../utils/is-supported-import';
|
|
4
|
+
const functionName = 'styled';
|
|
5
|
+
const checkDefinitionHasImport = (def, importSources) => {
|
|
6
|
+
if (def.type !== 'ImportBinding') {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
if (!def.parent || !importSources.includes(def.parent.source.value)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// `@compiled/react` only exposes styled as a named export
|
|
14
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.compiled) && def.parent.source.value === CSS_IN_JS_IMPORTS.compiled) {
|
|
15
|
+
return def.node.type === 'ImportSpecifier' && def.node.imported.name === functionName;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// `@emotion/styled` only exposes styled as a default export
|
|
19
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.emotionStyled) && def.parent.source.value === CSS_IN_JS_IMPORTS.emotionStyled) {
|
|
20
|
+
return def.node.type === 'ImportDefaultSpecifier';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// `styled-components` only exposes styled as a default export
|
|
24
|
+
if (importSources.includes(CSS_IN_JS_IMPORTS.styledComponents) && def.parent.source.value === CSS_IN_JS_IMPORTS.styledComponents) {
|
|
25
|
+
return def.node.type === 'ImportDefaultSpecifier';
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
29
|
+
export const isStyled = (nodeToCheck, referencesInScope, importSources) => {
|
|
30
|
+
let nodeIdentifier = null;
|
|
31
|
+
|
|
32
|
+
// Handles styled.div`` case
|
|
33
|
+
if (nodeToCheck.type === 'MemberExpression' && nodeToCheck.object.type === 'Identifier') {
|
|
34
|
+
nodeIdentifier = nodeToCheck.object;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Handles styled(Base)`` case
|
|
38
|
+
if (nodeToCheck.type === 'CallExpression' && nodeToCheck.callee.type === 'Identifier') {
|
|
39
|
+
nodeIdentifier = nodeToCheck.callee;
|
|
40
|
+
}
|
|
41
|
+
return referencesInScope.some(reference => {
|
|
42
|
+
var _reference$resolved;
|
|
43
|
+
return reference.identifier === nodeIdentifier && ((_reference$resolved = reference.resolved) === null || _reference$resolved === void 0 ? void 0 : _reference$resolved.defs.some(def => checkDefinitionHasImport(def, importSources)));
|
|
44
|
+
});
|
|
45
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getFirstSupportedImport } from '../get-first-supported-import';
|
|
2
2
|
/**
|
|
3
3
|
* Given a list of node, find and return the callee of the first Compiled or styled-components `styled` function call found in the list.
|
|
4
4
|
*
|
|
@@ -40,13 +40,9 @@ const findNode = nodes => {
|
|
|
40
40
|
* @returns The local name used to import the `styled` API.
|
|
41
41
|
*/
|
|
42
42
|
const getStyledImportSpecifierName = (context, importSources) => {
|
|
43
|
-
var
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
};
|
|
47
|
-
const source = context.getSourceCode();
|
|
48
|
-
const supportedImports = source.ast.body.filter(isSupportedImport);
|
|
49
|
-
return (_supportedImports$0$s = supportedImports[0].specifiers.find(spec => spec.type === 'ImportSpecifier' && spec.imported.name === 'styled')) === null || _supportedImports$0$s === void 0 ? void 0 : _supportedImports$0$s.local.name;
|
|
43
|
+
var _supportedImport$spec;
|
|
44
|
+
const supportedImport = getFirstSupportedImport(context, importSources);
|
|
45
|
+
return supportedImport === null || supportedImport === void 0 ? void 0 : (_supportedImport$spec = supportedImport.specifiers.find(spec => spec.type === 'ImportSpecifier' && spec.imported.name === 'styled' || spec.type === 'ImportDefaultSpecifier' && spec.local.name === 'styled')) === null || _supportedImport$spec === void 0 ? void 0 : _supportedImport$spec.local.name;
|
|
50
46
|
};
|
|
51
47
|
|
|
52
48
|
/**
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Original source from Compiled https://github.com/atlassian-labs/compiled/blob/master/packages/eslint-plugin/src/utils/create-no-tagged-template-expression-rule/index.ts
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
3
|
+
|
|
4
|
+
import { getImportSources } from '../is-supported-import';
|
|
5
|
+
import { generate } from './generate';
|
|
6
|
+
import { getTaggedTemplateExpressionOffset } from './get-tagged-template-expression-offset';
|
|
7
|
+
import { toArguments } from './to-arguments';
|
|
8
|
+
export const noTaggedTemplateExpressionRuleSchema = [{
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
importSources: {
|
|
12
|
+
type: 'array',
|
|
13
|
+
items: {
|
|
14
|
+
type: 'string'
|
|
15
|
+
},
|
|
16
|
+
uniqueItems: true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* When true, template strings containing multiline comments are completely skipped over.
|
|
23
|
+
*
|
|
24
|
+
* When false, multiline comments are stripped out. Ideally we would preserve them,
|
|
25
|
+
* but it would add a lot of complexity.
|
|
26
|
+
*/
|
|
27
|
+
const shouldSkipMultilineComments = false;
|
|
28
|
+
export const createNoTaggedTemplateExpressionRule = (isUsage, messageId) => context => {
|
|
29
|
+
const importSources = getImportSources(context);
|
|
30
|
+
return {
|
|
31
|
+
TaggedTemplateExpression(node) {
|
|
32
|
+
const {
|
|
33
|
+
references
|
|
34
|
+
} = context.getScope();
|
|
35
|
+
if (!isUsage(node.tag, references, importSources)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
context.report({
|
|
39
|
+
messageId,
|
|
40
|
+
node,
|
|
41
|
+
*fix(fixer) {
|
|
42
|
+
const {
|
|
43
|
+
quasi
|
|
44
|
+
} = node;
|
|
45
|
+
const source = context.getSourceCode();
|
|
46
|
+
|
|
47
|
+
// TODO Eventually handle comments instead of skipping them
|
|
48
|
+
// Skip auto-fixing comments
|
|
49
|
+
if (shouldSkipMultilineComments && quasi.quasis.map(q => q.value.raw).join('').match(/\/\*[\s\S]*\*\//g)) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Replace empty tagged template expression with the equivalent object call expression
|
|
54
|
+
if (!quasi.expressions.length && quasi.quasis.length === 1 && !quasi.quasis[0].value.raw.trim()) {
|
|
55
|
+
yield fixer.replaceText(quasi, '({})');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const args = toArguments(source, quasi);
|
|
59
|
+
|
|
60
|
+
// Skip invalid CSS
|
|
61
|
+
if (args.length < 1) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const oldCode = source.getText(node);
|
|
65
|
+
// Remove quasi:
|
|
66
|
+
// styled.div<Props>`
|
|
67
|
+
// color: red;
|
|
68
|
+
// `
|
|
69
|
+
// becomes
|
|
70
|
+
// styled.div<Props>
|
|
71
|
+
const withoutQuasi = oldCode.replace(source.getText(quasi), '');
|
|
72
|
+
const newCode = withoutQuasi +
|
|
73
|
+
// Indent the arguments after the tagged template expression range
|
|
74
|
+
generate(args, getTaggedTemplateExpressionOffset(node));
|
|
75
|
+
if (oldCode === newCode) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
yield fixer.insertTextBefore(node, newCode);
|
|
79
|
+
yield fixer.remove(node);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
@@ -39,7 +39,30 @@ const getArguments = (chars, expressions = []) => {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
const getValue = () => {
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* This branch is required for handling interpolated functions:
|
|
44
|
+
*
|
|
45
|
+
* css`
|
|
46
|
+
* color: ${(props) => props.textColor}
|
|
47
|
+
* `
|
|
48
|
+
*
|
|
49
|
+
* But it also breaks interpolations of multiple tokens:
|
|
50
|
+
*
|
|
51
|
+
* css`
|
|
52
|
+
* padding: ${token('space.100')} ${token('space.200')}
|
|
53
|
+
* `
|
|
54
|
+
*
|
|
55
|
+
* which becomes invalid syntax:
|
|
56
|
+
*
|
|
57
|
+
* css({
|
|
58
|
+
* padding: token('space.100')token('space.200')
|
|
59
|
+
* })
|
|
60
|
+
*
|
|
61
|
+
* Limiting this branch to when `expressions.length === 1` seems
|
|
62
|
+
* to allow both cases to work. There may be other edge cases,
|
|
63
|
+
* but none were caught by the existing test suite.
|
|
64
|
+
*/
|
|
65
|
+
if (!value.trim().length && expressions.length === 1) {
|
|
43
66
|
return {
|
|
44
67
|
type: 'expression',
|
|
45
68
|
expression: expressions.map(e => e.expression).join('')
|
|
@@ -134,7 +157,10 @@ export const toArguments = (source, template) => {
|
|
|
134
157
|
};
|
|
135
158
|
for (const [i, quasi] of template.quasis.entries()) {
|
|
136
159
|
// Deal with selectors across multiple lines
|
|
137
|
-
const styleTemplateElement = quasi.value.raw.replace(
|
|
160
|
+
const styleTemplateElement = quasi.value.raw.replace(/\/\*(.|\n|\r)*?\*\//g, '') // Removes multi-line comments
|
|
161
|
+
// Remove single line comments
|
|
162
|
+
// Negative lookbehind to handle URL-like double slashes
|
|
163
|
+
.replace(/(?<!https?:)\/\/.*$/gm, '').replace(/(\r\n|\n|\r)/gm, ' ').replace(/\s+/g, ' ');
|
|
138
164
|
for (const char of styleTemplateElement) {
|
|
139
165
|
switch (char) {
|
|
140
166
|
case '{':
|
|
@@ -10,15 +10,17 @@ import { ESLintUtils } from '@typescript-eslint/utils';
|
|
|
10
10
|
* @private
|
|
11
11
|
* @deprecated
|
|
12
12
|
*/
|
|
13
|
-
export const createRule = ESLintUtils.RuleCreator(name =>
|
|
13
|
+
export const createRule = ESLintUtils.RuleCreator(name => getRuleUrl(name));
|
|
14
14
|
/**
|
|
15
15
|
* Tiny wrapped over the ESLint rule module type that ensures
|
|
16
16
|
* there is a docs link to our ESLint plugin documentation page,
|
|
17
17
|
* as well as improving type support.
|
|
18
18
|
*/
|
|
19
19
|
export const createLintRule = rule => {
|
|
20
|
-
|
|
21
|
-
const url = `https://atlassian.design/components/eslint-plugin-design-system/usage#${ruleName}`;
|
|
22
|
-
rule.meta.docs.url = url;
|
|
20
|
+
rule.meta.docs.url = getRuleUrl(rule.meta.name);
|
|
23
21
|
return rule;
|
|
24
|
-
};
|
|
22
|
+
};
|
|
23
|
+
function getRuleUrl(ruleName) {
|
|
24
|
+
const name = ruleName.replace('/', '-'); // If it's a nested rule, ensure the url is clean and matches codegen/gatsby
|
|
25
|
+
return `https://atlassian.design/components/eslint-plugin-design-system/${name}/usage`;
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Get the first import declaration in the file that matches any of the packages
|
|
4
|
+
* in `importSources`.
|
|
5
|
+
*
|
|
6
|
+
* @param context Rule context.
|
|
7
|
+
* @param importSources The packages to check import statements for. If importSources
|
|
8
|
+
* contains more than one package, the first import statement
|
|
9
|
+
* detected in the file that matches any of the packages will be
|
|
10
|
+
* returned.
|
|
11
|
+
* @returns The first import declaration found in the file.
|
|
12
|
+
*/
|
|
13
|
+
export const getFirstSupportedImport = (context, importSources) => {
|
|
14
|
+
const isSupportedImport = node => {
|
|
15
|
+
return isNodeOfType(node, 'ImportDeclaration') && typeof node.source.value === 'string' && importSources.includes(node.source.value);
|
|
16
|
+
};
|
|
17
|
+
const source = context.getSourceCode();
|
|
18
|
+
const supportedImports = source.ast.body.filter(isSupportedImport);
|
|
19
|
+
if (supportedImports.length) {
|
|
20
|
+
return supportedImports[0];
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -4,22 +4,22 @@ export const CSS_IN_JS_IMPORTS = {
|
|
|
4
4
|
compiled: '@compiled/react',
|
|
5
5
|
emotionReact: '@emotion/react',
|
|
6
6
|
emotionCore: '@emotion/core',
|
|
7
|
+
emotionStyled: '@emotion/styled',
|
|
7
8
|
styledComponents: 'styled-components',
|
|
8
|
-
atlaskitCss: '@atlaskit/css'
|
|
9
|
+
atlaskitCss: '@atlaskit/css',
|
|
10
|
+
atlaskitPrimitives: '@atlaskit/primitives'
|
|
9
11
|
};
|
|
10
12
|
|
|
11
13
|
// A CSS-in-JS library an import of a valid css, cx, cssMap, etc.
|
|
12
14
|
// function might originate from, e.g. @compiled/react, @emotion/core.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* By default all known import sources are checked against.
|
|
17
|
+
*/
|
|
18
|
+
export const DEFAULT_IMPORT_SOURCES = Object.values(CSS_IN_JS_IMPORTS);
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Given the ESLint rule context, extract and parse the value of the importSources rule option.
|
|
18
|
-
* The importSources option is used to
|
|
19
|
-
* should apply to.
|
|
20
|
-
*
|
|
21
|
-
* Note that `@compiled/react` and `@atlaskit/css` are always included in importSources, regardless
|
|
22
|
-
* of what importSources is configured to by the user.
|
|
22
|
+
* The importSources option is used to override which libraries an ESLint rule applies to.
|
|
23
23
|
*
|
|
24
24
|
* @param context The rule context.
|
|
25
25
|
* @returns An array of strings representing what CSS-in-JS packages that should be checked, based
|
|
@@ -31,7 +31,7 @@ export const getImportSources = context => {
|
|
|
31
31
|
return DEFAULT_IMPORT_SOURCES;
|
|
32
32
|
}
|
|
33
33
|
if (options[0].importSources && Array.isArray(options[0].importSources)) {
|
|
34
|
-
return
|
|
34
|
+
return options[0].importSources;
|
|
35
35
|
}
|
|
36
36
|
return DEFAULT_IMPORT_SOURCES;
|
|
37
37
|
};
|
|
@@ -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::5647ce9c10ba880cffece66b5924fd6e>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -20,9 +20,11 @@ export default {
|
|
|
20
20
|
'@atlaskit/design-system/no-exported-css': 'warn',
|
|
21
21
|
'@atlaskit/design-system/no-exported-keyframes': 'warn',
|
|
22
22
|
'@atlaskit/design-system/no-invalid-css-map': 'error',
|
|
23
|
+
'@atlaskit/design-system/no-keyframes-tagged-template-expression': 'error',
|
|
23
24
|
'@atlaskit/design-system/no-margin': 'warn',
|
|
24
25
|
'@atlaskit/design-system/no-nested-styles': 'error',
|
|
25
26
|
'@atlaskit/design-system/no-physical-properties': 'error',
|
|
27
|
+
'@atlaskit/design-system/no-styled-tagged-template-expression': 'error',
|
|
26
28
|
'@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
|
|
27
29
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
28
30
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|