Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions docs/data/material/components/form-group/form-group.a11y.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"FormGroupA11yStates": {
"rules": {
"aria-allowed-attr": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-conditional-attr": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-deprecated-role": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-hidden-focus": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-prohibited-attr": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-required-attr": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-roles": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-valid-attr": {
"status": "pass",
"tags": ["wcag2a"]
},
"aria-valid-attr-value": {
"status": "pass",
"tags": ["wcag2a"]
},
"color-contrast": {
"status": "pass",
"tags": ["wcag2aa"]
},
"duplicate-id-aria": {
"status": "pass",
"tags": ["wcag2a"]
},
"form-field-multiple-labels": {
"status": "pass",
"tags": ["wcag2a"]
},
"label": {
"status": "pass",
"tags": ["wcag2a"]
},
"nested-interactive": {
"status": "pass",
"tags": ["wcag2a"]
},
"target-size": {
"status": "pass",
"tags": ["wcag22aa"]
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<p class="description">How Material UI components conform to WCAG 2.2 Level A and AA, reported in VPAT terms for procurement and accessibility review.</p>

:::warning
**Draft — partial coverage.** This report covers the 13 components assessed so far, not the whole library. It has not been reviewed by an external auditor, and no assistive-technology testing has been performed yet. See [Scope and limitations](#scope-and-limitations) before relying on it for a procurement decision.
**Draft — partial coverage.** This report covers only the components in the [component table](#conformance-by-component), not the whole library. It has not been reviewed by an external auditor, and no assistive-technology testing has been performed yet. See [Scope and limitations](#scope-and-limitations) before relying on it for a procurement decision.
:::

## About this report
Expand Down Expand Up @@ -43,6 +43,7 @@ Each row counts only the criteria that **apply** to that component; criteria tha
| [Button](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Button/accessibility.md) | 15 | 12 | 27 | 24 | 3 | 20/27 | 11 |
| [Checkbox](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Checkbox/accessibility.md) | 14 | 11 | 25 | 24 | 1 | 22/25 | 11 |
| [CircularProgress](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/CircularProgress/accessibility.md) | 6 | 5 | 11 | 8 | 3 | 6/11 | 1 |
| [FormGroup](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/FormGroup/accessibility.md) | 5 | 2 | 7 | 7 | 0 | 4/7 | 2 |
| [LinearProgress](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/LinearProgress/accessibility.md) | 6 | 5 | 11 | 8 | 3 | 6/11 | 1 |
| [Radio](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Radio/accessibility.md) | 14 | 11 | 25 | 24 | 1 | 23/25 | 11 |
| [RadioGroup](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/RadioGroup/accessibility.md) | 6 | 1 | 7 | 7 | 0 | 4/7 | 2 |
Expand Down Expand Up @@ -106,7 +107,7 @@ const theme = createTheme({ focusVisible: true });
Read this section before citing the report.
:::

- **Component coverage is partial.** 13 components are assessed. Widely used components including Select, Autocomplete, Dialog, Menu, Table, Tabs, Slider, Tooltip, Snackbar, and Drawer are **not yet assessed**, and this report says nothing about them.
- **Component coverage is partial.** Only the components in the [component table](#conformance-by-component) are assessed. Widely used components including Select, Autocomplete, Dialog, Menu, Table, Tabs, Slider, Tooltip, Snackbar, and Drawer are **not yet assessed**, and this report says nothing about them.
- **No assistive-technology testing.** No screen-reader passes have been performed. Criteria that depend on how a specific assistive technology behaves are assessed from the exposed accessibility tree, not from observed behavior.
- **Level AAA is out of scope**, as it is for a standard VPAT.
- **Components are rated in isolation**, as rendered with default props and the default theme. Customization, composition, and your surrounding page can change the result.
Expand Down
89 changes: 88 additions & 1 deletion docs/data/material/getting-started/accessibility/scorecard.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"standard": "WCAG 2.2 Level A and AA",
"componentCount": 13,
"componentCount": 14,
"totals": {
"rated": 32,
"supports": 27,
Expand Down Expand Up @@ -1538,6 +1538,93 @@
"automated": 1
}
},
{
"component": "FormGroup",
"counts": {
"supports": 7,
"partiallySupports": 0,
"doesNotSupport": 0,
"notApplicable": 48,
"flagged": 3,
"rated": 7
},
"gaps": [],
"criteria": [
{
"number": "1.3.1",
"name": "Info and Relationships",
"level": "A",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Hybrid",
"flagged": false
},
{
"number": "1.3.2",
"name": "Meaningful Sequence",
"level": "A",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Manual",
"flagged": true
},
{
"number": "1.3.3",
"name": "Sensory Characteristics",
"level": "A",
"conformance": "Supports",
"responsibility": "Author",
"group": "Manual",
"flagged": false
},
{
"number": "1.4.10",
"name": "Reflow",
"level": "AA",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Automated",
"flagged": false
},
{
"number": "2.4.3",
"name": "Focus Order",
"level": "A",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Automated",
"flagged": false
},
{
"number": "2.4.6",
"name": "Headings and Labels",
"level": "AA",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Manual",
"flagged": true
},
{
"number": "3.3.2",
"name": "Labels or Instructions",
"level": "A",
"conformance": "Supports",
"responsibility": "Shared",
"group": "Hybrid",
"flagged": true
}
],
"summary": {
"rated": 7,
"levelA": 5,
"levelAA": 2,
"supports": 7,
"partiallySupports": 0,
"doesNotSupport": 0,
"verified": 4,
"automated": 2
}
},
{
"component": "LinearProgress",
"counts": {
Expand Down
87 changes: 86 additions & 1 deletion packages/mui-material/src/FormGroup/FormGroup.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { describe, it, expect } from 'vitest';
import { createRenderer, screen } from '@mui/internal-test-utils';
import * as React from 'react';
import { createRenderer, screen, within, isJsdom } from '@mui/internal-test-utils';
import FormGroup, { formGroupClasses as classes } from '@mui/material/FormGroup';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import describeConformance from '../../test/describeConformance';

describe('<FormGroup />', () => {
Expand Down Expand Up @@ -42,4 +44,87 @@ describe('<FormGroup />', () => {
});
});
});

describe('accessibility', () => {
it('renders no role of its own', () => {
const { container } = render(
<FormGroup>
<input type="checkbox" aria-label="Cheese" />
</FormGroup>,
);

expect(container.firstChild).not.to.have.attribute('role');
expect(screen.queryByRole('group')).to.equal(null);
});

it('gets its group name from a fieldset legend', () => {
render(
<FormControl component="fieldset">
<FormLabel component="legend">Toppings</FormLabel>
<FormGroup>
<input type="checkbox" aria-label="Cheese" />
</FormGroup>
</FormControl>,
);

const group = screen.getByRole('group', { name: 'Toppings' });
expect(within(group).getByRole('checkbox', { name: 'Cheese' })).not.to.equal(null);
});

it('makes the controls of a row group tab stops in DOM order', async () => {
const { user } = render(
<FormGroup row>
<input type="checkbox" aria-label="Email" />
<input type="checkbox" aria-label="Push" />
<input type="checkbox" aria-label="Text message" />
</FormGroup>,
);

for (const name of ['Email', 'Push', 'Text message']) {
// eslint-disable-next-line no-await-in-loop
await user.tab();
expect(screen.getByRole('checkbox', { name })).toHaveFocus();
}
});
});

describe('WCAG 2.2 conformance', () => {
it('1.3.1 Info and Relationships: becomes a named group with role="group" and aria-labelledby', () => {
render(
<React.Fragment>
<span id="share">Share with</span>
<FormGroup role="group" aria-labelledby="share">
<input type="checkbox" aria-label="Team" />
</FormGroup>
</React.Fragment>,
);

expect(screen.getByRole('group')).toHaveAccessibleName('Share with');
});

// JSDOM has no layout
it.skipIf(isJsdom())(
'2.4.3 Focus Order: a row group shows its controls from left to right in tab order',
async () => {
const { user } = render(
<FormGroup row>
<input type="checkbox" aria-label="Email" />
<input type="checkbox" aria-label="Push" />
<input type="checkbox" aria-label="Text message" />
</FormGroup>,
);

let previousLeft = -Infinity;
for (const name of ['Email', 'Push', 'Text message']) {
// eslint-disable-next-line no-await-in-loop
await user.tab();
const checkbox = screen.getByRole('checkbox', { name });
expect(checkbox).toHaveFocus();
const { left } = checkbox.getBoundingClientRect();
expect(left).to.be.above(previousLeft);
previousLeft = left;
}
},
);
});
});
28 changes: 28 additions & 0 deletions packages/mui-material/src/FormGroup/accessibility.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"axe": "docs/data/material/components/form-group/form-group.a11y.json",
"criteria": {
"1.3.2": { "responsibility": "Shared", "flagged": true },
"2.4.6": { "group": "Manual", "flagged": true },
"3.3.2": { "flagged": true }
},
"notApplicable": [
"1.1.1",
"1.4.1",
"1.4.3",
"1.4.4",
"1.4.5",
"1.4.11",
"1.4.12",
"2.1.1",
"2.1.2",
"2.4.7",
"2.4.11",
"2.5.2",
"2.5.3",
"2.5.8",
"3.2.1",
"3.2.2",
"3.2.4",
"4.1.2"
]
}
Loading
Loading