@atlaskit/eslint-plugin-design-system 13.32.0 → 13.34.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 +14 -0
- package/README.md +2 -0
- package/dist/cjs/presets/all-flat.codegen.js +3 -1
- package/dist/cjs/presets/all.codegen.js +3 -1
- package/dist/cjs/presets/recommended-flat.codegen.js +3 -1
- package/dist/cjs/presets/recommended.codegen.js +3 -1
- package/dist/cjs/rules/index.codegen.js +5 -1
- package/dist/cjs/rules/use-simple-field/index.js +138 -0
- package/dist/cjs/rules/use-simple-form/index.js +162 -0
- package/dist/es2019/presets/all-flat.codegen.js +3 -1
- package/dist/es2019/presets/all.codegen.js +3 -1
- package/dist/es2019/presets/recommended-flat.codegen.js +3 -1
- package/dist/es2019/presets/recommended.codegen.js +3 -1
- package/dist/es2019/rules/index.codegen.js +5 -1
- package/dist/es2019/rules/use-simple-field/index.js +124 -0
- package/dist/es2019/rules/use-simple-form/index.js +150 -0
- package/dist/esm/presets/all-flat.codegen.js +3 -1
- package/dist/esm/presets/all.codegen.js +3 -1
- package/dist/esm/presets/recommended-flat.codegen.js +3 -1
- package/dist/esm/presets/recommended.codegen.js +3 -1
- package/dist/esm/rules/index.codegen.js +5 -1
- package/dist/esm/rules/use-simple-field/index.js +132 -0
- package/dist/esm/rules/use-simple-form/index.js +156 -0
- package/dist/types/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types/presets/all.codegen.d.ts +1 -1
- package/dist/types/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types/presets/recommended.codegen.d.ts +1 -1
- package/dist/types/rules/index.codegen.d.ts +1 -1
- package/dist/types/rules/use-simple-field/index.d.ts +4 -0
- package/dist/types/rules/use-simple-form/index.d.ts +5 -0
- package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/use-simple-field/index.d.ts +4 -0
- package/dist/types-ts4.5/rules/use-simple-form/index.d.ts +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 13.34.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`dd764a0fde24c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dd764a0fde24c) -
|
|
8
|
+
Add rule to enforce simple ADS forms.
|
|
9
|
+
|
|
10
|
+
## 13.33.0
|
|
11
|
+
|
|
12
|
+
### Minor Changes
|
|
13
|
+
|
|
14
|
+
- [`dfd88c3eda55b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/dfd88c3eda55b) -
|
|
15
|
+
Add rule to enforce simplified fields in form implementations.
|
|
16
|
+
|
|
3
17
|
## 13.32.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -116,6 +116,8 @@ module.exports = {
|
|
|
116
116
|
| <a href="./src/rules/use-primitives/README.md">use-primitives</a> | Encourage the usage of primitives components. | | Yes | Yes |
|
|
117
117
|
| <a href="./src/rules/use-primitives-text/README.md">use-primitives-text</a> | Encourage the usage of text components. | Yes | Yes | Yes |
|
|
118
118
|
| <a href="./src/rules/use-should-render-to-parent/README.md">use-should-render-to-parent</a> | Encourages makers to use the `shouldRenderToParent` where possible in Atlassian Design System `Popup` and `DropdownMenu` components. | Yes | | Yes |
|
|
119
|
+
| <a href="./src/rules/use-simple-field/README.md">use-simple-field</a> | Encourage use of simple field for better developer experience and accessibility. | Yes | | Yes |
|
|
120
|
+
| <a href="./src/rules/use-simple-form/README.md">use-simple-form</a> | Encourage use of simple form for better developer experience and accessibility. | Yes | | Yes |
|
|
119
121
|
| <a href="./src/rules/use-spotlight-package/README.md">use-spotlight-package</a> | Discourage the use of @atlaskit/onboarding in favor of @atlaskit/spotlight. | | Yes | Yes |
|
|
120
122
|
| <a href="./src/rules/use-tag-group-label/README.md">use-tag-group-label</a> | Ensures tag groups are described to assistive technology by a direct label or by another element. | Yes | | Yes |
|
|
121
123
|
| <a href="./src/rules/use-tokens-shape/README.md">use-tokens-shape</a> | Enforces usage of shape design tokens rather than hard-coded values. | | 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::1e1e5efbb1ffcefdebdd86064e50fd4a>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -80,6 +80,8 @@ var rules = {
|
|
|
80
80
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
81
81
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
82
82
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
83
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
84
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
83
85
|
'@atlaskit/design-system/use-spotlight-package': 'warn',
|
|
84
86
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
85
87
|
'@atlaskit/design-system/use-tokens-shape': 'error',
|
|
@@ -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::474fa7fcdd540003aa6622a9e52497fa>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -79,6 +79,8 @@ var rules = {
|
|
|
79
79
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
80
80
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
81
81
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
82
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
83
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
82
84
|
'@atlaskit/design-system/use-spotlight-package': 'warn',
|
|
83
85
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
84
86
|
'@atlaskit/design-system/use-tokens-shape': 'error',
|
|
@@ -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::cb96c76e14fd1bfeec1ecf16f2787d10>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -62,6 +62,8 @@ var rules = {
|
|
|
62
62
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
63
63
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
64
64
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
65
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
66
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
65
67
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
66
68
|
'@atlaskit/design-system/use-tokens-typography': 'warn',
|
|
67
69
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
@@ -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::7d6723309ffe428e466de19a384d02c9>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -61,6 +61,8 @@ var rules = {
|
|
|
61
61
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
62
62
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
63
63
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
64
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
65
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
64
66
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
65
67
|
'@atlaskit/design-system/use-tokens-typography': 'warn',
|
|
66
68
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
@@ -72,6 +72,8 @@ var _usePopupLabel = _interopRequireDefault(require("./use-popup-label"));
|
|
|
72
72
|
var _usePrimitives = _interopRequireDefault(require("./use-primitives"));
|
|
73
73
|
var _usePrimitivesText = _interopRequireDefault(require("./use-primitives-text"));
|
|
74
74
|
var _useShouldRenderToParent = _interopRequireDefault(require("./use-should-render-to-parent"));
|
|
75
|
+
var _useSimpleField = _interopRequireDefault(require("./use-simple-field"));
|
|
76
|
+
var _useSimpleForm = _interopRequireDefault(require("./use-simple-form"));
|
|
75
77
|
var _useSpotlightPackage = _interopRequireDefault(require("./use-spotlight-package"));
|
|
76
78
|
var _useTagGroupLabel = _interopRequireDefault(require("./use-tag-group-label"));
|
|
77
79
|
var _useTokensShape = _interopRequireDefault(require("./use-tokens-shape"));
|
|
@@ -80,7 +82,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
|
|
|
80
82
|
var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
|
|
81
83
|
/**
|
|
82
84
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
83
|
-
* @codegen <<SignedSource::
|
|
85
|
+
* @codegen <<SignedSource::f9f7263c6ed88b95a13cbfbe56cfc380>>
|
|
84
86
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
85
87
|
*/
|
|
86
88
|
|
|
@@ -152,6 +154,8 @@ var rules = exports.rules = {
|
|
|
152
154
|
'use-primitives': _usePrimitives.default,
|
|
153
155
|
'use-primitives-text': _usePrimitivesText.default,
|
|
154
156
|
'use-should-render-to-parent': _useShouldRenderToParent.default,
|
|
157
|
+
'use-simple-field': _useSimpleField.default,
|
|
158
|
+
'use-simple-form': _useSimpleForm.default,
|
|
155
159
|
'use-spotlight-package': _useSpotlightPackage.default,
|
|
156
160
|
'use-tag-group-label': _useTagGroupLabel.default,
|
|
157
161
|
'use-tokens-shape': _useTokensShape.default,
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.convertField = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var _createRule = require("../utils/create-rule");
|
|
9
|
+
var FORM_PACKAGE = '@atlaskit/form';
|
|
10
|
+
var MESSAGE_COMPONENTS = ['ErrorMessage', 'HelperMessage', 'ValidMessage'];
|
|
11
|
+
var convertField = exports.convertField = 'Convert field to simple field';
|
|
12
|
+
var rule = (0, _createRule.createLintRule)({
|
|
13
|
+
meta: {
|
|
14
|
+
name: 'use-simple-field',
|
|
15
|
+
type: 'suggestion',
|
|
16
|
+
hasSuggestions: true,
|
|
17
|
+
docs: {
|
|
18
|
+
description: 'Encourage use of simple field for better developer experience and accessibility.',
|
|
19
|
+
recommended: true,
|
|
20
|
+
severity: 'warn'
|
|
21
|
+
},
|
|
22
|
+
messages: {
|
|
23
|
+
useSimpleField: 'The simplified field implementation can be used here.'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
create: function create(context) {
|
|
27
|
+
var fieldImport;
|
|
28
|
+
var messageImports = [];
|
|
29
|
+
return {
|
|
30
|
+
ImportDeclaration: function ImportDeclaration(node) {
|
|
31
|
+
var source = node.source.value;
|
|
32
|
+
|
|
33
|
+
// Ignore anomalies
|
|
34
|
+
if (typeof source !== 'string') {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (!node.specifiers.length) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// If it's not from our package, ignore.
|
|
42
|
+
if (source !== FORM_PACKAGE) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
var namedImportSpecifiers = node.specifiers.filter(function (spec) {
|
|
46
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(spec, 'ImportSpecifier');
|
|
47
|
+
});
|
|
48
|
+
namedImportSpecifiers.forEach(function (spec) {
|
|
49
|
+
if (spec.type === 'ImportSpecifier' && 'name' in spec.imported) {
|
|
50
|
+
var name = spec.imported.name;
|
|
51
|
+
var local = spec.local;
|
|
52
|
+
if (MESSAGE_COMPONENTS.includes(name)) {
|
|
53
|
+
messageImports.push(local);
|
|
54
|
+
} else if (name === 'Field') {
|
|
55
|
+
fieldImport = local.name;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
JSXElement: function JSXElement(node) {
|
|
61
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// if no field import exists, skip
|
|
69
|
+
if (!fieldImport) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// if component is not field, skip
|
|
74
|
+
if (node.openingElement.name.name !== fieldImport) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// if message imports exist, skip because we can't really dig around
|
|
79
|
+
// inside the field to see if they exist because of memory constraints
|
|
80
|
+
if (messageImports.length > 0) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// if component exists as a prop, skip because it's already simple
|
|
85
|
+
var attributes = node.openingElement.attributes;
|
|
86
|
+
var componentAttr = attributes.find(function (attr) {
|
|
87
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && (0, _eslintCodemodUtils.isNodeOfType)(attr.name, 'JSXIdentifier') && attr.name.name === 'component';
|
|
88
|
+
});
|
|
89
|
+
if (componentAttr) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// if children is not a render prop, skip
|
|
94
|
+
var renderProps = node.children.find(function (child) {
|
|
95
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(child, 'JSXExpressionContainer');
|
|
96
|
+
});
|
|
97
|
+
if (!renderProps) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
var renderPropExpression = renderProps.expression;
|
|
101
|
+
// If not an arrow func, ignore
|
|
102
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(renderPropExpression, 'ArrowFunctionExpression')) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
var renderPropParams = renderPropExpression.params;
|
|
106
|
+
// if it is not an object pattern, skip
|
|
107
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(renderPropParams[0], 'ObjectPattern')) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// if component uses more than just fieldProps in render props, skip
|
|
111
|
+
var renderPropArgProperties = renderPropParams[0].properties;
|
|
112
|
+
var fieldPropsProp = renderPropArgProperties.find(function (property) {
|
|
113
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(property, 'Property') && (0, _eslintCodemodUtils.isNodeOfType)(property.key, 'Identifier') && property.key.name === 'fieldProps';
|
|
114
|
+
});
|
|
115
|
+
if (renderPropArgProperties.length > 1 || !fieldPropsProp) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
var lastProp = attributes.slice(-1)[0] || node.openingElement.name;
|
|
119
|
+
var sourceCode = context.sourceCode;
|
|
120
|
+
var renderPropsText = sourceCode.getText(renderProps);
|
|
121
|
+
context.report({
|
|
122
|
+
node: node,
|
|
123
|
+
messageId: 'useSimpleField',
|
|
124
|
+
suggest: [{
|
|
125
|
+
desc: convertField,
|
|
126
|
+
fix: function fix(fixer) {
|
|
127
|
+
var fixes = [];
|
|
128
|
+
fixes.push(fixer.insertTextAfter(lastProp, " component=".concat(renderPropsText, " ")));
|
|
129
|
+
fixes.push(fixer.remove(renderProps));
|
|
130
|
+
return fixes;
|
|
131
|
+
}
|
|
132
|
+
}]
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
var _default = exports.default = rule;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.topLevelAttributeNames = exports.default = exports.convertForm = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var _createRule = require("../utils/create-rule");
|
|
9
|
+
var FORM_PACKAGE = '@atlaskit/form';
|
|
10
|
+
var topLevelAttributeNames = exports.topLevelAttributeNames = ['autocomplete', 'id', 'label', 'labelId', 'onKeyDown', 'onSubmit', 'name', 'noValidate', 'ref', 'xcss'];
|
|
11
|
+
var convertForm = exports.convertForm = 'Convert form to simple form';
|
|
12
|
+
var rule = (0, _createRule.createLintRule)({
|
|
13
|
+
meta: {
|
|
14
|
+
name: 'use-simple-form',
|
|
15
|
+
type: 'suggestion',
|
|
16
|
+
hasSuggestions: true,
|
|
17
|
+
docs: {
|
|
18
|
+
description: 'Encourage use of simple form for better developer experience and accessibility.',
|
|
19
|
+
recommended: true,
|
|
20
|
+
severity: 'warn'
|
|
21
|
+
},
|
|
22
|
+
messages: {
|
|
23
|
+
useSimpleForm: 'The simplified form implementation can be used here.'
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
create: function create(context) {
|
|
27
|
+
var formImport;
|
|
28
|
+
return {
|
|
29
|
+
ImportDeclaration: function ImportDeclaration(node) {
|
|
30
|
+
var source = node.source.value;
|
|
31
|
+
|
|
32
|
+
// Ignore anomalies
|
|
33
|
+
if (typeof source !== 'string') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!node.specifiers.length) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// If it's not from our package, ignore.
|
|
41
|
+
if (source !== FORM_PACKAGE) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var defaultImportSpecifiers = node.specifiers.filter(function (spec) {
|
|
45
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(spec, 'ImportDefaultSpecifier');
|
|
46
|
+
});
|
|
47
|
+
if (defaultImportSpecifiers.length > 0) {
|
|
48
|
+
formImport = defaultImportSpecifiers[0].local.name;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
JSXElement: function JSXElement(node) {
|
|
52
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// if no form import exists, skip
|
|
60
|
+
if (!formImport) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// if component is not field, skip
|
|
65
|
+
if (node.openingElement.name.name !== formImport) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// if children is not a render prop, skip
|
|
70
|
+
var renderProps = node.children.find(function (child) {
|
|
71
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(child, 'JSXExpressionContainer');
|
|
72
|
+
});
|
|
73
|
+
if (!renderProps) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
var renderPropExpression = renderProps.expression;
|
|
77
|
+
// If not an arrow func, ignore
|
|
78
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(renderPropExpression, 'ArrowFunctionExpression')) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
var renderPropParams = renderPropExpression.params;
|
|
82
|
+
// if it is not an object pattern, skip
|
|
83
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(renderPropParams[0], 'ObjectPattern')) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// if component uses more than just formProps in render props, skip
|
|
87
|
+
var renderPropArgProperties = renderPropParams[0].properties;
|
|
88
|
+
var formPropsProp = renderPropArgProperties.find(function (property) {
|
|
89
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(property, 'Property') && (0, _eslintCodemodUtils.isNodeOfType)(property.key, 'Identifier') && property.key.name === 'formProps';
|
|
90
|
+
});
|
|
91
|
+
if (renderPropArgProperties.length > 1 || !formPropsProp) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
var attributes = node.openingElement.attributes;
|
|
95
|
+
var lastProp = attributes.slice(-1)[0] || node.openingElement.name;
|
|
96
|
+
var sourceCode = context.sourceCode;
|
|
97
|
+
|
|
98
|
+
// if html form is not first child, don't give a fix
|
|
99
|
+
var renderPropBody = renderPropExpression.body;
|
|
100
|
+
var firstChildIsHTMLForm = (0, _eslintCodemodUtils.isNodeOfType)(renderPropBody, 'JSXElement') && (0, _eslintCodemodUtils.isNodeOfType)(renderPropBody.openingElement.name, 'JSXIdentifier') && renderPropBody.openingElement.name.name === 'form';
|
|
101
|
+
|
|
102
|
+
// If this is not an HTML form. skip because we can't convert
|
|
103
|
+
if (!firstChildIsHTMLForm) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
context.report({
|
|
107
|
+
node: node,
|
|
108
|
+
messageId: 'useSimpleForm',
|
|
109
|
+
suggest: [{
|
|
110
|
+
desc: convertForm,
|
|
111
|
+
fix: function fix(fixer) {
|
|
112
|
+
var fixes = [];
|
|
113
|
+
|
|
114
|
+
// add each attribute in the HTML form inside to the AK form
|
|
115
|
+
var attrs = {
|
|
116
|
+
topLevel: [],
|
|
117
|
+
formProps: []
|
|
118
|
+
};
|
|
119
|
+
var htmlFormAttributes = renderPropBody.openingElement.attributes;
|
|
120
|
+
htmlFormAttributes.forEach(function (attr) {
|
|
121
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && (0, _eslintCodemodUtils.isNodeOfType)(attr.name, 'JSXIdentifier')) {
|
|
122
|
+
if (topLevelAttributeNames.includes(attr.name.name)) {
|
|
123
|
+
attrs.topLevel.push(attr);
|
|
124
|
+
} else {
|
|
125
|
+
attrs.formProps.push(attr);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
attrs.topLevel.forEach(function (attr) {
|
|
130
|
+
fixes.push(fixer.insertTextAfter(lastProp, " ".concat(sourceCode.getText(attr))));
|
|
131
|
+
});
|
|
132
|
+
if (attrs.formProps.length > 0) {
|
|
133
|
+
var formPropsText = attrs.formProps.map(function (attr) {
|
|
134
|
+
return sourceCode.getText(attr).replace(/^([^=]*)/, "'$1'").replace('=', ': ');
|
|
135
|
+
}).join(',\n');
|
|
136
|
+
fixes.push(fixer.insertTextAfter(lastProp, " formProps={{\n".concat(formPropsText, "\n}} ")));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// remove the body of the AK form
|
|
140
|
+
fixes.push(fixer.remove(renderProps));
|
|
141
|
+
|
|
142
|
+
// Get all children text of HTML form to be added to AK form
|
|
143
|
+
var childrenText = '<>';
|
|
144
|
+
renderPropBody.children.forEach(function (child) {
|
|
145
|
+
// Doing `as any` because it doesn't like spread props. I
|
|
146
|
+
// added a test that verifies that this does indeed work,
|
|
147
|
+
// though, so it's fine.
|
|
148
|
+
childrenText += sourceCode.getText(child);
|
|
149
|
+
});
|
|
150
|
+
childrenText += '</>';
|
|
151
|
+
|
|
152
|
+
// Add the children of the HTML form to the children of the AK form
|
|
153
|
+
node.closingElement && fixes.push(fixer.insertTextBefore(node.closingElement, childrenText));
|
|
154
|
+
return fixes;
|
|
155
|
+
}
|
|
156
|
+
}]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
var _default = exports.default = rule;
|
|
@@ -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::1e1e5efbb1ffcefdebdd86064e50fd4a>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -74,6 +74,8 @@ const rules = {
|
|
|
74
74
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
75
75
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
76
76
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
77
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
78
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
77
79
|
'@atlaskit/design-system/use-spotlight-package': 'warn',
|
|
78
80
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
79
81
|
'@atlaskit/design-system/use-tokens-shape': 'error',
|
|
@@ -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::474fa7fcdd540003aa6622a9e52497fa>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -73,6 +73,8 @@ const rules = {
|
|
|
73
73
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
74
74
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
75
75
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
76
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
77
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
76
78
|
'@atlaskit/design-system/use-spotlight-package': 'warn',
|
|
77
79
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
78
80
|
'@atlaskit/design-system/use-tokens-shape': 'error',
|
|
@@ -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::cb96c76e14fd1bfeec1ecf16f2787d10>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -56,6 +56,8 @@ const rules = {
|
|
|
56
56
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
57
57
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
58
58
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
59
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
60
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
59
61
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
60
62
|
'@atlaskit/design-system/use-tokens-typography': 'warn',
|
|
61
63
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
@@ -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::7d6723309ffe428e466de19a384d02c9>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -55,6 +55,8 @@ const rules = {
|
|
|
55
55
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
56
56
|
'@atlaskit/design-system/use-primitives-text': 'warn',
|
|
57
57
|
'@atlaskit/design-system/use-should-render-to-parent': 'warn',
|
|
58
|
+
'@atlaskit/design-system/use-simple-field': 'warn',
|
|
59
|
+
'@atlaskit/design-system/use-simple-form': 'warn',
|
|
58
60
|
'@atlaskit/design-system/use-tag-group-label': 'warn',
|
|
59
61
|
'@atlaskit/design-system/use-tokens-typography': 'warn',
|
|
60
62
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
@@ -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::f9f7263c6ed88b95a13cbfbe56cfc380>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -71,6 +71,8 @@ import usePopupLabel from './use-popup-label';
|
|
|
71
71
|
import usePrimitives from './use-primitives';
|
|
72
72
|
import usePrimitivesText from './use-primitives-text';
|
|
73
73
|
import useShouldRenderToParent from './use-should-render-to-parent';
|
|
74
|
+
import useSimpleField from './use-simple-field';
|
|
75
|
+
import useSimpleForm from './use-simple-form';
|
|
74
76
|
import useSpotlightPackage from './use-spotlight-package';
|
|
75
77
|
import useTagGroupLabel from './use-tag-group-label';
|
|
76
78
|
import useTokensShape from './use-tokens-shape';
|
|
@@ -145,6 +147,8 @@ export const rules = {
|
|
|
145
147
|
'use-primitives': usePrimitives,
|
|
146
148
|
'use-primitives-text': usePrimitivesText,
|
|
147
149
|
'use-should-render-to-parent': useShouldRenderToParent,
|
|
150
|
+
'use-simple-field': useSimpleField,
|
|
151
|
+
'use-simple-form': useSimpleForm,
|
|
148
152
|
'use-spotlight-package': useSpotlightPackage,
|
|
149
153
|
'use-tag-group-label': useTagGroupLabel,
|
|
150
154
|
'use-tokens-shape': useTokensShape,
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
const FORM_PACKAGE = '@atlaskit/form';
|
|
4
|
+
const MESSAGE_COMPONENTS = ['ErrorMessage', 'HelperMessage', 'ValidMessage'];
|
|
5
|
+
export const convertField = 'Convert field to simple field';
|
|
6
|
+
const rule = createLintRule({
|
|
7
|
+
meta: {
|
|
8
|
+
name: 'use-simple-field',
|
|
9
|
+
type: 'suggestion',
|
|
10
|
+
hasSuggestions: true,
|
|
11
|
+
docs: {
|
|
12
|
+
description: 'Encourage use of simple field for better developer experience and accessibility.',
|
|
13
|
+
recommended: true,
|
|
14
|
+
severity: 'warn'
|
|
15
|
+
},
|
|
16
|
+
messages: {
|
|
17
|
+
useSimpleField: 'The simplified field implementation can be used here.'
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
let fieldImport;
|
|
22
|
+
let messageImports = [];
|
|
23
|
+
return {
|
|
24
|
+
ImportDeclaration(node) {
|
|
25
|
+
const source = node.source.value;
|
|
26
|
+
|
|
27
|
+
// Ignore anomalies
|
|
28
|
+
if (typeof source !== 'string') {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!node.specifiers.length) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// If it's not from our package, ignore.
|
|
36
|
+
if (source !== FORM_PACKAGE) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const namedImportSpecifiers = node.specifiers.filter(spec => isNodeOfType(spec, 'ImportSpecifier'));
|
|
40
|
+
namedImportSpecifiers.forEach(spec => {
|
|
41
|
+
if (spec.type === 'ImportSpecifier' && 'name' in spec.imported) {
|
|
42
|
+
const name = spec.imported.name;
|
|
43
|
+
const local = spec.local;
|
|
44
|
+
if (MESSAGE_COMPONENTS.includes(name)) {
|
|
45
|
+
messageImports.push(local);
|
|
46
|
+
} else if (name === 'Field') {
|
|
47
|
+
fieldImport = local.name;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
JSXElement(node) {
|
|
53
|
+
if (!isNodeOfType(node, 'JSXElement')) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// if no field import exists, skip
|
|
61
|
+
if (!fieldImport) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// if component is not field, skip
|
|
66
|
+
if (node.openingElement.name.name !== fieldImport) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// if message imports exist, skip because we can't really dig around
|
|
71
|
+
// inside the field to see if they exist because of memory constraints
|
|
72
|
+
if (messageImports.length > 0) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// if component exists as a prop, skip because it's already simple
|
|
77
|
+
const attributes = node.openingElement.attributes;
|
|
78
|
+
const componentAttr = attributes.find(attr => isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && attr.name.name === 'component');
|
|
79
|
+
if (componentAttr) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// if children is not a render prop, skip
|
|
84
|
+
const renderProps = node.children.find(child => isNodeOfType(child, 'JSXExpressionContainer'));
|
|
85
|
+
if (!renderProps) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const renderPropExpression = renderProps.expression;
|
|
89
|
+
// If not an arrow func, ignore
|
|
90
|
+
if (!isNodeOfType(renderPropExpression, 'ArrowFunctionExpression')) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const renderPropParams = renderPropExpression.params;
|
|
94
|
+
// if it is not an object pattern, skip
|
|
95
|
+
if (!isNodeOfType(renderPropParams[0], 'ObjectPattern')) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// if component uses more than just fieldProps in render props, skip
|
|
99
|
+
const renderPropArgProperties = renderPropParams[0].properties;
|
|
100
|
+
const fieldPropsProp = renderPropArgProperties.find(property => isNodeOfType(property, 'Property') && isNodeOfType(property.key, 'Identifier') && property.key.name === 'fieldProps');
|
|
101
|
+
if (renderPropArgProperties.length > 1 || !fieldPropsProp) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const lastProp = attributes.slice(-1)[0] || node.openingElement.name;
|
|
105
|
+
const sourceCode = context.sourceCode;
|
|
106
|
+
const renderPropsText = sourceCode.getText(renderProps);
|
|
107
|
+
context.report({
|
|
108
|
+
node: node,
|
|
109
|
+
messageId: 'useSimpleField',
|
|
110
|
+
suggest: [{
|
|
111
|
+
desc: convertField,
|
|
112
|
+
fix: fixer => {
|
|
113
|
+
const fixes = [];
|
|
114
|
+
fixes.push(fixer.insertTextAfter(lastProp, ` component=${renderPropsText} `));
|
|
115
|
+
fixes.push(fixer.remove(renderProps));
|
|
116
|
+
return fixes;
|
|
117
|
+
}
|
|
118
|
+
}]
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
export default rule;
|