Skip to content

Commit 3669d45

Browse files
committed
SplitButton needs label
1 parent 3977d44 commit 3669d45

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

COVERAGE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ We currently cover the following components:
1515
- [X] CompoundButton
1616
- [] MenuButton
1717
- [X] MenuItem
18-
- [] SplitButton
18+
- [x] SplitButton
1919
- [x] ToggleButton
2020
- [] ToolbarToggleButton
2121
- [] Card
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Accessibility: SplitButton must have an accessible label (`@microsoft/fluentui-jsx-a11y/splitButton-needs-labelling`)
2+
3+
💼 This rule is enabled in the ✅ `recommended` config.
4+
5+
<!-- end auto-generated rule header -->
6+
7+
SplitButton without a label or accessible labeling lack an accessible name for assistive technology users.
8+
9+
SplitButton components need a visual label.
10+
11+
Please add label, or aria-labelledby.
12+
13+
<https://www.w3.org/WAI/standards-guidelines/act/rules/97a4e1/>
14+
15+
## Rule Details
16+
17+
This rule aims to...
18+
19+
Examples of **incorrect** code for this rule:
20+
21+
```jsx
22+
<SplitButton />
23+
```
24+
25+
```jsx
26+
<SplitButton disabled/>
27+
```
28+
29+
Examples of **correct** code for this rule:
30+
31+
```jsx
32+
<SplitButton> Example</SplitButton>
33+
```
34+
35+
```jsx
36+
<SplitButton aria-label="My button"/>
37+
```
38+
39+
```jsx
40+
<SplitButton disabled>Disabled State</SplitButton>
41+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
import { ESLintUtils } from "@typescript-eslint/utils";
5+
import { makeLabeledControlRule } from "../../util/ruleFactory";
6+
7+
//------------------------------------------------------------------------------
8+
// Rule Definition
9+
//------------------------------------------------------------------------------
10+
11+
export default ESLintUtils.RuleCreator.withoutDocs(
12+
makeLabeledControlRule({
13+
component: "SplitButton",
14+
messageId: "noUnlabeledSplitButton",
15+
description: "Accessibility: SplitButton must have an accessible name via title, aria-label",
16+
labelProps: ["aria-label"],
17+
allowFieldParent: true,
18+
allowHtmlFor: false,
19+
allowLabelledBy: true,
20+
allowWrappingLabel: false,
21+
allowTooltipParent: false,
22+
allowDescribedBy: false,
23+
allowLabeledChild: false
24+
})
25+
);

lib/rules/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export { default as inputComponentsRequireAccessibleName } from "./input-compone
2020
export { default as linkMissingLabelling } from "./link-missing-labelling";
2121
export { default as menuItemNeedsLabelling } from "./menu-item-needs-labelling";
2222
export { default as noEmptyButtons } from "./buttons/no-empty-buttons";
23+
export { default as splitButtonNeedsLabelling } from "./buttons/splitButton-needs-labelling";
2324
export { default as noEmptyComponents } from "./no-empty-components";
2425
export { default as preferAriaOverTitleAttribute } from "./prefer-aria-over-title-attribute";
2526
export { default as progressbarNeedsLabelling } from "./progressbar-needs-labelling";
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
import { Rule } from "eslint";
5+
import ruleTester from "../helper/ruleTester";
6+
import rule from "../../../../lib/rules/buttons/splitButton-needs-labelling";
7+
// -----------------------------------------------------------------------------
8+
// Tests
9+
// -----------------------------------------------------------------------------
10+
11+
ruleTester.run("splitButton-needs-labelling", rule as unknown as Rule.RuleModule, {
12+
valid: [
13+
// 1) aria-label on the SplitButton
14+
15+
`<SplitButton aria-label="Example">Example</SplitButton>
16+
`,
17+
// 2) Field wrapper with label prop
18+
`
19+
<SplitButton aria-label="Example" disabled> Disabled State </SplitButton>
20+
`
21+
],
22+
23+
invalid: [
24+
// Unlabeled SwatchPicker (children present, but no accessible name)
25+
{
26+
code: `
27+
<SplitButton>Example</SplitButton>
28+
`,
29+
errors: [{ messageId: "noUnlabeledSplitButton" }]
30+
},
31+
{
32+
// 7) Native <label> wrapping (implicit label)
33+
code: `
34+
<SplitButton disabled>Example</SplitButton>
35+
`,
36+
errors: [{ messageId: "noUnlabeledSplitButton" }]
37+
}
38+
]
39+
});

0 commit comments

Comments
 (0)