Skip to content

fix(linter): no-redundant-roles false positives for <header>, <footer>, and <input>#22745

Open
12122J wants to merge 3 commits into
oxc-project:mainfrom
12122J:fix/no-redundant-roles-header-footer-input
Open

fix(linter): no-redundant-roles false positives for <header>, <footer>, and <input>#22745
12122J wants to merge 3 commits into
oxc-project:mainfrom
12122J:fix/no-redundant-roles-header-footer-input

Conversation

@12122J

@12122J 12122J commented May 26, 2026

Copy link
Copy Markdown

Fixes #22743

Root cause

Two separate issues caused false positives:

<header> and <footer>: Their implicit roles ("banner" / "contentinfo") are ancestor-dependent — they only apply when the element is not inside article, aside, main, nav, or section. The rule cannot determine the correct role without ancestor traversal, so it was always treating the role as redundant. This matches the same approach taken by eslint-plugin-jsx-a11y, which omits these elements for the same reason.

<input>: The static ELEMENT_ROLE_MAP lists all possible roles for <input> (combobox, checkbox, radio, textbox, etc.). The rule was accepting any of them as implicit, so <input role="combobox"> with no list attribute was flagged even though a plain text input's implicit role is textbox, not combobox — the combobox role only applies when a list attribute points to a <datalist> (HTML-AAM §3.5.77).

Fix

  • Skip <header> and <footer> in the rule entirely.
  • For <input>, compute the concrete implicit role from the element's actual type and list attributes instead of accepting every role from the static map.

Tests

  • Added <header role="banner"> and <footer role="contentinfo"> to the pass set (moved from fail).
  • Added <input role="combobox"> (no list) and <input role="combobox" type="text"> (no list) to the pass set.
  • Added four new fail cases covering <input> with roles that correctly match the element's attributes.
  • All existing pass/fail cases continue to behave identically.

AI disclosure

I used Claude Code to locate the relevant files and assist with writing the fix. The solution was reviewed and validated by running the test suite locally (cargo test --lib -p oxc_linter -- no_redundant_roles passes).

…>, and <input>

`<header>` and `<footer>` have ancestor-dependent implicit roles: they
are only "banner"/"contentinfo" when *not* inside article/aside/main/
nav/section. Without traversing ancestors we cannot know the correct
role, so we skip them entirely — matching eslint-plugin-jsx-a11y.

For `<input>`, the static element-role map listed all *possible* input
roles (combobox, checkbox, radio, etc.). The rule was treating any of
those as redundant, so `<input role="combobox">` without a `list`
attribute was wrongly flagged even though a plain text input's implicit
role is `textbox`, not `combobox`. The fix computes the concrete
implicit role from the element's actual `type` and `list` attributes
using the HTML-AAM mapping.

Fixes oxc-project#22743
@12122J 12122J requested a review from camc314 as a code owner May 26, 2026 18:45
@camc314 camc314 added the A-linter Area - Linter label May 27, 2026
@camc314 camc314 self-assigned this May 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

linter: jsx-a11y/no-redundant-roles incorrect implicit roles for <input> and <header> cause false positives

2 participants