@atlaskit/eslint-plugin-design-system 13.5.0 → 13.6.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 +8 -0
- package/README.md +1 -0
- package/dist/cjs/presets/all-flat.codegen.js +2 -1
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/presets/recommended-flat.codegen.js +2 -1
- package/dist/cjs/presets/recommended.codegen.js +2 -1
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/no-html-checkbox/index.js +34 -0
- package/dist/cjs/rules/no-html-checkbox/node-types/index.js +12 -0
- package/dist/cjs/rules/no-html-checkbox/node-types/jsx-element/index.js +27 -0
- package/dist/cjs/rules/no-html-checkbox/node-types/supported.js +70 -0
- package/dist/cjs/rules/utils/get-jsx-element-by-name.js +53 -0
- package/dist/cjs/rules/utils/get-styled-component-call.js +47 -0
- package/dist/es2019/presets/all-flat.codegen.js +2 -1
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/presets/recommended-flat.codegen.js +2 -1
- package/dist/es2019/presets/recommended.codegen.js +2 -1
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/no-html-checkbox/index.js +28 -0
- package/dist/es2019/rules/no-html-checkbox/node-types/index.js +1 -0
- package/dist/es2019/rules/no-html-checkbox/node-types/jsx-element/index.js +19 -0
- package/dist/es2019/rules/no-html-checkbox/node-types/supported.js +60 -0
- package/dist/es2019/rules/utils/get-jsx-element-by-name.js +39 -0
- package/dist/es2019/rules/utils/get-styled-component-call.js +42 -0
- package/dist/esm/presets/all-flat.codegen.js +2 -1
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/presets/recommended-flat.codegen.js +2 -1
- package/dist/esm/presets/recommended.codegen.js +2 -1
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/no-html-checkbox/index.js +28 -0
- package/dist/esm/rules/no-html-checkbox/node-types/index.js +1 -0
- package/dist/esm/rules/no-html-checkbox/node-types/jsx-element/index.js +18 -0
- package/dist/esm/rules/no-html-checkbox/node-types/supported.js +61 -0
- package/dist/esm/rules/utils/get-jsx-element-by-name.js +47 -0
- package/dist/esm/rules/utils/get-styled-component-call.js +42 -0
- package/dist/types/index.codegen.d.ts +9 -0
- package/dist/types/presets/all-flat.codegen.d.ts +1 -0
- package/dist/types/presets/all.codegen.d.ts +1 -0
- package/dist/types/presets/recommended-flat.codegen.d.ts +1 -0
- package/dist/types/presets/recommended.codegen.d.ts +1 -0
- package/dist/types/rules/index.codegen.d.ts +1 -0
- package/dist/types/rules/no-html-checkbox/index.d.ts +3 -0
- package/dist/types/rules/no-html-checkbox/node-types/index.d.ts +1 -0
- package/dist/types/rules/no-html-checkbox/node-types/jsx-element/index.d.ts +8 -0
- package/dist/types/rules/no-html-checkbox/node-types/supported.d.ts +7 -0
- package/dist/types/rules/utils/get-jsx-element-by-name.d.ts +6 -0
- package/dist/types/rules/utils/get-styled-component-call.d.ts +6 -0
- package/dist/types-ts4.5/index.codegen.d.ts +9 -0
- package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -0
- package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -0
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/no-html-checkbox/index.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-html-checkbox/node-types/index.d.ts +1 -0
- package/dist/types-ts4.5/rules/no-html-checkbox/node-types/jsx-element/index.d.ts +8 -0
- package/dist/types-ts4.5/rules/no-html-checkbox/node-types/supported.d.ts +7 -0
- package/dist/types-ts4.5/rules/utils/get-jsx-element-by-name.d.ts +6 -0
- package/dist/types-ts4.5/rules/utils/get-styled-component-call.d.ts +6 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 13.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#145045](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/145045)
|
|
8
|
+
[`5aa392ee60fd9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5aa392ee60fd9) -
|
|
9
|
+
Add rule to encourage the usage of ADS checkboxes over native checkbox input elements.
|
|
10
|
+
|
|
3
11
|
## 13.5.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -68,6 +68,7 @@ module.exports = {
|
|
|
68
68
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-exported-keyframes/README.md">no-exported-keyframes</a> | Forbid exporting `keyframes` function calls. Exporting `css` function calls can result in unexpected behaviour at runtime, and is not statically analysable. | | | |
|
|
69
69
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-html-anchor/README.md">no-html-anchor</a> | Discourage direct usage of HTML anchor elements in favor of Atlassian Design System link components. | Yes | | Yes |
|
|
70
70
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-html-button/README.md">no-html-button</a> | Discourage direct usage of HTML button elements in favor of Atlassian Design System button components. | Yes | | |
|
|
71
|
+
| <a href="./packages/design-system/eslint-plugin/src/rules/no-html-checkbox/README.md">no-html-checkbox</a> | Discourage direct usage of HTML checkbox elements in favor of the Atlassian Design System checkbox component. | Yes | | Yes |
|
|
71
72
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-invalid-css-map/README.md">no-invalid-css-map</a> | Checks the validity of a CSS map created through cssMap. This is intended to be used alongside TypeScript's type-checking. | Yes | | |
|
|
72
73
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-keyframes-tagged-template-expression/README.md">no-keyframes-tagged-template-expression</a> | Disallows any `keyframe` tagged template expressions that originate from Emotion, Styled Components or Compiled | | Yes | |
|
|
73
74
|
| <a href="./packages/design-system/eslint-plugin/src/rules/no-legacy-icons/README.md">no-legacy-icons</a> | Enforces no legacy icons are used. | | Yes | Yes |
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
9
|
-
* @codegen <<SignedSource::
|
|
9
|
+
* @codegen <<SignedSource::c78819ddb772edbd8d5e2dc246c52d11>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -29,6 +29,7 @@ var _default = exports.default = {
|
|
|
29
29
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
30
30
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
31
31
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
32
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
32
33
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
33
34
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
34
35
|
}],
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
9
|
-
* @codegen <<SignedSource::
|
|
9
|
+
* @codegen <<SignedSource::d35975a64956ac336de205b1272c43f1>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -28,6 +28,7 @@ var _default = exports.default = {
|
|
|
28
28
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
29
29
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
30
30
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
31
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
31
32
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
32
33
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
33
34
|
}],
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
9
|
-
* @codegen <<SignedSource::
|
|
9
|
+
* @codegen <<SignedSource::b96889a18bb45c45fa23ed42442732ba>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -24,6 +24,7 @@ var _default = exports.default = {
|
|
|
24
24
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
25
25
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
26
26
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
27
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
27
28
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
28
29
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
29
30
|
}],
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
9
|
-
* @codegen <<SignedSource::
|
|
9
|
+
* @codegen <<SignedSource::bd1d631a2db18da8a0726bec36044a51>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -23,6 +23,7 @@ var _default = exports.default = {
|
|
|
23
23
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
24
24
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
25
25
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
26
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
26
27
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
27
28
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
28
29
|
}],
|
|
@@ -24,6 +24,7 @@ var _noExportedCss = _interopRequireDefault(require("./no-exported-css"));
|
|
|
24
24
|
var _noExportedKeyframes = _interopRequireDefault(require("./no-exported-keyframes"));
|
|
25
25
|
var _noHtmlAnchor = _interopRequireDefault(require("./no-html-anchor"));
|
|
26
26
|
var _noHtmlButton = _interopRequireDefault(require("./no-html-button"));
|
|
27
|
+
var _noHtmlCheckbox = _interopRequireDefault(require("./no-html-checkbox"));
|
|
27
28
|
var _noInvalidCssMap = _interopRequireDefault(require("./no-invalid-css-map"));
|
|
28
29
|
var _noKeyframesTaggedTemplateExpression = _interopRequireDefault(require("./no-keyframes-tagged-template-expression"));
|
|
29
30
|
var _noLegacyIcons = _interopRequireDefault(require("./no-legacy-icons"));
|
|
@@ -58,7 +59,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
|
|
|
58
59
|
var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
|
|
59
60
|
/**
|
|
60
61
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
61
|
-
* @codegen <<SignedSource::
|
|
62
|
+
* @codegen <<SignedSource::622bf05b9ade457d05e872b25c71ba5d>>
|
|
62
63
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
63
64
|
*/
|
|
64
65
|
|
|
@@ -82,6 +83,7 @@ var rules = exports.rules = {
|
|
|
82
83
|
'no-exported-keyframes': _noExportedKeyframes.default,
|
|
83
84
|
'no-html-anchor': _noHtmlAnchor.default,
|
|
84
85
|
'no-html-button': _noHtmlButton.default,
|
|
86
|
+
'no-html-checkbox': _noHtmlCheckbox.default,
|
|
85
87
|
'no-invalid-css-map': _noInvalidCssMap.default,
|
|
86
88
|
'no-keyframes-tagged-template-expression': _noKeyframesTaggedTemplateExpression.default,
|
|
87
89
|
'no-legacy-icons': _noLegacyIcons.default,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _createRule = require("../utils/create-rule");
|
|
8
|
+
var _nodeTypes = require("./node-types");
|
|
9
|
+
var rule = (0, _createRule.createLintRule)({
|
|
10
|
+
meta: {
|
|
11
|
+
name: 'no-html-checkbox',
|
|
12
|
+
type: 'suggestion',
|
|
13
|
+
hasSuggestions: true,
|
|
14
|
+
docs: {
|
|
15
|
+
description: 'Discourage direct usage of HTML checkbox elements in favor of the Atlassian Design System checkbox component.',
|
|
16
|
+
recommended: true,
|
|
17
|
+
severity: 'warn'
|
|
18
|
+
},
|
|
19
|
+
messages: {
|
|
20
|
+
noHtmlCheckbox: "This <{{ name }}> should be replaced with a checkbox component from the Atlassian Design System. ADS components include event tracking, ensure accessible implementations, and provide access to ADS styling features like design tokens."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
create: function create(context) {
|
|
24
|
+
return {
|
|
25
|
+
// transforms <input type="checkbox" css={...}> usages
|
|
26
|
+
JSXElement: function JSXElement(node) {
|
|
27
|
+
_nodeTypes.JSXElement.lint(node, {
|
|
28
|
+
context: context
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
var _default = exports.default = rule;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "JSXElement", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _jsxElement.JSXElement;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _jsxElement = require("./jsx-element");
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.JSXElement = void 0;
|
|
8
|
+
var ast = _interopRequireWildcard(require("../../../../ast-nodes"));
|
|
9
|
+
var _supported = require("../supported");
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
var JSXElement = exports.JSXElement = {
|
|
13
|
+
lint: function lint(node, _ref) {
|
|
14
|
+
var context = _ref.context;
|
|
15
|
+
if (!(0, _supported.isSupportedForLint)(node)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
var nodeName = ast.JSXElement.getName(node);
|
|
19
|
+
context.report({
|
|
20
|
+
node: node.openingElement,
|
|
21
|
+
messageId: 'noHtmlCheckbox',
|
|
22
|
+
data: {
|
|
23
|
+
name: nodeName
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _typeof = require("@babel/runtime/helpers/typeof");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.isSupportedForLint = isSupportedForLint;
|
|
8
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
9
|
+
var ast = _interopRequireWildcard(require("../../../ast-nodes"));
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
var supportedElements = [{
|
|
13
|
+
name: 'input',
|
|
14
|
+
attributes: [{
|
|
15
|
+
name: 'type',
|
|
16
|
+
values: ['checkbox']
|
|
17
|
+
}]
|
|
18
|
+
}];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Determines if the given JSX element is a supported element to lint with this rule.
|
|
22
|
+
*/
|
|
23
|
+
function isSupportedForLint(jsxNode, elementName) {
|
|
24
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxNode, 'JSXElement')) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Allow passing in the element name because the jsxNode doesn't
|
|
29
|
+
// represent the element name with styled components
|
|
30
|
+
var elName = elementName || ast.JSXElement.getName(jsxNode);
|
|
31
|
+
if (!elName) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Only check native HTML elements, not components
|
|
36
|
+
if (elName[0] !== elName[0].toLowerCase()) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
var supportedElement = supportedElements.find(function (_ref) {
|
|
40
|
+
var name = _ref.name;
|
|
41
|
+
return name === elName;
|
|
42
|
+
});
|
|
43
|
+
if (!supportedElement) {
|
|
44
|
+
supportedElement = supportedElements.find(function (_ref2) {
|
|
45
|
+
var name = _ref2.name;
|
|
46
|
+
return name === '*';
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
if (!supportedElement) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Check if the element has any attributes that are not supported
|
|
54
|
+
var attributes = ast.JSXElement.getAttributes(jsxNode);
|
|
55
|
+
if (supportedElement.attributes && !supportedElement.attributes.every(function (_ref3) {
|
|
56
|
+
var name = _ref3.name,
|
|
57
|
+
values = _ref3.values;
|
|
58
|
+
return attributes.some(function (attribute) {
|
|
59
|
+
if (attribute.type === 'JSXSpreadAttribute') {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
var isMatchingName = attribute.name.name === name;
|
|
63
|
+
var isMatchingValues = values && attribute.value && attribute.value.type === 'Literal' && typeof attribute.value.value === 'string' && (values === null || values === void 0 ? void 0 : values.includes(attribute.value.value));
|
|
64
|
+
return isMatchingName && isMatchingValues;
|
|
65
|
+
});
|
|
66
|
+
})) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getJsxElementByName = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
10
|
+
/**
|
|
11
|
+
* Given a component name finds its JSX usage
|
|
12
|
+
*/
|
|
13
|
+
var getJsxElementByName = exports.getJsxElementByName = function getJsxElementByName(componentName, scope) {
|
|
14
|
+
var _variableDeclaration$;
|
|
15
|
+
var variableDeclaration = scope.variables.find(function (v) {
|
|
16
|
+
return v.name === componentName;
|
|
17
|
+
});
|
|
18
|
+
if (!variableDeclaration) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// length here should be exactly 2 to indicate only two references:
|
|
23
|
+
// one being the variable declaration itself
|
|
24
|
+
// second being the JSX call site
|
|
25
|
+
// we might consider handling multiple local JSX call sites in the future
|
|
26
|
+
// but "this is good enough for now"™️
|
|
27
|
+
if (variableDeclaration.references.length !== 2) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
var jsxUsage = (_variableDeclaration$ = variableDeclaration.references[1]) === null || _variableDeclaration$ === void 0 ? void 0 : _variableDeclaration$.identifier;
|
|
31
|
+
var _variableDeclaration$2 = variableDeclaration.references.map(function (ref) {
|
|
32
|
+
return ref === null || ref === void 0 ? void 0 : ref.identifier;
|
|
33
|
+
}),
|
|
34
|
+
_variableDeclaration$3 = (0, _slicedToArray2.default)(_variableDeclaration$2, 2),
|
|
35
|
+
firstIdentifier = _variableDeclaration$3[0],
|
|
36
|
+
secondIdentifier = _variableDeclaration$3[1];
|
|
37
|
+
// Check if the first reference is a JSXOpeningElement and the second is not or vice versa
|
|
38
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(firstIdentifier, 'JSXIdentifier') && !(0, _eslintCodemodUtils.isNodeOfType)(secondIdentifier, 'JSXIdentifier')) {
|
|
39
|
+
jsxUsage = firstIdentifier;
|
|
40
|
+
} else if ((0, _eslintCodemodUtils.isNodeOfType)(secondIdentifier, 'JSXIdentifier') && !(0, _eslintCodemodUtils.isNodeOfType)(firstIdentifier, 'JSXIdentifier')) {
|
|
41
|
+
jsxUsage = secondIdentifier;
|
|
42
|
+
} else {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxUsage, 'JSXIdentifier')) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
var jsxOpeningElement = jsxUsage.parent;
|
|
49
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(jsxOpeningElement, 'JSXOpeningElement')) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
return jsxOpeningElement;
|
|
53
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getStyledComponentCall = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
/**
|
|
9
|
+
* Returns a styled component
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
var getStyledComponentCall = exports.getStyledComponentCall = function getStyledComponentCall(node) {
|
|
13
|
+
// halts unless we are dealing with a styled component
|
|
14
|
+
if (!isStyledCallExpression(node)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
// halts if the component is being exported directly
|
|
18
|
+
if ((0, _eslintCodemodUtils.closestOfType)(node, 'ExportNamedDeclaration')) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
var styledComponentVariableRef = node.parent;
|
|
22
|
+
// halts if the styled component is not assigned to a variable immediately
|
|
23
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(styledComponentVariableRef, 'VariableDeclarator')) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
return styledComponentVariableRef;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Some verbose precondition checks but all it does is check
|
|
31
|
+
* a call expression is of form `styled.a` or `styled2.a`
|
|
32
|
+
*/
|
|
33
|
+
var isStyledCallExpression = function isStyledCallExpression(call) {
|
|
34
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(call, 'CallExpression')) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee, 'MemberExpression')) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(call.callee.object, 'Identifier') || !(0, _eslintCodemodUtils.isNodeOfType)(call.callee.property, 'Identifier')) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
if (/^styled2?$/.test(call.callee.object.name)) {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
};
|
|
@@ -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::c78819ddb772edbd8d5e2dc246c52d11>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -24,6 +24,7 @@ export default {
|
|
|
24
24
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
25
25
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
26
26
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
27
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
27
28
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
28
29
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
29
30
|
}],
|
|
@@ -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::d35975a64956ac336de205b1272c43f1>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -23,6 +23,7 @@ export default {
|
|
|
23
23
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
24
24
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
25
25
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
26
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
26
27
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
27
28
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
28
29
|
}],
|
|
@@ -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::b96889a18bb45c45fa23ed42442732ba>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -19,6 +19,7 @@ export default {
|
|
|
19
19
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
20
20
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
21
21
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
22
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
22
23
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
23
24
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
24
25
|
}],
|
|
@@ -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::bd1d631a2db18da8a0726bec36044a51>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -18,6 +18,7 @@ export default {
|
|
|
18
18
|
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
19
19
|
'@atlaskit/design-system/no-html-anchor': 'warn',
|
|
20
20
|
'@atlaskit/design-system/no-html-button': 'warn',
|
|
21
|
+
'@atlaskit/design-system/no-html-checkbox': 'warn',
|
|
21
22
|
'@atlaskit/design-system/no-invalid-css-map': ['error', {
|
|
22
23
|
allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
|
|
23
24
|
}],
|
|
@@ -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::622bf05b9ade457d05e872b25c71ba5d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -22,6 +22,7 @@ import noExportedCss from './no-exported-css';
|
|
|
22
22
|
import noExportedKeyframes from './no-exported-keyframes';
|
|
23
23
|
import noHtmlAnchor from './no-html-anchor';
|
|
24
24
|
import noHtmlButton from './no-html-button';
|
|
25
|
+
import noHtmlCheckbox from './no-html-checkbox';
|
|
25
26
|
import noInvalidCssMap from './no-invalid-css-map';
|
|
26
27
|
import noKeyframesTaggedTemplateExpression from './no-keyframes-tagged-template-expression';
|
|
27
28
|
import noLegacyIcons from './no-legacy-icons';
|
|
@@ -74,6 +75,7 @@ export const rules = {
|
|
|
74
75
|
'no-exported-keyframes': noExportedKeyframes,
|
|
75
76
|
'no-html-anchor': noHtmlAnchor,
|
|
76
77
|
'no-html-button': noHtmlButton,
|
|
78
|
+
'no-html-checkbox': noHtmlCheckbox,
|
|
77
79
|
'no-invalid-css-map': noInvalidCssMap,
|
|
78
80
|
'no-keyframes-tagged-template-expression': noKeyframesTaggedTemplateExpression,
|
|
79
81
|
'no-legacy-icons': noLegacyIcons,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createLintRule } from '../utils/create-rule';
|
|
2
|
+
import { JSXElement } from './node-types';
|
|
3
|
+
const rule = createLintRule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: 'no-html-checkbox',
|
|
6
|
+
type: 'suggestion',
|
|
7
|
+
hasSuggestions: true,
|
|
8
|
+
docs: {
|
|
9
|
+
description: 'Discourage direct usage of HTML checkbox elements in favor of the Atlassian Design System checkbox component.',
|
|
10
|
+
recommended: true,
|
|
11
|
+
severity: 'warn'
|
|
12
|
+
},
|
|
13
|
+
messages: {
|
|
14
|
+
noHtmlCheckbox: `This <{{ name }}> should be replaced with a checkbox component from the Atlassian Design System. ADS components include event tracking, ensure accessible implementations, and provide access to ADS styling features like design tokens.`
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
create(context) {
|
|
18
|
+
return {
|
|
19
|
+
// transforms <input type="checkbox" css={...}> usages
|
|
20
|
+
JSXElement(node) {
|
|
21
|
+
JSXElement.lint(node, {
|
|
22
|
+
context
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
export default rule;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { JSXElement } from './jsx-element';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as ast from '../../../../ast-nodes';
|
|
2
|
+
import { isSupportedForLint } from '../supported';
|
|
3
|
+
export const JSXElement = {
|
|
4
|
+
lint(node, {
|
|
5
|
+
context
|
|
6
|
+
}) {
|
|
7
|
+
if (!isSupportedForLint(node)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const nodeName = ast.JSXElement.getName(node);
|
|
11
|
+
context.report({
|
|
12
|
+
node: node.openingElement,
|
|
13
|
+
messageId: 'noHtmlCheckbox',
|
|
14
|
+
data: {
|
|
15
|
+
name: nodeName
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import * as ast from '../../../ast-nodes';
|
|
3
|
+
const supportedElements = [{
|
|
4
|
+
name: 'input',
|
|
5
|
+
attributes: [{
|
|
6
|
+
name: 'type',
|
|
7
|
+
values: ['checkbox']
|
|
8
|
+
}]
|
|
9
|
+
}];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Determines if the given JSX element is a supported element to lint with this rule.
|
|
13
|
+
*/
|
|
14
|
+
export function isSupportedForLint(jsxNode, elementName) {
|
|
15
|
+
if (!isNodeOfType(jsxNode, 'JSXElement')) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Allow passing in the element name because the jsxNode doesn't
|
|
20
|
+
// represent the element name with styled components
|
|
21
|
+
const elName = elementName || ast.JSXElement.getName(jsxNode);
|
|
22
|
+
if (!elName) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Only check native HTML elements, not components
|
|
27
|
+
if (elName[0] !== elName[0].toLowerCase()) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
let supportedElement = supportedElements.find(({
|
|
31
|
+
name
|
|
32
|
+
}) => name === elName);
|
|
33
|
+
if (!supportedElement) {
|
|
34
|
+
supportedElement = supportedElements.find(({
|
|
35
|
+
name
|
|
36
|
+
}) => name === '*');
|
|
37
|
+
}
|
|
38
|
+
if (!supportedElement) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Check if the element has any attributes that are not supported
|
|
43
|
+
const attributes = ast.JSXElement.getAttributes(jsxNode);
|
|
44
|
+
if (supportedElement.attributes && !supportedElement.attributes.every(({
|
|
45
|
+
name,
|
|
46
|
+
values
|
|
47
|
+
}) => {
|
|
48
|
+
return attributes.some(attribute => {
|
|
49
|
+
if (attribute.type === 'JSXSpreadAttribute') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
const isMatchingName = attribute.name.name === name;
|
|
53
|
+
const isMatchingValues = values && attribute.value && attribute.value.type === 'Literal' && typeof attribute.value.value === 'string' && (values === null || values === void 0 ? void 0 : values.includes(attribute.value.value));
|
|
54
|
+
return isMatchingName && isMatchingValues;
|
|
55
|
+
});
|
|
56
|
+
})) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Given a component name finds its JSX usage
|
|
5
|
+
*/
|
|
6
|
+
export const getJsxElementByName = (componentName, scope) => {
|
|
7
|
+
var _variableDeclaration$;
|
|
8
|
+
const variableDeclaration = scope.variables.find(v => v.name === componentName);
|
|
9
|
+
if (!variableDeclaration) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// length here should be exactly 2 to indicate only two references:
|
|
14
|
+
// one being the variable declaration itself
|
|
15
|
+
// second being the JSX call site
|
|
16
|
+
// we might consider handling multiple local JSX call sites in the future
|
|
17
|
+
// but "this is good enough for now"™️
|
|
18
|
+
if (variableDeclaration.references.length !== 2) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
let jsxUsage = (_variableDeclaration$ = variableDeclaration.references[1]) === null || _variableDeclaration$ === void 0 ? void 0 : _variableDeclaration$.identifier;
|
|
22
|
+
const [firstIdentifier, secondIdentifier] = variableDeclaration.references.map(ref => ref === null || ref === void 0 ? void 0 : ref.identifier);
|
|
23
|
+
// Check if the first reference is a JSXOpeningElement and the second is not or vice versa
|
|
24
|
+
if (isNodeOfType(firstIdentifier, 'JSXIdentifier') && !isNodeOfType(secondIdentifier, 'JSXIdentifier')) {
|
|
25
|
+
jsxUsage = firstIdentifier;
|
|
26
|
+
} else if (isNodeOfType(secondIdentifier, 'JSXIdentifier') && !isNodeOfType(firstIdentifier, 'JSXIdentifier')) {
|
|
27
|
+
jsxUsage = secondIdentifier;
|
|
28
|
+
} else {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!isNodeOfType(jsxUsage, 'JSXIdentifier')) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const jsxOpeningElement = jsxUsage.parent;
|
|
35
|
+
if (!isNodeOfType(jsxOpeningElement, 'JSXOpeningElement')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
return jsxOpeningElement;
|
|
39
|
+
};
|