Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-use-semantic-elements-base-concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#9245](https://github.com/biomejs/biome/issues/9245): the [`useSemanticElements`](https://biomejs.dev/linter/rules/use-semantic-elements/) rule no longer suggests `<output>` for `role="status"` and `role="alert"`. The `<output>` element is only a `relatedConcept` of these roles, not a direct semantic equivalent. These roles are now excluded from suggestions, aligning with the intended behavior of the upstream `prefer-tag-over-role` rule.
11 changes: 10 additions & 1 deletion crates/biome_js_analyze/src/lint/a11y/use_semantic_elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ declare_lint_rule! {
/// <>
/// <input type="checkbox">label</input>
/// <hr/>
/// <div role="status"></div>
/// </>;
/// ```
///
Expand Down Expand Up @@ -90,7 +91,15 @@ impl Rule for UseSemanticElements {
// - option: <option> in browsers have divergent/unexpected behavior, with Safari hiding elements by default.
// - listbox: <datalist> isn’t always correct for all listbox uses
// See https://www.w3.org/WAI/ARIA/apg/patterns/combobox/. In most examples, roles are explicit
if role_value == "combobox" || role_value == "listbox" || role_value == "option" {
// - status: <output> is only a relatedConcept, not a baseConcept of the status role.
// Using <output> for status is misleading (see #9245, eslint-plugin-jsx-a11y#920)
// - alert: <output> is only a relatedConcept, same issue as status
if role_value == "combobox"
|| role_value == "listbox"
|| role_value == "option"
|| role_value == "status"
|| role_value == "alert"
{
return None;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
<div role="paragraph" ></div>
<div role="complementary" ></div>
<div role="blockquote" ></div>
<div role="status" ></div>
<div role="contentinfo" ></div>
<div role="region" ></div>
</>
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ expression: invalid.jsx
<div role="paragraph" ></div>
<div role="complementary" ></div>
<div role="blockquote" ></div>
<div role="status" ></div>
<div role="contentinfo" ></div>
<div role="region" ></div>
</>
Expand Down Expand Up @@ -608,7 +607,7 @@ invalid.jsx:37:10 lint/a11y/useSemanticElements ━━━━━━━━━━
> 37 │ <div role="complementary" ></div>
│ ^^^^^^^^^^^^^^^^^^^^
38 │ <div role="blockquote" ></div>
39 │ <div role="status" ></div>
39 │ <div role="contentinfo" ></div>

i For examples and more information, see WAI-ARIA Roles

Expand All @@ -625,8 +624,8 @@ invalid.jsx:38:10 lint/a11y/useSemanticElements ━━━━━━━━━━
37 │ <div role="complementary" ></div>
> 38 │ <div role="blockquote" ></div>
│ ^^^^^^^^^^^^^^^^^
39 │ <div role="status" ></div>
40 │ <div role="contentinfo" ></div>
39 │ <div role="contentinfo" ></div>
40 │ <div role="region" ></div>

i For examples and more information, see WAI-ARIA Roles

Expand All @@ -636,51 +635,33 @@ invalid.jsx:38:10 lint/a11y/useSemanticElements ━━━━━━━━━━
```
invalid.jsx:39:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<output>

37 │ <div role="complementary" ></div>
38 │ <div role="blockquote" ></div>
> 39 │ <div role="status" ></div>
│ ^^^^^^^^^^^^^
40 │ <div role="contentinfo" ></div>
41 │ <div role="region" ></div>

i For examples and more information, see WAI-ARIA Roles


```

```
invalid.jsx:40:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<footer>

37 │ <div role="complementary" ></div>
38 │ <div role="blockquote" ></div>
39 │ <div role="status" ></div>
> 40 │ <div role="contentinfo" ></div>
> 39 │ <div role="contentinfo" ></div>
│ ^^^^^^^^^^^^^^^^^^
41 │ <div role="region" ></div>
42 │ </>
40 │ <div role="region" ></div>
41 │ </>

i For examples and more information, see WAI-ARIA Roles


```

```
invalid.jsx:41:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid.jsx:40:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<section>

39 │ <div role="status" ></div>
40 │ <div role="contentinfo" ></div>
> 41 │ <div role="region" ></div>
38 │ <div role="blockquote" ></div>
39 │ <div role="contentinfo" ></div>
> 40 │ <div role="region" ></div>
│ ^^^^^^^^^^^^^
42 │ </>
43
41 │ </>
42

i For examples and more information, see WAI-ARIA Roles

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
<div role="paragraph" />
<div role="complementary" />
<div role="blockquote" />
<div role="status" />
<div role="contentinfo" />
<div role="region" />
</>
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ expression: invalid_self_closing.jsx
<div role="paragraph" />
<div role="complementary" />
<div role="blockquote" />
<div role="status" />
<div role="contentinfo" />
<div role="region" />
</>
Expand Down Expand Up @@ -608,7 +607,7 @@ invalid_self_closing.jsx:37:10 lint/a11y/useSemanticElements ━━━━━━
> 37 │ <div role="complementary" />
│ ^^^^^^^^^^^^^^^^^^^^
38 │ <div role="blockquote" />
39 │ <div role="status" />
39 │ <div role="contentinfo" />

i For examples and more information, see WAI-ARIA Roles

Expand All @@ -625,8 +624,8 @@ invalid_self_closing.jsx:38:10 lint/a11y/useSemanticElements ━━━━━━
37 │ <div role="complementary" />
> 38 │ <div role="blockquote" />
│ ^^^^^^^^^^^^^^^^^
39 │ <div role="status" />
40 │ <div role="contentinfo" />
39 │ <div role="contentinfo" />
40 │ <div role="region" />

i For examples and more information, see WAI-ARIA Roles

Expand All @@ -636,51 +635,33 @@ invalid_self_closing.jsx:38:10 lint/a11y/useSemanticElements ━━━━━━
```
invalid_self_closing.jsx:39:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<output>

37 │ <div role="complementary" />
38 │ <div role="blockquote" />
> 39 │ <div role="status" />
│ ^^^^^^^^^^^^^
40 │ <div role="contentinfo" />
41 │ <div role="region" />

i For examples and more information, see WAI-ARIA Roles


```

```
invalid_self_closing.jsx:40:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<footer>

37 │ <div role="complementary" />
38 │ <div role="blockquote" />
39 │ <div role="status" />
> 40 │ <div role="contentinfo" />
> 39 │ <div role="contentinfo" />
│ ^^^^^^^^^^^^^^^^^^
41 │ <div role="region" />
42 │ </>
40 │ <div role="region" />
41 │ </>

i For examples and more information, see WAI-ARIA Roles


```

```
invalid_self_closing.jsx:41:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
invalid_self_closing.jsx:40:10 lint/a11y/useSemanticElements ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× The elements with this role can be changed to the following elements:
<section>

39 │ <div role="status" />
40 │ <div role="contentinfo" />
> 41 │ <div role="region" />
38 │ <div role="blockquote" />
39 │ <div role="contentinfo" />
> 40 │ <div role="region" />
│ ^^^^^^^^^^^^^
42 │ </>
43
41 │ </>
42

i For examples and more information, see WAI-ARIA Roles

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,8 @@ export const Component2 = () => (
{children}
</Card>
</>

/* status role should not generate diagnostics (see #9245) */
<>
<div role="status"></div>
</>
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ export const Component2 = () => (
</Card>
</>

/* status role should not generate diagnostics (see #9245) */
<>
<div role="status"></div>
</>

```

_Note: The parser emitted 4 diagnostics which are not shown here._