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
9 changes: 7 additions & 2 deletions .claude/skills/contributing/references/a11y-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Comment thread
mart-sessman marked this conversation as resolved.

## Audit Procedure

### 1. Read the Component
Expand Down Expand Up @@ -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
Expand All @@ -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
- [ ] 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

Expand Down
7 changes: 6 additions & 1 deletion .github/ISSUE_TEMPLATE/new-tedi-ready-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@ 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))_
- [ ] 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
- [ ] Component’s **API (props, slots, events)** is documented
- [ ] **ZeroHeight is updated** with design/development guidelines
- [ ] **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)
7 changes: 6 additions & 1 deletion .github/ISSUE_TEMPLATE/react-tedi-ready-component-issue.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@ 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))_
- [ ] 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
- [ ] Component’s **API (props, slots, events)** is documented
- [ ] **ZeroHeight is updated** with design/development guidelines
- [ ] **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)
6 changes: 6 additions & 0 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ 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. To turn it off in a
// story, use options.rules too: config.rules can't override it.
options: {
rules: { 'target-size': { enabled: true } },
},
},
backgrounds: {
options: {
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/tedi/components/form/input-group/input-group.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ const SearchCategoryPrefixRow = () => {
};

export const StartDynamic: Story = {
parameters: {
a11y: {
options: {
// react-select's whole control is the pointer target, so axe flagging its inner input is a false positive.
rules: { 'target-size': { enabled: false } },
},
},
},
render: () => (
<VerticalSpacing>
<PhonePrefixRow />
Expand Down
24 changes: 24 additions & 0 deletions src/tedi/components/form/select/select.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,14 @@ const iconPickerOptions: ISelectOption<IconData>[] = (
).map((d, i) => ({ value: String(i + 1), label: d.name, customData: d }));

export const ValueType: Story = {
parameters: {
a11y: {
options: {
// react-select's whole control is the pointer target, so axe flagging its inner input is a false positive.
rules: { 'target-size': { enabled: false } },
},
},
},
render: () => (
<VerticalSpacing>
<Select id="value-no-value" label="No value" options={options} isClearable={false} />
Expand Down Expand Up @@ -343,6 +351,14 @@ export const ValueType: Story = {
* label shows in a popover on hover/focus.
*/
export const EllipsisTags: Story = {
parameters: {
a11y: {
options: {
// react-select's whole control is the pointer target, so axe flagging its inner input is a false positive.
rules: { 'target-size': { enabled: false } },
},
},
},
render: () => {
const longOptions: ISelectOption[] = [
{ value: 'a', label: 'A fairly long option label that does not fit' },
Expand Down Expand Up @@ -677,6 +693,14 @@ export const Examples: Story = {
* needs to be lifted (form integration, programmatic updates, etc.).
*/
export const MultipleHandled: Story = {
parameters: {
a11y: {
options: {
// react-select's whole control is the pointer target, so axe flagging its inner input is a false positive.
rules: { 'target-size': { enabled: false } },
},
},
},
render: MultipleHandledTemplate,
args: {
id: 'multiple-handled-example',
Expand Down
Loading