Skip to content

Commit

Permalink
fix(linter): allow SVG elements with role="img" (#3837)
Browse files Browse the repository at this point in the history
  • Loading branch information
togami2864 committed Sep 9, 2024
1 parent 0d347e4 commit b93a266
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 1 deletion.
17 changes: 17 additions & 0 deletions crates/biome_aria/src/roles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,23 @@ impl<'a> AriaRoles {
return false;
}

// Allow SVG elements with role="img" attribute
// This is recommended for accessibility purposes
// Example:
// ```
// <svg role="img" aria-label="Description of your SVG image"></svg>;
// ```
// For more information, see:
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/img_role#svg_and_roleimg
if element_name == "svg"
&& attributes
.as_ref()
.and_then(|a| a.get("role"))
.map_or(false, |values| values.iter().any(|x| x == "img"))
{
return false;
}

// SVG elements, by default, do not have interactive semantics.
// They are primarily used for graphics and visual rendering. While they can be made interactive with additional
// attributes and JavaScript, inherently they don't provide user interaction capabilities.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ impl Rule for NoInteractiveElementToNoninteractiveRole {
return None;
}

// A <svg> element can be given an "img" to make it non-interactive for a11y reasons.
if element_name.text_trimmed() == "svg" && role_attribute_value == "img" {
return None;
}

// A <canvas> element can be given an "img" to make it non-interactive for a11y reasons.
if element_name.text_trimmed() == "canvas" && role_attribute_value == "img" {
return None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ impl Rule for UseSemanticElements {
fn run(ctx: &RuleContext<Self>) -> Self::Signals {
let node = ctx.query();

let role_attribute = node.find_attribute_by_name("role").unwrap();
let role_attribute = node.find_attribute_by_name("role").ok().flatten();

if let Some(attr) = role_attribute {
// check is not interactive element
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ export const Component2 = () => (
hello world
</div>
);

export const C = <svg role="img" aria-label="Description of your SVG image">
</svg>;
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,7 @@ export const Component2 = () => (
</div>
);

export const C = <svg role="img" aria-label="Description of your SVG image">
</svg>;

```

0 comments on commit b93a266

Please sign in to comment.