@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.
Files changed (38) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -0
  3. package/dist/cjs/presets/all-flat.codegen.js +3 -1
  4. package/dist/cjs/presets/all.codegen.js +3 -1
  5. package/dist/cjs/presets/recommended-flat.codegen.js +3 -1
  6. package/dist/cjs/presets/recommended.codegen.js +3 -1
  7. package/dist/cjs/rules/index.codegen.js +5 -1
  8. package/dist/cjs/rules/use-simple-field/index.js +138 -0
  9. package/dist/cjs/rules/use-simple-form/index.js +162 -0
  10. package/dist/es2019/presets/all-flat.codegen.js +3 -1
  11. package/dist/es2019/presets/all.codegen.js +3 -1
  12. package/dist/es2019/presets/recommended-flat.codegen.js +3 -1
  13. package/dist/es2019/presets/recommended.codegen.js +3 -1
  14. package/dist/es2019/rules/index.codegen.js +5 -1
  15. package/dist/es2019/rules/use-simple-field/index.js +124 -0
  16. package/dist/es2019/rules/use-simple-form/index.js +150 -0
  17. package/dist/esm/presets/all-flat.codegen.js +3 -1
  18. package/dist/esm/presets/all.codegen.js +3 -1
  19. package/dist/esm/presets/recommended-flat.codegen.js +3 -1
  20. package/dist/esm/presets/recommended.codegen.js +3 -1
  21. package/dist/esm/rules/index.codegen.js +5 -1
  22. package/dist/esm/rules/use-simple-field/index.js +132 -0
  23. package/dist/esm/rules/use-simple-form/index.js +156 -0
  24. package/dist/types/presets/all-flat.codegen.d.ts +1 -1
  25. package/dist/types/presets/all.codegen.d.ts +1 -1
  26. package/dist/types/presets/recommended-flat.codegen.d.ts +1 -1
  27. package/dist/types/presets/recommended.codegen.d.ts +1 -1
  28. package/dist/types/rules/index.codegen.d.ts +1 -1
  29. package/dist/types/rules/use-simple-field/index.d.ts +4 -0
  30. package/dist/types/rules/use-simple-form/index.d.ts +5 -0
  31. package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -1
  32. package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -1
  33. package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -1
  34. package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
  35. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
  36. package/dist/types-ts4.5/rules/use-simple-field/index.d.ts +4 -0
  37. package/dist/types-ts4.5/rules/use-simple-form/index.d.ts +5 -0
  38. 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::4fa72535ce2bc0a19a6fb01c951150db>>
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::dcf6bf4496c97fd6ad4c1d8d65337a6b>>
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::27c9a3631c47b134bfb9da3e921e0601>>
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::52a31bc6cdeb7a9818a0e225d21c88f2>>
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::ca89575f70ae79af2f43113bdc77c0c5>>
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::4fa72535ce2bc0a19a6fb01c951150db>>
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::dcf6bf4496c97fd6ad4c1d8d65337a6b>>
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::27c9a3631c47b134bfb9da3e921e0601>>
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::52a31bc6cdeb7a9818a0e225d21c88f2>>
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::ca89575f70ae79af2f43113bdc77c0c5>>
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;