From 8f5636def8d857fb4f034e4734cdc06b0bc7e2b8 Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:35:31 +0300 Subject: [PATCH 01/10] docs: state the accessibility standard TEDI follows TEDI-Design-System/general#248 --- .claude/skills/contributing/references/a11y-review.md | 9 +++++++-- README.md | 8 ++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.claude/skills/contributing/references/a11y-review.md b/.claude/skills/contributing/references/a11y-review.md index d01d1c234..3e255ab14 100644 --- a/.claude/skills/contributing/references/a11y-review.md +++ b/.claude/skills/contributing/references/a11y-review.md @@ -2,6 +2,10 @@ Target component: `$ARGUMENTS` +## Standard + +TEDI follows EN 301 549 and, for web content, **WCAG 2.2 level AA**. Review against WCAG 2.2 AA. Components released before TEDI moved to WCAG 2.2 were built against WCAG 2.1 AA, so check the criteria new in 2.2 explicitly (2.4.11 Focus Not Obscured, 2.5.7 Dragging Movements, 2.5.8 Target Size) and report a failure as a Major finding like any other AA violation. The [accessibility page on tedi.ee](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8) is the canonical statement. + ## Audit Procedure ### 1. Read the Component @@ -39,6 +43,7 @@ Check against WAI-ARIA Authoring Practices for the component pattern: - [ ] Focus returns to trigger element when overlay closes - [ ] `tabIndex={-1}` used for programmatically focusable non-interactive elements - [ ] No focus on hidden/invisible elements +- [ ] Focused element is not fully hidden behind sticky headers, overlays or other content (WCAG 2.4.11, AA) - [ ] Uses `FloatingFocusManager` for overlay focus trapping (floating-ui pattern) ### 5. Visual & Motion @@ -51,8 +56,8 @@ Check against WAI-ARIA Authoring Practices for the component pattern: ### 6. Touch & Pointer -- [ ] Touch targets minimum 44x44 CSS pixels -- [ ] Adequate spacing between touch targets +- [ ] Touch targets at least 24x24 CSS pixels, or enough spacing around smaller targets (WCAG 2.5.8, AA); prefer 44x44 (WCAG 2.5.5, AAA) +- [ ] Anything done by dragging also works with a single click or tap (WCAG 2.5.7, AA) - [ ] No functionality dependent on hover alone (touch devices can't hover) - [ ] Uses `useIsTouchDevice()` hook where applicable for touch-specific behavior diff --git a/README.md b/README.md index a90eeadce..df23a7c3b 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,14 @@ Usage instructions and detailed documentation for using the components in your a --- +## Accessibility + +TEDI follows EN 301 549 and, for web content, WCAG 2.2 level AA. Components released before TEDI moved to WCAG 2.2 were built and tested against WCAG 2.1 AA and are being reviewed for the new criteria. + +The [accessibility page on tedi.ee](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8) (in Estonian) describes how components are tested, what TEDI covers and what stays with your project, and how to report an accessibility issue. + +--- + ## Getting Started (Using the package) If you are installing `@tedi-design-system/react` in your own project, follow the From fb3ec01d916c2390f8d13eb34deb12630a9fb596 Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:38:29 +0300 Subject: [PATCH 02/10] docs: add accessibility items to component issue template DoD TEDI-Design-System/general#248 --- .github/ISSUE_TEMPLATE/new-tedi-ready-component.md | 3 +++ .github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md index 9bb56f481..4edc32f60 100644 --- a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md +++ b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md @@ -21,13 +21,16 @@ Design: - [ ] CodeCov passes its threshold _(80% on the changed code, with 10% tolerance — a separate gate from the Jest one above)_ - [ ] The component has passed **code review** - [ ] The component has passed **Chromatic visual review** +- [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations - [ ] Include edge cases, empty/error states - [ ] Component’s **API (props, slots, events)** is documented - [ ] **ZeroHeight is updated** with design/development guidelines +- [ ] WCAG guidelines for the component are documented in ZeroHeight - [ ] **External dependencies** used in the component are documented in **Storybook and Zeroheight**, with rationale - [ ] **Semantic commit format** `type(scope): Subject text #issue-ref` is used (for `semantic-release`), with the **issue reference required** - see [Commit convention](https://github.com/TEDI-Design-System/general/wiki/Commit-convention) - [ ] External libraries **comply with [validated open source licenses](https://github.com/TEDI-Design-System/general/wiki/Definition-of-Done#validated-open-source-component-licences)** - [ ] Component is versioned correctly and ready for release if required - [ ] Update the **React** development status on the [statuses page in Zeroheight](https://www.tedi.ee/1ee8444b7/p/300e17-komponentide-staatused) +- [ ] Update the **WCAG** status on the [statuses page in Zeroheight](https://www.tedi.ee/1ee8444b7/p/300e17-komponentide-staatused) diff --git a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md index 03f13ef1c..1a3894162 100644 --- a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md +++ b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md @@ -28,13 +28,16 @@ assignees: '' - [ ] CodeCov passes its threshold _(80% on the changed code, with 10% tolerance — a separate gate from the Jest one above)_ - [ ] The component has passed **code review** - [ ] The component has passed **Chromatic visual review** +- [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations - [ ] Include edge cases, empty/error states - [ ] Component’s **API (props, slots, events)** is documented - [ ] **ZeroHeight is updated** with design/development guidelines +- [ ] WCAG guidelines for the component are documented in ZeroHeight - [ ] **External dependencies** used in the component are documented in **Storybook and Zeroheight**, with rationale - [ ] **Semantic commit format** `type(scope): Subject text #issue-ref` is used (for `semantic-release`), with the **issue reference required** - see [Commit convention](https://github.com/TEDI-Design-System/general/wiki/Commit-convention) - [ ] External libraries **comply with [validated open source licenses](https://github.com/TEDI-Design-System/general/wiki/Definition-of-Done#validated-open-source-component-licences)** - [ ] Component is versioned correctly and ready for release if required - [ ] Update the **React** development status on the [statuses page in Zeroheight](https://www.tedi.ee/1ee8444b7/p/300e17-komponentide-staatused) +- [ ] Update the **WCAG** status on the [statuses page in Zeroheight](https://www.tedi.ee/1ee8444b7/p/300e17-komponentide-staatused) From 2a948f45ded93a29c0921d9025f2318891946a48 Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:41:28 +0300 Subject: [PATCH 03/10] docs: add automated accessibility tests to component issue template DoD TEDI-Design-System/general#248 --- .github/ISSUE_TEMPLATE/new-tedi-ready-component.md | 1 + .github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md index 4edc32f60..ff25b53fd 100644 --- a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md +++ b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md @@ -21,6 +21,7 @@ Design: - [ ] CodeCov passes its threshold _(80% on the changed code, with 10% tolerance — a separate gate from the Jest one above)_ - [ ] The component has passed **code review** - [ ] The component has passed **Chromatic visual review** +- [ ] The component has passed the **automated accessibility tests** _(axe checks on the Storybook stories, run in CI)_ - [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations diff --git a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md index 1a3894162..213baafdb 100644 --- a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md +++ b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md @@ -28,6 +28,7 @@ assignees: '' - [ ] CodeCov passes its threshold _(80% on the changed code, with 10% tolerance — a separate gate from the Jest one above)_ - [ ] The component has passed **code review** - [ ] The component has passed **Chromatic visual review** +- [ ] The component has passed the **automated accessibility tests** _(axe checks on the Storybook stories, run in CI)_ - [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations From c0da3381bdecd28013280e3efc1c593e13eaea4e Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:43:17 +0300 Subject: [PATCH 04/10] docs: add manual browser and device testing to component issue template DoD TEDI-Design-System/general#248 --- .github/ISSUE_TEMPLATE/new-tedi-ready-component.md | 1 + .github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md index ff25b53fd..8b49f5622 100644 --- a/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md +++ b/.github/ISSUE_TEMPLATE/new-tedi-ready-component.md @@ -23,6 +23,7 @@ Design: - [ ] The component has passed **Chromatic visual review** - [ ] The component has passed the **automated accessibility tests** _(axe checks on the Storybook stories, run in CI)_ - [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ +- [ ] The component has been manually tested in **Chrome, Firefox, Safari and Edge**, and on **iOS and Android** devices - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations - [ ] Include edge cases, empty/error states diff --git a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md index 213baafdb..8943f285d 100644 --- a/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md +++ b/.github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md @@ -30,6 +30,7 @@ assignees: '' - [ ] The component has passed **Chromatic visual review** - [ ] The component has passed the **automated accessibility tests** _(axe checks on the Storybook stories, run in CI)_ - [ ] The component has been manually tested against **WCAG 2.2 AA** _(see [Ligipääsetavus](https://www.tedi.ee/1ee8444b7/p/33df89-sissejuhatus/b/05a2e8))_ +- [ ] The component has been manually tested in **Chrome, Firefox, Safari and Edge**, and on **iOS and Android** devices - [ ] **Storybook stories** are created: - [ ] Cover all Figma variations - [ ] Include edge cases, empty/error states From 3ccfceafab73993935eb41fccc0bb735e153554b Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:44:26 +0300 Subject: [PATCH 05/10] docs: correct WCAG 2.5.7 wording in a11y review checklist TEDI-Design-System/general#248 --- .claude/skills/contributing/references/a11y-review.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/contributing/references/a11y-review.md b/.claude/skills/contributing/references/a11y-review.md index 3e255ab14..173fea322 100644 --- a/.claude/skills/contributing/references/a11y-review.md +++ b/.claude/skills/contributing/references/a11y-review.md @@ -57,7 +57,7 @@ Check against WAI-ARIA Authoring Practices for the component pattern: ### 6. Touch & Pointer - [ ] Touch targets at least 24x24 CSS pixels, or enough spacing around smaller targets (WCAG 2.5.8, AA); prefer 44x44 (WCAG 2.5.5, AAA) -- [ ] Anything done by dragging also works with a single click or tap (WCAG 2.5.7, AA) +- [ ] Anything done by dragging can also be done with a single pointer without dragging, e.g. clicks or taps, possibly several (WCAG 2.5.7, AA). Exceptions: dragging is essential, or the behavior comes from the browser and is not modified by the component - [ ] No functionality dependent on hover alone (touch devices can't hover) - [ ] Uses `useIsTouchDevice()` hook where applicable for touch-specific behavior From eec2fa39f9e7d8c8989ef60292c767fab7dc9af0 Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 09:44:53 +0300 Subject: [PATCH 06/10] docs: use pointer terminology for WCAG 2.5.8 in a11y review checklist TEDI-Design-System/general#248 --- .claude/skills/contributing/references/a11y-review.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/contributing/references/a11y-review.md b/.claude/skills/contributing/references/a11y-review.md index 173fea322..6bb91b1fd 100644 --- a/.claude/skills/contributing/references/a11y-review.md +++ b/.claude/skills/contributing/references/a11y-review.md @@ -56,7 +56,7 @@ Check against WAI-ARIA Authoring Practices for the component pattern: ### 6. Touch & Pointer -- [ ] Touch targets at least 24x24 CSS pixels, or enough spacing around smaller targets (WCAG 2.5.8, AA); prefer 44x44 (WCAG 2.5.5, AAA) +- [ ] Pointer targets (mouse, touch, stylus) at least 24x24 CSS pixels, or enough spacing around smaller targets (WCAG 2.5.8, AA); prefer 44x44 (WCAG 2.5.5, AAA) - [ ] Anything done by dragging can also be done with a single pointer without dragging, e.g. clicks or taps, possibly several (WCAG 2.5.7, AA). Exceptions: dragging is essential, or the behavior comes from the browser and is not modified by the component - [ ] No functionality dependent on hover alone (touch devices can't hover) - [ ] Uses `useIsTouchDevice()` hook where applicable for touch-specific behavior From ceb6ce6c165a9549b6bb26739430207069aafd9a Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 10:05:16 +0300 Subject: [PATCH 07/10] test: enable axe target-size rule in Storybook a11y tests #1010 --- .storybook/preview.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 789b391bf..f26510e69 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -64,6 +64,11 @@ const preview: Preview = { viewMode: 'docs', a11y: { test: 'error', + // axe leaves target-size (WCAG 2.2, 2.5.8) off by default. Set via options.rules, not + // config.rules, so stories that override config.rules don't drop it. + options: { + rules: { 'target-size': { enabled: true } }, + }, }, backgrounds: { options: { From e3d4de09e3c1bc056280d9c3349fc6009241a54b Mon Sep 17 00:00:00 2001 From: m2rt Date: Tue, 20 Oct 2026 10:28:43 +0300 Subject: [PATCH 08/10] test: turn off target-size for react-select input false positives #1010 --- .../form/input-group/input-group.stories.tsx | 11 +++++++++ .../components/form/select/select.stories.tsx | 24 +++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/tedi/components/form/input-group/input-group.stories.tsx b/src/tedi/components/form/input-group/input-group.stories.tsx index a09847ca8..28b7bc4a3 100644 --- a/src/tedi/components/form/input-group/input-group.stories.tsx +++ b/src/tedi/components/form/input-group/input-group.stories.tsx @@ -204,6 +204,17 @@ const SearchCategoryPrefixRow = () => { }; export const StartDynamic: Story = { + parameters: { + a11y: { + config: { + // react-select's whole control is the pointer target, so axe flagging its inner input is a false positive. + rules: [ + { id: 'color-contrast', enabled: false }, + { id: 'target-size', enabled: false }, + ], + }, + }, + }, render: () => ( diff --git a/src/tedi/components/form/select/select.stories.tsx b/src/tedi/components/form/select/select.stories.tsx index da41dc71a..6801a317e 100644 --- a/src/tedi/components/form/select/select.stories.tsx +++ b/src/tedi/components/form/select/select.stories.tsx @@ -259,6 +259,14 @@ const iconPickerOptions: ISelectOption[] = ( ).map((d, i) => ({ value: String(i + 1), label: d.name, customData: d })); export const ValueType: Story = { + parameters: { + a11y: { + config: { + // react-select's whole control is the pointer target, so axe flagging its inner input is a false positive. + rules: [{ id: 'target-size', enabled: false }], + }, + }, + }, render: () => (