eslint-plugin-react-a11y 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/AGENTS.md +110 -0
  2. package/CHANGELOG.md +37 -0
  3. package/LICENSE +22 -0
  4. package/README.md +213 -0
  5. package/package.json +79 -0
  6. package/src/index.d.ts +40 -0
  7. package/src/index.js +279 -0
  8. package/src/rules/alt-text.d.ts +23 -0
  9. package/src/rules/alt-text.js +205 -0
  10. package/src/rules/anchor-ambiguous-text.d.ts +20 -0
  11. package/src/rules/anchor-ambiguous-text.js +169 -0
  12. package/src/rules/anchor-has-content.d.ts +20 -0
  13. package/src/rules/anchor-has-content.js +85 -0
  14. package/src/rules/anchor-is-valid.d.ts +23 -0
  15. package/src/rules/anchor-is-valid.js +100 -0
  16. package/src/rules/aria-activedescendant-has-tabindex.d.ts +15 -0
  17. package/src/rules/aria-activedescendant-has-tabindex.js +63 -0
  18. package/src/rules/aria-props.d.ts +15 -0
  19. package/src/rules/aria-props.js +51 -0
  20. package/src/rules/aria-role.d.ts +21 -0
  21. package/src/rules/aria-role.js +72 -0
  22. package/src/rules/aria-unsupported-elements.d.ts +15 -0
  23. package/src/rules/aria-unsupported-elements.js +54 -0
  24. package/src/rules/autocomplete-valid.d.ts +20 -0
  25. package/src/rules/autocomplete-valid.js +79 -0
  26. package/src/rules/click-events-have-key-events.d.ts +15 -0
  27. package/src/rules/click-events-have-key-events.js +60 -0
  28. package/src/rules/control-has-associated-label.d.ts +24 -0
  29. package/src/rules/control-has-associated-label.js +178 -0
  30. package/src/rules/heading-has-content.d.ts +20 -0
  31. package/src/rules/heading-has-content.js +72 -0
  32. package/src/rules/html-has-lang.d.ts +15 -0
  33. package/src/rules/html-has-lang.js +50 -0
  34. package/src/rules/iframe-has-title.d.ts +15 -0
  35. package/src/rules/iframe-has-title.js +51 -0
  36. package/src/rules/img-redundant-alt.d.ts +21 -0
  37. package/src/rules/img-redundant-alt.js +85 -0
  38. package/src/rules/interactive-supports-focus.d.ts +20 -0
  39. package/src/rules/interactive-supports-focus.js +81 -0
  40. package/src/rules/label-has-associated-control.d.ts +24 -0
  41. package/src/rules/label-has-associated-control.js +93 -0
  42. package/src/rules/lang.d.ts +15 -0
  43. package/src/rules/lang.js +53 -0
  44. package/src/rules/media-has-caption.d.ts +22 -0
  45. package/src/rules/media-has-caption.js +84 -0
  46. package/src/rules/mouse-events-have-key-events.d.ts +17 -0
  47. package/src/rules/mouse-events-have-key-events.js +62 -0
  48. package/src/rules/no-access-key.d.ts +15 -0
  49. package/src/rules/no-access-key.js +43 -0
  50. package/src/rules/no-aria-hidden-on-focusable.d.ts +15 -0
  51. package/src/rules/no-aria-hidden-on-focusable.js +67 -0
  52. package/src/rules/no-autofocus.d.ts +20 -0
  53. package/src/rules/no-autofocus.js +59 -0
  54. package/src/rules/no-distracting-elements.d.ts +20 -0
  55. package/src/rules/no-distracting-elements.js +64 -0
  56. package/src/rules/no-interactive-element-to-noninteractive-role.d.ts +18 -0
  57. package/src/rules/no-interactive-element-to-noninteractive-role.js +86 -0
  58. package/src/rules/no-keyboard-inaccessible-elements.d.ts +24 -0
  59. package/src/rules/no-keyboard-inaccessible-elements.js +136 -0
  60. package/src/rules/no-missing-aria-labels.d.ts +24 -0
  61. package/src/rules/no-missing-aria-labels.js +131 -0
  62. package/src/rules/no-noninteractive-element-interactions.d.ts +20 -0
  63. package/src/rules/no-noninteractive-element-interactions.js +78 -0
  64. package/src/rules/no-noninteractive-element-to-interactive-role.d.ts +18 -0
  65. package/src/rules/no-noninteractive-element-to-interactive-role.js +95 -0
  66. package/src/rules/no-noninteractive-tabindex.d.ts +22 -0
  67. package/src/rules/no-noninteractive-tabindex.js +172 -0
  68. package/src/rules/no-redundant-roles.d.ts +24 -0
  69. package/src/rules/no-redundant-roles.js +115 -0
  70. package/src/rules/no-static-element-interactions.d.ts +20 -0
  71. package/src/rules/no-static-element-interactions.js +72 -0
  72. package/src/rules/prefer-tag-over-role.d.ts +15 -0
  73. package/src/rules/prefer-tag-over-role.js +101 -0
  74. package/src/rules/role-has-required-aria-props.d.ts +15 -0
  75. package/src/rules/role-has-required-aria-props.js +65 -0
  76. package/src/rules/role-supports-aria-props.d.ts +15 -0
  77. package/src/rules/role-supports-aria-props.js +115 -0
  78. package/src/rules/scope.d.ts +15 -0
  79. package/src/rules/scope.js +49 -0
  80. package/src/rules/tabindex-no-positive.d.ts +15 -0
  81. package/src/rules/tabindex-no-positive.js +55 -0
  82. package/src/types/index.d.ts +208 -0
  83. package/src/types/index.js +7 -0
package/AGENTS.md ADDED
@@ -0,0 +1,110 @@
1
+ # AGENTS.md
2
+
3
+ > Context for AI coding agents working on eslint-plugin-react-a11y
4
+
5
+ ## Setup Commands
6
+
7
+ ```bash
8
+ # Install dependencies (from monorepo root)
9
+ npm install
10
+
11
+ # Build this package
12
+ nx build eslint-plugin-react-a11y
13
+
14
+ # Run tests
15
+ nx test eslint-plugin-react-a11y
16
+
17
+ # Run tests with coverage
18
+ nx test eslint-plugin-react-a11y --coverage
19
+
20
+ # Lint this package
21
+ nx lint eslint-plugin-react-a11y
22
+ ```
23
+
24
+ ## Code Style
25
+
26
+ - TypeScript strict mode with `@interlace/eslint-devkit` types
27
+ - Use `AST_NODE_TYPES` constants, never string literals for node types
28
+ - Use `formatLLMMessage()` for all rule error messages
29
+ - Include WCAG reference in every accessibility message
30
+ - Use `c8 ignore` comments with documented reasons for untestable code
31
+ - Single-pass AST traversal patterns (O(n) complexity)
32
+
33
+ ## Testing Instructions
34
+
35
+ - Tests use `@typescript-eslint/rule-tester` with Vitest
36
+ - Each rule has `index.ts` (implementation) and `*.test.ts` (tests) in same directory
37
+ - Run specific rule test: `nx test eslint-plugin-react-a11y --testPathPattern="img-requires-alt"`
38
+ - Coverage target: ≥90% lines, ≥95% functions
39
+ - All tests must pass before committing
40
+
41
+ ## Project Structure
42
+
43
+ ```
44
+ src/
45
+ ├── index.ts # Plugin entry, 4 configs
46
+ └── rules/ # 37 rule directories
47
+ └── [rule-name]/
48
+ ├── index.ts # Rule implementation
49
+ └── *.test.ts # Rule tests
50
+ ```
51
+
52
+ ## Plugin Purpose
53
+
54
+ React accessibility ESLint plugin with **37 LLM-optimized rules** for WCAG 2.1 compliance. Covers anchor elements, ARIA attributes, form controls, images, interactive elements, and focus management.
55
+
56
+ ## Available Presets
57
+
58
+ | Preset | Description |
59
+ | ------------- | --------------------------------------- |
60
+ | `recommended` | Balanced accessibility (37 rules mixed) |
61
+ | `strict` | All 37 rules as errors |
62
+ | `wcag-a` | WCAG 2.1 Level A compliance (16 rules) |
63
+ | `wcag-aa` | WCAG 2.1 Level AA compliance (24 rules) |
64
+
65
+ ## Rule Categories
66
+
67
+ | Category | Rules | WCAG |
68
+ | -------- | -------------------------------------------------------------------------------------------- | ------------ |
69
+ | Anchor | `anchor-ambiguous-text`, `anchor-has-content`, `anchor-is-valid` | 2.4.4 |
70
+ | ARIA | `aria-activedescendant-has-tabindex`, `aria-props`, `aria-role`, `aria-unsupported-elements` | 4.1.2 |
71
+ | Forms | `autocomplete-valid`, `control-has-associated-label`, `label-has-associated-control` | 1.3.1, 1.3.5 |
72
+ | Events | `click-events-have-key-events`, `mouse-events-have-key-events` | 2.1.1 |
73
+ | Images | `img-redundant-alt`, `img-requires-alt` | 1.1.1 |
74
+ | Focus | `interactive-supports-focus`, `no-autofocus`, `tabindex-no-positive` | 2.4.3 |
75
+
76
+ ## Error Message Format
77
+
78
+ All rules produce WCAG-referenced messages:
79
+
80
+ ```
81
+ ♿ WCAG 1.1.1 | Image missing alt text | CRITICAL
82
+ Fix: Add alt="Descriptive text about image" | https://www.w3.org/WAI/tutorials/images/
83
+ ```
84
+
85
+ ## Common Fix Patterns
86
+
87
+ ```tsx
88
+ // Image alt (WCAG 1.1.1)
89
+ // BAD: <img src="photo.jpg" />
90
+ // GOOD: <img src="photo.jpg" alt="Description of image" />
91
+
92
+ // Anchor content (WCAG 2.4.4)
93
+ // BAD: <a href="/page">Click here</a>
94
+ // GOOD: <a href="/page">View product details</a>
95
+
96
+ // Form labels (WCAG 1.3.1)
97
+ // BAD: <input type="text" />
98
+ // GOOD: <label>Name: <input type="text" /></label>
99
+ // GOOD: <input type="text" aria-label="Name" />
100
+
101
+ // Keyboard events (WCAG 2.1.1)
102
+ // BAD: <div onClick={handleClick}>...</div>
103
+ // GOOD: <div onClick={handleClick} onKeyDown={handleKeyDown} tabIndex={0}>...</div>
104
+ ```
105
+
106
+ ## Security Considerations
107
+
108
+ - All rules map to WCAG 2.1 success criteria
109
+ - Covers Level A, AA, and AAA requirements
110
+ - Prevents common accessibility anti-patterns
package/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [1.0.0] - 2025-12-05
9
+
10
+ ### Added
11
+
12
+ - Initial release with 37 accessibility rules
13
+ - WCAG 2.1 Level A, AA, and AAA coverage
14
+ - LLM-optimized error messages with structured 2-line format
15
+ - Auto-fix capabilities for applicable rules
16
+ - ESLint 8 and ESLint 9 flat config support
17
+ - TypeScript type definitions for all rule options
18
+ - Four preset configurations:
19
+ - `recommended` - Balanced accessibility enforcement
20
+ - `strict` - All rules as errors
21
+ - `wcag-a` - WCAG 2.1 Level A compliance
22
+ - `wcag-aa` - WCAG 2.1 Level AA compliance
23
+
24
+ ### Rule Categories
25
+
26
+ - **Anchor Rules (3)**: `anchor-ambiguous-text`, `anchor-has-content`, `anchor-is-valid`
27
+ - **ARIA Rules (4)**: `aria-activedescendant-has-tabindex`, `aria-props`, `aria-role`, `aria-unsupported-elements`
28
+ - **Form & Input Rules (3)**: `autocomplete-valid`, `control-has-associated-label`, `label-has-associated-control`
29
+ - **Event Rules (2)**: `click-events-have-key-events`, `mouse-events-have-key-events`
30
+ - **Content Rules (5)**: `heading-has-content`, `html-has-lang`, `iframe-has-title`, `lang`, `media-has-caption`
31
+ - **Image Rules (2)**: `img-redundant-alt`, `img-requires-alt`
32
+ - **Interactive Element Rules (6)**: `interactive-supports-focus`, `no-interactive-element-to-noninteractive-role`, `no-noninteractive-element-interactions`, `no-noninteractive-element-to-interactive-role`, `no-noninteractive-tabindex`, `no-static-element-interactions`
33
+ - **Focus & Navigation Rules (5)**: `no-access-key`, `no-aria-hidden-on-focusable`, `no-autofocus`, `no-keyboard-inaccessible-elements`, `tabindex-no-positive`
34
+ - **Visual & Distraction Rules (3)**: `no-distracting-elements`, `no-missing-aria-labels`, `no-redundant-roles`
35
+ - **Role Rules (3)**: `role-has-required-aria-props`, `role-supports-aria-props`, `prefer-tag-over-role`
36
+ - **Scope Rule (1)**: `scope`
37
+
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ofri Peretz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,213 @@
1
+ <p align="center">
2
+ <a href="https://eslint.interlace.tools" target="blank"><img src="https://eslint.interlace.tools/eslint-interlace-logo-light.svg" alt="ESLint Interlace Logo" width="120" /></a>
3
+ </p>
4
+
5
+ <p align="center">
6
+ Accessibility (a11y) rules for React applications, enforcing WCAG standards.
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/eslint-plugin-react-a11y" target="_blank"><img src="https://img.shields.io/npm/v/eslint-plugin-react-a11y.svg" alt="NPM Version" /></a>
11
+ <a href="https://www.npmjs.com/package/eslint-plugin-react-a11y" target="_blank"><img src="https://img.shields.io/npm/dm/eslint-plugin-react-a11y.svg" alt="NPM Downloads" /></a>
12
+ <a href="https://opensource.org/licenses/MIT" target="_blank"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="Package License" /></a>
13
+ <a href="https://app.codecov.io/gh/ofri-peretz/eslint/components?components%5B0%5D=react-a11y" target="_blank"><img src="https://codecov.io/gh/ofri-peretz/eslint/graph/badge.svg?component=react-a11y" alt="Codecov" /></a>
14
+ <a href="https://github.com/ofri-peretz/eslint" target="_blank"><img src="https://img.shields.io/badge/Since-Dec_2025-blue?logo=rocket&logoColor=white" alt="Since Dec 2025" /></a>
15
+ </p>
16
+
17
+ ## Description
18
+
19
+ This plugin ensures your React applications are accessible to all users by strictly enforcing WCAG standards. It automatically detects common accessibility issues in your JSX, such as missing alt text or improper aria labels, and guides you toward compliant solutions. Implementing these rules helps you build inclusive web experiences that meet modern accessibility requirements.
20
+
21
+ ## Philosophy
22
+
23
+ **Interlace** fosters **strength through integration**. We **interlace** accessibility directly into your workflow, creating inclusive applications by design. Tools should **guide rather than gatekeep**, providing educational feedback that strengthens developers.
24
+
25
+ **Why an independent ecosystem?** 🚀 Ship fast without upstream bureaucracy • 🤖 AI-optimized messages (WCAG, severity, fixes) • ⚡ Unified codebase for performance • 🏗️ Consistent patterns across all plugins • 📚 Educational "why" explanations
26
+
27
+ All rules are **clean-room implementations** following `eslint-plugin-jsx-a11y` naming conventions — familiar API, better engineering.
28
+
29
+ ## Getting Started
30
+
31
+ - To check out the [guide](https://eslint.interlace.tools/docs/react-a11y), visit [eslint.interlace.tools](https://eslint.interlace.tools). 📚
32
+ - 要查看中文 [指南](https://eslint.interlace.tools/docs/react-a11y), 请访问 [eslint.interlace.tools](https://eslint.interlace.tools). 📚
33
+ - [가이드](https://eslint.interlace.tools/docs/react-a11y) 문서는 [eslint.interlace.tools](https://eslint.interlace.tools)에서 확인하실 수 있습니다. 📚
34
+ - [ガイド](https://eslint.interlace.tools/docs/react-a11y)は [eslint.interlace.tools](https://eslint.interlace.tools)でご確認ください。 📚
35
+ - Para ver la [guía](https://eslint.interlace.tools/docs/react-a11y), visita [eslint.interlace.tools](https://eslint.interlace.tools). 📚
36
+ - للاطلاع على [الدليل](https://eslint.interlace.tools/docs/react-a11y)، قم بزيارة [eslint.interlace.tools](https://eslint.interlace.tools). 📚
37
+
38
+ ```bash
39
+ npm install eslint-plugin-react-a11y --save-dev
40
+ ```
41
+
42
+ ## Quick Start
43
+
44
+ ```javascript
45
+ // eslint.config.js
46
+ import reactA11y from 'eslint-plugin-react-a11y';
47
+
48
+ export default [reactA11y.configs.recommended];
49
+ ```
50
+
51
+ ## ⚙️ Configuration Presets
52
+
53
+ | Preset | Description |
54
+ | :------------ | :---------------------------------------------------------------------------- |
55
+ | `recommended` | Enables critical accessibility rules (WCAG Level A as errors, AA as warnings) |
56
+ | `strict` | Enforces all rules as errors for maximum WCAG compliance |
57
+ | `wcag-a` | Only rules required for WCAG 2.1 Level A compliance |
58
+ | `wcag-aa` | Includes Level A + additional rules for Level AA compliance |
59
+
60
+ ## Configuration Examples
61
+
62
+ ### Basic Usage
63
+
64
+ ```javascript
65
+ // eslint.config.js
66
+ import reactA11y from 'eslint-plugin-react-a11y';
67
+
68
+ export default [reactA11y.configs.recommended];
69
+ ```
70
+
71
+ ### With TypeScript
72
+
73
+ ```javascript
74
+ import reactA11y from 'eslint-plugin-react-a11y';
75
+ import tseslint from 'typescript-eslint';
76
+
77
+ export default [
78
+ ...tseslint.configs.recommended,
79
+ reactA11y.configs.recommended,
80
+ {
81
+ files: ['**/*.{ts,tsx}'],
82
+ rules: {
83
+ 'react-a11y/img-requires-alt': 'error',
84
+ },
85
+ },
86
+ ];
87
+ ```
88
+
89
+ ### Strict WCAG Compliance
90
+
91
+ ```javascript
92
+ import reactA11y from 'eslint-plugin-react-a11y';
93
+
94
+ export default [
95
+ reactA11y.configs['wcag-aa'],
96
+ {
97
+ // Additional customizations
98
+ },
99
+ ];
100
+ ```
101
+
102
+ ### Custom Configuration
103
+
104
+ ```javascript
105
+ import reactA11y from 'eslint-plugin-react-a11y';
106
+
107
+ export default [
108
+ {
109
+ plugins: {
110
+ 'react-a11y': reactA11y,
111
+ },
112
+ rules: {
113
+ 'react-a11y/img-requires-alt': [
114
+ 'error',
115
+ {
116
+ allowAriaLabel: true,
117
+ allowAriaLabelledby: true,
118
+ },
119
+ ],
120
+ 'react-a11y/anchor-ambiguous-text': [
121
+ 'warn',
122
+ {
123
+ words: ['click here', 'here', 'more', 'read more', 'learn more'],
124
+ },
125
+ ],
126
+ },
127
+ },
128
+ ];
129
+ ```
130
+
131
+ ## Rules
132
+
133
+ **Legend**
134
+
135
+ | Icon | Description |
136
+ | :--: | :----------------------------------------------------------------- |
137
+ | 💼 | **Recommended**: Included in the recommended preset. |
138
+ | ⚠️ | **Warns**: Set towarn in recommended preset. |
139
+ | 🔧 | **Auto-fixable**: Automatically fixable by the `--fix` CLI option. |
140
+ | 💡 | **Suggestions**: Providing code suggestions in IDE. |
141
+ | 🚫 | **Deprecated**: This rule is deprecated. |
142
+
143
+ | Rule | WCAG Criterion | Description | 💼 | ⚠️ | 🔧 | 💡 | 🚫 |
144
+ | :------------------------------------------------------------------------------------------------------------------ | :------------- | :---------------------------------------------------- | :-: | :-: | :-: | :-: | :-: |
145
+ | [`alt-text`](https://eslint.interlace.tools/docs/react-a11y/rules/alt-text) | 1.1.1 | Image missing alt text | 💼 | | | | |
146
+ | [`html-has-lang`](https://eslint.interlace.tools/docs/react-a11y/rules/html-has-lang) | 3.1.1 | html element missing lang attribute | 💼 | | | | |
147
+ | [`iframe-has-title`](https://eslint.interlace.tools/docs/react-a11y/rules/iframe-has-title) | 2.4.1 | iframe element missing title | 💼 | | | | |
148
+ | [`mouse-events-have-key-events`](https://eslint.interlace.tools/docs/react-a11y/rules/mouse-events-have-key-events) | 2.1.1 | onMouseOver must be accompanied by onFocus | 💼 | | | | |
149
+ | [`no-access-key`](https://eslint.interlace.tools/docs/react-a11y/rules/no-access-key) | 2.1.1 | No access key attribute allowed | 💼 | | | | |
150
+ | [`no-autofocus`](https://eslint.interlace.tools/docs/react-a11y/rules/no-autofocus) | 2.4.3 | No autofocus attribute allowed | 💼 | | | | |
151
+ | [`no-distracting-elements`](https://eslint.interlace.tools/docs/react-a11y/rules/no-distracting-elements) | 2.2.2 | Distracting elements (marquee, blink) are not allowed | 💼 | | | | |
152
+ | [`aria-props`](https://eslint.interlace.tools/docs/react-a11y/rules/aria-props) | 4.1.2 | Invalid ARIA attribute | 💼 | | | | |
153
+ | [`aria-role`](https://eslint.interlace.tools/docs/react-a11y/rules/aria-role) | 4.1.2 | Invalid ARIA role | 💼 | | | | |
154
+ | [`role-has-required-aria-props`](https://eslint.interlace.tools/docs/react-a11y/rules/role-has-required-aria-props) | 4.1.2 | Role missing required aria props | 💼 | | | | |
155
+ | [`aria-unsupported-elements`](https://eslint.interlace.tools/docs/react-a11y/rules/aria-unsupported-elements) | 4.1.2 | Element does not support ARIA roles/props | 💼 | | | | |
156
+ | [`click-events-have-key-events`](https://eslint.interlace.tools/docs/react-a11y/rules/click-events-have-key-events) | 2.1.1 | onClick must be accompanied by onKeyUp/KeyDown | 💼 | | | | |
157
+ | [`heading-has-content`](https://eslint.interlace.tools/docs/react-a11y/rules/heading-has-content) | 1.3.1 | Headings must have content | 💼 | | | | |
158
+ | [`label-has-associated-control`](https://eslint.interlace.tools/docs/react-a11y/rules/label-has-associated-control) | 3.3.2 | Form label must be associated with a control | 💼 | | | | |
159
+ | [`tabindex-no-positive`](https://eslint.interlace.tools/docs/react-a11y/rules/tabindex-no-positive) | 2.4.3 | Avoid positive tabIndex | 💼 | | | | |
160
+
161
+ ---
162
+
163
+ ## AI-Optimized Messages
164
+
165
+ This plugin is optimized for ESLint's [Model Context Protocol (MCP)](https://eslint.org/docs/latest/use/mcp), enabling AI assistants like **Cursor**, **GitHub Copilot**, and **Claude** to:
166
+
167
+ - Understand the exact vulnerability type via CWE references
168
+ - Apply the correct fix using structured guidance
169
+ - Provide educational context to developers
170
+
171
+ ```bash
172
+ src/components/Button.tsx
173
+ 12:5 error 🔒 CWE-20 WCAG:4.1.2 CVSS:5.3 | Interactive element missing accessible name | CRITICAL [WCAG 2.1 A]
174
+ Fix: Add aria-label="Submit Order" or inner text | https://eslint.interlace.tools/...
175
+ ```
176
+
177
+ ```json
178
+ // .cursor/mcp.json
179
+ {
180
+ "mcpServers": {
181
+ "eslint": {
182
+ "command": "npx",
183
+ "args": ["@eslint/mcp@latest"]
184
+ }
185
+ }
186
+ }
187
+ ```
188
+
189
+ By providing this structured context (CWE, OWASP, Fix), we enable AI tools to **reason** about the security flaw rather than hallucinating. This allows Copilot/Cursor to suggest the _exact_ correct fix immediately.
190
+
191
+ ## 🔗 Related ESLint Plugins
192
+
193
+ Part of the **Interlace ESLint Ecosystem** — AI-native security plugins with LLM-optimized error messages:
194
+
195
+ | Plugin | Downloads | Description |
196
+ | :----------------------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------: | :------------------------------------------ |
197
+ | [`eslint-plugin-secure-coding`](https://www.npmjs.com/package/eslint-plugin-secure-coding) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-secure-coding.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-secure-coding) | General security rules & OWASP guidelines. |
198
+ | [`eslint-plugin-pg`](https://www.npmjs.com/package/eslint-plugin-pg) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-pg.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-pg) | PostgreSQL security & best practices. |
199
+ | [`eslint-plugin-crypto`](https://www.npmjs.com/package/eslint-plugin-crypto) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-crypto.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-crypto) | NodeJS Cryptography security rules. |
200
+ | [`eslint-plugin-jwt`](https://www.npmjs.com/package/eslint-plugin-jwt) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-jwt.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-jwt) | JWT security & best practices. |
201
+ | [`eslint-plugin-browser-security`](https://www.npmjs.com/package/eslint-plugin-browser-security) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-browser-security.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-browser-security) | Browser-specific security & XSS prevention. |
202
+ | [`eslint-plugin-express-security`](https://www.npmjs.com/package/eslint-plugin-express-security) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-express-security.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-express-security) | Express.js security hardening rules. |
203
+ | [`eslint-plugin-lambda-security`](https://www.npmjs.com/package/eslint-plugin-lambda-security) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-lambda-security.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-lambda-security) | AWS Lambda security best practices. |
204
+ | [`eslint-plugin-nestjs-security`](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-nestjs-security.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-nestjs-security) | NestJS security rules & patterns. |
205
+ | [`eslint-plugin-import-next`](https://www.npmjs.com/package/eslint-plugin-import-next) | [![downloads](https://img.shields.io/npm/dt/eslint-plugin-import-next.svg?style=flat-square)](https://www.npmjs.com/package/eslint-plugin-import-next) | Next-gen import sorting & architecture. |
206
+
207
+ ## 📄 License
208
+
209
+ MIT © [Ofri Peretz](https://github.com/ofri-peretz)
210
+
211
+ <p align="center">
212
+ <a href="https://eslint.interlace.tools/docs/react-a11y"><img src="https://eslint.interlace.tools/images/og-react-a11y.png" alt="ESLint Interlace Plugin" width="300" /></a>
213
+ </p>
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "eslint-plugin-react-a11y",
3
+ "version": "2.1.0",
4
+ "description": "React accessibility ESLint plugin with 37 LLM-optimized rules for WCAG 2.1 compliance. Provides structured error messages for AI assistants and auto-fix capabilities.",
5
+ "type": "commonjs",
6
+ "main": "./src/index.js",
7
+ "types": "./src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./src/index.d.ts",
11
+ "default": "./src/index.js"
12
+ },
13
+ "./types": {
14
+ "types": "./src/types/index.d.ts",
15
+ "default": "./src/types/index.js"
16
+ }
17
+ },
18
+ "author": "Ofri Peretz <ofriperetzdev@gmail.com>",
19
+ "license": "MIT",
20
+ "homepage": "https://github.com/ofri-peretz/eslint#readme",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/ofri-peretz/eslint.git",
24
+ "directory": "packages/eslint-plugin-react-a11y"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/ofri-peretz/eslint/issues"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "files": [
33
+ "src/",
34
+ "dist/",
35
+ "README.md",
36
+ "LICENSE",
37
+ "CHANGELOG.md",
38
+ "AGENTS.md"
39
+ ],
40
+ "keywords": [
41
+ "eslint",
42
+ "eslint-plugin",
43
+ "eslintplugin",
44
+ "interlace-quality",
45
+ "accessibility",
46
+ "a11y",
47
+ "react",
48
+ "wcag",
49
+ "wcag-2.1",
50
+ "aria",
51
+ "screen-reader",
52
+ "ada-compliance",
53
+ "section-508",
54
+ "llm-optimized",
55
+ "ai-assistant",
56
+ "auto-fix",
57
+ "typescript",
58
+ "linting",
59
+ "code-quality",
60
+ "ast",
61
+ "static-analysis",
62
+ "mcp",
63
+ "model-context-protocol",
64
+ "github-copilot",
65
+ "cursor-ai",
66
+ "claude-ai"
67
+ ],
68
+ "engines": {
69
+ "node": ">=18.0.0"
70
+ },
71
+ "dependencies": {
72
+ "tslib": "^2.3.0",
73
+ "@interlace/eslint-devkit": "*"
74
+ },
75
+ "devDependencies": {
76
+ "@typescript-eslint/parser": "^8.46.2",
77
+ "@typescript-eslint/rule-tester": "^8.46.2"
78
+ }
79
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright (c) 2025 Ofri Peretz
3
+ * Licensed under the MIT License. Use of this source code is governed by the
4
+ * MIT license that can be found in the LICENSE file.
5
+ */
6
+ /**
7
+ * eslint-plugin-react-a11y
8
+ *
9
+ * A comprehensive React accessibility ESLint plugin with 37 LLM-optimized rules
10
+ * for detecting and preventing accessibility violations in React/JSX code.
11
+ *
12
+ * Features:
13
+ * - WCAG 2.1 Level A, AA, and AAA compliance
14
+ * - LLM-optimized error messages with fix suggestions
15
+ * - Auto-fix capabilities where safe
16
+ * - Structured context for AI assistants
17
+ *
18
+ * @see https://github.com/ofri-peretz/eslint#readme
19
+ */
20
+ import type { TSESLint } from '@interlace/eslint-devkit';
21
+ /**
22
+ * Collection of all accessibility ESLint rules
23
+ */
24
+ export declare const rules: Record<string, TSESLint.RuleModule<string, readonly unknown[]>>;
25
+ /**
26
+ * ESLint Plugin object
27
+ */
28
+ export declare const plugin: TSESLint.FlatConfig.Plugin;
29
+ /**
30
+ * Preset configurations for accessibility rules
31
+ */
32
+ export declare const configs: Record<string, TSESLint.FlatConfig.Config>;
33
+ /**
34
+ * Default export for ESLint plugin
35
+ */
36
+ export default plugin;
37
+ /**
38
+ * Re-export types (will be created in types/index.ts)
39
+ */
40
+ export * from './types/index';