@a11yfred/neighbor 1.0.4 → 2.0.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.
- package/CHANGELOG.md +88 -71
- package/CONTRIBUTING.md +41 -41
- package/README.md +4 -466
- package/RULES-CONTENT.md +245 -86
- package/RULES-CSS.md +41 -19
- package/RULES-MARKUP.md +168 -93
- package/RULES.md +47 -28
- package/lib/content-rules.js +216 -0
- package/lib/framework-rules.js +282 -0
- package/lib/helpers-webcomponents.js +134 -0
- package/lib/rules.js +376 -11
- package/lib/ulam-rules.js +145 -10
- package/neighbor-content.mjs +1 -1
- package/neighbor-eslint-angular.mjs +29 -8
- package/neighbor-eslint-lit.mjs +85 -0
- package/neighbor-eslint-remix3.mjs +49 -0
- package/neighbor-eslint-vue.mjs +26 -6
- package/neighbor-eslint-webcomponents.mjs +41 -0
- package/neighbor-eslint.mjs +13 -6
- package/neighbor-stylelint.mjs +141 -3
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,74 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<!-- markdownlint-disable MD024 -->
|
|
4
|
+
|
|
5
|
+
All notable changes to this project will be documented in this file.
|
|
6
|
+
|
|
7
|
+
## [2.0.0] - 2026-05-24
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Native iOS Linting (SwiftUI)**: 9 custom SwiftLint rules for SwiftUI accessibility, distributed via `.swiftlint.yml`. Checks for disabled focus effects, hardcoded font sizes, redundant accessibility labels, small touch targets, restrictive orientation locks, and more. See [apps/ios-app/README.md](apps/ios-app/README.md).
|
|
12
|
+
- **Native Android Linting (Jetpack Compose)**: 8 custom Android Lint detector rules for Jetpack Compose, distributed as a standard Gradle lint module. Checks for missing `contentDescription`, hardcoded `sp` text, small touch targets, missing `stateDescription`, `pointerInput` without semantics, disabled traversal groups, restrictive orientation, and forced light mode. See [apps/android-app/README.md](apps/android-app/README.md).
|
|
13
|
+
- **Microsoft Word Add-in**: An Office.js add-in that checks Word documents for exclusionary and ableist language while you type. Built with React, Fluent UI, and Vite. See [apps/word-addin/README.md](apps/word-addin/README.md).
|
|
14
|
+
- **New Stylelint Rules**:
|
|
15
|
+
- `neighbor/no-text-justify` (error): Disallows `text-align: justify` which creates uneven word spacing that is hard for dyslexic users to read (SC 1.4.8).
|
|
16
|
+
- `neighbor/no-absolute-viewport-text` (warn): Warns on pure viewport units (`vw`, `vh`) for text sizing which block browser zoom (SC 1.4.4).
|
|
17
|
+
- `neighbor/no-user-select-all-none` (warn): Warns on `user-select: none` which prevents text selection and translation (SC 1.4.4).
|
|
18
|
+
- **New Content Rules**:
|
|
19
|
+
- `no-exclusive-language`: Tech jargon and culturally appropriated terms (blacklist, master/slave, sanity check, spirit animal).
|
|
20
|
+
- `no-colonial-and-violent-language`: Words rooted in colonialism or violence applied to people (stakeholder, target population, tackle).
|
|
21
|
+
- `no-deficit-language`: Words that reduce people to their circumstances (the homeless, inmate, addict, at-risk youth).
|
|
22
|
+
- `no-gendered-language`: Gendered pronouns when gender is unknown (he/she, his or her, mum and dad).
|
|
23
|
+
- `no-anti-lgbtq-language`: Outdated or pathologizing terms about sexual orientation and gender identity.
|
|
24
|
+
- `no-device-specific-action`: Device-specific input actions (click, tap, swipe).
|
|
25
|
+
- **New Markup Rules**:
|
|
26
|
+
- `vue-router-focus-management` (off): Warns if a Vue Router view transition happens without managing focus.
|
|
27
|
+
- `react-spa-focus-management` (warn): Warns if a React Router or Remix transition happens without managing focus.
|
|
28
|
+
- **Remix 3 Support**: Added a dedicated ESLint configuration (`@a11yfred/neighbor/remix3`) for file-based routing.
|
|
29
|
+
- **Web Components / Vanilla HTML Support**: Added a dedicated ESLint configuration (`@a11yfred/neighbor/webcomponents`) using `@html-eslint/parser`.
|
|
30
|
+
- **App Stubs**: Scaffolded workspace directories for `webapp`, `chrome-extension`, `firefox-extension`, and `electron-app`.
|
|
31
|
+
- **Vale Dictionary**: Compiled Vale-compatible dictionary containing textlint content vocabulary for standalone Markdown checking.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **Rule Severities**: All recommended framework ARIA rules and Vale content rules are now set to `warn` by default to reduce friction on initial adoption.
|
|
36
|
+
- **Rule Severities**: The `prefer-aria-disabled` rule is explicitly set to `error`, as previously documented.
|
|
37
|
+
- **Linter Dependencies**: Dropped `eslint-plugin-jsx-a11y` as a direct dependency. It is now an optional `peerDependency`, meaning teams using only Web Components or text linting are not forced to install React accessibility rules. `eslint-plugin-vuejs-accessibility` and `@angular-eslint/eslint-plugin-template` have also been properly registered as optional.
|
|
38
|
+
- **Vale Configs**: Automatically generated and packaged the latest content rules for `@a11yfred/vale-config-neighbor`.
|
|
39
|
+
- **CI/CD**: Fixed publish workflow to publish from `packages/neighbor/` and `packages/textlint-rule-neighbor/` instead of the monorepo root. Fixed Vale zip path.
|
|
40
|
+
|
|
41
|
+
### Documentation
|
|
42
|
+
|
|
43
|
+
- Comprehensive 6-pass documentation audit for markdownlint compliance, accuracy, plain language, and ESL friendliness.
|
|
44
|
+
- All rule tables sorted by severity (most severe first) then alphabetically.
|
|
45
|
+
- Contractions replaced with full forms across all authored documentation.
|
|
46
|
+
- All ecosystem tools (ESLint, Stylelint, textlint, Vale, SwiftLint, Android Lint, Word Add-in) documented in README.
|
|
47
|
+
- Grammatical em dashes and en dashes replaced with hyphens across the entire codebase.
|
|
48
|
+
- AI-assisted development disclaimer added to README.
|
|
49
|
+
|
|
50
|
+
## 1.1.0 - 2026-05-23
|
|
51
|
+
|
|
52
|
+
- **New rule:** `no-disabled-and-aria-disabled`: Elements with both `disabled` and `aria-disabled` attributes cause conflicting states in assistive tech
|
|
53
|
+
- **Severity change:** `prefer-aria-disabled` moved from `off` to `error` by default to enforce discoverable form controls in tab order.
|
|
4
54
|
|
|
5
|
-
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 1.0.6 - 2026-05-13
|
|
58
|
+
|
|
59
|
+
**Changed:**
|
|
6
60
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
61
|
+
- **Documentation:** Add severity column to all rule tables in README
|
|
62
|
+
- **Docs cleanup:** Remove em dashes, fix MD036/MD040 markdownlint issues across all docs
|
|
63
|
+
|
|
64
|
+
**Fixed:**
|
|
65
|
+
|
|
66
|
+
- **`no-placeholder-only`**: no longer false-positives on `<input>` elements inside a `role="search"` landmark with an accessible name. The input is correctly labeled at the group level in that pattern.
|
|
67
|
+
- **`no-dialog-without-close`**: no longer false-positives on `role="dialog"` elements whose children are passed dynamically (`{children}`). When a close button cannot be statically detected, the rule skips rather than reporting.
|
|
9
68
|
|
|
10
69
|
---
|
|
11
70
|
|
|
12
|
-
## 1.0.0
|
|
71
|
+
## 1.0.0 - 2026-05-12
|
|
13
72
|
|
|
14
73
|
### Breaking change
|
|
15
74
|
|
|
@@ -17,98 +76,56 @@ CSS rules renamed from `ulam/` to `neighbor/` namespace:
|
|
|
17
76
|
|
|
18
77
|
| Old | New |
|
|
19
78
|
| --- | --- |
|
|
20
|
-
| `ulam/user-preferences` | `neighbor/user-preferences` |
|
|
21
|
-
| `ulam/no-outline-none` | `neighbor/no-outline-none` |
|
|
22
79
|
| `ulam/no-forced-colors-none` | `neighbor/no-forced-colors-none` |
|
|
80
|
+
| `ulam/no-outline-none` | `neighbor/no-outline-none` |
|
|
81
|
+
| `ulam/user-preferences` | `neighbor/user-preferences` |
|
|
23
82
|
|
|
24
83
|
Update your `.stylelintrc.json` to use the new names.
|
|
25
84
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## 0.4.0 - 2026-05-12
|
|
85
|
+
### Added
|
|
29
86
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### New content rules (all `warn`)
|
|
87
|
+
- **New rule:** `neighbor/no-forced-colors-none`: `forced-color-adjust: none` inside `@media (forced-colors)` actively opts out of Windows High Contrast Mode
|
|
88
|
+
- **New entry point:** `@a11yfred/neighbor/content`: An ESLint plugin for accessibility and inclusion problems in web and app copy. Lints string literals and JSX text in JS/TS/JSX/TSX files.
|
|
89
|
+
- **New content rules (all `warn`):**
|
|
35
90
|
|
|
36
91
|
| Rule | What it flags |
|
|
37
92
|
| --- | --- |
|
|
38
93
|
| `no-ableist-language` | Slurs, suffering-framing, and condescending euphemisms when writing about disability ("wheelchair-bound", "suffers from", "special needs", "differently abled") |
|
|
94
|
+
| `no-all-caps-prose` | ALL CAPS words that screen readers may spell out letter-by-letter |
|
|
95
|
+
| `no-ampersand-in-prose` | `&` in place of "and" in prose - announced inconsistently across AT vendors |
|
|
96
|
+
| `no-directional-language` | Layout-dependent position instructions ("see above", "in the right sidebar", "as shown below") |
|
|
39
97
|
| `no-disability-metaphor` | Figurative uses of disability language ("blind spot", "tone deaf", "paralyzed by", "crippling debt") |
|
|
40
98
|
| `no-english-idiom` | English idioms and sports metaphors opaque to ESL and international readers ("slam dunk", "boil the ocean", "circle back", "touch base") |
|
|
41
|
-
| `no-vague-cta` | Vague link and button text ("click here", "read more", "here", "learn more") |
|
|
42
|
-
| `no-directional-language` | Layout-dependent position instructions ("see above", "in the right sidebar", "as shown below") |
|
|
43
99
|
| `no-unexplained-abbreviation` | Acronyms used without a prior expansion in the same file |
|
|
44
|
-
| `no-
|
|
100
|
+
| `no-vague-cta` | Vague link and button text ("click here", "read more", "here", "learn more") |
|
|
45
101
|
| `no-vague-error-message` | Error messages that don't explain what went wrong ("An error occurred", "Something went wrong") |
|
|
46
|
-
| `no-ampersand-in-prose` | `&` in place of "and" in prose - announced inconsistently across AT vendors |
|
|
47
102
|
|
|
48
103
|
Rules are synthesised from 17 sources spanning W3C WAI, government plain language guides (US, UK, Australia, Canada), and disability language authorities (NCDJ, AP Stylebook, ADA National Network, APA Style, SIGACCESS). See [RULES-CONTENT.md](RULES-CONTENT.md) for full methodology and source citations.
|
|
49
104
|
|
|
50
|
-
|
|
105
|
+
- **New rule reference pages:** RULES.md is now an index. Full references split into:
|
|
106
|
+
- [RULES-MARKUP.md](RULES-MARKUP.md): ESLint markup rules
|
|
107
|
+
- [RULES-CSS.md](RULES-CSS.md): Stylelint CSS rules
|
|
108
|
+
- [RULES-CONTENT.md](RULES-CONTENT.md): content rules with sources and methodology
|
|
109
|
+
- **New entry point alias:** `@a11yfred/neighbor/stylelint` added as an explicit stylelint alias alongside the default export.
|
|
110
|
+
- **Additional rules:** `no-labelledby-missing-target`, `no-dynamic-content-without-live`, `form-field-multiple-labels`, `no-empty-table-header` added to core markup rules (all run on React, Vue, and Angular).
|
|
51
111
|
|
|
52
|
-
|
|
112
|
+
### Changed
|
|
53
113
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
114
|
+
- **Severity changes:** 10 rules moved from `warn` to `off` in the recommended config. They flag real problems but are too noisy for most codebases by default. All remain available to opt in individually:
|
|
115
|
+
- `no-application-role`, `no-grid-role`, `no-aria-roledescription`, `no-aria-readonly`, `no-tab-without-controls`, `no-href-hash`, `warn-role-alert`, `prefer-aria-disabled`, `no-target-blank-without-label`, `no-dialog-without-close`
|
|
116
|
+
- `no-tooltip-role-misuse` and `no-menu-role-on-nav` remain on as warns.
|
|
117
|
+
- **Extended rules:** `no-announce-in-render` now runs in Vue and Angular plugins (not just React). Safe contexts are tuned per framework: Vue recognizes `onMounted`, `watch`, `watchEffect`, `nextTick`; Angular recognizes `ngOnInit`, `ngAfterViewInit`, `ngOnChanges`, and class method event handlers.
|
|
57
118
|
|
|
58
|
-
###
|
|
59
|
-
|
|
60
|
-
`@a11yfred/neighbor/stylelint` added as an explicit stylelint alias alongside the default export.
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## 0.3.0 - 2026-05-12
|
|
65
|
-
|
|
66
|
-
### New rule
|
|
67
|
-
|
|
68
|
-
| Rule | What it catches |
|
|
69
|
-
| --- | --- |
|
|
70
|
-
| `neighbor/no-forced-colors-none` | `forced-color-adjust: none` inside `@media (forced-colors)` - actively opts out of Windows High Contrast Mode |
|
|
71
|
-
|
|
72
|
-
### Severity changes
|
|
73
|
-
|
|
74
|
-
10 rules moved from `warn` to `off` in the recommended config - they flag real problems but are too noisy for most codebases by default. All remain available to opt in individually:
|
|
75
|
-
|
|
76
|
-
`no-application-role`, `no-grid-role`, `no-aria-roledescription`, `no-aria-readonly`, `no-tab-without-controls`, `no-href-hash`, `warn-role-alert`, `prefer-aria-disabled`, `no-target-blank-without-label`, `no-dialog-without-close`
|
|
77
|
-
|
|
78
|
-
`no-tooltip-role-misuse` and `no-menu-role-on-nav` remain on as warns.
|
|
79
|
-
|
|
80
|
-
### Docs
|
|
119
|
+
### Documentation
|
|
81
120
|
|
|
82
121
|
- WCAG SC and HTML spec links added throughout README and RULES.md
|
|
83
122
|
- CONTRIBUTING.md, PR template, and issue templates added
|
|
84
123
|
- README table of contents added
|
|
124
|
+
- README now includes correct parser snippets for Vue and Angular, and separate setup sections for Remix 2 and Remix 3
|
|
85
125
|
- @ulam described as a JavaScript framework (not React-based)
|
|
86
126
|
|
|
87
127
|
---
|
|
88
128
|
|
|
89
|
-
## 0.
|
|
90
|
-
|
|
91
|
-
### New rules
|
|
92
|
-
|
|
93
|
-
| Rule | What it catches |
|
|
94
|
-
|---|---|
|
|
95
|
-
| `no-labelledby-missing-target` | `aria-labelledby`/`describedby`/`controls`/`owns`/`activedescendant` referencing an `id` that doesn't exist in the file |
|
|
96
|
-
| `no-dynamic-content-without-live` | `dangerouslySetInnerHTML` / `v-html` / `[innerHTML]` on an element outside a live region |
|
|
97
|
-
| `form-field-multiple-labels` | Multiple `<label for="…">` elements targeting the same input |
|
|
98
|
-
| `no-empty-table-header` | `<th>` or `role="columnheader"/"rowheader"` with no accessible text |
|
|
99
|
-
|
|
100
|
-
All four rules run on React, Vue, and Angular.
|
|
101
|
-
|
|
102
|
-
### Extended rules
|
|
103
|
-
|
|
104
|
-
**`no-announce-in-render`** now runs in the Vue and Angular plugins, not just React. Safe contexts are tuned per framework - Vue recognises `onMounted`, `watch`, `watchEffect`, `nextTick`; Angular recognises `ngOnInit`, `ngAfterViewInit`, `ngOnChanges`, and class method event handlers.
|
|
105
|
-
|
|
106
|
-
### Setup improvements
|
|
107
|
-
|
|
108
|
-
README now includes correct parser snippets for Vue and Angular, and separate setup sections for Remix 2 and Remix 3.
|
|
109
|
-
|
|
110
|
-
---
|
|
111
|
-
|
|
112
|
-
## 0.1.0 - 2026-04-30
|
|
129
|
+
## 0.1.0 - 2026-04-30
|
|
113
130
|
|
|
114
131
|
Initial release.
|
package/CONTRIBUTING.md
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
# Contributing to @a11yfred/neighbor
|
|
2
2
|
|
|
3
|
-
Neighbor is maintained by [@a11yfred](https://github.com/a11yfred).
|
|
3
|
+
Neighbor is maintained by [@a11yfred](https://github.com/a11yfred). We welcome help from the accessibility community: experts, screen reader users, spec readers, and anyone who sees something missing in other tools.
|
|
4
4
|
|
|
5
5
|
## What belongs here
|
|
6
6
|
|
|
7
|
-
A rule belongs in neighbor if it meets all three
|
|
7
|
+
A rule belongs in neighbor if it meets all three checks:
|
|
8
8
|
|
|
9
|
-
1. **
|
|
10
|
-
2. **Not
|
|
11
|
-
3. **Expert-backed
|
|
9
|
+
1. **Easy to find in code**: The linter can find the problem just by looking at the code, without needing a browser. Things like color contrast belong in `axe-core`.
|
|
10
|
+
2. **Not in other tools**: Plugins like `jsx-a11y` or `vuejs-accessibility` do not already check it.
|
|
11
|
+
3. **Expert-backed**: A rule must come from WCAG, ARIA specs, or accessibility experts.
|
|
12
12
|
|
|
13
|
-
If you
|
|
13
|
+
If you are not sure, open an issue before writing the rule. Just describe the idea and where it comes from to start a conversation.
|
|
14
14
|
|
|
15
|
-
## What
|
|
15
|
+
## What does not belong here
|
|
16
16
|
|
|
17
|
-
- Rules that
|
|
18
|
-
- Rules already in jsx-a11y
|
|
19
|
-
-
|
|
20
|
-
- Rules
|
|
17
|
+
- Rules that need a browser to run (like checking CSS layout).
|
|
18
|
+
- Rules already in the standard accessibility linter for your framework (e.g., `jsx-a11y`, `vuejs-accessibility`, `@angular-eslint/template`, or `lit-a11y`). Neighbor works with them, it does not replace them.
|
|
19
|
+
- Code style rules that do not affect accessibility.
|
|
20
|
+
- Rules that give too many false warnings on real projects (see rejected rules in [RULES.md](RULES.md)).
|
|
21
21
|
|
|
22
22
|
## Setup
|
|
23
23
|
|
|
@@ -27,7 +27,7 @@ cd neighbor
|
|
|
27
27
|
npm install
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
There is no build step. Rules are simple JavaScript files. You can edit them and run ESLint directly.
|
|
31
31
|
|
|
32
32
|
## How rules are structured
|
|
33
33
|
|
|
@@ -53,63 +53,63 @@ export function makeMyNewRule(h) {
|
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
The `h`
|
|
56
|
+
The `h` helper gives you a single way to check code across React, Vue, and Angular:
|
|
57
57
|
|
|
58
58
|
| Helper | Returns |
|
|
59
|
-
|
|
59
|
+
| --- | --- |
|
|
60
|
+
| `h.elementVisitor` | AST node type string for `create()` visitor key |
|
|
61
|
+
| `h.elementWithChildrenVisitor` | visitor key for rules that need child access |
|
|
62
|
+
| `h.getAncestors(node)` | iterable of ancestor element nodes, root-ward |
|
|
60
63
|
| `h.getAttr(node, name)` | attribute node or `null` |
|
|
61
64
|
| `h.getAttrStringValue(attr)` | string or `null` (null for dynamic expressions) |
|
|
65
|
+
| `h.getChildOpeningElements(node)` | iterable of direct child element nodes |
|
|
62
66
|
| `h.getElementName(node)` | lowercase tag name, or `null` for custom components |
|
|
63
|
-
| `h.
|
|
67
|
+
| `h.getInnerHtmlAttr(node)` | `dangerouslySetInnerHTML` / `v-html` / `[innerHTML]` node or `null` |
|
|
68
|
+
| `h.getParent(node)` | parent element node or `null` |
|
|
64
69
|
| `h.getRoleValue(node)` | role string or `null` |
|
|
65
|
-
| `h.hasAccessibleName(node)` | boolean
|
|
70
|
+
| `h.hasAccessibleName(node)` | boolean: checks `aria-label` / `aria-labelledby` |
|
|
71
|
+
| `h.hasAttr(node, name)` | boolean |
|
|
66
72
|
| `h.isInteractiveElement(node)` | boolean |
|
|
67
|
-
| `h.getParent(node)` | parent element node or `null` |
|
|
68
|
-
| `h.getAncestors(node)` | iterable of ancestor element nodes, root-ward |
|
|
69
|
-
| `h.getChildOpeningElements(node)` | iterable of direct child element nodes |
|
|
70
|
-
| `h.getInnerHtmlAttr(node)` | `dangerouslySetInnerHTML` / `v-html` / `[innerHTML]` node or `null` |
|
|
71
|
-
| `h.elementVisitor` | AST node type string for `create()` visitor key |
|
|
72
|
-
| `h.elementWithChildrenVisitor` | visitor key for rules that need child access |
|
|
73
73
|
|
|
74
|
-
**Angular
|
|
74
|
+
**Angular warning:** `getParent()` and `getAncestors()` return `null` in Angular. The parser does not link child nodes to parent nodes. If your rule needs to look at parent nodes, it should fail quietly (skip the check, do not throw an error).
|
|
75
75
|
|
|
76
|
-
After writing your
|
|
76
|
+
After writing your rule function:
|
|
77
77
|
|
|
78
|
-
1. Add it to `RULE_FACTORIES` at the bottom of `lib/rules.js
|
|
79
|
-
2. Add it to `buildRecommendedRules()`
|
|
80
|
-
3. If
|
|
78
|
+
1. Add it to `RULE_FACTORIES` at the bottom of `lib/rules.js`.
|
|
79
|
+
2. Add it to `buildRecommendedRules()` and set the severity (`'error'`, `'warn'`, or `'off'`).
|
|
80
|
+
3. If the rule is only for Vue or Angular, add it to `buildPortabilityRules()` instead.
|
|
81
81
|
|
|
82
|
-
Stylelint rules live in [`neighbor-stylelint.mjs`](neighbor-stylelint.mjs)
|
|
82
|
+
Stylelint rules live in [`neighbor-stylelint.mjs`](neighbor-stylelint.mjs). They use PostCSS. Look at the existing rules to see how they work.
|
|
83
83
|
|
|
84
84
|
## Severity guidance
|
|
85
85
|
|
|
86
86
|
| Severity | When to use |
|
|
87
|
-
|
|
88
|
-
| `error` |
|
|
89
|
-
| `warn` |
|
|
90
|
-
| `off` |
|
|
87
|
+
| --- | --- |
|
|
88
|
+
| `error` | This breaks screen readers or violates HTML rules. There is no good reason to do this. |
|
|
89
|
+
| `warn` | This is usually bad, but sometimes there is a good reason to do it. |
|
|
90
|
+
| `off` | This rule gives too many warnings on normal code to be turned on by default. Users can turn it on if they want. |
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
If you are not sure, start with `warn`. It is easier to change a `warn` to an `error` later.
|
|
93
93
|
|
|
94
94
|
## Commit style
|
|
95
95
|
|
|
96
|
-
```
|
|
96
|
+
```text
|
|
97
97
|
feat: add no-my-new-rule (short description)
|
|
98
98
|
fix: correct false positive in no-existing-rule
|
|
99
99
|
docs: update RULES.md for no-my-new-rule
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
You do not need to include issue ticket numbers in your commit messages.
|
|
103
103
|
|
|
104
104
|
## Opening a PR
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
Please use the PR template. Here are the most important things:
|
|
107
107
|
|
|
108
|
-
- **What problem does this
|
|
109
|
-
- **Why can
|
|
110
|
-
- **
|
|
111
|
-
- **Does it
|
|
108
|
+
- **What problem does this find?** Link to WCAG, ARIA specs, or an expert guide.
|
|
109
|
+
- **Why can axe-core not catch this?** If `axe-core` can catch it, the rule probably belongs there.
|
|
110
|
+
- **When will this give false warnings?** Be honest. We prefer to set a rule to `off` instead of rejecting your PR.
|
|
111
|
+
- **Does it fail quietly in Angular?** Remember that parent-walking does not work in Angular.
|
|
112
112
|
|
|
113
113
|
## Questions
|
|
114
114
|
|
|
115
|
-
Open an issue or
|
|
115
|
+
Open an issue or talk to us in the [Web A11y Slack](https://web-a11y.slack.com). The `#tools` channel is a great place to talk about rule ideas before you start writing code.
|