@atlaskit/eslint-plugin-design-system 10.5.0 → 10.6.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 +8 -0
- package/README.md +1 -0
- package/constellation/index/usage.mdx +1 -0
- package/constellation/use-menu-section-title/usage.mdx +55 -0
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/presets/recommended.codegen.js +2 -1
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/use-menu-section-title/index.js +85 -0
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/presets/recommended.codegen.js +2 -1
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/use-menu-section-title/index.js +79 -0
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/presets/recommended.codegen.js +2 -1
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/use-menu-section-title/index.js +79 -0
- package/dist/types/index.codegen.d.ts +2 -0
- package/dist/types/presets/all.codegen.d.ts +2 -1
- package/dist/types/presets/recommended.codegen.d.ts +2 -1
- package/dist/types/rules/index.codegen.d.ts +1 -0
- package/dist/types/rules/use-menu-section-title/index.d.ts +3 -0
- package/dist/types-ts4.5/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +2 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-menu-section-title/index.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 10.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#99829](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/99829)
|
|
8
|
+
[`f15d4f35b8f6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f15d4f35b8f6) -
|
|
9
|
+
Add `use-menu-section-title` eslint rule.
|
|
10
|
+
|
|
3
11
|
## 10.5.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -81,6 +81,7 @@ module.exports = {
|
|
|
81
81
|
| <a href="./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 | |
|
|
82
82
|
| <a href="./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 |
|
|
83
83
|
| <a href="./src/rules/use-latest-xcss-syntax/README.md">use-latest-xcss-syntax</a> | Enforces usage of space design tokens rather than hard-coded values in xcss. | Yes | Yes | |
|
|
84
|
+
| <a href="./src/rules/use-menu-section-title/README.md">use-menu-section-title</a> | Encourages makers to provide accessible title for Atlassian Design System Menu Section component. | Yes | | Yes |
|
|
84
85
|
| <a href="./src/rules/use-popup-label/README.md">use-popup-label</a> | Encourages to provide accessible name for Atlassian Design System Popup component. | Yes | | Yes |
|
|
85
86
|
| <a href="./src/rules/use-primitives/README.md">use-primitives</a> | Encourage the usage of primitives components. | | Yes | Yes |
|
|
86
87
|
| <a href="./src/rules/use-primitives-text/README.md">use-primitives-text</a> | Encourage the usage of text components. | | Yes | Yes |
|
|
@@ -44,6 +44,7 @@ This plugin contains rules that should be used when working with the
|
|
|
44
44
|
| <a href="/components/eslint-plugin-design-system/use-heading-level-in-spotlight-card/usage">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 | |
|
|
45
45
|
| <a href="/components/eslint-plugin-design-system/use-href-in-link-item/usage">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 |
|
|
46
46
|
| <a href="/components/eslint-plugin-design-system/use-latest-xcss-syntax/usage">use-latest-xcss-syntax</a> | Enforces usage of space design tokens rather than hard-coded values in xcss. | Yes | Yes | |
|
|
47
|
+
| <a href="/components/eslint-plugin-design-system/use-menu-section-title/usage">use-menu-section-title</a> | Encourages makers to provide accessible title for Atlassian Design System Menu Section component. | Yes | | Yes |
|
|
47
48
|
| <a href="/components/eslint-plugin-design-system/use-popup-label/usage">use-popup-label</a> | Encourages to provide accessible name for Atlassian Design System Popup component. | Yes | | Yes |
|
|
48
49
|
| <a href="/components/eslint-plugin-design-system/use-primitives/usage">use-primitives</a> | Encourage the usage of primitives components. | | Yes | Yes |
|
|
49
50
|
| <a href="/components/eslint-plugin-design-system/use-primitives-text/usage">use-primitives-text</a> | Encourage the usage of text components. | | Yes | Yes |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# use-menu-section-title
|
|
2
|
+
|
|
3
|
+
Section should have an accessible title or a reference to it, so that users of assistive
|
|
4
|
+
technologies could have contextual information of interaction with current element.
|
|
5
|
+
|
|
6
|
+
## Examples
|
|
7
|
+
|
|
8
|
+
This rule will indicate user with warning to strongly recommend usage of either `title` or `titleId`
|
|
9
|
+
prop.
|
|
10
|
+
|
|
11
|
+
### Incorrect
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
<Section>
|
|
15
|
+
^^^^^^ Missing either `title` or `titleId` prop.
|
|
16
|
+
Section content
|
|
17
|
+
</Section>
|
|
18
|
+
|
|
19
|
+
<Section title>
|
|
20
|
+
^^^^^ `title` prop is missing value.
|
|
21
|
+
Section content
|
|
22
|
+
</Section>
|
|
23
|
+
|
|
24
|
+
<Section title="">
|
|
25
|
+
^^^^^ `title` prop is missing accessible name value.
|
|
26
|
+
Section content
|
|
27
|
+
</Section>
|
|
28
|
+
|
|
29
|
+
<Section titleId>
|
|
30
|
+
^^^^^^^ `titleId` prop is missing reference value.
|
|
31
|
+
<h1 id="section-title">Section content title</hi>
|
|
32
|
+
</Section>
|
|
33
|
+
|
|
34
|
+
<Section titleId="">
|
|
35
|
+
^^^^^^^ `titleId` prop is missing reference value.
|
|
36
|
+
<h1 id="section-title">Section content title</hi>
|
|
37
|
+
</Section>
|
|
38
|
+
|
|
39
|
+
<Section titleId="section-title" title="Accessible title">
|
|
40
|
+
^^^^^^^ ^^^^^ Do not include both `titleId` and `title` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `title` to provide accessible name explicitly.
|
|
41
|
+
<h1 id="section-title">Section content title</hi>
|
|
42
|
+
</Section>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Correct
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
<Section title="Section content title">
|
|
49
|
+
Section content
|
|
50
|
+
</Section>
|
|
51
|
+
|
|
52
|
+
<Section titleId="section-title">
|
|
53
|
+
<h1 id="section-title">Section content title</hi>
|
|
54
|
+
</Section>
|
|
55
|
+
```
|
|
@@ -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::837556032f39113ae86785a120bb9ccb>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -44,6 +44,7 @@ var _default = exports.default = {
|
|
|
44
44
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
45
45
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
46
46
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
47
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
47
48
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
48
49
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
49
50
|
'@atlaskit/design-system/use-primitives-text': '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::b7ed527a03208f0bc68f9d34e4ef2260>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -34,6 +34,7 @@ var _default = exports.default = {
|
|
|
34
34
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
35
35
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
36
36
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
37
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
37
38
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
38
39
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
39
40
|
}
|
|
@@ -37,6 +37,7 @@ var _useHeading = _interopRequireDefault(require("./use-heading"));
|
|
|
37
37
|
var _useHeadingLevelInSpotlightCard = _interopRequireDefault(require("./use-heading-level-in-spotlight-card"));
|
|
38
38
|
var _useHrefInLinkItem = _interopRequireDefault(require("./use-href-in-link-item"));
|
|
39
39
|
var _useLatestXcssSyntax = _interopRequireDefault(require("./use-latest-xcss-syntax"));
|
|
40
|
+
var _useMenuSectionTitle = _interopRequireDefault(require("./use-menu-section-title"));
|
|
40
41
|
var _usePopupLabel = _interopRequireDefault(require("./use-popup-label"));
|
|
41
42
|
var _usePrimitives = _interopRequireDefault(require("./use-primitives"));
|
|
42
43
|
var _usePrimitivesText = _interopRequireDefault(require("./use-primitives-text"));
|
|
@@ -45,7 +46,7 @@ var _useTokensTypography = _interopRequireDefault(require("./use-tokens-typograp
|
|
|
45
46
|
var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
|
|
46
47
|
/**
|
|
47
48
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
48
|
-
* @codegen <<SignedSource::
|
|
49
|
+
* @codegen <<SignedSource::287628b11d396c2bcbcf6f4a175a3d3a>>
|
|
49
50
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
50
51
|
*/
|
|
51
52
|
var _default = exports.default = {
|
|
@@ -81,6 +82,7 @@ var _default = exports.default = {
|
|
|
81
82
|
'use-heading-level-in-spotlight-card': _useHeadingLevelInSpotlightCard.default,
|
|
82
83
|
'use-href-in-link-item': _useHrefInLinkItem.default,
|
|
83
84
|
'use-latest-xcss-syntax': _useLatestXcssSyntax.default,
|
|
85
|
+
'use-menu-section-title': _useMenuSectionTitle.default,
|
|
84
86
|
'use-popup-label': _usePopupLabel.default,
|
|
85
87
|
'use-primitives': _usePrimitives.default,
|
|
86
88
|
'use-primitives-text': _usePrimitivesText.default,
|
|
@@ -0,0 +1,85 @@
|
|
|
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
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
10
|
+
|
|
11
|
+
var elementsAccessibleNameProps = ['title', 'titleId'];
|
|
12
|
+
var rule = (0, _createRule.createLintRule)({
|
|
13
|
+
meta: {
|
|
14
|
+
name: 'use-menu-section-title',
|
|
15
|
+
type: 'suggestion',
|
|
16
|
+
docs: {
|
|
17
|
+
description: 'Encourages makers to provide accessible title for Atlassian Design System Menu Section component.',
|
|
18
|
+
recommended: true,
|
|
19
|
+
severity: 'warn'
|
|
20
|
+
},
|
|
21
|
+
messages: {
|
|
22
|
+
missingTitleProp: 'Missing accessible title. If there is no visible content to associate use `title` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
23
|
+
titlePropShouldHaveContents: 'Define the string that labels the interactive element.',
|
|
24
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of the element that defines the accessible name.',
|
|
25
|
+
noBothPropsUsage: 'Do not include both `titleId` and `title` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `title` to provide accessible name explicitly.'
|
|
26
|
+
},
|
|
27
|
+
hasSuggestions: true
|
|
28
|
+
},
|
|
29
|
+
create: function create(context) {
|
|
30
|
+
var contextLocalIdentifier = [];
|
|
31
|
+
return {
|
|
32
|
+
ImportDeclaration: function ImportDeclaration(node) {
|
|
33
|
+
var _node$specifiers;
|
|
34
|
+
var menuSectionIdentifier = (_node$specifiers = node.specifiers) === null || _node$specifiers === void 0 ? void 0 : _node$specifiers.filter(function (spec) {
|
|
35
|
+
if (node.source.value === '@atlaskit/menu') {
|
|
36
|
+
var _spec$imported;
|
|
37
|
+
return spec.type === 'ImportSpecifier' && ((_spec$imported = spec.imported) === null || _spec$imported === void 0 ? void 0 : _spec$imported.name) === 'Section';
|
|
38
|
+
} else if (node.source.value === '@atlaskit/menu/section') {
|
|
39
|
+
return spec.type === 'ImportDefaultSpecifier';
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
if (menuSectionIdentifier !== null && menuSectionIdentifier !== void 0 && menuSectionIdentifier.length) {
|
|
43
|
+
var local = menuSectionIdentifier[0].local;
|
|
44
|
+
contextLocalIdentifier.push(local.name);
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
JSXElement: function JSXElement(node) {
|
|
48
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
var name = node.openingElement.name.name;
|
|
55
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
56
|
+
var componentLabelProps = node.openingElement.attributes.filter(function (attr) {
|
|
57
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && (0, _eslintCodemodUtils.isNodeOfType)(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name);
|
|
58
|
+
});
|
|
59
|
+
if (componentLabelProps.length === 1) {
|
|
60
|
+
var prop = componentLabelProps[0];
|
|
61
|
+
if ('value' in prop && prop.value) {
|
|
62
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'Literal') && !prop.value.value || (0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
63
|
+
context.report({
|
|
64
|
+
node: prop,
|
|
65
|
+
messageId: prop.name.name === 'title' ? 'titlePropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else if (componentLabelProps.length > 1) {
|
|
70
|
+
context.report({
|
|
71
|
+
node: node.openingElement,
|
|
72
|
+
messageId: 'noBothPropsUsage'
|
|
73
|
+
});
|
|
74
|
+
} else {
|
|
75
|
+
context.report({
|
|
76
|
+
node: node.openingElement,
|
|
77
|
+
messageId: 'missingTitleProp'
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
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::837556032f39113ae86785a120bb9ccb>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -38,6 +38,7 @@ export default {
|
|
|
38
38
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
39
39
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
40
40
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
41
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
41
42
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
42
43
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
43
44
|
'@atlaskit/design-system/use-primitives-text': '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::b7ed527a03208f0bc68f9d34e4ef2260>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -28,6 +28,7 @@ export default {
|
|
|
28
28
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
29
29
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
30
30
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
31
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
31
32
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
32
33
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
33
34
|
}
|
|
@@ -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::287628b11d396c2bcbcf6f4a175a3d3a>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -35,6 +35,7 @@ import useHeading from './use-heading';
|
|
|
35
35
|
import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
|
|
36
36
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
37
37
|
import useLatestXcssSyntax from './use-latest-xcss-syntax';
|
|
38
|
+
import useMenuSectionTitle from './use-menu-section-title';
|
|
38
39
|
import usePopupLabel from './use-popup-label';
|
|
39
40
|
import usePrimitives from './use-primitives';
|
|
40
41
|
import usePrimitivesText from './use-primitives-text';
|
|
@@ -74,6 +75,7 @@ export default {
|
|
|
74
75
|
'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
|
|
75
76
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
76
77
|
'use-latest-xcss-syntax': useLatestXcssSyntax,
|
|
78
|
+
'use-menu-section-title': useMenuSectionTitle,
|
|
77
79
|
'use-popup-label': usePopupLabel,
|
|
78
80
|
'use-primitives': usePrimitives,
|
|
79
81
|
'use-primitives-text': usePrimitivesText,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
4
|
+
import { createLintRule } from '../utils/create-rule';
|
|
5
|
+
const elementsAccessibleNameProps = ['title', 'titleId'];
|
|
6
|
+
const rule = createLintRule({
|
|
7
|
+
meta: {
|
|
8
|
+
name: 'use-menu-section-title',
|
|
9
|
+
type: 'suggestion',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'Encourages makers to provide accessible title for Atlassian Design System Menu Section component.',
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'warn'
|
|
14
|
+
},
|
|
15
|
+
messages: {
|
|
16
|
+
missingTitleProp: 'Missing accessible title. If there is no visible content to associate use `title` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
17
|
+
titlePropShouldHaveContents: 'Define the string that labels the interactive element.',
|
|
18
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of the element that defines the accessible name.',
|
|
19
|
+
noBothPropsUsage: 'Do not include both `titleId` and `title` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `title` to provide accessible name explicitly.'
|
|
20
|
+
},
|
|
21
|
+
hasSuggestions: true
|
|
22
|
+
},
|
|
23
|
+
create(context) {
|
|
24
|
+
const contextLocalIdentifier = [];
|
|
25
|
+
return {
|
|
26
|
+
ImportDeclaration(node) {
|
|
27
|
+
var _node$specifiers;
|
|
28
|
+
const menuSectionIdentifier = (_node$specifiers = node.specifiers) === null || _node$specifiers === void 0 ? void 0 : _node$specifiers.filter(spec => {
|
|
29
|
+
if (node.source.value === '@atlaskit/menu') {
|
|
30
|
+
var _spec$imported;
|
|
31
|
+
return spec.type === 'ImportSpecifier' && ((_spec$imported = spec.imported) === null || _spec$imported === void 0 ? void 0 : _spec$imported.name) === 'Section';
|
|
32
|
+
} else if (node.source.value === '@atlaskit/menu/section') {
|
|
33
|
+
return spec.type === 'ImportDefaultSpecifier';
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (menuSectionIdentifier !== null && menuSectionIdentifier !== void 0 && menuSectionIdentifier.length) {
|
|
37
|
+
const {
|
|
38
|
+
local
|
|
39
|
+
} = menuSectionIdentifier[0];
|
|
40
|
+
contextLocalIdentifier.push(local.name);
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
JSXElement(node) {
|
|
44
|
+
if (!isNodeOfType(node, 'JSXElement')) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const name = node.openingElement.name.name;
|
|
51
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
52
|
+
const componentLabelProps = node.openingElement.attributes.filter(attr => isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name));
|
|
53
|
+
if (componentLabelProps.length === 1) {
|
|
54
|
+
const prop = componentLabelProps[0];
|
|
55
|
+
if ('value' in prop && prop.value) {
|
|
56
|
+
if (isNodeOfType(prop.value, 'Literal') && !prop.value.value || isNodeOfType(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
57
|
+
context.report({
|
|
58
|
+
node: prop,
|
|
59
|
+
messageId: prop.name.name === 'title' ? 'titlePropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} else if (componentLabelProps.length > 1) {
|
|
64
|
+
context.report({
|
|
65
|
+
node: node.openingElement,
|
|
66
|
+
messageId: 'noBothPropsUsage'
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
context.report({
|
|
70
|
+
node: node.openingElement,
|
|
71
|
+
messageId: 'missingTitleProp'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
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::
|
|
3
|
+
* @codegen <<SignedSource::837556032f39113ae86785a120bb9ccb>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -38,6 +38,7 @@ export default {
|
|
|
38
38
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
39
39
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
40
40
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
41
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
41
42
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
42
43
|
'@atlaskit/design-system/use-primitives': 'warn',
|
|
43
44
|
'@atlaskit/design-system/use-primitives-text': '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::b7ed527a03208f0bc68f9d34e4ef2260>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -28,6 +28,7 @@ export default {
|
|
|
28
28
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
29
29
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
30
30
|
'@atlaskit/design-system/use-latest-xcss-syntax': 'error',
|
|
31
|
+
'@atlaskit/design-system/use-menu-section-title': 'warn',
|
|
31
32
|
'@atlaskit/design-system/use-popup-label': 'warn',
|
|
32
33
|
'@atlaskit/design-system/use-visually-hidden': 'error'
|
|
33
34
|
}
|
|
@@ -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::287628b11d396c2bcbcf6f4a175a3d3a>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -35,6 +35,7 @@ import useHeading from './use-heading';
|
|
|
35
35
|
import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
|
|
36
36
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
37
37
|
import useLatestXcssSyntax from './use-latest-xcss-syntax';
|
|
38
|
+
import useMenuSectionTitle from './use-menu-section-title';
|
|
38
39
|
import usePopupLabel from './use-popup-label';
|
|
39
40
|
import usePrimitives from './use-primitives';
|
|
40
41
|
import usePrimitivesText from './use-primitives-text';
|
|
@@ -74,6 +75,7 @@ export default {
|
|
|
74
75
|
'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
|
|
75
76
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
76
77
|
'use-latest-xcss-syntax': useLatestXcssSyntax,
|
|
78
|
+
'use-menu-section-title': useMenuSectionTitle,
|
|
77
79
|
'use-popup-label': usePopupLabel,
|
|
78
80
|
'use-primitives': usePrimitives,
|
|
79
81
|
'use-primitives-text': usePrimitivesText,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
4
|
+
import { createLintRule } from '../utils/create-rule';
|
|
5
|
+
var elementsAccessibleNameProps = ['title', 'titleId'];
|
|
6
|
+
var rule = createLintRule({
|
|
7
|
+
meta: {
|
|
8
|
+
name: 'use-menu-section-title',
|
|
9
|
+
type: 'suggestion',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'Encourages makers to provide accessible title for Atlassian Design System Menu Section component.',
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'warn'
|
|
14
|
+
},
|
|
15
|
+
messages: {
|
|
16
|
+
missingTitleProp: 'Missing accessible title. If there is no visible content to associate use `title` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
17
|
+
titlePropShouldHaveContents: 'Define the string that labels the interactive element.',
|
|
18
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of the element that defines the accessible name.',
|
|
19
|
+
noBothPropsUsage: 'Do not include both `titleId` and `title` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `title` to provide accessible name explicitly.'
|
|
20
|
+
},
|
|
21
|
+
hasSuggestions: true
|
|
22
|
+
},
|
|
23
|
+
create: function create(context) {
|
|
24
|
+
var contextLocalIdentifier = [];
|
|
25
|
+
return {
|
|
26
|
+
ImportDeclaration: function ImportDeclaration(node) {
|
|
27
|
+
var _node$specifiers;
|
|
28
|
+
var menuSectionIdentifier = (_node$specifiers = node.specifiers) === null || _node$specifiers === void 0 ? void 0 : _node$specifiers.filter(function (spec) {
|
|
29
|
+
if (node.source.value === '@atlaskit/menu') {
|
|
30
|
+
var _spec$imported;
|
|
31
|
+
return spec.type === 'ImportSpecifier' && ((_spec$imported = spec.imported) === null || _spec$imported === void 0 ? void 0 : _spec$imported.name) === 'Section';
|
|
32
|
+
} else if (node.source.value === '@atlaskit/menu/section') {
|
|
33
|
+
return spec.type === 'ImportDefaultSpecifier';
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (menuSectionIdentifier !== null && menuSectionIdentifier !== void 0 && menuSectionIdentifier.length) {
|
|
37
|
+
var local = menuSectionIdentifier[0].local;
|
|
38
|
+
contextLocalIdentifier.push(local.name);
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
JSXElement: function JSXElement(node) {
|
|
42
|
+
if (!isNodeOfType(node, 'JSXElement')) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
var name = node.openingElement.name.name;
|
|
49
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
50
|
+
var componentLabelProps = node.openingElement.attributes.filter(function (attr) {
|
|
51
|
+
return isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name);
|
|
52
|
+
});
|
|
53
|
+
if (componentLabelProps.length === 1) {
|
|
54
|
+
var prop = componentLabelProps[0];
|
|
55
|
+
if ('value' in prop && prop.value) {
|
|
56
|
+
if (isNodeOfType(prop.value, 'Literal') && !prop.value.value || isNodeOfType(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
57
|
+
context.report({
|
|
58
|
+
node: prop,
|
|
59
|
+
messageId: prop.name.name === 'title' ? 'titlePropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} else if (componentLabelProps.length > 1) {
|
|
64
|
+
context.report({
|
|
65
|
+
node: node.openingElement,
|
|
66
|
+
messageId: 'noBothPropsUsage'
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
context.report({
|
|
70
|
+
node: node.openingElement,
|
|
71
|
+
messageId: 'missingTitleProp'
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
export default rule;
|
|
@@ -35,6 +35,7 @@ export declare const configs: {
|
|
|
35
35
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
36
36
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
37
37
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
38
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
38
39
|
'@atlaskit/design-system/use-popup-label': string;
|
|
39
40
|
'@atlaskit/design-system/use-primitives': string;
|
|
40
41
|
'@atlaskit/design-system/use-primitives-text': string;
|
|
@@ -68,6 +69,7 @@ export declare const configs: {
|
|
|
68
69
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
69
70
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
70
71
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
72
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
71
73
|
'@atlaskit/design-system/use-popup-label': string;
|
|
72
74
|
'@atlaskit/design-system/use-visually-hidden': string;
|
|
73
75
|
};
|
|
@@ -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::837556032f39113ae86785a120bb9ccb>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -38,6 +38,7 @@ declare const _default: {
|
|
|
38
38
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
39
39
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
40
40
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
41
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
41
42
|
'@atlaskit/design-system/use-popup-label': string;
|
|
42
43
|
'@atlaskit/design-system/use-primitives': string;
|
|
43
44
|
'@atlaskit/design-system/use-primitives-text': string;
|
|
@@ -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::b7ed527a03208f0bc68f9d34e4ef2260>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -28,6 +28,7 @@ declare const _default: {
|
|
|
28
28
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
29
29
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
30
30
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
31
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
31
32
|
'@atlaskit/design-system/use-popup-label': string;
|
|
32
33
|
'@atlaskit/design-system/use-visually-hidden': string;
|
|
33
34
|
};
|
|
@@ -35,6 +35,7 @@ declare const _default: {
|
|
|
35
35
|
'use-heading-level-in-spotlight-card': import("eslint").Rule.RuleModule;
|
|
36
36
|
'use-href-in-link-item': import("eslint").Rule.RuleModule;
|
|
37
37
|
'use-latest-xcss-syntax': import("eslint").Rule.RuleModule;
|
|
38
|
+
'use-menu-section-title': import("eslint").Rule.RuleModule;
|
|
38
39
|
'use-popup-label': import("eslint").Rule.RuleModule;
|
|
39
40
|
'use-primitives': import("eslint").Rule.RuleModule;
|
|
40
41
|
'use-primitives-text': import("eslint").Rule.RuleModule;
|
|
@@ -35,6 +35,7 @@ export declare const configs: {
|
|
|
35
35
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
36
36
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
37
37
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
38
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
38
39
|
'@atlaskit/design-system/use-popup-label': string;
|
|
39
40
|
'@atlaskit/design-system/use-primitives': string;
|
|
40
41
|
'@atlaskit/design-system/use-primitives-text': string;
|
|
@@ -68,6 +69,7 @@ export declare const configs: {
|
|
|
68
69
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
69
70
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
70
71
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
72
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
71
73
|
'@atlaskit/design-system/use-popup-label': string;
|
|
72
74
|
'@atlaskit/design-system/use-visually-hidden': string;
|
|
73
75
|
};
|
|
@@ -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::837556032f39113ae86785a120bb9ccb>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -38,6 +38,7 @@ declare const _default: {
|
|
|
38
38
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
39
39
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
40
40
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
41
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
41
42
|
'@atlaskit/design-system/use-popup-label': string;
|
|
42
43
|
'@atlaskit/design-system/use-primitives': string;
|
|
43
44
|
'@atlaskit/design-system/use-primitives-text': string;
|
|
@@ -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::b7ed527a03208f0bc68f9d34e4ef2260>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -28,6 +28,7 @@ declare const _default: {
|
|
|
28
28
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
29
29
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
30
30
|
'@atlaskit/design-system/use-latest-xcss-syntax': string;
|
|
31
|
+
'@atlaskit/design-system/use-menu-section-title': string;
|
|
31
32
|
'@atlaskit/design-system/use-popup-label': string;
|
|
32
33
|
'@atlaskit/design-system/use-visually-hidden': string;
|
|
33
34
|
};
|
|
@@ -39,6 +39,7 @@ declare const _default: {
|
|
|
39
39
|
'use-heading-level-in-spotlight-card': import("eslint").Rule.RuleModule;
|
|
40
40
|
'use-href-in-link-item': import("eslint").Rule.RuleModule;
|
|
41
41
|
'use-latest-xcss-syntax': import("eslint").Rule.RuleModule;
|
|
42
|
+
'use-menu-section-title': import("eslint").Rule.RuleModule;
|
|
42
43
|
'use-popup-label': import("eslint").Rule.RuleModule;
|
|
43
44
|
'use-primitives': import("eslint").Rule.RuleModule;
|
|
44
45
|
'use-primitives-text': import("eslint").Rule.RuleModule;
|
package/package.json
CHANGED