@atlaskit/eslint-plugin-design-system 8.20.0 → 8.21.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 +6 -0
- package/README.md +1 -0
- package/constellation/index/usage.mdx +60 -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-button-group-label/index.js +83 -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-button-group-label/index.js +75 -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-button-group-label/index.js +77 -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-button-group-label/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-button-group-label/index.d.ts +3 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @atlaskit/eslint-plugin-design-system
|
|
2
2
|
|
|
3
|
+
## 8.21.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#66250](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/66250) [`6ff74a16aee7`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/6ff74a16aee7) - Introducing new rule to encourage adding/referencing accessible name to a ButtonGroup component.
|
|
8
|
+
|
|
3
9
|
## 8.20.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ module.exports = {
|
|
|
65
65
|
| <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 | | |
|
|
66
66
|
| <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 | | |
|
|
67
67
|
| <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. | | | |
|
|
68
|
+
| <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 |
|
|
68
69
|
| <a href="./src/rules/use-drawer-label/README.md">use-drawer-label</a> | Encourages to provide accessible name for Atlassian Design System Drawer component. | Yes | | Yes |
|
|
69
70
|
| <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 | |
|
|
70
71
|
| <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 |
|
|
@@ -29,6 +29,7 @@ This plugin contains rules that should be used when working with the [Atlassian
|
|
|
29
29
|
| <a href="#no-unsafe-style-overrides">no-unsafe-style-overrides</a> | Discourage usage of unsafe style overrides used against the Atlassian Design System. | Yes | | |
|
|
30
30
|
| <a href="#no-unsupported-drag-and-drop-libraries">no-unsupported-drag-and-drop-libraries</a> | Disallow importing unsupported drag and drop modules. | Yes | | |
|
|
31
31
|
| <a href="#prefer-primitives">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. | | | |
|
|
32
|
+
| <a href="#use-button-group-label">use-button-group-label</a> | Ensures button groups are described to assistive technology by a direct label or by another element. | Yes | | Yes |
|
|
32
33
|
| <a href="#use-drawer-label">use-drawer-label</a> | Encourages to provide accessible name for Atlassian Design System Drawer component. | Yes | | Yes |
|
|
33
34
|
| <a href="#use-heading-level-in-spotlight-card">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 | |
|
|
34
35
|
| <a href="#use-href-in-link-item">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 |
|
|
@@ -767,6 +768,65 @@ This rule marks code as violations when it may be able to be replaced with a pri
|
|
|
767
768
|
</Component>
|
|
768
769
|
```
|
|
769
770
|
|
|
771
|
+
## use-button-group-label
|
|
772
|
+
|
|
773
|
+
ButtonGroup should have an accessible name or a reference to it, so that upon opening, users of assistive technologies could have contextual information of interaction with current element.
|
|
774
|
+
|
|
775
|
+
<h3>Examples</h3>
|
|
776
|
+
|
|
777
|
+
This rule will indicate user with warning to strongly recommend usage of either `label` or `titleId` prop.
|
|
778
|
+
|
|
779
|
+
#### Incorrect
|
|
780
|
+
|
|
781
|
+
```tsx
|
|
782
|
+
<ButtonGroup>
|
|
783
|
+
^^^^^^^^^^^ Missing either `label` or `titleId` prop.
|
|
784
|
+
<Button>Save</Button>
|
|
785
|
+
<Button>Edit</Button>
|
|
786
|
+
<Button>Delete</Button>
|
|
787
|
+
</ButtonGroup>
|
|
788
|
+
|
|
789
|
+
<ButtonGroup label="">
|
|
790
|
+
^^^^^ `label` prop is missing accessible name value.
|
|
791
|
+
<Button>Save</Button>
|
|
792
|
+
<Button>Edit</Button>
|
|
793
|
+
<Button>Delete</Button>
|
|
794
|
+
</ButtonGroup>
|
|
795
|
+
|
|
796
|
+
<h2 id="button-group-title">ButtonGroup content title</hi>
|
|
797
|
+
<ButtonGroup titleId="">
|
|
798
|
+
^^^^^^^ `titleId` prop is missing reference value.
|
|
799
|
+
<Button>Save</Button>
|
|
800
|
+
<Button>Edit</Button>
|
|
801
|
+
<Button>Delete</Button>
|
|
802
|
+
</ButtonGroup>
|
|
803
|
+
|
|
804
|
+
<h2 id="button-group-title">ButtonGroup content title</h2>
|
|
805
|
+
<ButtonGroup titleId="button-group-title" label="">
|
|
806
|
+
^^^^^^^ ^^^^^ Do not include both `titleId` and `label` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `label` to provide accessible name explicitly.
|
|
807
|
+
<Button>Save</Button>
|
|
808
|
+
<Button>Edit</Button>
|
|
809
|
+
<Button>Delete</Button>
|
|
810
|
+
</ButtonGroup>
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
#### Correct
|
|
814
|
+
|
|
815
|
+
```tsx
|
|
816
|
+
<ButtonGroup label="ButtonGroup content title">
|
|
817
|
+
<Button>Save</Button>
|
|
818
|
+
<Button>Edit</Button>
|
|
819
|
+
<Button>Delete</Button>
|
|
820
|
+
</ButtonGroup>
|
|
821
|
+
|
|
822
|
+
<h2 id="button-group-title">ButtonGroup content title</h2>
|
|
823
|
+
<ButtonGroup titleId="button-group-title">
|
|
824
|
+
<Button>Save</Button>
|
|
825
|
+
<Button>Edit</Button>
|
|
826
|
+
<Button>Delete</Button>
|
|
827
|
+
</ButtonGroup>
|
|
828
|
+
```
|
|
829
|
+
|
|
770
830
|
## use-drawer-label
|
|
771
831
|
|
|
772
832
|
Drawer should have an accessible name or a reference to it, so that upon opening, users of assistive technologies could have contextual information of interaction with current element.
|
|
@@ -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::d1a459e1ea71650f65b2890dc86cc398>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -28,6 +28,7 @@ var _default = exports.default = {
|
|
|
28
28
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
29
29
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
30
30
|
'@atlaskit/design-system/prefer-primitives': 'warn',
|
|
31
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
31
32
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
32
33
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
33
34
|
'@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::3b93cfbbe0ea14514b9600509632394b>>
|
|
10
10
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
11
11
|
*/
|
|
12
12
|
var _default = exports.default = {
|
|
@@ -23,6 +23,7 @@ var _default = exports.default = {
|
|
|
23
23
|
'@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
|
|
24
24
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
25
25
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
26
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
26
27
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
27
28
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
28
29
|
'@atlaskit/design-system/use-href-in-link-item': 'warn',
|
|
@@ -21,6 +21,7 @@ var _noUnsafeDesignTokenUsage = _interopRequireDefault(require("./no-unsafe-desi
|
|
|
21
21
|
var _noUnsafeStyleOverrides = _interopRequireDefault(require("./no-unsafe-style-overrides"));
|
|
22
22
|
var _noUnsupportedDragAndDropLibraries = _interopRequireDefault(require("./no-unsupported-drag-and-drop-libraries"));
|
|
23
23
|
var _preferPrimitives = _interopRequireDefault(require("./prefer-primitives"));
|
|
24
|
+
var _useButtonGroupLabel = _interopRequireDefault(require("./use-button-group-label"));
|
|
24
25
|
var _useDrawerLabel = _interopRequireDefault(require("./use-drawer-label"));
|
|
25
26
|
var _useHeadingLevelInSpotlightCard = _interopRequireDefault(require("./use-heading-level-in-spotlight-card"));
|
|
26
27
|
var _useHrefInLinkItem = _interopRequireDefault(require("./use-href-in-link-item"));
|
|
@@ -28,7 +29,7 @@ var _usePrimitives = _interopRequireDefault(require("./use-primitives"));
|
|
|
28
29
|
var _useVisuallyHidden = _interopRequireDefault(require("./use-visually-hidden"));
|
|
29
30
|
/**
|
|
30
31
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
31
|
-
* @codegen <<SignedSource::
|
|
32
|
+
* @codegen <<SignedSource::14cdfdcbd8b999ee097a1a5b245d7117>>
|
|
32
33
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
33
34
|
*/
|
|
34
35
|
var _default = exports.default = {
|
|
@@ -48,6 +49,7 @@ var _default = exports.default = {
|
|
|
48
49
|
'no-unsafe-style-overrides': _noUnsafeStyleOverrides.default,
|
|
49
50
|
'no-unsupported-drag-and-drop-libraries': _noUnsupportedDragAndDropLibraries.default,
|
|
50
51
|
'prefer-primitives': _preferPrimitives.default,
|
|
52
|
+
'use-button-group-label': _useButtonGroupLabel.default,
|
|
51
53
|
'use-drawer-label': _useDrawerLabel.default,
|
|
52
54
|
'use-heading-level-in-spotlight-card': _useHeadingLevelInSpotlightCard.default,
|
|
53
55
|
'use-href-in-link-item': _useHrefInLinkItem.default,
|
|
@@ -0,0 +1,83 @@
|
|
|
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 = ['label', 'titleId'];
|
|
12
|
+
var rule = (0, _createRule.createLintRule)({
|
|
13
|
+
meta: {
|
|
14
|
+
name: 'use-button-group-label',
|
|
15
|
+
type: 'suggestion',
|
|
16
|
+
docs: {
|
|
17
|
+
description: 'Ensures button groups are described to assistive technology by a direct label or by another element.',
|
|
18
|
+
recommended: true,
|
|
19
|
+
severity: 'warn'
|
|
20
|
+
},
|
|
21
|
+
messages: {
|
|
22
|
+
missingLabelProp: 'Missing accessible name. If there is no visible content to associate use `label` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
23
|
+
labelPropShouldHaveContents: 'Define string that labels the interactive element.',
|
|
24
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of element that define accessible name.',
|
|
25
|
+
noBothPropsUsage: 'Do not include both `titleId` and `label` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `label` 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
|
+
if (node.source.value === '@atlaskit/button') {
|
|
34
|
+
if (node.specifiers.length) {
|
|
35
|
+
var defaultImport = node.specifiers.filter(function (spec) {
|
|
36
|
+
return spec.type === 'ImportSpecifier';
|
|
37
|
+
});
|
|
38
|
+
if (defaultImport && defaultImport.length) {
|
|
39
|
+
var local = defaultImport[0].local;
|
|
40
|
+
contextLocalIdentifier.push(local.name);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
JSXElement: function JSXElement(node) {
|
|
46
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
var name = node.openingElement.name.name;
|
|
53
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
54
|
+
var componentLabelProps = node.openingElement.attributes.filter(function (attr) {
|
|
55
|
+
return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute') && (0, _eslintCodemodUtils.isNodeOfType)(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name);
|
|
56
|
+
});
|
|
57
|
+
if (componentLabelProps.length === 1) {
|
|
58
|
+
var prop = componentLabelProps[0];
|
|
59
|
+
if ('value' in prop && prop.value) {
|
|
60
|
+
if ((0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'Literal') && !prop.value.value || (0, _eslintCodemodUtils.isNodeOfType)(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
61
|
+
context.report({
|
|
62
|
+
node: prop,
|
|
63
|
+
messageId: prop.name.name === 'label' ? 'labelPropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else if (componentLabelProps.length > 1) {
|
|
68
|
+
context.report({
|
|
69
|
+
node: node.openingElement,
|
|
70
|
+
messageId: 'noBothPropsUsage'
|
|
71
|
+
});
|
|
72
|
+
} else {
|
|
73
|
+
context.report({
|
|
74
|
+
node: node.openingElement,
|
|
75
|
+
messageId: 'missingLabelProp'
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
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::d1a459e1ea71650f65b2890dc86cc398>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -22,6 +22,7 @@ export default {
|
|
|
22
22
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
23
23
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
24
24
|
'@atlaskit/design-system/prefer-primitives': 'warn',
|
|
25
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
25
26
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
26
27
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
27
28
|
'@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::3b93cfbbe0ea14514b9600509632394b>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -17,6 +17,7 @@ export default {
|
|
|
17
17
|
'@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
|
|
18
18
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
19
19
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
20
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
20
21
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
21
22
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
22
23
|
'@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::14cdfdcbd8b999ee097a1a5b245d7117>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -19,6 +19,7 @@ import noUnsafeDesignTokenUsage from './no-unsafe-design-token-usage';
|
|
|
19
19
|
import noUnsafeStyleOverrides from './no-unsafe-style-overrides';
|
|
20
20
|
import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-libraries';
|
|
21
21
|
import preferPrimitives from './prefer-primitives';
|
|
22
|
+
import useButtonGroupLabel from './use-button-group-label';
|
|
22
23
|
import useDrawerLabel from './use-drawer-label';
|
|
23
24
|
import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
|
|
24
25
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
@@ -41,6 +42,7 @@ export default {
|
|
|
41
42
|
'no-unsafe-style-overrides': noUnsafeStyleOverrides,
|
|
42
43
|
'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
|
|
43
44
|
'prefer-primitives': preferPrimitives,
|
|
45
|
+
'use-button-group-label': useButtonGroupLabel,
|
|
44
46
|
'use-drawer-label': useDrawerLabel,
|
|
45
47
|
'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
|
|
46
48
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
@@ -0,0 +1,75 @@
|
|
|
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 = ['label', 'titleId'];
|
|
6
|
+
const rule = createLintRule({
|
|
7
|
+
meta: {
|
|
8
|
+
name: 'use-button-group-label',
|
|
9
|
+
type: 'suggestion',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'Ensures button groups are described to assistive technology by a direct label or by another element.',
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'warn'
|
|
14
|
+
},
|
|
15
|
+
messages: {
|
|
16
|
+
missingLabelProp: 'Missing accessible name. If there is no visible content to associate use `label` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
17
|
+
labelPropShouldHaveContents: 'Define string that labels the interactive element.',
|
|
18
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of element that define accessible name.',
|
|
19
|
+
noBothPropsUsage: 'Do not include both `titleId` and `label` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `label` to provide accessible name explicitly.'
|
|
20
|
+
},
|
|
21
|
+
hasSuggestions: true
|
|
22
|
+
},
|
|
23
|
+
create(context) {
|
|
24
|
+
const contextLocalIdentifier = [];
|
|
25
|
+
return {
|
|
26
|
+
ImportDeclaration(node) {
|
|
27
|
+
if (node.source.value === '@atlaskit/button') {
|
|
28
|
+
if (node.specifiers.length) {
|
|
29
|
+
const defaultImport = node.specifiers.filter(spec => spec.type === 'ImportSpecifier');
|
|
30
|
+
if (defaultImport && defaultImport.length) {
|
|
31
|
+
const {
|
|
32
|
+
local
|
|
33
|
+
} = defaultImport[0];
|
|
34
|
+
contextLocalIdentifier.push(local.name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
JSXElement(node) {
|
|
40
|
+
if (!isNodeOfType(node, 'JSXElement')) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const name = node.openingElement.name.name;
|
|
47
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
48
|
+
const componentLabelProps = node.openingElement.attributes.filter(attr => isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name));
|
|
49
|
+
if (componentLabelProps.length === 1) {
|
|
50
|
+
const prop = componentLabelProps[0];
|
|
51
|
+
if ('value' in prop && prop.value) {
|
|
52
|
+
if (isNodeOfType(prop.value, 'Literal') && !prop.value.value || isNodeOfType(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
53
|
+
context.report({
|
|
54
|
+
node: prop,
|
|
55
|
+
messageId: prop.name.name === 'label' ? 'labelPropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} else if (componentLabelProps.length > 1) {
|
|
60
|
+
context.report({
|
|
61
|
+
node: node.openingElement,
|
|
62
|
+
messageId: 'noBothPropsUsage'
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
context.report({
|
|
66
|
+
node: node.openingElement,
|
|
67
|
+
messageId: 'missingLabelProp'
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
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::d1a459e1ea71650f65b2890dc86cc398>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -22,6 +22,7 @@ export default {
|
|
|
22
22
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
23
23
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
24
24
|
'@atlaskit/design-system/prefer-primitives': 'warn',
|
|
25
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
25
26
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
26
27
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
27
28
|
'@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::3b93cfbbe0ea14514b9600509632394b>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -17,6 +17,7 @@ export default {
|
|
|
17
17
|
'@atlaskit/design-system/no-unsafe-design-token-usage': 'error',
|
|
18
18
|
'@atlaskit/design-system/no-unsafe-style-overrides': 'warn',
|
|
19
19
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': 'error',
|
|
20
|
+
'@atlaskit/design-system/use-button-group-label': 'warn',
|
|
20
21
|
'@atlaskit/design-system/use-drawer-label': 'warn',
|
|
21
22
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': 'warn',
|
|
22
23
|
'@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::14cdfdcbd8b999ee097a1a5b245d7117>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -19,6 +19,7 @@ import noUnsafeDesignTokenUsage from './no-unsafe-design-token-usage';
|
|
|
19
19
|
import noUnsafeStyleOverrides from './no-unsafe-style-overrides';
|
|
20
20
|
import noUnsupportedDragAndDropLibraries from './no-unsupported-drag-and-drop-libraries';
|
|
21
21
|
import preferPrimitives from './prefer-primitives';
|
|
22
|
+
import useButtonGroupLabel from './use-button-group-label';
|
|
22
23
|
import useDrawerLabel from './use-drawer-label';
|
|
23
24
|
import useHeadingLevelInSpotlightCard from './use-heading-level-in-spotlight-card';
|
|
24
25
|
import useHrefInLinkItem from './use-href-in-link-item';
|
|
@@ -41,6 +42,7 @@ export default {
|
|
|
41
42
|
'no-unsafe-style-overrides': noUnsafeStyleOverrides,
|
|
42
43
|
'no-unsupported-drag-and-drop-libraries': noUnsupportedDragAndDropLibraries,
|
|
43
44
|
'prefer-primitives': preferPrimitives,
|
|
45
|
+
'use-button-group-label': useButtonGroupLabel,
|
|
44
46
|
'use-drawer-label': useDrawerLabel,
|
|
45
47
|
'use-heading-level-in-spotlight-card': useHeadingLevelInSpotlightCard,
|
|
46
48
|
'use-href-in-link-item': useHrefInLinkItem,
|
|
@@ -0,0 +1,77 @@
|
|
|
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 = ['label', 'titleId'];
|
|
6
|
+
var rule = createLintRule({
|
|
7
|
+
meta: {
|
|
8
|
+
name: 'use-button-group-label',
|
|
9
|
+
type: 'suggestion',
|
|
10
|
+
docs: {
|
|
11
|
+
description: 'Ensures button groups are described to assistive technology by a direct label or by another element.',
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'warn'
|
|
14
|
+
},
|
|
15
|
+
messages: {
|
|
16
|
+
missingLabelProp: 'Missing accessible name. If there is no visible content to associate use `label` prop, otherwise pass id of element to `titleId` prop to be associated as label.',
|
|
17
|
+
labelPropShouldHaveContents: 'Define string that labels the interactive element.',
|
|
18
|
+
titleIdShouldHaveValue: '`titleId` should reference the id of element that define accessible name.',
|
|
19
|
+
noBothPropsUsage: 'Do not include both `titleId` and `label` properties. Use `titleId` if the label text is available in the DOM to reference it, otherwise use `label` 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
|
+
if (node.source.value === '@atlaskit/button') {
|
|
28
|
+
if (node.specifiers.length) {
|
|
29
|
+
var defaultImport = node.specifiers.filter(function (spec) {
|
|
30
|
+
return spec.type === 'ImportSpecifier';
|
|
31
|
+
});
|
|
32
|
+
if (defaultImport && defaultImport.length) {
|
|
33
|
+
var local = defaultImport[0].local;
|
|
34
|
+
contextLocalIdentifier.push(local.name);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
JSXElement: function JSXElement(node) {
|
|
40
|
+
if (!isNodeOfType(node, 'JSXElement')) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (!isNodeOfType(node.openingElement.name, 'JSXIdentifier')) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
var name = node.openingElement.name.name;
|
|
47
|
+
if (contextLocalIdentifier.includes(name)) {
|
|
48
|
+
var componentLabelProps = node.openingElement.attributes.filter(function (attr) {
|
|
49
|
+
return isNodeOfType(attr, 'JSXAttribute') && isNodeOfType(attr.name, 'JSXIdentifier') && elementsAccessibleNameProps.includes(attr.name.name);
|
|
50
|
+
});
|
|
51
|
+
if (componentLabelProps.length === 1) {
|
|
52
|
+
var prop = componentLabelProps[0];
|
|
53
|
+
if ('value' in prop && prop.value) {
|
|
54
|
+
if (isNodeOfType(prop.value, 'Literal') && !prop.value.value || isNodeOfType(prop.value, 'JSXExpressionContainer') && !prop.value.expression) {
|
|
55
|
+
context.report({
|
|
56
|
+
node: prop,
|
|
57
|
+
messageId: prop.name.name === 'label' ? 'labelPropShouldHaveContents' : 'titleIdShouldHaveValue'
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} else if (componentLabelProps.length > 1) {
|
|
62
|
+
context.report({
|
|
63
|
+
node: node.openingElement,
|
|
64
|
+
messageId: 'noBothPropsUsage'
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
context.report({
|
|
68
|
+
node: node.openingElement,
|
|
69
|
+
messageId: 'missingLabelProp'
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
export default rule;
|
|
@@ -19,6 +19,7 @@ export declare const configs: {
|
|
|
19
19
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
20
20
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
21
21
|
'@atlaskit/design-system/prefer-primitives': string;
|
|
22
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
22
23
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
23
24
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
24
25
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
@@ -40,6 +41,7 @@ export declare const configs: {
|
|
|
40
41
|
'@atlaskit/design-system/no-unsafe-design-token-usage': string;
|
|
41
42
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
42
43
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
44
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
43
45
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
44
46
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
45
47
|
'@atlaskit/design-system/use-href-in-link-item': 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::d1a459e1ea71650f65b2890dc86cc398>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -22,6 +22,7 @@ declare const _default: {
|
|
|
22
22
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
23
23
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
24
24
|
'@atlaskit/design-system/prefer-primitives': string;
|
|
25
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
25
26
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
26
27
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
27
28
|
'@atlaskit/design-system/use-href-in-link-item': 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::3b93cfbbe0ea14514b9600509632394b>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -17,6 +17,7 @@ declare const _default: {
|
|
|
17
17
|
'@atlaskit/design-system/no-unsafe-design-token-usage': string;
|
|
18
18
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
19
19
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
20
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
20
21
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
21
22
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
22
23
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
@@ -19,6 +19,7 @@ declare const _default: {
|
|
|
19
19
|
'no-unsafe-style-overrides': import("eslint").Rule.RuleModule;
|
|
20
20
|
'no-unsupported-drag-and-drop-libraries': import("eslint").Rule.RuleModule;
|
|
21
21
|
'prefer-primitives': import("eslint").Rule.RuleModule;
|
|
22
|
+
'use-button-group-label': import("eslint").Rule.RuleModule;
|
|
22
23
|
'use-drawer-label': import("eslint").Rule.RuleModule;
|
|
23
24
|
'use-heading-level-in-spotlight-card': import("eslint").Rule.RuleModule;
|
|
24
25
|
'use-href-in-link-item': import("eslint").Rule.RuleModule;
|
|
@@ -19,6 +19,7 @@ export declare const configs: {
|
|
|
19
19
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
20
20
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
21
21
|
'@atlaskit/design-system/prefer-primitives': string;
|
|
22
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
22
23
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
23
24
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
24
25
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
@@ -40,6 +41,7 @@ export declare const configs: {
|
|
|
40
41
|
'@atlaskit/design-system/no-unsafe-design-token-usage': string;
|
|
41
42
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
42
43
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
44
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
43
45
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
44
46
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
45
47
|
'@atlaskit/design-system/use-href-in-link-item': 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::d1a459e1ea71650f65b2890dc86cc398>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -22,6 +22,7 @@ declare const _default: {
|
|
|
22
22
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
23
23
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
24
24
|
'@atlaskit/design-system/prefer-primitives': string;
|
|
25
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
25
26
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
26
27
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
27
28
|
'@atlaskit/design-system/use-href-in-link-item': 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::3b93cfbbe0ea14514b9600509632394b>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
declare const _default: {
|
|
@@ -17,6 +17,7 @@ declare const _default: {
|
|
|
17
17
|
'@atlaskit/design-system/no-unsafe-design-token-usage': string;
|
|
18
18
|
'@atlaskit/design-system/no-unsafe-style-overrides': string;
|
|
19
19
|
'@atlaskit/design-system/no-unsupported-drag-and-drop-libraries': string;
|
|
20
|
+
'@atlaskit/design-system/use-button-group-label': string;
|
|
20
21
|
'@atlaskit/design-system/use-drawer-label': string;
|
|
21
22
|
'@atlaskit/design-system/use-heading-level-in-spotlight-card': string;
|
|
22
23
|
'@atlaskit/design-system/use-href-in-link-item': string;
|
|
@@ -23,6 +23,7 @@ declare const _default: {
|
|
|
23
23
|
'no-unsafe-style-overrides': import("eslint").Rule.RuleModule;
|
|
24
24
|
'no-unsupported-drag-and-drop-libraries': import("eslint").Rule.RuleModule;
|
|
25
25
|
'prefer-primitives': import("eslint").Rule.RuleModule;
|
|
26
|
+
'use-button-group-label': import("eslint").Rule.RuleModule;
|
|
26
27
|
'use-drawer-label': import("eslint").Rule.RuleModule;
|
|
27
28
|
'use-heading-level-in-spotlight-card': import("eslint").Rule.RuleModule;
|
|
28
29
|
'use-href-in-link-item': import("eslint").Rule.RuleModule;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/eslint-plugin-design-system",
|
|
3
3
|
"description": "The essential plugin for use with the Atlassian Design System.",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.21.0",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"registry": "https://registry.npmjs.org/"
|