UNPKG

@octopusdeploy/design-system-components

Version:
71 lines (49 loc) 3.04 kB
# Accessibility Patterns ## accessibleName Components that have no visible label require an `accessibleName` prop to provide an accessible name for screen readers. In these cases, the component's TypeScript interface enforces `accessibleName` as required. In some cases we may have been inconsistent and we may have another prop such as `ariaLabel` or even `aria-label` exposed directly. Always look at the component props to determine this as we never spread props onto underlying elements. **Always provide `accessibleName` when:** - Using `IconButton` without a visible label - Using `Switch` without a `label` prop - Using `CheckboxNew` without a `label` prop ```tsx // IconButton — accessibleName is always required <IconButton accessibleName="Delete deployment" icon={<DeleteIcon />} onClick={handleDelete} /> // Switch without a label — accessibleName is required <Switch accessibleName="Enable notifications" value={enabled} onChange={setEnabled} /> // Switch with a label — accessibleName is optional (label provides the accessible name) <Switch label="Enable notifications" value={enabled} onChange={setEnabled} /> // CheckboxNew with a label — accessibleName is optional (label provides the accessible name) <CheckboxNew label="Enable notifications" value={enabled} onChange={setEnabled} /> // CheckboxNew without a label — accessibleName is required <CheckboxNew accessibleName="Enable notifications" value={enabled} onChange={setEnabled} /> ``` ## Don't suppress type errors on accessibleName If TypeScript reports a missing `accessibleName`, provide one. Do not cast to `any` or suppress the error — the requirement exists for a reason. ## Semantic HTML within components Design system components render appropriate semantic HTML internally. Do not override the rendered element type using props like `component="div"` unless the component explicitly supports it and the use case is documented. ## Form field labels All form field components (`TextField`, `Select`, `NumberField`, etc.) require a `label` prop. This label is rendered visibly and associated with the input for accessibility. Do not omit labels or attempt to hide them with custom CSS. ## ARIA props Some components expose limited ARIA props (`aria-controls`, `aria-haspopup`, `aria-expanded`) for specific interactive patterns (e.g. a Button that controls a panel). Only pass these when the component explicitly documents them and the pattern requires it. Do not add arbitrary `aria-*` props by spreading onto design system components — the components manage their own ARIA semantics and usually don't spread onto the underlying element. ## Testing accessibility New components in the design system are tested with `vitest-axe`. When writing tests for pages or features, run axe checks to catch accessibility violations: ```tsx import { axe } from "vitest-axe"; it("has no accessibility violations", async () => { const { container } = render(<MyComponent />); expect(await axe(container)).toHaveNoViolations(); }); ```