diff --git a/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs b/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs index e4f75e076..f19f38710 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/html_has_lang.rs @@ -11,7 +11,12 @@ use oxc_diagnostics::{ use oxc_macros::declare_oxc_lint; use oxc_span::Span; -use crate::{context::LintContext, rule::Rule, utils::has_jsx_prop_lowercase, AstNode}; +use crate::{ + context::LintContext, + rule::Rule, + utils::{get_element_type, has_jsx_prop_lowercase}, + AstNode, +}; #[derive(Debug, Error, Diagnostic)] enum HtmlHasLangDiagnostic { @@ -64,15 +69,19 @@ impl Rule for HtmlHasLang { let AstKind::JSXOpeningElement(jsx_el) = node.kind() else { return; }; - let JSXElementName::Identifier(identifier) = &jsx_el.name else { + + let Some(element_type) = get_element_type(ctx, jsx_el) else { return; }; - let name = identifier.name.as_str(); - if name != "html" { + if element_type != "html" { return; } + let JSXElementName::Identifier(identifier) = &jsx_el.name else { + return; + }; + has_jsx_prop_lowercase(jsx_el, "lang").map_or_else( || ctx.diagnostic(HtmlHasLangDiagnostic::MissingLangProp(identifier.span)), |lang_prop| { @@ -99,25 +108,35 @@ fn is_valid_lang_prop(item: &JSXAttributeItem) -> bool { fn test() { use crate::tester::Tester; + fn settings() -> serde_json::Value { + serde_json::json!({ + "jsx-a11y": { + "components": { + "HTMLTop": "html", + } + } + }) + } + let pass = vec![ - (r"
;", None), - (r#""#, None), - (r#""#, None), - (r";", None), - (r";", None), - (r";", None), - // TODO: When polymorphic components are supported - // (r#""#, None), + (r"
;", None, None), + (r#""#, None, None), + (r#""#, None, None), + (r";", None, None), + (r";", None, None), + (r";", None, None), + ("", None, Some(settings())), ]; let fail = vec![ - (r";", None), - (r";", None), - (r";", None), - (r#";"#, None), - // TODO: When polymorphic components are supported - // (r";", None), + (r";", None, None), + (r";", None, None), + (r";", None, None), + (r#";"#, None, None), + ("", None, Some(settings())), ]; - Tester::new(HtmlHasLang::NAME, pass, fail).with_jsx_a11y_plugin(true).test_and_snapshot(); + Tester::new_with_settings(HtmlHasLang::NAME, pass, fail) + .with_jsx_a11y_plugin(true) + .test_and_snapshot(); } diff --git a/crates/oxc_linter/src/snapshots/html_has_lang.snap b/crates/oxc_linter/src/snapshots/html_has_lang.snap index 71f8eec71..91fa0c620 100644 --- a/crates/oxc_linter/src/snapshots/html_has_lang.snap +++ b/crates/oxc_linter/src/snapshots/html_has_lang.snap @@ -1,5 +1,6 @@ --- source: crates/oxc_linter/src/tester.rs +assertion_line: 144 expression: html_has_lang --- ⚠ eslint-plugin-jsx-a11y(html-has-lang): Missing lang attribute. @@ -30,4 +31,11 @@ expression: html_has_lang ╰──── help: Must have meaningful value for `lang` prop. + ⚠ eslint-plugin-jsx-a11y(html-has-lang): Missing lang attribute. + ╭─[html_has_lang.tsx:1:1] + 1 │ + · ─────── + ╰──── + help: Add a lang attribute to the html element whose value represents the primary language of document. +