@atlaskit/eslint-plugin-design-system 8.31.0 → 8.32.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 +12 -0
- package/README.md +1 -0
- package/constellation/consistent-css-prop-usage/usage.mdx +1 -1
- package/constellation/index/usage.mdx +1 -0
- package/constellation/no-css-tagged-template-expression/usage.mdx +1 -1
- package/constellation/no-empty-styled-expression/usage.mdx +1 -1
- package/constellation/no-exported-css/usage.mdx +2 -2
- package/constellation/no-exported-keyframes/usage.mdx +2 -2
- package/constellation/no-html-button-element/usage.mdx +26 -0
- package/constellation/no-keyframes-tagged-template-expression/usage.mdx +1 -3
- package/constellation/no-styled-tagged-template-expression/usage.mdx +2 -4
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/rules/consistent-css-prop-usage/index.js +375 -334
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/no-html-button-element/index.js +107 -0
- package/dist/cjs/rules/no-html-button-element/utils.js +18 -0
- package/dist/cjs/rules/prefer-primitives/utils.js +1 -1
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/rules/consistent-css-prop-usage/index.js +283 -267
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/no-html-button-element/index.js +101 -0
- package/dist/es2019/rules/no-html-button-element/utils.js +12 -0
- package/dist/es2019/rules/prefer-primitives/utils.js +1 -1
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/rules/consistent-css-prop-usage/index.js +375 -334
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/no-html-button-element/index.js +101 -0
- package/dist/esm/rules/no-html-button-element/utils.js +12 -0
- package/dist/esm/rules/prefer-primitives/utils.js +1 -1
- package/dist/types/index.codegen.d.ts +1 -0
- package/dist/types/presets/all.codegen.d.ts +2 -1
- package/dist/types/rules/index.codegen.d.ts +1 -0
- package/dist/types/rules/no-html-button-element/index.d.ts +3 -0
- package/dist/types/rules/no-html-button-element/utils.d.ts +2 -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/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/no-html-button-element/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-html-button-element/utils.d.ts +2 -0
- package/package.json +1 -1
|
@@ -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::23062a8759ba919facf30a402e5546bd>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -15,6 +15,7 @@ import noDeprecatedImports from './no-deprecated-imports';
|
|
|
15
15
|
import noEmptyStyledExpression from './no-empty-styled-expression';
|
|
16
16
|
import noExportedCss from './no-exported-css';
|
|
17
17
|
import noExportedKeyframes from './no-exported-keyframes';
|
|
18
|
+
import noHtmlButtonElement from './no-html-button-element';
|
|
18
19
|
import noInvalidCssMap from './no-invalid-css-map';
|
|
19
20
|
import noKeyframesTaggedTemplateExpression from './no-keyframes-tagged-template-expression';
|
|
20
21
|
import noMargin from './no-margin';
|
|
@@ -45,6 +46,7 @@ export default {
|
|
|
45
46
|
'no-empty-styled-expression': noEmptyStyledExpression,
|
|
46
47
|
'no-exported-css': noExportedCss,
|
|
47
48
|
'no-exported-keyframes': noExportedKeyframes,
|
|
49
|
+
'no-html-button-element': noHtmlButtonElement,
|
|
48
50
|
'no-invalid-css-map': noInvalidCssMap,
|
|
49
51
|
'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpression,
|
|
50
52
|
'no-margin': noMargin,
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
4
|
+
import { createLintRule } from '../utils/create-rule';
|
|
5
|
+
import { shouldSuggest } from './utils';
|
|
6
|
+
const buttonDocsUrl = 'https://atlassian.design/components/button';
|
|
7
|
+
const pressableDocsUrl = 'https://atlassian.design/components/primitives/pressable/';
|
|
8
|
+
const rule = createLintRule({
|
|
9
|
+
meta: {
|
|
10
|
+
name: 'no-html-button-element',
|
|
11
|
+
type: 'suggestion',
|
|
12
|
+
hasSuggestions: false,
|
|
13
|
+
docs: {
|
|
14
|
+
description: 'Prevent direct usage of HTML button elements and enforce usage of Button and Pressable.',
|
|
15
|
+
recommended: false,
|
|
16
|
+
severity: 'warn'
|
|
17
|
+
},
|
|
18
|
+
messages: {
|
|
19
|
+
noHtmlButtonElement: `This "{{element}}" should be replaced with a Button component. If beyond the capabilities of the Button component, use the Pressable primitive. See ${buttonDocsUrl} and ${pressableDocsUrl} for guidance.`
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
create(context) {
|
|
23
|
+
return {
|
|
24
|
+
// Look for <button> HTML elements
|
|
25
|
+
// Look for styled calls/templates - styled.button(...)
|
|
26
|
+
JSXOpeningElement(node) {
|
|
27
|
+
if (!isNodeOfType(node, 'JSXOpeningElement')) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if (!isNodeOfType(node.name, 'JSXIdentifier')) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const suggest = shouldSuggest(node === null || node === void 0 ? void 0 : node.parent);
|
|
34
|
+
if (suggest) {
|
|
35
|
+
context.report({
|
|
36
|
+
node: node,
|
|
37
|
+
messageId: 'noHtmlButtonElement',
|
|
38
|
+
data: {
|
|
39
|
+
element: node.name.name
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
// styled.button`` | styled2.button`` | styled.button()
|
|
45
|
+
'MemberExpression[object.name="styled"],MemberExpression[object.name="styled2"]': node => {
|
|
46
|
+
if (!isNodeOfType(node, 'MemberExpression')) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// styled.button``
|
|
51
|
+
if (isNodeOfType(node.property, 'Identifier')) {
|
|
52
|
+
if (node.property.name === 'button') {
|
|
53
|
+
const styledIdentifier = node.object.name;
|
|
54
|
+
const elementName = node.property.name;
|
|
55
|
+
|
|
56
|
+
// Including the `styled.` portion in the message to help makers understand it's not just the `button` element that should be replaced
|
|
57
|
+
const reportName = `${styledIdentifier}.${elementName}`; // styled.button
|
|
58
|
+
|
|
59
|
+
context.report({
|
|
60
|
+
node: node,
|
|
61
|
+
messageId: 'noHtmlButtonElement',
|
|
62
|
+
data: {
|
|
63
|
+
element: reportName
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
// styled(X)``
|
|
70
|
+
'CallExpression[callee.name="styled"]': node => {
|
|
71
|
+
if (!isNodeOfType(node, 'CallExpression')) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// styled('button')`` - We only care about 'button', ignore extending other components
|
|
76
|
+
if (isNodeOfType(node.arguments[0], 'Literal')) {
|
|
77
|
+
const argValue = node.arguments[0].raw;
|
|
78
|
+
if (typeof argValue === 'string') {
|
|
79
|
+
const suggest = argValue.replaceAll(`'`, '') === 'button';
|
|
80
|
+
if (suggest) {
|
|
81
|
+
const styledIdentifier = node.callee.name;
|
|
82
|
+
const elementName = argValue;
|
|
83
|
+
|
|
84
|
+
// Including the `styled()` portion in the message to help makers understand it's not just the `button` element that should be replaced
|
|
85
|
+
const reportName = `${styledIdentifier}(${elementName})`; // styled('button')
|
|
86
|
+
|
|
87
|
+
context.report({
|
|
88
|
+
node: node,
|
|
89
|
+
messageId: 'noHtmlButtonElement',
|
|
90
|
+
data: {
|
|
91
|
+
element: reportName
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
export default rule;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
-
export const validPrimitiveElements = new Set(['div', 'span', 'article', 'aside', 'dialog', 'footer', 'header', 'li', 'main', 'nav', 'ol', 'section', 'ul']);
|
|
2
|
+
export const validPrimitiveElements = new Set(['div', 'span', 'article', 'aside', 'dialog', 'footer', 'header', 'li', 'main', 'nav', 'ol', 'section', 'ul', 'button']);
|
|
3
3
|
const getChildrenByType = (node, types) => {
|
|
4
4
|
return node.children.filter(child => {
|
|
5
5
|
return types.find(type => isNodeOfType(child, type));
|
|
@@ -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::bcb633b9d5c2def00d43b11139433c5c>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -18,6 +18,7 @@ export default {
|
|
|
18
18
|
'@atlaskit/design-system/no-empty-styled-expression': 'warn',
|
|
19
19
|
'@atlaskit/design-system/no-exported-css': 'warn',
|
|
20
20
|
'@atlaskit/design-system/no-exported-keyframes': 'warn',
|
|
21
|
+
'@atlaskit/design-system/no-html-button-element': 'warn',
|
|
21
22
|
'@atlaskit/design-system/no-invalid-css-map': 'error',
|
|
22
23
|
'@atlaskit/design-system/no-keyframes-tagged-template-expression': 'error',
|
|
23
24
|
'@atlaskit/design-system/no-margin': 'warn',
|