@atlaskit/eslint-plugin-design-system 13.31.0 → 13.33.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 (46) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +76 -75
  3. package/dist/cjs/presets/all-flat.codegen.js +3 -2
  4. package/dist/cjs/presets/all.codegen.js +3 -2
  5. package/dist/cjs/presets/recommended-flat.codegen.js +3 -2
  6. package/dist/cjs/presets/recommended.codegen.js +3 -2
  7. package/dist/cjs/rules/index.codegen.js +5 -3
  8. package/dist/cjs/rules/no-placeholder/index.js +162 -0
  9. package/dist/cjs/rules/use-simple-field/index.js +138 -0
  10. package/dist/es2019/presets/all-flat.codegen.js +3 -2
  11. package/dist/es2019/presets/all.codegen.js +3 -2
  12. package/dist/es2019/presets/recommended-flat.codegen.js +3 -2
  13. package/dist/es2019/presets/recommended.codegen.js +3 -2
  14. package/dist/es2019/rules/index.codegen.js +5 -3
  15. package/dist/es2019/rules/no-placeholder/index.js +142 -0
  16. package/dist/es2019/rules/use-simple-field/index.js +124 -0
  17. package/dist/esm/presets/all-flat.codegen.js +3 -2
  18. package/dist/esm/presets/all.codegen.js +3 -2
  19. package/dist/esm/presets/recommended-flat.codegen.js +3 -2
  20. package/dist/esm/presets/recommended.codegen.js +3 -2
  21. package/dist/esm/rules/index.codegen.js +5 -3
  22. package/dist/esm/rules/no-placeholder/index.js +154 -0
  23. package/dist/esm/rules/use-simple-field/index.js +132 -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/no-placeholder/index.d.ts +6 -0
  30. package/dist/types/rules/{no-utility-icons → use-simple-field}/index.d.ts +1 -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/no-placeholder/index.d.ts +6 -0
  37. package/dist/types-ts4.5/rules/{no-utility-icons → use-simple-field}/index.d.ts +1 -0
  38. package/package.json +2 -2
  39. package/dist/cjs/rules/no-utility-icons/checks.js +0 -246
  40. package/dist/cjs/rules/no-utility-icons/index.js +0 -49
  41. package/dist/es2019/rules/no-utility-icons/checks.js +0 -177
  42. package/dist/es2019/rules/no-utility-icons/index.js +0 -44
  43. package/dist/esm/rules/no-utility-icons/checks.js +0 -239
  44. package/dist/esm/rules/no-utility-icons/index.js +0 -43
  45. package/dist/types/rules/no-utility-icons/checks.d.ts +0 -10
  46. package/dist/types-ts4.5/rules/no-utility-icons/checks.d.ts +0 -10
@@ -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;
@@ -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::23364c0ee38a3772c2a588841ed22c55>>
3
+ * @codegen <<SignedSource::05e8a8ff80cb4a88a89ccd31570686f6>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -45,6 +45,7 @@ var rules = {
45
45
  '@atlaskit/design-system/no-margin': 'warn',
46
46
  '@atlaskit/design-system/no-nested-styles': 'error',
47
47
  '@atlaskit/design-system/no-physical-properties': 'error',
48
+ '@atlaskit/design-system/no-placeholder': 'warn',
48
49
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
49
50
  '@atlaskit/design-system/no-styled-tagged-template-expression': 'error',
50
51
  '@atlaskit/design-system/no-to-match-snapshot': 'error',
@@ -53,7 +54,6 @@ var rules = {
53
54
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
54
55
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
55
56
  '@atlaskit/design-system/no-unused-css-map': 'warn',
56
- '@atlaskit/design-system/no-utility-icons': 'warn',
57
57
  '@atlaskit/design-system/prefer-primitives': 'warn',
58
58
  '@atlaskit/design-system/use-button-group-label': 'warn',
59
59
  '@atlaskit/design-system/use-character-counter-field': 'warn',
@@ -74,6 +74,7 @@ var 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',
77
78
  '@atlaskit/design-system/use-spotlight-package': 'warn',
78
79
  '@atlaskit/design-system/use-tag-group-label': 'warn',
79
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::760141a986e4947e8a1ce74480931f43>>
3
+ * @codegen <<SignedSource::f2a8bbab8acdaf84ca6e295124378517>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -44,6 +44,7 @@ var rules = {
44
44
  '@atlaskit/design-system/no-margin': 'warn',
45
45
  '@atlaskit/design-system/no-nested-styles': 'error',
46
46
  '@atlaskit/design-system/no-physical-properties': 'error',
47
+ '@atlaskit/design-system/no-placeholder': 'warn',
47
48
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
48
49
  '@atlaskit/design-system/no-styled-tagged-template-expression': 'error',
49
50
  '@atlaskit/design-system/no-to-match-snapshot': 'error',
@@ -52,7 +53,6 @@ var rules = {
52
53
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
53
54
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
54
55
  '@atlaskit/design-system/no-unused-css-map': 'warn',
55
- '@atlaskit/design-system/no-utility-icons': 'warn',
56
56
  '@atlaskit/design-system/prefer-primitives': 'warn',
57
57
  '@atlaskit/design-system/use-button-group-label': 'warn',
58
58
  '@atlaskit/design-system/use-character-counter-field': 'warn',
@@ -73,6 +73,7 @@ var 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',
76
77
  '@atlaskit/design-system/use-spotlight-package': 'warn',
77
78
  '@atlaskit/design-system/use-tag-group-label': 'warn',
78
79
  '@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::ba71ef89188bdc20d0ec948cc00f6436>>
3
+ * @codegen <<SignedSource::2ca5e0a897270a5cfe3e234d7948ed0f>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -32,12 +32,12 @@ var rules = {
32
32
  allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
33
33
  }],
34
34
  '@atlaskit/design-system/no-nested-styles': 'error',
35
+ '@atlaskit/design-system/no-placeholder': 'warn',
35
36
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
36
37
  '@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
37
38
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
38
39
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
39
40
  '@atlaskit/design-system/no-unused-css-map': 'warn',
40
- '@atlaskit/design-system/no-utility-icons': 'warn',
41
41
  '@atlaskit/design-system/use-button-group-label': 'warn',
42
42
  '@atlaskit/design-system/use-character-counter-field': 'warn',
43
43
  '@atlaskit/design-system/use-correct-field': 'warn',
@@ -56,6 +56,7 @@ var 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',
59
60
  '@atlaskit/design-system/use-tag-group-label': 'warn',
60
61
  '@atlaskit/design-system/use-tokens-typography': 'warn',
61
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::5c119e0ab08e1f39d471b2b827bbb4de>>
3
+ * @codegen <<SignedSource::aee2986e6e48e70acef7dfa4ba53747d>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -31,12 +31,12 @@ var rules = {
31
31
  allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
32
32
  }],
33
33
  '@atlaskit/design-system/no-nested-styles': 'error',
34
+ '@atlaskit/design-system/no-placeholder': 'warn',
34
35
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
35
36
  '@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
36
37
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
37
38
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
38
39
  '@atlaskit/design-system/no-unused-css-map': 'warn',
39
- '@atlaskit/design-system/no-utility-icons': 'warn',
40
40
  '@atlaskit/design-system/use-button-group-label': 'warn',
41
41
  '@atlaskit/design-system/use-character-counter-field': 'warn',
42
42
  '@atlaskit/design-system/use-correct-field': 'warn',
@@ -55,6 +55,7 @@ var 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',
58
59
  '@atlaskit/design-system/use-tag-group-label': 'warn',
59
60
  '@atlaskit/design-system/use-tokens-typography': 'warn',
60
61
  '@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::7b80dfb4568d4c5f7c84d7c382b81de9>>
3
+ * @codegen <<SignedSource::030718cab57dce4d3b39031485e53af4>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -42,6 +42,7 @@ import noLegacyIcons from './no-legacy-icons';
42
42
  import noMargin from './no-margin';
43
43
  import noNestedStyles from './no-nested-styles';
44
44
  import noPhysicalProperties from './no-physical-properties';
45
+ import noPlaceholder from './no-placeholder';
45
46
  import noSeparatorWithListElements from './no-separator-with-list-elements';
46
47
  import noStyledTaggedTemplateExpression from './no-styled-tagged-template-expression';
47
48
  import noToMatchSnapshot from './no-to-match-snapshot';
@@ -50,7 +51,6 @@ import noUnsafeInlineSnapshot from './no-unsafe-inline-snapshot';
50
51
  import noUnsafeStyleOverrides from './no-unsafe-style-overrides';
51
52
  import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-libraries';
52
53
  import noUnusedCssMap from './no-unused-css-map';
53
- import noUtilityIcons from './no-utility-icons';
54
54
  import preferPrimitives from './prefer-primitives';
55
55
  import useButtonGroupLabel from './use-button-group-label';
56
56
  import useCharacterCounterField from './use-character-counter-field';
@@ -71,6 +71,7 @@ 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';
74
75
  import useSpotlightPackage from './use-spotlight-package';
75
76
  import useTagGroupLabel from './use-tag-group-label';
76
77
  import useTokensShape from './use-tokens-shape';
@@ -116,6 +117,7 @@ export var rules = {
116
117
  'no-margin': noMargin,
117
118
  'no-nested-styles': noNestedStyles,
118
119
  'no-physical-properties': noPhysicalProperties,
120
+ 'no-placeholder': noPlaceholder,
119
121
  'no-separator-with-list-elements': noSeparatorWithListElements,
120
122
  'no-styled-tagged-template-expression': noStyledTaggedTemplateExpression,
121
123
  'no-to-match-snapshot': noToMatchSnapshot,
@@ -124,7 +126,6 @@ export var rules = {
124
126
  'no-unsafe-style-overrides': noUnsafeStyleOverrides,
125
127
  'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
126
128
  'no-unused-css-map': noUnusedCssMap,
127
- 'no-utility-icons': noUtilityIcons,
128
129
  'prefer-primitives': preferPrimitives,
129
130
  'use-button-group-label': useButtonGroupLabel,
130
131
  'use-character-counter-field': useCharacterCounterField,
@@ -145,6 +146,7 @@ export var rules = {
145
146
  'use-primitives': usePrimitives,
146
147
  'use-primitives-text': usePrimitivesText,
147
148
  'use-should-render-to-parent': useShouldRenderToParent,
149
+ 'use-simple-field': useSimpleField,
148
150
  'use-spotlight-package': useSpotlightPackage,
149
151
  'use-tag-group-label': useTagGroupLabel,
150
152
  'use-tokens-shape': useTokensShape,
@@ -0,0 +1,154 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import * as ast from '../../ast-nodes';
3
+ import { createLintRule } from '../utils/create-rule';
4
+ export var AFFECTED_HTML_ELEMENTS = ['input', 'textarea'];
5
+ export var AFFECTED_ATLASKIT_PACKAGES = {
6
+ '@atlaskit/datetime-picker': ['DatePicker', 'TimePicker', 'DateTimePicker'],
7
+ '@atlaskit/select': ['default', 'AsyncCreatableSelect', 'CheckboxSelect', 'CountrySelect', 'CreatableSelect', 'PopupSelect', 'RadioSelect'],
8
+ '@atlaskit/textarea': ['default'],
9
+ '@atlaskit/textfield': ['default']
10
+ };
11
+ export var ATLASKIT_FORM_PACKAGE = '@atlaskit/form';
12
+ export var ATLASKIT_FIELD_IMPORT = 'Field';
13
+ var rule = createLintRule({
14
+ meta: {
15
+ name: 'no-placeholder',
16
+ type: 'problem',
17
+ docs: {
18
+ description: 'Placeholders should not be used. If information should be given to the user about the proper type or formatting of a value, this should be included using a helper message that is associated to the input instead.',
19
+ recommended: true,
20
+ severity: 'warn'
21
+ },
22
+ messages: {
23
+ noPlaceholder: 'Placeholders should not be used. Use separate information to help users associated using `aria-describedby` instead.',
24
+ noPlaceholderOnSimpleField: 'Placeholders should not be used. Use the `helperMessage` prop instead.',
25
+ noPlaceholderOnComplexField: 'Placeholders should not be used. Use the `HelperMessage` component instead.'
26
+ }
27
+ },
28
+ create: function create(context) {
29
+ var hasFieldImport = false;
30
+ var fieldLocalName = null;
31
+ var localComponentNames = [];
32
+ return {
33
+ ImportDeclaration: function ImportDeclaration(node) {
34
+ var source = node.source.value;
35
+ if (typeof source !== 'string') {
36
+ return;
37
+ }
38
+
39
+ // Ignore non-atlaskit input/form packages
40
+ if (!Object.keys(AFFECTED_ATLASKIT_PACKAGES).includes(source) && ATLASKIT_FORM_PACKAGE !== source) {
41
+ return;
42
+ }
43
+ if (!node.specifiers.length) {
44
+ return;
45
+ }
46
+ var defaultImport = node.specifiers.filter(function (spec) {
47
+ return spec.type === 'ImportDefaultSpecifier';
48
+ });
49
+ var namedImport = node.specifiers.filter(function (spec) {
50
+ return spec.type === 'ImportSpecifier';
51
+ });
52
+ if (source === ATLASKIT_FORM_PACKAGE) {
53
+ if (namedImport.length && namedImport[0].type === 'ImportSpecifier' && 'name' in namedImport[0].imported && namedImport[0].imported.name === ATLASKIT_FIELD_IMPORT) {
54
+ hasFieldImport = true;
55
+ fieldLocalName = namedImport[0].local.name;
56
+ }
57
+ } else {
58
+ var importNames = AFFECTED_ATLASKIT_PACKAGES[source];
59
+ var usesDefaultImport = importNames.includes('default');
60
+ var possibleNamedImports = importNames.filter(function (importName) {
61
+ return importName !== 'default';
62
+ });
63
+ if (usesDefaultImport && defaultImport.length && defaultImport[0].local) {
64
+ localComponentNames.push(defaultImport[0].local.name);
65
+ // or if popup and using a named import
66
+ } else if (possibleNamedImports.length >= 1 && namedImport.length) {
67
+ namedImport.forEach(function (imp) {
68
+ if (imp.type === 'ImportSpecifier' && 'name' in imp.imported && possibleNamedImports.includes(imp.imported.name)) {
69
+ localComponentNames.push(imp.local.name);
70
+ }
71
+ });
72
+ }
73
+ }
74
+ },
75
+ JSXElement: function JSXElement(node) {
76
+ if (!isNodeOfType(node, 'JSXElement')) {
77
+ return false;
78
+ }
79
+ var elName = ast.JSXElement.getName(node);
80
+ if (!elName) {
81
+ return false;
82
+ }
83
+
84
+ // If it is one of the affected native HTML elements
85
+ if (AFFECTED_HTML_ELEMENTS.includes(elName)) {
86
+ // if has a placeholder attribute
87
+ var hasPlaceholderAttribute = node.openingElement.attributes.find(function (attr) {
88
+ return isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
89
+ });
90
+ if (hasPlaceholderAttribute) {
91
+ return context.report({
92
+ node: node.openingElement,
93
+ messageId: 'noPlaceholder'
94
+ });
95
+ }
96
+ // Else, it is a React component
97
+ } else {
98
+ // if none of the affected packages is imported, return
99
+ if (localComponentNames.length === 0) {
100
+ return;
101
+ }
102
+ // if component name is not in the list, exit
103
+ if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier') || !localComponentNames.includes(node.openingElement.name.name)) {
104
+ return;
105
+ }
106
+ if (hasFieldImport && fieldLocalName) {
107
+ var _node = node;
108
+ var hasParentField = false;
109
+ var fieldType = 'Complex';
110
+ // If node is a Field element or if
111
+ while (isNodeOfType(_node, 'JSXElement') && isNodeOfType(_node.openingElement.name, 'JSXIdentifier') && !hasParentField) {
112
+ var name = _node.openingElement.name.name;
113
+ hasParentField = hasParentField || name === fieldLocalName;
114
+ _node = _node.parent;
115
+ // Skip up until a JSXElement or JSXAttribute is reached
116
+ if (isNodeOfType(_node, 'JSXFragment') || isNodeOfType(_node, 'ArrowFunctionExpression') || isNodeOfType(_node, 'JSXExpressionContainer') || isNodeOfType(_node, 'JSXAttribute')) {
117
+ while (_node && !isNodeOfType(_node, 'JSXElement') && !isNodeOfType(_node, 'Program')) {
118
+ if (isNodeOfType(_node, 'JSXAttribute')) {
119
+ fieldType = 'Simple';
120
+ }
121
+ _node = _node.parent;
122
+ }
123
+ }
124
+ }
125
+ if (hasParentField) {
126
+ // if has a placeholder attribute
127
+ var _hasPlaceholderAttribute = node.openingElement.attributes.find(function (attr) {
128
+ return isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
129
+ });
130
+ if (_hasPlaceholderAttribute) {
131
+ return context.report({
132
+ node: node.openingElement,
133
+ messageId: "noPlaceholderOn".concat(fieldType, "Field")
134
+ });
135
+ }
136
+ }
137
+ } else {
138
+ // if has a placeholder attribute
139
+ var _hasPlaceholderAttribute2 = node.openingElement.attributes.find(function (attr) {
140
+ return isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
141
+ });
142
+ if (_hasPlaceholderAttribute2) {
143
+ return context.report({
144
+ node: node.openingElement,
145
+ messageId: 'noPlaceholder'
146
+ });
147
+ }
148
+ }
149
+ }
150
+ }
151
+ };
152
+ }
153
+ });
154
+ export default rule;
@@ -0,0 +1,132 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import { createLintRule } from '../utils/create-rule';
3
+ var FORM_PACKAGE = '@atlaskit/form';
4
+ var MESSAGE_COMPONENTS = ['ErrorMessage', 'HelperMessage', 'ValidMessage'];
5
+ export var convertField = 'Convert field to simple field';
6
+ var 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: function create(context) {
21
+ var fieldImport;
22
+ var messageImports = [];
23
+ return {
24
+ ImportDeclaration: function ImportDeclaration(node) {
25
+ var 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
+ var namedImportSpecifiers = node.specifiers.filter(function (spec) {
40
+ return isNodeOfType(spec, 'ImportSpecifier');
41
+ });
42
+ namedImportSpecifiers.forEach(function (spec) {
43
+ if (spec.type === 'ImportSpecifier' && 'name' in spec.imported) {
44
+ var name = spec.imported.name;
45
+ var local = spec.local;
46
+ if (MESSAGE_COMPONENTS.includes(name)) {
47
+ messageImports.push(local);
48
+ } else if (name === 'Field') {
49
+ fieldImport = local.name;
50
+ }
51
+ }
52
+ });
53
+ },
54
+ JSXElement: function JSXElement(node) {
55
+ if (!isNodeOfType(node, 'JSXElement')) {
56
+ return;
57
+ }
58
+ if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
59
+ return;
60
+ }
61
+
62
+ // if no field import exists, skip
63
+ if (!fieldImport) {
64
+ return;
65
+ }
66
+
67
+ // if component is not field, skip
68
+ if (node.openingElement.name.name !== fieldImport) {
69
+ return;
70
+ }
71
+
72
+ // if message imports exist, skip because we can't really dig around
73
+ // inside the field to see if they exist because of memory constraints
74
+ if (messageImports.length > 0) {
75
+ return;
76
+ }
77
+
78
+ // if component exists as a prop, skip because it's already simple
79
+ var attributes = node.openingElement.attributes;
80
+ var componentAttr = attributes.find(function (attr) {
81
+ return isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && attr.name.name === 'component';
82
+ });
83
+ if (componentAttr) {
84
+ return;
85
+ }
86
+
87
+ // if children is not a render prop, skip
88
+ var renderProps = node.children.find(function (child) {
89
+ return isNodeOfType(child, 'JSXExpressionContainer');
90
+ });
91
+ if (!renderProps) {
92
+ return;
93
+ }
94
+ var renderPropExpression = renderProps.expression;
95
+ // If not an arrow func, ignore
96
+ if (!isNodeOfType(renderPropExpression, 'ArrowFunctionExpression')) {
97
+ return;
98
+ }
99
+ var renderPropParams = renderPropExpression.params;
100
+ // if it is not an object pattern, skip
101
+ if (!isNodeOfType(renderPropParams[0], 'ObjectPattern')) {
102
+ return;
103
+ }
104
+ // if component uses more than just fieldProps in render props, skip
105
+ var renderPropArgProperties = renderPropParams[0].properties;
106
+ var fieldPropsProp = renderPropArgProperties.find(function (property) {
107
+ return isNodeOfType(property, 'Property') && isNodeOfType(property.key, 'Identifier') && property.key.name === 'fieldProps';
108
+ });
109
+ if (renderPropArgProperties.length > 1 || !fieldPropsProp) {
110
+ return;
111
+ }
112
+ var lastProp = attributes.slice(-1)[0] || node.openingElement.name;
113
+ var sourceCode = context.sourceCode;
114
+ var renderPropsText = sourceCode.getText(renderProps);
115
+ context.report({
116
+ node: node,
117
+ messageId: 'useSimpleField',
118
+ suggest: [{
119
+ desc: convertField,
120
+ fix: function fix(fixer) {
121
+ var fixes = [];
122
+ fixes.push(fixer.insertTextAfter(lastProp, " component=".concat(renderPropsText, " ")));
123
+ fixes.push(fixer.remove(renderProps));
124
+ return fixes;
125
+ }
126
+ }]
127
+ });
128
+ }
129
+ };
130
+ }
131
+ });
132
+ export 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::23364c0ee38a3772c2a588841ed22c55>>
3
+ * @codegen <<SignedSource::05e8a8ff80cb4a88a89ccd31570686f6>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Linter } from 'eslint';
@@ -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::760141a986e4947e8a1ce74480931f43>>
3
+ * @codegen <<SignedSource::f2a8bbab8acdaf84ca6e295124378517>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { ESLint } from 'eslint';
@@ -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::ba71ef89188bdc20d0ec948cc00f6436>>
3
+ * @codegen <<SignedSource::2ca5e0a897270a5cfe3e234d7948ed0f>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Linter } from 'eslint';
@@ -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::5c119e0ab08e1f39d471b2b827bbb4de>>
3
+ * @codegen <<SignedSource::aee2986e6e48e70acef7dfa4ba53747d>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { ESLint } from 'eslint';
@@ -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::7b80dfb4568d4c5f7c84d7c382b81de9>>
3
+ * @codegen <<SignedSource::030718cab57dce4d3b39031485e53af4>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Rule } from 'eslint';
@@ -0,0 +1,6 @@
1
+ export declare const AFFECTED_HTML_ELEMENTS: string[];
2
+ export declare const AFFECTED_ATLASKIT_PACKAGES: Record<string, string[]>;
3
+ export declare const ATLASKIT_FORM_PACKAGE = "@atlaskit/form";
4
+ export declare const ATLASKIT_FIELD_IMPORT = "Field";
5
+ declare const rule: import("eslint").Rule.RuleModule;
6
+ export default rule;
@@ -1,3 +1,4 @@
1
1
  import type { Rule } from 'eslint';
2
+ export declare const convertField = "Convert field to simple field";
2
3
  declare const rule: Rule.RuleModule;
3
4
  export 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::23364c0ee38a3772c2a588841ed22c55>>
3
+ * @codegen <<SignedSource::05e8a8ff80cb4a88a89ccd31570686f6>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
  import type { Linter } from 'eslint';