@atlaskit/eslint-plugin-design-system 13.31.0 → 13.32.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 (43) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/dist/cjs/presets/all-flat.codegen.js +2 -2
  4. package/dist/cjs/presets/all.codegen.js +2 -2
  5. package/dist/cjs/presets/recommended-flat.codegen.js +2 -2
  6. package/dist/cjs/presets/recommended.codegen.js +2 -2
  7. package/dist/cjs/rules/index.codegen.js +3 -3
  8. package/dist/cjs/rules/no-placeholder/index.js +162 -0
  9. package/dist/es2019/presets/all-flat.codegen.js +2 -2
  10. package/dist/es2019/presets/all.codegen.js +2 -2
  11. package/dist/es2019/presets/recommended-flat.codegen.js +2 -2
  12. package/dist/es2019/presets/recommended.codegen.js +2 -2
  13. package/dist/es2019/rules/index.codegen.js +3 -3
  14. package/dist/es2019/rules/no-placeholder/index.js +142 -0
  15. package/dist/esm/presets/all-flat.codegen.js +2 -2
  16. package/dist/esm/presets/all.codegen.js +2 -2
  17. package/dist/esm/presets/recommended-flat.codegen.js +2 -2
  18. package/dist/esm/presets/recommended.codegen.js +2 -2
  19. package/dist/esm/rules/index.codegen.js +3 -3
  20. package/dist/esm/rules/no-placeholder/index.js +154 -0
  21. package/dist/types/presets/all-flat.codegen.d.ts +1 -1
  22. package/dist/types/presets/all.codegen.d.ts +1 -1
  23. package/dist/types/presets/recommended-flat.codegen.d.ts +1 -1
  24. package/dist/types/presets/recommended.codegen.d.ts +1 -1
  25. package/dist/types/rules/index.codegen.d.ts +1 -1
  26. package/dist/types/rules/no-placeholder/index.d.ts +6 -0
  27. package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -1
  28. package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -1
  29. package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -1
  30. package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
  31. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
  32. package/dist/types-ts4.5/rules/no-placeholder/index.d.ts +6 -0
  33. package/package.json +2 -2
  34. package/dist/cjs/rules/no-utility-icons/checks.js +0 -246
  35. package/dist/cjs/rules/no-utility-icons/index.js +0 -49
  36. package/dist/es2019/rules/no-utility-icons/checks.js +0 -177
  37. package/dist/es2019/rules/no-utility-icons/index.js +0 -44
  38. package/dist/esm/rules/no-utility-icons/checks.js +0 -239
  39. package/dist/esm/rules/no-utility-icons/index.js +0 -43
  40. package/dist/types/rules/no-utility-icons/checks.d.ts +0 -10
  41. package/dist/types/rules/no-utility-icons/index.d.ts +0 -3
  42. package/dist/types-ts4.5/rules/no-utility-icons/checks.d.ts +0 -10
  43. package/dist/types-ts4.5/rules/no-utility-icons/index.d.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 13.32.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`7925336391df8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7925336391df8) -
8
+ Remove deprecated no-utility-icons ESLint rule as utility icons have been fully removed from
9
+ @atlaskit/icon package.
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
3
15
  ## 13.31.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -87,6 +87,7 @@ module.exports = {
87
87
  | <a href="./src/rules/no-margin/README.md">no-margin</a> | Disallow using the margin CSS property. | | | |
88
88
  | <a href="./src/rules/no-nested-styles/README.md">no-nested-styles</a> | Disallows use of nested styles in `css` functions. | Yes | | |
89
89
  | <a href="./src/rules/no-physical-properties/README.md">no-physical-properties</a> | Disallow physical properties and values in `css` and `cssMap` function calls. | | Yes | |
90
+ | <a href="./src/rules/no-placeholder/README.md">no-placeholder</a> | 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. | Yes | | |
90
91
  | <a href="./src/rules/no-separator-with-list-elements/README.md">no-separator-with-list-elements</a> | Warn when the `separator` prop is used with `as="li"`, `as="ol"`, or `as="dl"` in the Inline component. | Yes | | |
91
92
  | <a href="./src/rules/no-styled-tagged-template-expression/README.md">no-styled-tagged-template-expression</a> | Disallows any `styled` tagged template expressions that originate from Emotion, Styled Components or Compiled | | Yes | |
92
93
  | <a href="./src/rules/no-to-match-snapshot/README.md">no-to-match-snapshot</a> | Disallow using toMatchSnapshot() in favor of toMatchInlineSnapshot(). See https://hello.atlassian.net/wiki/spaces/DST/pages/6105892000/DSTRFC-038+-+Removal+of+.toMatchSnapshot for rationale. | | | |
@@ -95,7 +96,6 @@ module.exports = {
95
96
  | <a href="./src/rules/no-unsafe-style-overrides/README.md">no-unsafe-style-overrides</a> | Discourage usage of unsafe style overrides used against the Atlassian Design System. | Yes | | |
96
97
  | <a href="./src/rules/no-unsupported-drag-and-drop-libraries/README.md">no-unsupported-drag-and-drop-libraries</a> | Disallow importing unsupported drag and drop modules. | Yes | | |
97
98
  | <a href="./src/rules/no-unused-css-map/README.md">no-unused-css-map</a> | Detects unused styles in cssMap objects to help keep code clean. | Yes | | |
98
- | <a href="./src/rules/no-utility-icons/README.md">no-utility-icons</a> | Disallow use of deprecated utility icons, in favor of core icons with `size="small"`. | Yes | Yes | Yes |
99
99
  | <a href="./src/rules/prefer-primitives/README.md">prefer-primitives</a> | Increase awareness of primitive components via code hints. Strictly used for education purposes and discoverability. To enforce usage please refer to the `use-primitives` rule. | | | |
100
100
  | <a href="./src/rules/use-button-group-label/README.md">use-button-group-label</a> | Ensures button groups are described to assistive technology by a direct label or by another element. | Yes | | Yes |
101
101
  | <a href="./src/rules/use-character-counter-field/README.md">use-character-counter-field</a> | Suggests using CharacterCounterField or CharacterCounter when Textfield or Textarea components have maxLength or minLength props. | 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::23364c0ee38a3772c2a588841ed22c55>>
9
+ * @codegen <<SignedSource::4fa72535ce2bc0a19a6fb01c951150db>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -51,6 +51,7 @@ var rules = {
51
51
  '@atlaskit/design-system/no-margin': 'warn',
52
52
  '@atlaskit/design-system/no-nested-styles': 'error',
53
53
  '@atlaskit/design-system/no-physical-properties': 'error',
54
+ '@atlaskit/design-system/no-placeholder': 'warn',
54
55
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
55
56
  '@atlaskit/design-system/no-styled-tagged-template-expression': 'error',
56
57
  '@atlaskit/design-system/no-to-match-snapshot': 'error',
@@ -59,7 +60,6 @@ var rules = {
59
60
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
60
61
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
61
62
  '@atlaskit/design-system/no-unused-css-map': 'warn',
62
- '@atlaskit/design-system/no-utility-icons': 'warn',
63
63
  '@atlaskit/design-system/prefer-primitives': 'warn',
64
64
  '@atlaskit/design-system/use-button-group-label': 'warn',
65
65
  '@atlaskit/design-system/use-character-counter-field': 'warn',
@@ -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::760141a986e4947e8a1ce74480931f43>>
9
+ * @codegen <<SignedSource::dcf6bf4496c97fd6ad4c1d8d65337a6b>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -50,6 +50,7 @@ var rules = {
50
50
  '@atlaskit/design-system/no-margin': 'warn',
51
51
  '@atlaskit/design-system/no-nested-styles': 'error',
52
52
  '@atlaskit/design-system/no-physical-properties': 'error',
53
+ '@atlaskit/design-system/no-placeholder': 'warn',
53
54
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
54
55
  '@atlaskit/design-system/no-styled-tagged-template-expression': 'error',
55
56
  '@atlaskit/design-system/no-to-match-snapshot': 'error',
@@ -58,7 +59,6 @@ var rules = {
58
59
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
59
60
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
60
61
  '@atlaskit/design-system/no-unused-css-map': 'warn',
61
- '@atlaskit/design-system/no-utility-icons': 'warn',
62
62
  '@atlaskit/design-system/prefer-primitives': 'warn',
63
63
  '@atlaskit/design-system/use-button-group-label': 'warn',
64
64
  '@atlaskit/design-system/use-character-counter-field': 'warn',
@@ -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::ba71ef89188bdc20d0ec948cc00f6436>>
9
+ * @codegen <<SignedSource::27c9a3631c47b134bfb9da3e921e0601>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -38,12 +38,12 @@ var rules = {
38
38
  allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
39
39
  }],
40
40
  '@atlaskit/design-system/no-nested-styles': 'error',
41
+ '@atlaskit/design-system/no-placeholder': 'warn',
41
42
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
42
43
  '@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
43
44
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
44
45
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
45
46
  '@atlaskit/design-system/no-unused-css-map': 'warn',
46
- '@atlaskit/design-system/no-utility-icons': 'warn',
47
47
  '@atlaskit/design-system/use-button-group-label': 'warn',
48
48
  '@atlaskit/design-system/use-character-counter-field': 'warn',
49
49
  '@atlaskit/design-system/use-correct-field': 'warn',
@@ -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::5c119e0ab08e1f39d471b2b827bbb4de>>
9
+ * @codegen <<SignedSource::52a31bc6cdeb7a9818a0e225d21c88f2>>
10
10
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
11
11
  */
12
12
 
@@ -37,12 +37,12 @@ var rules = {
37
37
  allowedFunctionCalls: [['@atlaskit/tokens', 'token']]
38
38
  }],
39
39
  '@atlaskit/design-system/no-nested-styles': 'error',
40
+ '@atlaskit/design-system/no-placeholder': 'warn',
40
41
  '@atlaskit/design-system/no-separator-with-list-elements': 'warn',
41
42
  '@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
42
43
  '@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
43
44
  '@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
44
45
  '@atlaskit/design-system/no-unused-css-map': 'warn',
45
- '@atlaskit/design-system/no-utility-icons': 'warn',
46
46
  '@atlaskit/design-system/use-button-group-label': 'warn',
47
47
  '@atlaskit/design-system/use-character-counter-field': 'warn',
48
48
  '@atlaskit/design-system/use-correct-field': 'warn',
@@ -43,6 +43,7 @@ var _noLegacyIcons = _interopRequireDefault(require("./no-legacy-icons"));
43
43
  var _noMargin = _interopRequireDefault(require("./no-margin"));
44
44
  var _noNestedStyles = _interopRequireDefault(require("./no-nested-styles"));
45
45
  var _noPhysicalProperties = _interopRequireDefault(require("./no-physical-properties"));
46
+ var _noPlaceholder = _interopRequireDefault(require("./no-placeholder"));
46
47
  var _noSeparatorWithListElements = _interopRequireDefault(require("./no-separator-with-list-elements"));
47
48
  var _noStyledTaggedTemplateExpression = _interopRequireDefault(require("./no-styled-tagged-template-expression"));
48
49
  var _noToMatchSnapshot = _interopRequireDefault(require("./no-to-match-snapshot"));
@@ -51,7 +52,6 @@ var _noUnsafeInlineSnapshot = _interopRequireDefault(require("./no-unsafe-inline
51
52
  var _noUnsafeStyleOverrides = _interopRequireDefault(require("./no-unsafe-style-overrides"));
52
53
  var _noUnsupportedDragAndDropLibraries = _interopRequireDefault(require("./no-unsupported-drag-and-drop-libraries"));
53
54
  var _noUnusedCssMap = _interopRequireDefault(require("./no-unused-css-map"));
54
- var _noUtilityIcons = _interopRequireDefault(require("./no-utility-icons"));
55
55
  var _preferPrimitives = _interopRequireDefault(require("./prefer-primitives"));
56
56
  var _useButtonGroupLabel = _interopRequireDefault(require("./use-button-group-label"));
57
57
  var _useCharacterCounterField = _interopRequireDefault(require("./use-character-counter-field"));
@@ -80,7 +80,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
80
80
  var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
81
81
  /**
82
82
  * THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
83
- * @codegen <<SignedSource::7b80dfb4568d4c5f7c84d7c382b81de9>>
83
+ * @codegen <<SignedSource::ca89575f70ae79af2f43113bdc77c0c5>>
84
84
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
85
85
  */
86
86
 
@@ -123,6 +123,7 @@ var rules = exports.rules = {
123
123
  'no-margin': _noMargin.default,
124
124
  'no-nested-styles': _noNestedStyles.default,
125
125
  'no-physical-properties': _noPhysicalProperties.default,
126
+ 'no-placeholder': _noPlaceholder.default,
126
127
  'no-separator-with-list-elements': _noSeparatorWithListElements.default,
127
128
  'no-styled-tagged-template-expression': _noStyledTaggedTemplateExpression.default,
128
129
  'no-to-match-snapshot': _noToMatchSnapshot.default,
@@ -131,7 +132,6 @@ var rules = exports.rules = {
131
132
  'no-unsafe-style-overrides': _noUnsafeStyleOverrides.default,
132
133
  'no-unsupported-drag-and-drop-libraries': _noUnsupportedDragAndDropLibraries.default,
133
134
  'no-unused-css-map': _noUnusedCssMap.default,
134
- 'no-utility-icons': _noUtilityIcons.default,
135
135
  'prefer-primitives': _preferPrimitives.default,
136
136
  'use-button-group-label': _useButtonGroupLabel.default,
137
137
  'use-character-counter-field': _useCharacterCounterField.default,
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+
3
+ var _typeof = require("@babel/runtime/helpers/typeof");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = exports.ATLASKIT_FORM_PACKAGE = exports.ATLASKIT_FIELD_IMPORT = exports.AFFECTED_HTML_ELEMENTS = exports.AFFECTED_ATLASKIT_PACKAGES = void 0;
8
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
9
+ var ast = _interopRequireWildcard(require("../../ast-nodes"));
10
+ var _createRule = require("../utils/create-rule");
11
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
12
+ var AFFECTED_HTML_ELEMENTS = exports.AFFECTED_HTML_ELEMENTS = ['input', 'textarea'];
13
+ var AFFECTED_ATLASKIT_PACKAGES = exports.AFFECTED_ATLASKIT_PACKAGES = {
14
+ '@atlaskit/datetime-picker': ['DatePicker', 'TimePicker', 'DateTimePicker'],
15
+ '@atlaskit/select': ['default', 'AsyncCreatableSelect', 'CheckboxSelect', 'CountrySelect', 'CreatableSelect', 'PopupSelect', 'RadioSelect'],
16
+ '@atlaskit/textarea': ['default'],
17
+ '@atlaskit/textfield': ['default']
18
+ };
19
+ var ATLASKIT_FORM_PACKAGE = exports.ATLASKIT_FORM_PACKAGE = '@atlaskit/form';
20
+ var ATLASKIT_FIELD_IMPORT = exports.ATLASKIT_FIELD_IMPORT = 'Field';
21
+ var rule = (0, _createRule.createLintRule)({
22
+ meta: {
23
+ name: 'no-placeholder',
24
+ type: 'problem',
25
+ docs: {
26
+ 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.',
27
+ recommended: true,
28
+ severity: 'warn'
29
+ },
30
+ messages: {
31
+ noPlaceholder: 'Placeholders should not be used. Use separate information to help users associated using `aria-describedby` instead.',
32
+ noPlaceholderOnSimpleField: 'Placeholders should not be used. Use the `helperMessage` prop instead.',
33
+ noPlaceholderOnComplexField: 'Placeholders should not be used. Use the `HelperMessage` component instead.'
34
+ }
35
+ },
36
+ create: function create(context) {
37
+ var hasFieldImport = false;
38
+ var fieldLocalName = null;
39
+ var localComponentNames = [];
40
+ return {
41
+ ImportDeclaration: function ImportDeclaration(node) {
42
+ var source = node.source.value;
43
+ if (typeof source !== 'string') {
44
+ return;
45
+ }
46
+
47
+ // Ignore non-atlaskit input/form packages
48
+ if (!Object.keys(AFFECTED_ATLASKIT_PACKAGES).includes(source) && ATLASKIT_FORM_PACKAGE !== source) {
49
+ return;
50
+ }
51
+ if (!node.specifiers.length) {
52
+ return;
53
+ }
54
+ var defaultImport = node.specifiers.filter(function (spec) {
55
+ return spec.type === 'ImportDefaultSpecifier';
56
+ });
57
+ var namedImport = node.specifiers.filter(function (spec) {
58
+ return spec.type === 'ImportSpecifier';
59
+ });
60
+ if (source === ATLASKIT_FORM_PACKAGE) {
61
+ if (namedImport.length && namedImport[0].type === 'ImportSpecifier' && 'name' in namedImport[0].imported && namedImport[0].imported.name === ATLASKIT_FIELD_IMPORT) {
62
+ hasFieldImport = true;
63
+ fieldLocalName = namedImport[0].local.name;
64
+ }
65
+ } else {
66
+ var importNames = AFFECTED_ATLASKIT_PACKAGES[source];
67
+ var usesDefaultImport = importNames.includes('default');
68
+ var possibleNamedImports = importNames.filter(function (importName) {
69
+ return importName !== 'default';
70
+ });
71
+ if (usesDefaultImport && defaultImport.length && defaultImport[0].local) {
72
+ localComponentNames.push(defaultImport[0].local.name);
73
+ // or if popup and using a named import
74
+ } else if (possibleNamedImports.length >= 1 && namedImport.length) {
75
+ namedImport.forEach(function (imp) {
76
+ if (imp.type === 'ImportSpecifier' && 'name' in imp.imported && possibleNamedImports.includes(imp.imported.name)) {
77
+ localComponentNames.push(imp.local.name);
78
+ }
79
+ });
80
+ }
81
+ }
82
+ },
83
+ JSXElement: function JSXElement(node) {
84
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
85
+ return false;
86
+ }
87
+ var elName = ast.JSXElement.getName(node);
88
+ if (!elName) {
89
+ return false;
90
+ }
91
+
92
+ // If it is one of the affected native HTML elements
93
+ if (AFFECTED_HTML_ELEMENTS.includes(elName)) {
94
+ // if has a placeholder attribute
95
+ var hasPlaceholderAttribute = node.openingElement.attributes.find(function (attr) {
96
+ return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
97
+ });
98
+ if (hasPlaceholderAttribute) {
99
+ return context.report({
100
+ node: node.openingElement,
101
+ messageId: 'noPlaceholder'
102
+ });
103
+ }
104
+ // Else, it is a React component
105
+ } else {
106
+ // if none of the affected packages is imported, return
107
+ if (localComponentNames.length === 0) {
108
+ return;
109
+ }
110
+ // if component name is not in the list, exit
111
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier') || !localComponentNames.includes(node.openingElement.name.name)) {
112
+ return;
113
+ }
114
+ if (hasFieldImport && fieldLocalName) {
115
+ var _node = node;
116
+ var hasParentField = false;
117
+ var fieldType = 'Complex';
118
+ // If node is a Field element or if
119
+ while ((0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXElement') && (0, _eslintCodemodUtils.isNodeOfType)(_node.openingElement.name, 'JSXIdentifier') && !hasParentField) {
120
+ var name = _node.openingElement.name.name;
121
+ hasParentField = hasParentField || name === fieldLocalName;
122
+ _node = _node.parent;
123
+ // Skip up until a JSXElement or JSXAttribute is reached
124
+ if ((0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXFragment') || (0, _eslintCodemodUtils.isNodeOfType)(_node, 'ArrowFunctionExpression') || (0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXExpressionContainer') || (0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXAttribute')) {
125
+ while (_node && !(0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXElement') && !(0, _eslintCodemodUtils.isNodeOfType)(_node, 'Program')) {
126
+ if ((0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXAttribute')) {
127
+ fieldType = 'Simple';
128
+ }
129
+ _node = _node.parent;
130
+ }
131
+ }
132
+ }
133
+ if (hasParentField) {
134
+ // if has a placeholder attribute
135
+ var _hasPlaceholderAttribute = node.openingElement.attributes.find(function (attr) {
136
+ return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
137
+ });
138
+ if (_hasPlaceholderAttribute) {
139
+ return context.report({
140
+ node: node.openingElement,
141
+ messageId: "noPlaceholderOn".concat(fieldType, "Field")
142
+ });
143
+ }
144
+ }
145
+ } else {
146
+ // if has a placeholder attribute
147
+ var _hasPlaceholderAttribute2 = node.openingElement.attributes.find(function (attr) {
148
+ return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && attr.name.name === 'placeholder';
149
+ });
150
+ if (_hasPlaceholderAttribute2) {
151
+ return context.report({
152
+ node: node.openingElement,
153
+ messageId: 'noPlaceholder'
154
+ });
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::23364c0ee38a3772c2a588841ed22c55>>
3
+ * @codegen <<SignedSource::4fa72535ce2bc0a19a6fb01c951150db>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -45,6 +45,7 @@ const 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 @@ const 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',
@@ -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::dcf6bf4496c97fd6ad4c1d8d65337a6b>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -44,6 +44,7 @@ const 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 @@ const 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',
@@ -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::27c9a3631c47b134bfb9da3e921e0601>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -32,12 +32,12 @@ const 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',
@@ -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::52a31bc6cdeb7a9818a0e225d21c88f2>>
4
4
  * @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
5
5
  */
6
6
 
@@ -31,12 +31,12 @@ const 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',
@@ -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::ca89575f70ae79af2f43113bdc77c0c5>>
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';
@@ -116,6 +116,7 @@ export const rules = {
116
116
  'no-margin': noMargin,
117
117
  'no-nested-styles': noNestedStyles,
118
118
  'no-physical-properties': noPhysicalProperties,
119
+ 'no-placeholder': noPlaceholder,
119
120
  'no-separator-with-list-elements': noSeparatorWithListElements,
120
121
  'no-styled-tagged-template-expression': noStyledTaggedTemplateExpression,
121
122
  'no-to-match-snapshot': noToMatchSnapshot,
@@ -124,7 +125,6 @@ export const rules = {
124
125
  'no-unsafe-style-overrides': noUnsafeStyleOverrides,
125
126
  'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
126
127
  'no-unused-css-map': noUnusedCssMap,
127
- 'no-utility-icons': noUtilityIcons,
128
128
  'prefer-primitives': preferPrimitives,
129
129
  'use-button-group-label': useButtonGroupLabel,
130
130
  'use-character-counter-field': useCharacterCounterField,
@@ -0,0 +1,142 @@
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import * as ast from '../../ast-nodes';
3
+ import { createLintRule } from '../utils/create-rule';
4
+ export const AFFECTED_HTML_ELEMENTS = ['input', 'textarea'];
5
+ export const 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 const ATLASKIT_FORM_PACKAGE = '@atlaskit/form';
12
+ export const ATLASKIT_FIELD_IMPORT = 'Field';
13
+ const 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(context) {
29
+ let hasFieldImport = false;
30
+ let fieldLocalName = null;
31
+ const localComponentNames = [];
32
+ return {
33
+ ImportDeclaration(node) {
34
+ const 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
+ const defaultImport = node.specifiers.filter(spec => spec.type === 'ImportDefaultSpecifier');
47
+ const namedImport = node.specifiers.filter(spec => spec.type === 'ImportSpecifier');
48
+ if (source === ATLASKIT_FORM_PACKAGE) {
49
+ if (namedImport.length && namedImport[0].type === 'ImportSpecifier' && 'name' in namedImport[0].imported && namedImport[0].imported.name === ATLASKIT_FIELD_IMPORT) {
50
+ hasFieldImport = true;
51
+ fieldLocalName = namedImport[0].local.name;
52
+ }
53
+ } else {
54
+ const importNames = AFFECTED_ATLASKIT_PACKAGES[source];
55
+ const usesDefaultImport = importNames.includes('default');
56
+ const possibleNamedImports = importNames.filter(importName => importName !== 'default');
57
+ if (usesDefaultImport && defaultImport.length && defaultImport[0].local) {
58
+ localComponentNames.push(defaultImport[0].local.name);
59
+ // or if popup and using a named import
60
+ } else if (possibleNamedImports.length >= 1 && namedImport.length) {
61
+ namedImport.forEach(imp => {
62
+ if (imp.type === 'ImportSpecifier' && 'name' in imp.imported && possibleNamedImports.includes(imp.imported.name)) {
63
+ localComponentNames.push(imp.local.name);
64
+ }
65
+ });
66
+ }
67
+ }
68
+ },
69
+ JSXElement(node) {
70
+ if (!isNodeOfType(node, 'JSXElement')) {
71
+ return false;
72
+ }
73
+ const elName = ast.JSXElement.getName(node);
74
+ if (!elName) {
75
+ return false;
76
+ }
77
+
78
+ // If it is one of the affected native HTML elements
79
+ if (AFFECTED_HTML_ELEMENTS.includes(elName)) {
80
+ // if has a placeholder attribute
81
+ const hasPlaceholderAttribute = node.openingElement.attributes.find(attr => isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder');
82
+ if (hasPlaceholderAttribute) {
83
+ return context.report({
84
+ node: node.openingElement,
85
+ messageId: 'noPlaceholder'
86
+ });
87
+ }
88
+ // Else, it is a React component
89
+ } else {
90
+ // if none of the affected packages is imported, return
91
+ if (localComponentNames.length === 0) {
92
+ return;
93
+ }
94
+ // if component name is not in the list, exit
95
+ if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier') || !localComponentNames.includes(node.openingElement.name.name)) {
96
+ return;
97
+ }
98
+ if (hasFieldImport && fieldLocalName) {
99
+ let _node = node;
100
+ let hasParentField = false;
101
+ let fieldType = 'Complex';
102
+ // If node is a Field element or if
103
+ while (isNodeOfType(_node, 'JSXElement') && isNodeOfType(_node.openingElement.name, 'JSXIdentifier') && !hasParentField) {
104
+ const name = _node.openingElement.name.name;
105
+ hasParentField = hasParentField || name === fieldLocalName;
106
+ _node = _node.parent;
107
+ // Skip up until a JSXElement or JSXAttribute is reached
108
+ if (isNodeOfType(_node, 'JSXFragment') || isNodeOfType(_node, 'ArrowFunctionExpression') || isNodeOfType(_node, 'JSXExpressionContainer') || isNodeOfType(_node, 'JSXAttribute')) {
109
+ while (_node && !isNodeOfType(_node, 'JSXElement') && !isNodeOfType(_node, 'Program')) {
110
+ if (isNodeOfType(_node, 'JSXAttribute')) {
111
+ fieldType = 'Simple';
112
+ }
113
+ _node = _node.parent;
114
+ }
115
+ }
116
+ }
117
+ if (hasParentField) {
118
+ // if has a placeholder attribute
119
+ const hasPlaceholderAttribute = node.openingElement.attributes.find(attr => isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder');
120
+ if (hasPlaceholderAttribute) {
121
+ return context.report({
122
+ node: node.openingElement,
123
+ messageId: `noPlaceholderOn${fieldType}Field`
124
+ });
125
+ }
126
+ }
127
+ } else {
128
+ // if has a placeholder attribute
129
+ const hasPlaceholderAttribute = node.openingElement.attributes.find(attr => isNodeOfType(attr, 'JSXAttribute') && attr.name.name === 'placeholder');
130
+ if (hasPlaceholderAttribute) {
131
+ return context.report({
132
+ node: node.openingElement,
133
+ messageId: 'noPlaceholder'
134
+ });
135
+ }
136
+ }
137
+ }
138
+ }
139
+ };
140
+ }
141
+ });
142
+ export default rule;