diff --git a/.circleci/config.yml b/.circleci/config.yml index f34b506694e520..35fd3a987a213a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -95,6 +95,12 @@ jobs: - code-infra/check-static-changes - code-infra/check-generated: command: pnpm proptypes + - run: + # Fails when a conformance report changes without its rollup being + # regenerated, and when a report rates a criterion ⚙️ Automated + # without citing the test or axe rule that proves it. + name: Accessibility scorecard up to date? + command: pnpm a11y:scorecard:check - code-infra/check-generated: command: pnpm docs:api - code-infra/extract-error-codes diff --git a/docs/data/material/getting-started/accessibility/accessibility.md b/docs/data/material/getting-started/accessibility/accessibility.md new file mode 100644 index 00000000000000..3c7f51e1a5ece9 --- /dev/null +++ b/docs/data/material/getting-started/accessibility/accessibility.md @@ -0,0 +1,121 @@ +# Accessibility conformance report + +

How Material UI components conform to WCAG 2.2 Level A and AA, reported in VPAT terms for procurement and accessibility review.

+ +:::warning +**Draft — partial coverage.** This report covers the 12 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. +::: + +## About this report + +This is a Voluntary Product Accessibility Template (VPAT®) style report: it states how far Material UI meets the [Web Content Accessibility Guidelines 2.2](https://www.w3.org/TR/WCAG22/) at Levels A and AA, using the conformance vocabulary defined by the [Information Technology Industry Council](https://www.itic.org/policy/accessibility/vpat). + +Each component is rated criterion by criterion in its own report, kept next to the source code at `packages/mui-material/src//accessibility.md`. Those reports carry the reasoning, the responsibility split, and reproducible manual test steps for every criterion. **The table below summarizes them; follow a component link for the detail.** + +| Field | Value | +| :---------------- | :--------------------------------------------------------------------------------------------- | +| Product | Material UI (`@mui/material`) | +| Product type | React component library (software) | +| Version assessed | Results track the `master` branch; see [releases](https://github.com/mui/material-ui/releases) | +| Vendor | MUI | +| Standards applied | WCAG 2.2 Level A and AA | +| Report type | Self-assessment, published as source-controlled documentation | + +## Conformance by component + +Each row counts only the criteria that **apply** to that component; criteria that are Not Applicable are excluded. Levels are [cumulative](https://www.w3.org/WAI/WCAG2AA-Conformance) — AA includes all of A. + +- **Rated** — applicable Level A and AA criteria. +- **Verified** — criteria confirmed by a test or a recorded review. The remainder are assessed from the source but not yet re-verified; they are flagged 🚩 in the component report. The flag concerns evidence, not conformance. +- **Automated** — criteria a deterministic test proves on its own, so they cannot silently regress. + + + +| Component | Level A | Level AA | Rated | ✅ Supports | ⚠️ Partially Supports | Verified | Automated | +| :------------------------------------------------------------------------------------------------------------------------------- | ------: | -------: | ------: | ----------: | --------------------: | ----------: | --------: | +| [Accordion](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Accordion/accessibility.md) | 11 | 8 | 19 | 19 | 0 | 16/19 | 9 | +| [AccordionSummary](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/AccordionSummary/accessibility.md) | 13 | 11 | 24 | 23 | 1 | 21/24 | 11 | +| [Avatar](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Avatar/accessibility.md) | 5 | 6 | 11 | 9 | 2 | 6/11 | 2 | +| [Button](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Button/accessibility.md) | 15 | 12 | 27 | 23 | 4 | 20/27 | 11 | +| [Checkbox](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Checkbox/accessibility.md) | 14 | 11 | 25 | 23 | 2 | 22/25 | 11 | +| [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 | 23 | 2 | 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 | +| [Switch](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/Switch/accessibility.md) | 14 | 11 | 25 | 23 | 2 | 23/25 | 11 | +| [TextField](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/TextField/accessibility.md) | 14 | 14 | 28 | 25 | 3 | 24/28 | 12 | +| [ToggleButton](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/ToggleButton/accessibility.md) | 13 | 11 | 24 | 20 | 4 | 22/24 | 11 | +| [ToggleButtonGroup](https://github.com/mui/material-ui/blob/master/packages/mui-material/src/ToggleButtonGroup/accessibility.md) | 2 | 2 | 4 | 4 | 0 | 3/4 | 1 | +| **12 components** | **127** | **103** | **230** | **207** | **23** | **190/230** | **93** | + + + +**No component records a ❌ Does Not Support rating for any Level A or AA criterion.** + +Rolled up to the library level, where each criterion takes the worst rating any assessed component receives, 32 success criteria are exercised: **25 Supports, 7 Partially Supports, 0 Does Not Support.** + +The Level A and AA criteria absent from every row apply at the page or application level — [2.4.1 Bypass Blocks](https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks), [3.1.1 Language of Page](https://www.w3.org/WAI/WCAG22/Understanding/language-of-page), the [1.2.x Time-based Media](https://www.w3.org/TR/WCAG22/#time-based-media) set — and are the responsibility of the application. + +## How to read the ratings + +| Symbol | Term | Meaning | +| :----- | :----------------- | :---------------------------------------------- | +| ✅ | Supports | Met, with no known defects. | +| ⚠️ | Partially Supports | Some functionality does not meet the criterion. | +| ❌ | Does Not Support | Most functionality does not meet the criterion. | +| ➖ | Not Applicable | The criterion does not apply to this component. | + +Each criterion in a component report also records **who is responsible** for meeting it — ● the component, ◐ shared when used as documented, or ○ you, depending on your implementation and surrounding content. This distinction matters more for a component library than for an application, and the reports state it per criterion. + +:::info +An application built with Material UI is not automatically accessible. Material UI supplies accessible building blocks; meeting WCAG for a finished product remains the responsibility of the team building it. +::: + +## Known gaps + +Four issues account for almost every ⚠️ rating. Three are properties of the **default theme** rather than of the components' structure, so a theme resolves them today. + +| Gap | Criteria | Affected | Workaround | +| :--------------------------------------------------------------------------------------------- | :------------ | :---------------------------------------------------- | :-------------------------------------------------- | +| The keyboard focus indicator is the ripple, so `disableRipple`/`disableFocusRipple` removes it | 1.4.11, 2.4.7 | Button, Checkbox, Radio, Switch, Toggle Button | Style `.Mui-focusVisible` in your theme — see below | +| Some default palette colors fall short of contrast minimums | 1.4.3, 1.4.11 | Avatar, Button, TextField, Toggle Button, and others | Override the affected palette entries | +| Dynamic state changes are not announced | 4.1.3 | Button (`loading`), LinearProgress, TextField (error) | Render your own `aria-live` region alongside | +| Indefinite animation cannot be paused | 2.2.2 | LinearProgress (`indeterminate`, `query`, `buffer`) | Show it only while an operation is in flight | + +If you disable the ripple, restore a focus indicator in your theme: + +```js +const theme = createTheme({ + components: { + MuiButtonBase: { + styleOverrides: { + root: { + '&.Mui-focusVisible': { + outline: '2px solid currentColor', + outlineOffset: 2, + }, + }, + }, + }, + }, +}); +``` + +One genuine defect sits outside those four: Checkbox's `indeterminate` state sets `aria-checked="mixed"` on a native checkbox whose `checked` property is `false` (4.1.2), which ARIA in HTML disallows. It is tracked for a fix. + +## Scope and limitations + +:::warning +Read this section before citing the report. +::: + +- **Component coverage is partial.** 12 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. +- **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. +- **Evidence strength varies.** See the Verified column above; the shortfall is assessed from the source but not yet re-verified. +- **This is a self-assessment**, not audited by an independent third party. +- **Section 508 and EN 301 549 chapters are not yet included.** The WCAG results above supply the substance those chapters incorporate by reference, but the chapter-by-chapter mapping has not been written. + +## Feedback + +Accessibility defects are treated as bugs. Report them on [GitHub](https://github.com/mui/material-ui/issues/new/choose) with the component, the success criterion, and steps to reproduce. diff --git a/docs/data/material/getting-started/accessibility/scorecard.json b/docs/data/material/getting-started/accessibility/scorecard.json new file mode 100644 index 00000000000000..96311d3898fc46 --- /dev/null +++ b/docs/data/material/getting-started/accessibility/scorecard.json @@ -0,0 +1,2665 @@ +{ + "standard": "WCAG 2.2 Level A and AA", + "componentCount": 12, + "totals": { + "supports": 207, + "partiallySupports": 23, + "doesNotSupport": 0, + "notApplicable": 387, + "inherited": 43, + "flagged": 40 + }, + "criteria": [ + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "1.3.5", + "name": "Identify Input Purpose", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Partially Supports", + "flagged": true, + "affected": ["ToggleButton"] + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Partially Supports", + "flagged": true, + "affected": ["Avatar", "Button", "TextField", "ToggleButton"] + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "flagged": true, + "affected": [ + "AccordionSummary", + "Avatar", + "Button", + "Checkbox", + "LinearProgress", + "Radio", + "Switch", + "TextField", + "ToggleButton" + ] + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.2.2", + "name": "Pause, Stop, Hide", + "level": "A", + "conformance": "Partially Supports", + "flagged": true, + "affected": ["LinearProgress"] + }, + { + "number": "2.3.1", + "name": "Three Flashes or Below Threshold", + "level": "A", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.4.4", + "name": "Link Purpose (In Context)", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "flagged": false, + "affected": ["Button", "Checkbox", "Radio", "Switch", "ToggleButton"] + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "3.3.1", + "name": "Error Identification", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "flagged": true, + "affected": [] + }, + { + "number": "3.3.3", + "name": "Error Suggestion", + "level": "AA", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "flagged": false, + "affected": [] + }, + { + "number": "4.1.3", + "name": "Status Messages", + "level": "AA", + "conformance": "Partially Supports", + "flagged": true, + "affected": ["Button", "LinearProgress", "TextField"] + } + ], + "components": [ + { + "component": "Accordion", + "counts": { + "supports": "19", + "partiallySupports": "0", + "doesNotSupport": "0", + "notApplicable": "31", + "inherited": "5", + "flagged": "3/19" + }, + "gaps": [ + "Inherits: ⚠️ **1.4.11 Non-text Contrast** (the summary focus indicator) from [AccordionSummary](../AccordionSummary/accessibility.md)." + ], + "criteria": [ + { + "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.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 19, + "levelA": 11, + "levelAA": 8, + "supports": 19, + "partiallySupports": 0, + "doesNotSupport": 0, + "verified": 16, + "automated": 9 + } + }, + { + "component": "AccordionSummary", + "counts": { + "supports": "23", + "partiallySupports": "1", + "doesNotSupport": "0", + "notApplicable": "31", + "flagged": "3/24" + }, + "gaps": [ + "⚠️ **1.4.11 Non-text Contrast.** The keyboard-focus indicator is only a background tint (`action.focus`), about 1.3:1 against the adjacent `paper` surface, below the 3:1 minimum." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 24, + "levelA": 13, + "levelAA": 11, + "supports": 23, + "partiallySupports": 1, + "doesNotSupport": 0, + "verified": 21, + "automated": 11 + } + }, + { + "component": "Avatar", + "counts": { + "supports": "9", + "partiallySupports": "2", + "doesNotSupport": "0", + "notApplicable": "44", + "flagged": "5/11" + }, + "gaps": [ + "⚠️ **1.4.3 Contrast (Minimum).** Default letter and fallback avatars render white text on `grey[400]` (about 1.9:1), and the `deepOrange[500]` example is 3.16:1, both below 4.5:1; arbitrary `stringToColor` backgrounds are unguaranteed.", + "⚠️ **1.4.11 Non-text Contrast.** Meaningful icon-child avatars use the default white-on-`grey[400]` (1.9:1) or low-contrast author backgrounds (for example `green[500]` 2.78:1), below the 3:1 minimum for graphical objects." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 11, + "levelA": 5, + "levelAA": 6, + "supports": 9, + "partiallySupports": 2, + "doesNotSupport": 0, + "verified": 6, + "automated": 2 + } + }, + { + "component": "Button", + "counts": { + "supports": "23", + "partiallySupports": "4", + "doesNotSupport": "0", + "notApplicable": "28", + "flagged": "7/27" + }, + "gaps": [ + "⚠️ **1.4.3 Contrast (Minimum).** `info` and `warning` buttons fall short of 4.5:1 in every variant.", + "⚠️ **1.4.11 Non-text Contrast.** Focus-indicator, border, and icon contrast are untested; `disableRipple`/`disableFocusRipple` remove the `text`/`outlined` focus indicator, and `disableElevation` removes the `contained` one.", + "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` remove the `text`/`outlined` focus indicator; `contained` loses its indicator only when `disableElevation` is combined with them.", + "⚠️ **4.1.3 Status Messages.** The `loading` state adds no live region, so the change may go unannounced." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": true + }, + { + "number": "4.1.3", + "name": "Status Messages", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.4", + "name": "Link Purpose (In Context)", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 27, + "levelA": 15, + "levelAA": 12, + "supports": 23, + "partiallySupports": 4, + "doesNotSupport": 0, + "verified": 20, + "automated": 11 + } + }, + { + "component": "Checkbox", + "counts": { + "supports": "23", + "partiallySupports": "2", + "doesNotSupport": "0", + "notApplicable": "30", + "flagged": "3/25" + }, + "gaps": [ + "⚠️ **1.4.11 Non-text Contrast.** The default checkmark icons clear 3:1 (`warning` is the tightest at 3.11:1). The keyboard focus indicator is untested. `disableRipple`/`disableFocusRipple` or custom icons can drop below 3:1 — a faint custom unchecked box can be about 1.1:1 against the page.", + "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the default focus indicator (the focus ripple). None remains unless the author adds `.Mui-focusVisible` styling or enables the `theme.focusVisible` ring, which draws on the icon and does not depend on the ripple." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 25, + "levelA": 14, + "levelAA": 11, + "supports": 23, + "partiallySupports": 2, + "doesNotSupport": 0, + "verified": 22, + "automated": 11 + } + }, + { + "component": "LinearProgress", + "counts": { + "supports": "8", + "partiallySupports": "3", + "doesNotSupport": "0", + "notApplicable": "44", + "flagged": "5/11" + }, + "gaps": [ + "⚠️ **1.4.11 Non-text Contrast.** The fill-vs-track boundary falls below `3:1` for most palette colors in light mode, including the default `primary` (about `2.7:1`); in dark mode only `error` (`2.77:1`) falls short.", + "⚠️ **2.2.2 Pause, Stop, Hide.** The `indeterminate`, `query`, and `buffer` variants animate indefinitely with no built-in pause, stop, or hide control.", + "⚠️ **4.1.3 Status Messages.** The `progressbar` role is not a live region, so `value` changes are not announced unless the surrounding application adds one." + ], + "criteria": [ + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "2.2.2", + "name": "Pause, Stop, Hide", + "level": "A", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "2.3.1", + "name": "Three Flashes or Below Threshold", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "4.1.3", + "name": "Status Messages", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 11, + "levelA": 6, + "levelAA": 5, + "supports": 8, + "partiallySupports": 3, + "doesNotSupport": 0, + "verified": 6, + "automated": 1 + } + }, + { + "component": "Radio", + "counts": { + "supports": "23", + "partiallySupports": "2", + "doesNotSupport": "0", + "notApplicable": "30", + "flagged": "2/25" + }, + "gaps": [ + "⚠️ **1.4.11 Non-text Contrast.** The default dot and circle clear 3:1 (`warning` is the tightest at 3.11:1), but the keyboard focus indicator is untested and `disableRipple`/`disableFocusRipple` or custom icons can drop below 3:1 (the `CustomizedRadios` unchecked circle is about 1.1:1 against the page).", + "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the focus ripple, leaving none unless the author adds `.Mui-focusVisible` styling." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 25, + "levelA": 14, + "levelAA": 11, + "supports": 23, + "partiallySupports": 2, + "doesNotSupport": 0, + "verified": 23, + "automated": 11 + } + }, + { + "component": "RadioGroup", + "counts": { + "supports": "7", + "partiallySupports": "0", + "doesNotSupport": "0", + "notApplicable": "30", + "inherited": "18", + "flagged": "3/7" + }, + "gaps": [], + "criteria": [ + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 7, + "levelA": 6, + "levelAA": 1, + "supports": 7, + "partiallySupports": 0, + "doesNotSupport": 0, + "verified": 4, + "automated": 2 + } + }, + { + "component": "Switch", + "counts": { + "supports": "23", + "partiallySupports": "2", + "doesNotSupport": "0", + "notApplicable": "30", + "flagged": "2/25" + }, + "gaps": [ + "⚠️ **1.4.11 Non-text Contrast.** In light mode the thumb and track stay under 3:1. The off-state white thumb is about 2.7:1 on the gray track, and the track is about 2.7:1 on the page. Each checked color measures 1.8:1 to 2.6:1 thumb-on-track. The focus indicator is untested, and `disableRipple` removes it.", + "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` removes the default focus indicator (the focus ripple), leaving none unless the author adds `.Mui-focusVisible` styling." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 25, + "levelA": 14, + "levelAA": 11, + "supports": 23, + "partiallySupports": 2, + "doesNotSupport": 0, + "verified": 23, + "automated": 11 + } + }, + { + "component": "TextField", + "counts": { + "supports": "25", + "partiallySupports": "3", + "doesNotSupport": "0", + "notApplicable": "27", + "flagged": "4/28" + }, + "gaps": [ + "⚠️ **1.4.3 Contrast (Minimum).** The placeholder (about 2.55:1), the focused `warning` label (3.11:1), and the focused color labels on the filled surface (`primary` 4.04:1) fall short of 4.5:1.", + "⚠️ **1.4.11 Non-text Contrast.** The default `outlined` resting border (`rgba(0, 0, 0, 0.23)`, about 1.74:1) is below 3:1; the `filled` underline (about 3.03:1) clears it only marginally.", + "⚠️ **4.1.3 Status Messages.** A dynamically shown error is associated to the input but is not a live region, so it may go unannounced when focus is elsewhere." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": true + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.3.3", + "name": "Error Suggestion", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "4.1.3", + "name": "Status Messages", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.5", + "name": "Identify Input Purpose", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "3.3.2", + "name": "Labels or Instructions", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": true + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "3.3.1", + "name": "Error Identification", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 28, + "levelA": 14, + "levelAA": 14, + "supports": 25, + "partiallySupports": 3, + "doesNotSupport": 0, + "verified": 24, + "automated": 12 + } + }, + { + "component": "ToggleButton", + "counts": { + "supports": "20", + "partiallySupports": "4", + "doesNotSupport": "0", + "notApplicable": "31", + "flagged": "2/24" + }, + "gaps": [ + "⚠️ **1.4.1 Use of Color.** For the color variants (`primary`, `error`, `info`, `success`), the selected and unselected labels are near-identical in grayscale lightness, so the pressed state is conveyed almost entirely by hue.", + "⚠️ **1.4.3 Contrast (Minimum).** When selected, the `primary`, `error`, `info`, and `warning` labels (their `color.main` text over the tinted selected background) fall short of 4.5:1.", + "⚠️ **1.4.11 Non-text Contrast.** The focus indicator is the ripple; `disableRipple`/`disableFocusRipple` remove it, leaving no focus indicator. The selected-state fill is untested for 3:1.", + "⚠️ **2.4.7 Focus Visible.** `disableRipple`/`disableFocusRipple` remove the only keyboard focus indicator; the Toggle Button has no box-shadow fallback." + ], + "criteria": [ + { + "number": "1.3.2", + "name": "Meaningful Sequence", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.3.3", + "name": "Sensory Characteristics", + "level": "A", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.5", + "name": "Images of Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.11", + "name": "Focus Not Obscured (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "3.2.4", + "name": "Consistent Identification", + "level": "AA", + "conformance": "Supports", + "responsibility": "Author", + "group": "Manual", + "flagged": false + }, + { + "number": "1.1.1", + "name": "Non-text Content", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.1", + "name": "Use of Color", + "level": "A", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "1.4.3", + "name": "Contrast (Minimum)", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.11", + "name": "Non-text Contrast", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": true + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "2.4.7", + "name": "Focus Visible", + "level": "AA", + "conformance": "Partially Supports", + "responsibility": "Component", + "group": "Hybrid", + "flagged": false + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Hybrid", + "flagged": false + }, + { + "number": "1.4.4", + "name": "Resize Text", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "1.4.12", + "name": "Text Spacing", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.1", + "name": "Keyboard", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.1.2", + "name": "No Keyboard Trap", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.4.3", + "name": "Focus Order", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.2", + "name": "Pointer Cancellation", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.3", + "name": "Label in Name", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + }, + { + "number": "2.5.8", + "name": "Target Size (Minimum)", + "level": "AA", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.1", + "name": "On Focus", + "level": "A", + "conformance": "Supports", + "responsibility": "Component", + "group": "Automated", + "flagged": false + }, + { + "number": "3.2.2", + "name": "On Input", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 24, + "levelA": 13, + "levelAA": 11, + "supports": 20, + "partiallySupports": 4, + "doesNotSupport": 0, + "verified": 22, + "automated": 11 + } + }, + { + "component": "ToggleButtonGroup", + "counts": { + "supports": "4", + "partiallySupports": "0", + "doesNotSupport": "0", + "notApplicable": "31", + "inherited": "20", + "flagged": "1/4" + }, + "gaps": [], + "criteria": [ + { + "number": "1.3.1", + "name": "Info and Relationships", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "2.4.6", + "name": "Headings and Labels", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": true + }, + { + "number": "4.1.2", + "name": "Name, Role, Value", + "level": "A", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Manual", + "flagged": false + }, + { + "number": "1.4.10", + "name": "Reflow", + "level": "AA", + "conformance": "Supports", + "responsibility": "Shared", + "group": "Automated", + "flagged": false + } + ], + "summary": { + "rated": 4, + "levelA": 2, + "levelAA": 2, + "supports": 4, + "partiallySupports": 0, + "doesNotSupport": 0, + "verified": 3, + "automated": 1 + } + } + ] +} diff --git a/docs/data/material/pages.ts b/docs/data/material/pages.ts index f98fc7ea8c8a92..74d3b61f8c65a8 100644 --- a/docs/data/material/pages.ts +++ b/docs/data/material/pages.ts @@ -17,6 +17,7 @@ const pages: MuiPage[] = [ { pathname: '/material-ui/getting-started/learn' }, { pathname: '/material-ui/getting-started/design-resources' }, { pathname: '/material-ui/getting-started/faq', title: 'FAQs' }, + { pathname: '/material-ui/getting-started/accessibility' }, { pathname: '/material-ui/getting-started/supported-components' }, { pathname: '/material-ui/getting-started/supported-platforms' }, { pathname: '/material-ui/getting-started/support' }, diff --git a/docs/pages/material-ui/getting-started/accessibility.js b/docs/pages/material-ui/getting-started/accessibility.js new file mode 100644 index 00000000000000..a13a6b59e091dc --- /dev/null +++ b/docs/pages/material-ui/getting-started/accessibility.js @@ -0,0 +1,6 @@ +import { MarkdownDocs } from '@mui/internal-core-docs/MarkdownDocs'; +import * as pageProps from 'docs/data/material/getting-started/accessibility/accessibility.md?muiMarkdown'; + +export default function Page() { + return ; +} diff --git a/package.json b/package.json index d48cc8c9bba8a6..00e0609d2a29ff 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "release:build": "lerna run --concurrency 8 --no-private build --skip-nx-cache", "release:changelog": "node scripts/releaseChangelog.mjs", "release:pack": "tsx scripts/releasePack.mts", + "a11y:scorecard": "node scripts/a11yScorecard.mjs", + "a11y:scorecard:check": "node scripts/a11yScorecard.mjs --check", "docs:api": "rimraf --glob ./docs/pages/**/api-docs ./docs/pages/**/api && pnpm docs:api:build", "docs:api:build": "tsx ./scripts/buildApiDocs/index.ts", "docs:llms:build": "rimraf --glob ./docs/public/material-ui/ && tsx ./scripts/buildLlmsDocs/index.ts --projectSettings ./packages-internal/api-docs-builder-core/materialUi/projectSettings.ts", diff --git a/packages/mui-material/src/AccordionSummary/accessibility.md b/packages/mui-material/src/AccordionSummary/accessibility.md index df4cf6c6628e95..aab74a88a720f8 100644 --- a/packages/mui-material/src/AccordionSummary/accessibility.md +++ b/packages/mui-material/src/AccordionSummary/accessibility.md @@ -10,7 +10,7 @@ This is the item-level report for the accordion header button. The root `