Skip to content

feat(html/noPositiveTabindex): port noPositiveTabindex rule to HTML#8501

Merged
dyc3 merged 2 commits intobiomejs:nextfrom
tt-a1i:feat/html-no-positive-tabindex-next
Dec 18, 2025
Merged

feat(html/noPositiveTabindex): port noPositiveTabindex rule to HTML#8501
dyc3 merged 2 commits intobiomejs:nextfrom
tt-a1i:feat/html-no-positive-tabindex-next

Conversation

@tt-a1i
Copy link
Contributor

@tt-a1i tt-a1i commented Dec 18, 2025

Summary

Contributes to #8155

Ports the existing JSX noPositiveTabindex rule to HTML. This rule prevents the usage of positive integers on the tabindex attribute, which can disrupt natural keyboard navigation order.

Changes:

  • Added noPositiveTabindex rule for HTML in crates/biome_html_analyze/src/lint/a11y/
  • Added test cases for invalid and valid HTML
  • Includes unsafe fix to remove the tabindex attribute

Test plan

  • Added invalid.html with positive tabindex values (1, 5, 2, 10, 99)
  • Added valid.html with valid tabindex values (0, -1)
  • All tests pass

AI Assistance Disclosure

I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.

Port the existing JSX noPositiveTabindex rule to HTML. The rule prevents
the usage of positive integers on the tabindex attribute, which can disrupt
natural keyboard navigation order.

Contributes to biomejs#8155
@changeset-bot
Copy link

changeset-bot bot commented Dec 18, 2025

🦋 Changeset detected

Latest commit: c419b89

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 14 packages
Name Type
@biomejs/biome Minor
@biomejs/cli-win32-x64 Minor
@biomejs/cli-win32-arm64 Minor
@biomejs/cli-darwin-x64 Minor
@biomejs/cli-darwin-arm64 Minor
@biomejs/cli-linux-x64 Minor
@biomejs/cli-linux-arm64 Minor
@biomejs/cli-linux-x64-musl Minor
@biomejs/cli-linux-arm64-musl Minor
@biomejs/wasm-web Minor
@biomejs/wasm-bundler Minor
@biomejs/wasm-nodejs Minor
@biomejs/backend-jsonrpc Patch
@biomejs/js-api Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added A-Project Area: project A-Linter Area: linter L-HTML Language: HTML and super languages labels Dec 18, 2025
@codspeed-hq
Copy link

codspeed-hq bot commented Dec 18, 2025

CodSpeed Performance Report

Merging #8501 will not alter performance

Comparing tt-a1i:feat/html-no-positive-tabindex-next (c419b89) with next (c61892d)

Summary

✅ 1 untouched
⏩ 154 skipped1

Footnotes

  1. 154 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.

@tt-a1i tt-a1i marked this pull request as ready for review December 18, 2025 14:31
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 18, 2025

Walkthrough

This PR adds an HTML accessibility lint rule noPositiveTabindex that flags positive tabindex values, registers the rule in the A11y lint group, and provides diagnostics plus an automatic fix (removes the offending attribute). It also adds tests for valid and invalid cases and a changeset declaring a minor release.

Possibly related PRs

Suggested reviewers

  • ematipico

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarises the main change: porting the noPositiveTabindex rule from JSX to HTML, which matches the changeset content.
Description check ✅ Passed The description is well-related to the changeset, detailing the rule's purpose, implementation location, test cases, and approach — all directly corresponding to the changes made.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 28aab2a and c419b89.

📒 Files selected for processing (1)
  • .changeset/html-no-positive-tabindex.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .changeset/html-no-positive-tabindex.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: autofix
  • GitHub Check: Documentation
  • GitHub Check: Test (depot-windows-2022-16)
  • GitHub Check: Lint project (depot-windows-2022)
  • GitHub Check: Check Dependencies
  • GitHub Check: End-to-end tests
  • GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Test (depot-ubuntu-24.04-arm-16)
  • GitHub Check: Bench (biome_configuration)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
.changeset/html-no-positive-tabindex.md (1)

5-5: Consider adding a code example.

As per coding guidelines for changesets, rule additions should include a code example to help users understand what the rule detects.

🔎 Suggested enhancement:
-Added [`noPositiveTabindex`](https://biomejs.dev/linter/rules/no-positive-tabindex/) rule for HTML. This rule prevents the usage of positive integers on the `tabindex` attribute, which can disrupt natural keyboard navigation order.
+Added [`noPositiveTabindex`](https://biomejs.dev/linter/rules/no-positive-tabindex/) rule for HTML. This rule prevents the usage of positive integers on the `tabindex` attribute, which can disrupt natural keyboard navigation order.
+
+```html
+<div tabindex="1"></div>
+```
crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs (1)

52-55: Consider reducing visibility.

NoPositiveTabindexState appears to be used only within this module. You could tighten encapsulation with pub(crate) unless there's a convention requiring pub for rule state structs.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c61892d and 28aab2a.

⛔ Files ignored due to path filters (5)
  • crates/biome_configuration/src/analyzer/linter/rules.rs is excluded by !**/rules.rs and included by **
  • crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/invalid.html.snap is excluded by !**/*.snap and included by **
  • crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/valid.html.snap is excluded by !**/*.snap and included by **
  • packages/@biomejs/backend-jsonrpc/src/workspace.ts is excluded by !**/backend-jsonrpc/src/workspace.ts and included by **
  • packages/@biomejs/biome/configuration_schema.json is excluded by !**/configuration_schema.json and included by **
📒 Files selected for processing (5)
  • .changeset/html-no-positive-tabindex.md (1 hunks)
  • crates/biome_html_analyze/src/lint/a11y.rs (1 hunks)
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs (1 hunks)
  • crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/invalid.html (1 hunks)
  • crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/valid.html (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
crates/**/*.rs

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Update inline rustdoc documentation for rules, assists, and their options when adding new features or changing existing features in Rust crates

Files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
.changeset/*.md

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Write changesets that are concise (1-3 sentences), user-focused, use past tense for actions taken and present tense for Biome behavior, include code examples for rules, and end sentences with periods

Files:

  • .changeset/html-no-positive-tabindex.md
🧠 Learnings (24)
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/nursery/**/*.rs : New rules must be placed inside the `nursery` group as an incubation space exempt from semantic versioning, with promotion to appropriate groups done during minor/major releases

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRestricted` prefix for rules that report user-banned entities (e.g., `noRestrictedGlobals`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUndeclared` prefix for rules that report undefined entities (e.g., `noUndeclaredVariables`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnknown` prefix for rules that report mistyped entities in CSS (e.g., `noUnknownUnit`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnsafe` prefix for rules that report code leading to runtime failures (e.g., `noUnsafeOptionalChaining`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `declare_lint_rule!` macro must include metadata fields: `version` (set to 'next'), `name` (rule identifier), `language` (applicable language), `recommended` (boolean), and optional fields like `severity`, `fix_kind`, `sources`, `domains`, and `deprecated`

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Deprecate rules by adding a `deprecated` field to the `declare_lint_rule!` macro with a message explaining the reason for deprecation (e.g., 'Use the rule noAnotherVar')

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUnused` prefix for rules that report unused entities (e.g., `noUnusedVariables`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noRedundant` prefix for rules that report redundant code (e.g., `noRedundantUseStrict`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noEmpty` prefix for rules that report empty code (e.g., `noEmptyBlockStatements`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `use` prefix naming convention when the sole intention is to mandate a single concept (e.g., `useValidLang` to enforce valid HTML lang attribute values)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noMisleading` prefix for rules that report valid but potentially misleading code (e.g., `noMisleadingCharacterClass`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Rules should use the `no` prefix naming convention when the sole intention is to forbid a single concept (e.g., `noDebugger` to disallow debugger statements)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Framework-specific rules should be named using the `use` or `no` prefix followed by the framework name (e.g., `noVueReservedProps`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noUseless` prefix for rules that report unnecessary code that could be removed or simplified (e.g., `noUselessConstructor`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Set rule severity to `error` for correctness/security/a11y rules, `warn` for suspicious/performance rules, `info` for style/complexity rules, and `info` for actions

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noInvalid` prefix for rules that report runtime errors from mistyping (e.g., `noInvalidConstructorSuper`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Code actions must specify a `fix_kind` field in the `declare_lint_rule!` macro as either `FixKind::Safe` or `FixKind::Unsafe` to indicate whether fixes always preserve program behavior

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Lint rules must be implemented using the `Rule` trait with type parameters: `Query` (node type to analyze), `State` (information for signals), `Signals` (return type from run function), and `Options` (rule configuration)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `run` function of a lint rule should return `Option<Self::State>` or an iterable like `Vec<Self::State>` or `Box<[Self::State]>` to signal zero or more diagnostics

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : In rule documentation code blocks, mark invalid examples with the `expect_diagnostic` property and valid examples without it; each invalid example must emit exactly one diagnostic

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `diagnostic` function must return a `RuleDiagnostic` that defines the message reported to the user using the `markup!` macro

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : The `action` function must return a `JsRuleAction` (or equivalent language-specific action type) with category `ctx.action_category(ctx.category(), ctx.group())` and applicability from `ctx.metadata().applicability()`

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
📚 Learning: 2025-11-27T23:04:02.022Z
Learnt from: CR
Repo: biomejs/biome PR: 0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-11-27T23:04:02.022Z
Learning: Applies to crates/biome_analyze/**/*analyze/src/lint/**/*.rs : Use the `noConstant` prefix for rules that report computations always evaluated to the same value (e.g., `noConstantMathMinMaxClamp`)

Applied to files:

  • crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs
🧬 Code graph analysis (1)
crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs (2)
crates/biome_analyze/src/rule.rs (3)
  • sources (630-633)
  • same (249-254)
  • recommended (615-618)
crates/biome_html_syntax/src/attr_ext.rs (1)
  • string_value (9-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint project (depot-windows-2022)
🔇 Additional comments (8)
crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/valid.html (1)

1-7: Good test coverage for the valid cases.

The test file covers the essential valid scenarios: tabindex="0", tabindex="-1", and elements without the attribute.

Consider adding edge cases like tabindex="" or tabindex="abc" to document how the rule handles non-integer values (which are treated as valid per the implementation).

crates/biome_html_analyze/tests/specs/a11y/noPositiveTabindex/invalid.html (1)

1-6: Solid test coverage for invalid cases.

Good variety of positive tabindex values across different HTML element types. This ensures the rule correctly triggers diagnostics for the full range of invalid scenarios.

crates/biome_html_analyze/src/lint/a11y/no_positive_tabindex.rs (5)

10-50: Well-documented rule with proper metadata.

The rule declaration follows all conventions: version: "next", severity: Severity::Error for a11y rules, fix_kind: FixKind::Unsafe (appropriate since removing the attribute alters tab behaviour), and proper source attribution. The WCAG 2.4.3 reference is a nice touch.

Based on learnings, this implementation aligns with the required declare_lint_rule! metadata fields.


63-79: Clean implementation with proper early returns.

Good use of the ? operator for clean control flow. The logic correctly extracts the tabindex value and validates it.


81-99: Helpful diagnostic messages.

The primary message is clear, and the two notes provide excellent context about why positive tabindex values are problematic and what to use instead.


101-111: Fix implementation is correct.

The fix removes the attribute entirely, which aligns with the Unsafe designation — users should verify this doesn't break their intended tab order.


114-123: Sensible validation logic.

The approach of treating parse failures as valid (since browsers ignore non-integers) is pragmatic. The trim() handles whitespace nicely.

crates/biome_html_analyze/src/lint/a11y.rs (1)

9-9: Module correctly integrated via codegen—all aspects check out.

The file is properly generated via xtask/codegen, and the rule registration at line 9 and line 15 are both correct. The no_positive_tabindex module is alphabetically ordered, the rule is properly registered in the declare_lint_group! macro, and the rule implementation follows all guidelines: it uses the correct "no" prefix, has version set to "next", specifies severity as Error (appropriate for a11y rules), includes fix_kind: FixKind::Unsafe, provides documentation with proper HTML code-block tags, and references the source. No issues found.

Also applies to: 15–15

@dyc3 dyc3 mentioned this pull request Dec 18, 2025
32 tasks
Copy link
Contributor

@dyc3 dyc3 left a comment

Choose a reason for hiding this comment

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

Nice work!

@dyc3 dyc3 merged commit 8eb3f19 into biomejs:next Dec 18, 2025
15 checks passed
@github-actions github-actions bot mentioned this pull request Feb 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-Linter Area: linter A-Project Area: project L-HTML Language: HTML and super languages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants