Skip to content

feat(linter): extends no-redundant-roles and prefer-tag-over-role support roles#22069

Merged
camchenry merged 2 commits into
oxc-project:mainfrom
mehm8128:feat/extends-two-a11y-rules-creating-element-role-mapping
May 7, 2026
Merged

feat(linter): extends no-redundant-roles and prefer-tag-over-role support roles#22069
camchenry merged 2 commits into
oxc-project:mainfrom
mehm8128:feat/extends-two-a11y-rules-creating-element-role-mapping

Conversation

@mehm8128

@mehm8128 mehm8128 commented May 2, 2026

Copy link
Copy Markdown
Contributor

related to #21910
continued from #21933

There are still some missing roles after the previous PR and I also found no-redundant-roles rule has missing roles.
So I defined complete element-to-role mapping referencing html-aria document and use it for no-redundant-roles and prefer-tag-over-role

@mehm8128
mehm8128 requested a review from camc314 as a code owner May 2, 2026 08:52
@mehm8128 mehm8128 changed the title feat(linter): extends no-redundant-roles and prefer-tag-over-role feat(linter): extends no-redundant-roles and prefer-tag-over-role support roles May 2, 2026
@camc314 camc314 added the A-linter Area - Linter label May 2, 2026
@codspeed-hq

codspeed-hq Bot commented May 2, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 47 skipped benchmarks1


Comparing mehm8128:feat/extends-two-a11y-rules-creating-element-role-mapping (c98edf9) with main (bc1408c)

Open in CodSpeed

Footnotes

  1. 47 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Comment thread crates/oxc_linter/src/utils/react.rs Outdated
@camchenry camchenry self-assigned this May 5, 2026

@camchenry camchenry left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this makes sense to me. I appreciate the links to the specification, that is helpful to verify the accuracy of these changes.

@camchenry camchenry added the 0-merge Merge with Graphite Merge Queue label May 7, 2026
@graphite-app

graphite-app Bot commented May 7, 2026

Copy link
Copy Markdown
Contributor

Merge activity

  • May 7, 2:56 AM UTC: @mehm8128 we removed the merge queue label because we could not find a Graphite account associated with your GitHub profile.

You must have a Graphite account in order to use the merge queue. Create an account and try again using this link

@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label May 7, 2026
@camchenry
camchenry merged commit 60bed4a into oxc-project:main May 7, 2026
27 checks passed
camc314 added a commit that referenced this pull request May 11, 2026
# Oxlint
### 💥 BREAKING CHANGES

- 00ce512 oxlint/lsp: [**BREAKING**] Don't fix suggestions on fixAll
code actions & command (#22195) (Sysix)

### 🚀 Features

- 0eeceaf linter/no-unused-vars: Rename parameter with initializer
(#22308) (camc314)
- fa0232b linter/no-unused-vars: Add param rename suggestion (#22285)
(Ryota Misumi)
- ae59305 linter/promise/no-promise-in-callback: Add
`exemptDeclarations` option (#22275) (Mikhail Baev)
- 60bed4a linter: Extends `no-redundant-roles` and
`prefer-tag-over-role` support roles (#22069) (mehm8128)
- 545c80f linter/eslint: Implement `prefer-regex-literals` rule (#22192)
(Mikhail Baev)
- cf86d7a linter: Bulk suppression (#19328) (Said Atrahouch)
- 23abd22 linter/jsx-a11y: Implement
no-noninteractive-element-to-interactive-role (#21264) (Pedro Tainha)
- fbb8f22 linter: Support `ignores` in overrides (#22148) (camc314)
- 5a4414d oxlint/lsp: Support `rulesCustomization` lsp option (#21858)
(Sysix)

### 🐛 Bug Fixes

- 610f4c7 linter/no-unused-vars: Avoid renaming captured vars (#22310)
(camc314)
- 6b50f23 oxlint/cli: Load root config by searching up parent
directories (#22272) (Sysix)
- 31a5de7 linter: Rename override `ignores` to `excludeFiles` (#22283)
(camc314)
- 26d5d7b linter: Add missing vitest/valid-describe-callback
functionality (#22279) (camchenry)
- 784530f linter: `valid-title`: detect `String.raw` strings (#22271)
(Sysix)
- 080d90e linter: Move `no-debugger` fix to suggestion (#22256) (Sysix)
- 25b7017 linter: Undocument override `ignores` option (#22213)
(camc314)
- 7bb00dd linter: Fix role-has-required-aria-props (#22097) (mehm8128)
- d25279e linter/disable-directives: Improve parsing of names,
descriptions (#22184) (camc314)
- a59e447 linter/disable-directives: Ignore invalid enable suffixes
(#22179) (camc314)
- aafef0f ci: Disable bulk supression test on big endian (#22175)
(camc314)
- 281daec linter/vue/define-props-destructuring: Add
`only-when-assigned` config opt (#22142) (camc314)
- 46ab679 linter/plugins: Trim leading newline for partial sources
(#20928) (bab)
- 29ff6d9 linter: Update docs for no_alias_methods rule to be
Vitest-specific and add toThrowError alias (#22129) (camchenry)

### ⚡ Performance

- 9414bee linter/role-has-required-aria-props: Avoid intermediate vec
(#22212) (camc314)
- 3883ea3 linter/no-useless-escape: Drop unnecessary Vec collect
(#22171) (connorshea)
- 42c3029 linter/check-property-names: Replace split-collect-pop-join
with rfind (#22172) (connorshea)
- 9551d53 linter: Remove unnecessary Vec collect in CFG edge traversal
(#22167) (connorshea)
- 26fa2fc linter/aria-role: Remove unnecessary string allocations in run
method (#22168) (connorshea)
- c9ce045 linter/getter-return: Remove unnecessary Vec collect in CFG
edge traversal (#22166) (connorshea)
- 72bd846 linter/no-this-in-sfc: Reorder cheap name check, avoid String
allocation (#22164) (connorshea)

### 📚 Documentation

- 4da212a linter/no-unused-vars: Add docs to
`rename_unused_function_parameter` (#22311) (camc314)
- 27c4628 linter/forbid-dom-props: Escape jsx examples in lint rule docs
(#22254) (4MBL)
- 3f81147 linter: Improve the `react/jsx-key` rule docs. (#22162)
(connorshea)
- 07f03cc linter/consistent-return: Add note about `noImplicitReturns`
coverage (#22156) (camc314)
- 7c1e049 oxlint/lsp: Improve autogenerated lsp docs (#22154) (Sysix)
- 87b3e38 linter: Update docs to be vitest-specific for
consistent-test-it (#22128) (camchenry)
# Oxfmt
### 💥 BREAKING CHANGES

- 5c6c390 oxfmt: [**BREAKING**] Respect more git ignore options, align
with Oxlint (#22210) (leaysgur)

### 🚀 Features

- 6e8e818 oxfmt: Experimental .svelte support (#21700) (leaysgur)

### 🐛 Bug Fixes

- e2a20b6 formatter: Add space after commas in import attributes
(#22274) (Leonabcd123)

### ⚡ Performance

- b756682 oxfmt: Optimize nested config prescan (#22232) (Jovi De
Croock)
- f14e81e formatter/sort_imports: Skip sort for single import runs
(#22204) (leaysgur)
- 32255b1 formatter: Process `ImportDeclaration`s in a run (#22079)
(overlookmotel)

### 📚 Documentation

- 4da6f4c formatter: Correct comment (#22217) (overlookmotel)
- ef3507d formatter/sort_imports: Refresh docs (#22203) (leaysgur)

Co-authored-by: Cameron <[email protected]>
jbabin91 added a commit to oakoss/finance-tracker that referenced this pull request May 21, 2026
oxlint 1.64 (via oxc-project/oxc#22069) regressed `jsx-a11y/no-redundant-roles`: the rule now checks the explicit role against the SET of all possible implicit roles for an element, rather than the actual implicit role given the element's attributes. This produces false positives on spec-correct ARIA 1.2 patterns like `<input role="combobox" aria-expanded>` (input's implicit role is `textbox`, not `combobox`, unless the `list` attribute is set).

Disable the rule in `.oxlintrc.json` and re-enable it via `eslint-plugin-jsx-a11y` in `eslint.config.js`. The upstream package (6.10.2) implements the rule correctly per HTML AAM — verified by direct Linter API tests:

- `<input role="textbox" />` -> flagged (correct redundancy)
- `<input role="combobox" aria-expanded>` -> not flagged
- `<nav role="navigation">` -> exempted by the rule's default

The eslint config block sits after `oxlint.buildFromOxlintConfigFile(...)` so it wins the merge; `eslint --print-config` confirms the rule resolves to error. `// @ts-expect-error` on the import because eslint-plugin-jsx-a11y ships no type declarations.

Three code fixes the now-correctly-running rule surfaces:

- `src/components/ui/input-group.tsx`: drop `role="group"` from the `<fieldset>` wrapper. fieldset's implicit role is `group` per HTML AAM. No consumer relies on the explicit role; existing e2e selectors and the `data-slot="input-group"` targeting path are unaffected.
- `src/modules/rules/components/payee-aliases-tab.tsx`: drop `role="listitem"` from `<li>`. Same reasoning; `e2e/app/rules.test.ts:343` uses `getByRole('listitem', { name })` which still matches via the implicit role plus the existing `aria-label`.
- `src/hooks/use-hydrated.test.ts`: hoist the `Probe` SSR-render helper out of the `it()` callback to satisfy `unicorn/consistent-function-scoping` (it closes over no parent-scope variables).

oxlint stays pinned at 1.63.0 in this commit; the follow-up will bump it once `jsx-a11y/control-has-associated-label` errors (a separate 1.65 regression surfacing ~25 missing aria-label additions) are addressed.
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.

3 participants