diff --git a/crates/oxc_linter/src/rules/jsx_a11y/aria_proptypes.rs b/crates/oxc_linter/src/rules/jsx_a11y/aria_proptypes.rs index 2b6b61c1353be..bedd4f8d4327d 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/aria_proptypes.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/aria_proptypes.rs @@ -136,6 +136,13 @@ fn is_valid_value_for_aria_prop_type( matches!(value_string.as_str(), "true" | "false" | "mixed") } AriaPropType::String | AriaPropType::Id => { + // Template literals with expressions always produce strings at runtime + if let JSXAttributeValue::ExpressionContainer(container) = value + && let JSXExpression::TemplateLiteral(t) = &container.expression + && t.single_quasi().is_none() + { + return true; + } parse_aria_prop_value_as_string(value, false).is_some() } AriaPropType::Integer | AriaPropType::Number => { @@ -150,6 +157,15 @@ fn is_valid_value_for_aria_prop_type( } } AriaPropType::IdList => { + // Template literals with expressions always produce strings at runtime and are + // valid for ID list ARIA props (e.g., `${id}-label` or `${id}-label ${id}-help-text`). + if let JSXAttributeValue::ExpressionContainer(container) = value + && let JSXExpression::TemplateLiteral(t) = &container.expression + && t.single_quasi().is_none() + { + return true; + } + let Some(value_string) = parse_aria_prop_value_as_string(value, false) else { return false; }; @@ -364,6 +380,7 @@ fn test() { "
", "", "", + "", "", r#""#, "", @@ -375,6 +392,9 @@ fn test() { r#""#, "", "", + "", + "", + "", "", "", "", @@ -382,6 +402,7 @@ fn test() { r#""#, r#""#, "", + "", r#""#, r#""#, "", @@ -491,6 +512,15 @@ fn test() { "", "", "", + // Ensure that template literals with expressions are allowed for idlist aria props. + "", + "", + "", + "", + "", + "", + "", + "", ]; let fail = vec![ @@ -533,6 +563,12 @@ fn test() { r#""#, r#""#, r#""#, + // Fails because these should not allow boolean values or numbers. + "", + "", + "", + // Fails because this is a string, and so not interpolated. + r#""#, ]; Tester::new(AriaProptypes::NAME, AriaProptypes::PLUGIN, pass, fail).test_and_snapshot(); diff --git a/crates/oxc_linter/src/snapshots/jsx_a11y_aria_proptypes.snap b/crates/oxc_linter/src/snapshots/jsx_a11y_aria_proptypes.snap index 2a15dd7d0094f..3f807108258eb 100644 --- a/crates/oxc_linter/src/snapshots/jsx_a11y_aria_proptypes.snap +++ b/crates/oxc_linter/src/snapshots/jsx_a11y_aria_proptypes.snap @@ -312,3 +312,35 @@ source: crates/oxc_linter/src/tester.rs ╰──── help: The valid value for 'aria-relevant' is: a space-separated list of the following tokens: additions, all, removals, text. You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes + + ⚠ eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-labelledby'. + ╭─[aria_proptypes.tsx:1:6] + 1 │ + · ────────────────────── + ╰──── + help: The valid value for 'aria-labelledby' is: a space-separated list of element IDs. + You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes + + ⚠ eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-labelledby'. + ╭─[aria_proptypes.tsx:1:6] + 1 │ + · ─────────────────────── + ╰──── + help: The valid value for 'aria-labelledby' is: a space-separated list of element IDs. + You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes + + ⚠ eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-labelledby'. + ╭─[aria_proptypes.tsx:1:6] + 1 │ + · ───────────────────── + ╰──── + help: The valid value for 'aria-labelledby' is: a space-separated list of element IDs. + You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes + + ⚠ eslint-plugin-jsx-a11y(aria-proptypes): This is not a valid ARIA state and property value for 'aria-hidden'. + ╭─[aria_proptypes.tsx:1:6] + 1 │ + · ───────────────────── + ╰──── + help: The valid value for 'aria-hidden' is: 'true' or 'false'. + You can find a list of valid ARIA state and property values at https://www.w3.org/TR/wai-aria/#x6-7-definitions-of-states-and-properties-all-aria-attributes