diff --git a/.changeset/port-no-redundant-roles-html.md b/.changeset/port-no-redundant-roles-html.md new file mode 100644 index 000000000000..66f7717a8745 --- /dev/null +++ b/.changeset/port-no-redundant-roles-html.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": minor +--- + +Ported [`noRedundantRoles`](https://biomejs.dev/linter/rules/no-redundant-roles/) a11y lint rule to HTML, Vue, Svelte, and Astro files. diff --git a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs index 19098c2ea68f..60e8e3eb8067 100644 --- a/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs +++ b/crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs @@ -249,6 +249,14 @@ pub(crate) fn migrate_eslint_any_rule( .get_or_insert(Default::default()); rule.set_level(rule.level().max(rule_severity.into())); } + "@html-eslint/no-redundant-role" => { + let group = rules.a11y.get_or_insert_with(Default::default); + let rule = group + .unwrap_group_as_mut() + .no_redundant_roles + .get_or_insert(Default::default()); + rule.set_level(rule.level().max(rule_severity.into())); + } "@html-eslint/require-button-type" => { let group = rules.a11y.get_or_insert_with(Default::default); let rule = group diff --git a/crates/biome_html_analyze/src/lint/a11y/no_redundant_roles.rs b/crates/biome_html_analyze/src/lint/a11y/no_redundant_roles.rs new file mode 100644 index 000000000000..3952a03d8570 --- /dev/null +++ b/crates/biome_html_analyze/src/lint/a11y/no_redundant_roles.rs @@ -0,0 +1,360 @@ +use biome_analyze::{ + Ast, FixKind, Rule, RuleDiagnostic, RuleSource, context::RuleContext, declare_lint_rule, +}; +use biome_aria_metadata::AriaRole; +use biome_console::markup; +use biome_diagnostics::Severity; +use biome_html_syntax::{AnyHtmlElement, HtmlFileSource}; +use biome_rowan::{AstNode, AstNodeList, BatchMutationExt, Text, TextRange, TokenText}; +use biome_rule_options::no_redundant_roles::NoRedundantRolesOptions; +use biome_string_case::StrLikeExtension; + +use crate::HtmlRuleAction; + +declare_lint_rule! { + /// Enforce explicit `role` property is not the same as implicit/default role property on an element. + /// + /// ## Examples + /// + /// ### Invalid + /// + /// ```html,expect_diagnostic + /// + /// ``` + /// + /// ```html,expect_diagnostic + /// + /// ``` + /// + /// ```html,expect_diagnostic + ///