@atlaskit/eslint-plugin-design-system 13.27.1 → 13.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +2 -0
- package/dist/cjs/presets/all-flat.codegen.js +3 -1
- package/dist/cjs/presets/all.codegen.js +3 -1
- package/dist/cjs/presets/recommended-flat.codegen.js +3 -1
- package/dist/cjs/presets/recommended.codegen.js +3 -1
- package/dist/cjs/rules/index.codegen.js +5 -1
- package/dist/cjs/rules/use-character-counter-field/index.js +139 -0
- package/dist/cjs/rules/use-field-message-wrapper/index.js +125 -0
- package/dist/es2019/presets/all-flat.codegen.js +3 -1
- package/dist/es2019/presets/all.codegen.js +3 -1
- package/dist/es2019/presets/recommended-flat.codegen.js +3 -1
- package/dist/es2019/presets/recommended.codegen.js +3 -1
- package/dist/es2019/rules/index.codegen.js +5 -1
- package/dist/es2019/rules/use-character-counter-field/index.js +131 -0
- package/dist/es2019/rules/use-field-message-wrapper/index.js +115 -0
- package/dist/esm/presets/all-flat.codegen.js +3 -1
- package/dist/esm/presets/all.codegen.js +3 -1
- package/dist/esm/presets/recommended-flat.codegen.js +3 -1
- package/dist/esm/presets/recommended.codegen.js +3 -1
- package/dist/esm/rules/index.codegen.js +5 -1
- package/dist/esm/rules/use-character-counter-field/index.js +133 -0
- package/dist/esm/rules/use-field-message-wrapper/index.js +119 -0
- package/dist/types/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types/presets/all.codegen.d.ts +1 -1
- package/dist/types/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types/presets/recommended.codegen.d.ts +1 -1
- package/dist/types/rules/index.codegen.d.ts +1 -1
- package/dist/types/rules/use-character-counter-field/index.d.ts +5 -0
- package/dist/types/rules/use-field-message-wrapper/index.d.ts +3 -0
- package/dist/types-ts4.5/presets/all-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/all.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended-flat.codegen.d.ts +1 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -1
- package/dist/types-ts4.5/rules/use-character-counter-field/index.d.ts +5 -0
- package/dist/types-ts4.5/rules/use-field-message-wrapper/index.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 13.29.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`3e6f7b52a2689`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3e6f7b52a2689) -
|
|
8
|
+
Add rule to suggest usage of CharacterCounterField when using Textfield or Textarea with
|
|
9
|
+
minLength/maxLength properties
|
|
10
|
+
|
|
11
|
+
## 13.28.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- [`3f069f2616f1b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3f069f2616f1b) -
|
|
16
|
+
Add rule to enforce usage of message wrapper for field messaging components.
|
|
17
|
+
|
|
3
18
|
## 13.27.1
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -98,10 +98,12 @@ module.exports = {
|
|
|
98
98
|
| <a href="./packages/design-system/eslint-plugin/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="./packages/design-system/eslint-plugin/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="./packages/design-system/eslint-plugin/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
|
+
| <a href="./packages/design-system/eslint-plugin/src/rules/use-character-counter-field/README.md">use-character-counter-field</a> | Suggests using CharacterCounterField when Textfield or Textarea components have maxLength or minLength props within a Form. | Yes | | |
|
|
101
102
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-correct-field/README.md">use-correct-field</a> | Ensure makers use appropriate field component for their respective form elements. | Yes | Yes | Yes |
|
|
102
103
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-cx-function-in-xcss/README.md">use-cx-function-in-xcss</a> | Enforces cx function use to combine styles in xcss. | Yes | Yes | Yes |
|
|
103
104
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-datetime-picker-calendar-button/README.md">use-datetime-picker-calendar-button</a> | Encourages makers to use calendar button in Atlassian Design System's date picker and datetime picker components. | Yes | Yes | Yes |
|
|
104
105
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-drawer-label/README.md">use-drawer-label</a> | Encourages to provide accessible name for Atlassian Design System Drawer component. | Yes | | Yes |
|
|
106
|
+
| <a href="./packages/design-system/eslint-plugin/src/rules/use-field-message-wrapper/README.md">use-field-message-wrapper</a> | Encourage use of message wrapper component when using form message components. | Yes | | Yes |
|
|
105
107
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-heading/README.md">use-heading</a> | Encourage the usage of heading components. | Yes | Yes | Yes |
|
|
106
108
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-heading-level-in-spotlight-card/README.md">use-heading-level-in-spotlight-card</a> | Inform developers of eventual requirement of `headingLevel` prop in `SpotlightCard` component. The heading level should be the appropriate level according to the surrounding context. | Yes | Yes | |
|
|
107
109
|
| <a href="./packages/design-system/eslint-plugin/src/rules/use-href-in-link-item/README.md">use-href-in-link-item</a> | Inform developers of eventual requirement of `href` prop in `LinkItem` component. Elements with a `link` role require an `href` attribute for users to properly navigate, particularly those using assistive technologies. If no valid `href` is required for your use case, consider using a `ButtonItem` instead. | Yes | Yes | Yes |
|
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
9
|
-
* @codegen <<SignedSource::
|
|
9
|
+
* @codegen <<SignedSource::131350ebc877f42247042c6e7327fe18>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -62,10 +62,12 @@ var rules = {
|
|
|
62
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
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
65
66
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
66
67
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
67
68
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
68
69
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
70
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
69
71
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
70
72
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
71
73
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
9
|
+
* @codegen <<SignedSource::b3ddf9ee0a27aaf8a318a6579d48ce99>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -61,10 +61,12 @@ var rules = {
|
|
|
61
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
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
64
65
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
65
66
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
66
67
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
67
68
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
69
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
68
70
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
69
71
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
70
72
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
9
|
+
* @codegen <<SignedSource::ba71ef89188bdc20d0ec948cc00f6436>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -45,10 +45,12 @@ var rules = {
|
|
|
45
45
|
'@atlaskit/design-system/no-unused-css-map': 'warn',
|
|
46
46
|
'@atlaskit/design-system/no-utility-icons': 'warn',
|
|
47
47
|
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
48
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
48
49
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
49
50
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
50
51
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
51
52
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
53
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
52
54
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
53
55
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
54
56
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
9
|
+
* @codegen <<SignedSource::5c119e0ab08e1f39d471b2b827bbb4de>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
|
|
@@ -44,10 +44,12 @@ var rules = {
|
|
|
44
44
|
'@atlaskit/design-system/no-unused-css-map': 'warn',
|
|
45
45
|
'@atlaskit/design-system/no-utility-icons': 'warn',
|
|
46
46
|
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
47
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
47
48
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
48
49
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
49
50
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
50
51
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
52
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
51
53
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
52
54
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
53
55
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
@@ -54,10 +54,12 @@ var _noUnusedCssMap = _interopRequireDefault(require("./no-unused-css-map"));
|
|
|
54
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
|
+
var _useCharacterCounterField = _interopRequireDefault(require("./use-character-counter-field"));
|
|
57
58
|
var _useCorrectField = _interopRequireDefault(require("./use-correct-field"));
|
|
58
59
|
var _useCxFunctionInXcss = _interopRequireDefault(require("./use-cx-function-in-xcss"));
|
|
59
60
|
var _useDatetimePickerCalendarButton = _interopRequireDefault(require("./use-datetime-picker-calendar-button"));
|
|
60
61
|
var _useDrawerLabel = _interopRequireDefault(require("./use-drawer-label"));
|
|
62
|
+
var _useFieldMessageWrapper = _interopRequireDefault(require("./use-field-message-wrapper"));
|
|
61
63
|
var _useHeading = _interopRequireDefault(require("./use-heading"));
|
|
62
64
|
var _useHeadingLevelInSpotlightCard = _interopRequireDefault(require("./use-heading-level-in-spotlight-card"));
|
|
63
65
|
var _useHrefInLinkItem = _interopRequireDefault(require("./use-href-in-link-item"));
|
|
@@ -78,7 +80,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
|
|
|
78
80
|
var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
|
|
79
81
|
/**
|
|
80
82
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
81
|
-
* @codegen <<SignedSource::
|
|
83
|
+
* @codegen <<SignedSource::02be73e0813b6f22038f0f3f2ad6865d>>
|
|
82
84
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
83
85
|
*/
|
|
84
86
|
|
|
@@ -132,10 +134,12 @@ var rules = exports.rules = {
|
|
|
132
134
|
'no-utility-icons': _noUtilityIcons.default,
|
|
133
135
|
'prefer-primitives': _preferPrimitives.default,
|
|
134
136
|
'use-button-group-label': _useButtonGroupLabel.default,
|
|
137
|
+
'use-character-counter-field': _useCharacterCounterField.default,
|
|
135
138
|
'use-correct-field': _useCorrectField.default,
|
|
136
139
|
'use-cx-function-in-xcss': _useCxFunctionInXcss.default,
|
|
137
140
|
'use-datetime-picker-calendar-button': _useDatetimePickerCalendarButton.default,
|
|
138
141
|
'use-drawer-label': _useDrawerLabel.default,
|
|
142
|
+
'use-field-message-wrapper': _useFieldMessageWrapper.default,
|
|
139
143
|
'use-heading': _useHeading.default,
|
|
140
144
|
'use-heading-level-in-spotlight-card': _useHeadingLevelInSpotlightCard.default,
|
|
141
145
|
'use-href-in-link-item': _useHrefInLinkItem.default,
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ruleName = exports.message = exports.default = void 0;
|
|
7
|
+
var _eslintCodemodUtils = require("eslint-codemod-utils");
|
|
8
|
+
var _jsxElement = require("../../ast-nodes/jsx-element");
|
|
9
|
+
var _createRule = require("../utils/create-rule");
|
|
10
|
+
var TEXTFIELD_PACKAGE = '@atlaskit/textfield';
|
|
11
|
+
var TEXTAREA_PACKAGE = '@atlaskit/textarea';
|
|
12
|
+
var FORM_PACKAGE = '@atlaskit/form';
|
|
13
|
+
var message = exports.message = 'When using `maxLength` or `minLength` props with Textfield/Textarea inside a Form, use `CharacterCounterField` from `@atlaskit/form` instead of Field and remove the props from the Textfield/Textarea. This ensures accessibility through real time feedback and aligns with the design system. Read more about [character counter fields](https://atlassian.design/components/form/examples#character-counter-field)';
|
|
14
|
+
var ruleName = exports.ruleName = __dirname.split('/').slice(-1)[0];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if a node is inside a Form component or Field component
|
|
18
|
+
*/
|
|
19
|
+
function isInsideFormOrField(node, formComponentNames) {
|
|
20
|
+
var current = node;
|
|
21
|
+
|
|
22
|
+
// Traverse up the AST to find parent JSX elements
|
|
23
|
+
while (current) {
|
|
24
|
+
var parent = current.parent;
|
|
25
|
+
if (!parent) {
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check if parent is a JSXElement with a name we're tracking
|
|
30
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(parent, 'JSXElement') && (0, _eslintCodemodUtils.isNodeOfType)(parent.openingElement.name, 'JSXIdentifier')) {
|
|
31
|
+
var parentName = parent.openingElement.name.name;
|
|
32
|
+
|
|
33
|
+
// Check if this is a Form component or Field component
|
|
34
|
+
if (formComponentNames.has(parentName)) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Check if parent is inside a JSXExpressionContainer (render prop pattern)
|
|
40
|
+
// This handles: <Field>{({ fieldProps }) => <Textfield {...fieldProps} />}</Field>
|
|
41
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(parent, 'JSXExpressionContainer')) {
|
|
42
|
+
// Continue traversing up to find the Field/Form
|
|
43
|
+
current = parent;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Check if parent is an arrow function (render prop)
|
|
48
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(parent, 'ArrowFunctionExpression')) {
|
|
49
|
+
current = parent;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
current = parent;
|
|
53
|
+
}
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
var rule = (0, _createRule.createLintRule)({
|
|
57
|
+
meta: {
|
|
58
|
+
name: ruleName,
|
|
59
|
+
type: 'suggestion',
|
|
60
|
+
docs: {
|
|
61
|
+
description: 'Suggests using CharacterCounterField when Textfield or Textarea components have maxLength or minLength props within a Form.',
|
|
62
|
+
recommended: true,
|
|
63
|
+
severity: 'warn'
|
|
64
|
+
},
|
|
65
|
+
messages: {
|
|
66
|
+
useCharacterCounterField: message
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
create: function create(context) {
|
|
70
|
+
// Track imported component names
|
|
71
|
+
var importedComponents = new Map();
|
|
72
|
+
var formComponentNames = new Set();
|
|
73
|
+
return {
|
|
74
|
+
ImportDeclaration: function ImportDeclaration(node) {
|
|
75
|
+
var source = node.source.value;
|
|
76
|
+
if (typeof source !== 'string') {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Track Form package imports (Form, Field, etc.)
|
|
81
|
+
if (source === FORM_PACKAGE) {
|
|
82
|
+
node.specifiers.forEach(function (spec) {
|
|
83
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(spec, 'ImportDefaultSpecifier')) {
|
|
84
|
+
// Default import: import Form from '@atlaskit/form'
|
|
85
|
+
formComponentNames.add(spec.local.name);
|
|
86
|
+
} else if ((0, _eslintCodemodUtils.isNodeOfType)(spec, 'ImportSpecifier')) {
|
|
87
|
+
// Named import: import { Form, Field } from '@atlaskit/form'
|
|
88
|
+
formComponentNames.add(spec.local.name);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Track Textfield and Textarea imports
|
|
95
|
+
if (source === TEXTFIELD_PACKAGE || source === TEXTAREA_PACKAGE) {
|
|
96
|
+
var defaultImport = node.specifiers.find(function (spec) {
|
|
97
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(spec, 'ImportDefaultSpecifier');
|
|
98
|
+
});
|
|
99
|
+
if (defaultImport && (0, _eslintCodemodUtils.isNodeOfType)(defaultImport, 'ImportDefaultSpecifier')) {
|
|
100
|
+
var localName = defaultImport.local.name;
|
|
101
|
+
importedComponents.set(localName, {
|
|
102
|
+
localName: localName,
|
|
103
|
+
package: source
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
JSXElement: function JSXElement(node) {
|
|
109
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
var elementName = node.openingElement.name.name;
|
|
116
|
+
|
|
117
|
+
// Check if this element is one of our tracked components
|
|
118
|
+
var componentInfo = importedComponents.get(elementName);
|
|
119
|
+
if (!componentInfo) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check if the component has maxLength or minLength props
|
|
124
|
+
var hasMaxLength = _jsxElement.JSXElementHelper.getAttributeByName(node, 'maxLength');
|
|
125
|
+
var hasMinLength = _jsxElement.JSXElementHelper.getAttributeByName(node, 'minLength');
|
|
126
|
+
if (hasMaxLength || hasMinLength) {
|
|
127
|
+
// Only warn if inside a Form or Field component
|
|
128
|
+
if (isInsideFormOrField(node, formComponentNames)) {
|
|
129
|
+
context.report({
|
|
130
|
+
node: node,
|
|
131
|
+
messageId: 'useCharacterCounterField'
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
var _default = exports.default = rule;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = 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 rule = (0, _createRule.createLintRule)({
|
|
12
|
+
meta: {
|
|
13
|
+
name: 'use-field-message-wrapper',
|
|
14
|
+
type: 'suggestion',
|
|
15
|
+
hasSuggestions: true,
|
|
16
|
+
docs: {
|
|
17
|
+
description: 'Encourage use of message wrapper component when using form message components.',
|
|
18
|
+
recommended: true,
|
|
19
|
+
severity: 'warn'
|
|
20
|
+
},
|
|
21
|
+
messages: {
|
|
22
|
+
useMessageWrapper: "All ADS form messaging components within a field should be wrapped by the `MessageWrapper` component from the form package. Consider also using the [simplified field implementation](https://atlassian.design/components/form/examples#simple-implementation-1) to handle styling and accessible messaging directly."
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
create: function create(context) {
|
|
26
|
+
var fieldImport;
|
|
27
|
+
var messageWrapperImport;
|
|
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;
|
|
56
|
+
} else if (name === 'MessageWrapper') {
|
|
57
|
+
messageWrapperImport = local;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
JSXElement: function JSXElement(node) {
|
|
63
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
var name = node.openingElement.name.name;
|
|
70
|
+
|
|
71
|
+
// if it's not a message component, skip
|
|
72
|
+
if (messageImports.length === 0 || !messageImports.find(function (imp) {
|
|
73
|
+
return imp.name === name;
|
|
74
|
+
})) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// if no field import exists, skip. It needs to be within our field
|
|
79
|
+
if (!fieldImport) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// If no message wrapper import exists, then it's definitely an error
|
|
84
|
+
if (!messageWrapperImport) {
|
|
85
|
+
return context.report({
|
|
86
|
+
node: node,
|
|
87
|
+
messageId: 'useMessageWrapper'
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// check for if field and message wrapper are parents
|
|
92
|
+
var _node = node;
|
|
93
|
+
var hasParentField = false;
|
|
94
|
+
var hasParentMessageWrapper = false;
|
|
95
|
+
while ((0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXElement') && (0, _eslintCodemodUtils.isNodeOfType)(_node.openingElement.name, 'JSXIdentifier') && !hasParentField) {
|
|
96
|
+
var _name = _node.openingElement.name.name;
|
|
97
|
+
hasParentField = hasParentField || _name === fieldImport.name;
|
|
98
|
+
hasParentMessageWrapper = hasParentMessageWrapper || _name === messageWrapperImport.name;
|
|
99
|
+
_node = _node.parent;
|
|
100
|
+
// Skip up until a JSXElement is reached
|
|
101
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXFragment') || (0, _eslintCodemodUtils.isNodeOfType)(_node, 'ArrowFunctionExpression') || (0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXExpressionContainer')) {
|
|
102
|
+
while (_node && !(0, _eslintCodemodUtils.isNodeOfType)(_node, 'JSXElement') && !(0, _eslintCodemodUtils.isNodeOfType)(_node, 'Program')) {
|
|
103
|
+
_node = _node.parent;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// if not field, skip because this doesn't matter
|
|
109
|
+
if (!hasParentField) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// if it has a message wrapper, skip
|
|
114
|
+
if (hasParentMessageWrapper) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
context.report({
|
|
118
|
+
node: node,
|
|
119
|
+
messageId: 'useMessageWrapper'
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
var _default = exports.default = rule;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::131350ebc877f42247042c6e7327fe18>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -56,10 +56,12 @@ const rules = {
|
|
|
56
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
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
59
60
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
60
61
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
61
62
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
62
63
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
64
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
63
65
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
64
66
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
65
67
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
3
|
+
* @codegen <<SignedSource::b3ddf9ee0a27aaf8a318a6579d48ce99>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -55,10 +55,12 @@ const rules = {
|
|
|
55
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
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
58
59
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
59
60
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
60
61
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
61
62
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
63
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
62
64
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
63
65
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
64
66
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
3
|
+
* @codegen <<SignedSource::ba71ef89188bdc20d0ec948cc00f6436>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -39,10 +39,12 @@ const rules = {
|
|
|
39
39
|
'@atlaskit/design-system/no-unused-css-map': 'warn',
|
|
40
40
|
'@atlaskit/design-system/no-utility-icons': 'warn',
|
|
41
41
|
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
42
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
42
43
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
43
44
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
44
45
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
45
46
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
47
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
46
48
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
47
49
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
48
50
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
3
|
+
* @codegen <<SignedSource::5c119e0ab08e1f39d471b2b827bbb4de>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -38,10 +38,12 @@ const rules = {
|
|
|
38
38
|
'@atlaskit/design-system/no-unused-css-map': 'warn',
|
|
39
39
|
'@atlaskit/design-system/no-utility-icons': 'warn',
|
|
40
40
|
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
41
|
+
'@atlaskit/design-system/use-character-counter-field': 'warn',
|
|
41
42
|
'@atlaskit/design-system/use-correct-field': 'warn',
|
|
42
43
|
'@atlaskit/design-system/use-cx-function-in-xcss': 'error',
|
|
43
44
|
'@atlaskit/design-system/use-datetime-picker-calendar-button': 'warn',
|
|
44
45
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
46
|
+
'@atlaskit/design-system/use-field-message-wrapper': 'warn',
|
|
45
47
|
'@atlaskit/design-system/use-heading': 'warn',
|
|
46
48
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
47
49
|
'@atlaskit/design-system/use-href-in-link-item': '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::
|
|
3
|
+
* @codegen <<SignedSource::02be73e0813b6f22038f0f3f2ad6865d>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -53,10 +53,12 @@ import noUnusedCssMap from './no-unused-css-map';
|
|
|
53
53
|
import noUtilityIcons from './no-utility-icons';
|
|
54
54
|
import preferPrimitives from './prefer-primitives';
|
|
55
55
|
import useButtonGroupLabel from './use-button-group-label';
|
|
56
|
+
import useCharacterCounterField from './use-character-counter-field';
|
|
56
57
|
import useCorrectField from './use-correct-field';
|
|
57
58
|
import useCxFunctionInXcss from './use-cx-function-in-xcss';
|
|
58
59
|
import useDatetimePickerCalendarButton from './use-datetime-picker-calendar-button';
|
|
59
60
|
import useDrawerLabel from './use-drawer-label';
|
|
61
|
+
import useFieldMessageWrapper from './use-field-message-wrapper';
|
|
60
62
|
import useHeading from './use-heading';
|
|
61
63
|
import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
|
|
62
64
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
@@ -125,10 +127,12 @@ export const rules = {
|
|
|
125
127
|
'no-utility-icons': noUtilityIcons,
|
|
126
128
|
'prefer-primitives': preferPrimitives,
|
|
127
129
|
'use-button-group-label': useButtonGroupLabel,
|
|
130
|
+
'use-character-counter-field': useCharacterCounterField,
|
|
128
131
|
'use-correct-field': useCorrectField,
|
|
129
132
|
'use-cx-function-in-xcss': useCxFunctionInXcss,
|
|
130
133
|
'use-datetime-picker-calendar-button': useDatetimePickerCalendarButton,
|
|
131
134
|
'use-drawer-label': useDrawerLabel,
|
|
135
|
+
'use-field-message-wrapper': useFieldMessageWrapper,
|
|
132
136
|
'use-heading': useHeading,
|
|
133
137
|
'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
|
|
134
138
|
'use-href-in-link-item': useHrefInLinkItem,
|