Repository: biomejs/biome (language: rust)

Issue:
💅 `noLabelWithoutControl` should allow labeling `button` tags
### Environment information

```bash
biome: The term 'biome' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
```


### Rule name

noLabelWithoutControl

### Playground link

https://biomejs.dev/playground/?code=ZQB4AHAAbwByAHQAIABjAG8AbgBzAHQAIABNAGUAbgB1ACAAPQAgACgAKQAgAD0APgAgAHsACgAgACAALwAvACAAYwBvAG4AcwB0ACAAaQBzAEgAeQBkAHIAYQB0AGUAZAAgAD0AIAB1AHMAZQBIAHkAZAByAGEAdABpAG8AbgBDAG8AbgB0AGUAeAB0ACgAKQA7AAoAIAAgAGMAbwBuAHMAdAAgAGkAcwBEAGUAcwBrAHQAbwBwACAAPQAgAHUAcwBlAE0AZQBkAGkAYQBRAHUAZQByAHkAKAAnACgAbQBpAG4ALQB3AGkAZAB0AGgAOgAgADEANAA0ADAAcAB4ACkAJwApADsACgAgACAAYwBvAG4AcwB0ACAAWwBpAHMATwBwAGUAbgBNAGUAbgB1ACwAIABzAGUAdABJAHMATwBwAGUAbgBNAGUAbgB1AF0AIAA9ACAAdQBzAGUAUQB1AGUAcgB5AFMAdABhAHQAZQAoAAoAIAAgACAAIAAnAGkAcwBPAHAAZQBuAE0AZQBuAHUAJwAsAAoAIAAgACAAIABwAGEAcgBzAGUAQQBzAEIAbwBvAGwAZQBhAG4ALgB3AGkAdABoAEQAZQBmAGEAdQBsAHQAKABmAGEAbABzAGUAKQAsAAoAIAAgACkAOwAKAAoAIAAgAGMAbwBuAHMAdAAgAGMAbABvAHMAZQBNAGUAbgB1ACAAPQAgAHUAcwBlAEMAYQBsAGwAYgBhAGMAawAoACgAKQAgAD0APgAgAHMAZQB0AEkAcwBPAHAAZQBuAE0AZQBuAHUAKABmAGEAbABzAGUAKQAsACAAWwBzAGUAdABJAHMATwBwAGUAbgBNAGUAbgB1AF0AKQA7AAoACgAgACAALwAvACAAZABpAHMAYQBiAGwAZQAgAHMAYwByAG8AbABsAGkAbgBnAAoAIAAgAHUAcwBlAEUAZgBmAGUAYwB0ACgAKAApACAAPQA%2BACAAewAKACAAIAAgACAAZABvAGMAdQBtAGUAbgB0AC4AYgBvAGQAeQAuAHMAdAB5AGwAZQAuAG8AdgBlAHIAZgBsAG8AdwBZACAAPQAgAGkAcwBPAHAAZQBuAE0AZQBuAHUAIAA%2FACAAJwBoAGkAZABkAGUAbgAnACAAOgAgACcAYQB1AHQAbwAnADsACgAgACAAfQAsACAAWwBpAHMATwBwAGUAbgBNAGUAbgB1AF0AKQA7AAoACgAgACAALwAvACAAYwBvAG4AcwB0ACAAaQBzAEkAbgBlAHIAdAAgAD0AIABpAHMASAB5AGQAcgBhAHQAZQBkACAAPwAgACgAaQBzAEQAZQBzAGsAdABvAHAAIAA%2FACAAZgBhAGwAcwBlACAAOgAgACEAaQBzAE8AcABlAG4ATQBlAG4AdQApACAAOgAgAGYAYQBsAHMAZQA7AAoAIAAgAGMAbwBuAHMAdAAgAGkAcwBJAG4AZQByAHQAIAA9ACAAaQBzAEQAZQBzAGsAdABvAHAAIAA%2FACAAZgBhAGwAcwBlACAAOgAgACEAaQBzAE8AcABlAG4ATQBlAG4AdQA7AAoACgAgACAAcgBlAHQAdQByAG4AIAAoAAoAIAAgACAAIAA8AD4ACgAgACAAIAAgACAAIAA8AEEAYwB0AGkAbwBuAAoAIAAgACAAIAAgACAAIAAgAGMAbABhAHMAcwBOAGEAbQBlAD0AIgBmAGwAZQB4ACAAaQB0AGUAbQBzAC0AYwBlAG4AdABlAHIAIABqAHUAcwB0AGkAZgB5AC0AYwBlAG4AdABlAHIAIAByAG8AdQBuAGQAZQBkAC0AWwA2ADIAcAB4AF0AIABwAC0AMQAuADUAIAB0AGUAeAB0AC0AMgB4AGwAIAB0AGUAeAB0AC0AYgBsAGEAYwBrACAAdAByAGEAbgBzAGkAdABpAG8AbgAtAGMAbwBsAG8AcgBzACAAaABvAHYAZQByADoAYgBnAC0AZwBhAGwAbABlAHIAeQAgAG0AZAA6AGgAaQBkAGQAZQBuACIACgAgACAAIAAgACAAIAAgACAAYQByAGkAYQAtAGwAYQBiAGUAbAA9ACIAbwBwAGUAbgAgAE0AZQBuAHUAIgAKACAAIAAgACAAIAAgACAAIABhAHIAaQBhAC0AaABhAHMAcABvAHAAdQBwAD0AIgBkAGkAYQBsAG8AZwAiAAoAIAAgACAAIAAgACAAIAAgAG8AbgBDAGwAaQBjAGsAPQB7ACgAKQAgAD0APgAgAHMAZQB0AEkAcwBPAHAAZQBuAE0AZQBuAHUAKAB0AHIAdQBlACkAfQAKACAAIAAgACAAIAAgAD4ACgAgACAAIAAgACAAIAAgACAAPABJAGMAbwBuACAAbgBhAG0AZQA9ACIAbQBlAG4AdQAiACAAYwBsAGEAcwBzAE4AYQBtAGUAPQAiAHMAaQB6AGUALQA2ACIAIAAvAD4ACgAgACAAIAAgACAAIAA8AC8AQQBjAHQAaQBvAG4APgAKACAAIAAgACAAIAAgADwAaQBuAHAAdQB0AAoAIAAgACAAIAAgACAAIAAgAGMAaABlAGMAawBlAGQAPQB7AGkAcwBPAHAAZQBuAE0AZQBuAHUAfQAKACAAIAAgACAAIAAgACAAIABvAG4AQwBoAGEAbgBnAGUAPQB7ACgAZQApACAAPQA%2BACAAcwBlAHQASQBzAE8AcABlAG4ATQBlAG4AdQAoAGUALgB0AGEAcgBnAGUAdAAuAGMAaABlAGMAawBlAGQAKQB9AAoAIAAgACAAIAAgACAAIAAgAGMAbABhAHMAcwBOAGEAbQBlAD0AIgBwAGUAZQByACAAaABpAGQAZABlAG4AIgAKACAAIAAgACAAIAAgACAAIAB0AHkAcABlAD0AIgBjAGgAZQBjAGsAYgBvAHgAIgAKACAAIAAgACAAIAAgACAAIABpAGQAPQAiAGIAdQByAGcAZQByACIACgAgACAAIAAgACAAIAAvAD4ACgAgACAAIAAgACAAIAA8AGQAaQB2ACAAYwBsAGEAcwBzAE4AYQBtAGUAPQAiAGEAYgBzAG8AbAB1AHQAZQAgAGwAZQBmAHQALQAwACAAdABvAHAALQAwACAAegAtADUAMAAgAGgALQBzAGMAcgBlAGUAbgAgAHcALQBmAHUAbABsACAALQB0AHIAYQBuAHMAbABhAHQAZQAtAHkALQBmAHUAbABsACAAcABlAGUAcgAtAGMAaABlAGMAawBlAGQAOgAtAHQAcgBhAG4AcwBsAGEAdABlAC0AeQAtADAAIABtAGQAOgBzAHQAYQB0AGkAYwAgAG0AZAA6AHMAaQB6AGUALQBhAHUAdABvACAAbQBkADoALQB0AHIAYQBuAHMAbABhAHQAZQAtAHkALQAwACAAcABlAGUAcgAtAGMAaABlAGMAawBlAGQAOgBbACYAXwBkAGkAdgBdADoALQB0AHIAYQBuAHMAbABhAHQAZQAtAHkALQAwACIAPgAKACAAIAAgACAAIAAgACAAIAA8AGQAaQB2ACAAYwBsAGEAcwBzAE4AYQBtAGUAPQAiAGEAYgBzAG8AbAB1AHQAZQAgAGwAZQBmAHQALQAwACAAdABvAHAALQAwACAAegAtADEAMAAgAHcALQBmAHUAbABsACAALQB0AHIAYQBuAHMAbABhAHQAZQAtAHkALQBmAHUAbABsACAAYgBnAC0AdwBoAGkAdABlACAAdAByAGEAbgBzAGkAdABpAG8AbgAtAHQAcgBhAG4AcwBmAG8AcgBtACAAbQBkADoAcwB0AGEAdABpAGMAIABtAGQAOgB3AC0AYQB1AHQAbwAgAG0AZAA6AC0AdAByAGEAbgBzAGwAYQB0AGUALQB5AC0AMAAiAD4ACgAgACAAIAAgACAAIAAgACAAIAAgADwAZABpAHYAIABjAGwAYQBzAHMATgBhAG0AZQA9ACIAYwBvAG4AdABhAGkAbgBlAHIAIABzAGkAegBlAC0AZgB1AGwAbAAgAG0AZAA6AG4AbwAtAGMAbwBuAHQAYQBpAG4AZQByACIAPgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgADwAZABpAHYAIABjAGwAYQBzAHMATgBhAG0AZQA9ACIAcgBlAGwAYQB0AGkAdgBlACIAPgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAPABBAGMAdABpAG8AbgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAGEAcgBpAGEALQBsAGEAYgBlAGwAPQAiAEMAbABvAHMAZQAgAG0AZQBuAHUAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAGMAbABhAHMAcwBOAGEAbQBlAD0AIgBhAGIAcwBvAGwAdQB0AGUAIAByAGkAZwBoAHQALQAwACAAdABvAHAALQA1ACAAbQB0ADoAdABvAHAALQA4ACAAbQBkADoAaABpAGQAZABlAG4AIgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAGkAZAA9ACIAYgB1AHIAZwBlAHIAIgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAPgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgADwASQBjAG8AbgAgAG4AYQBtAGUAPQAiAGwAdQBjAGkAZABlAC8AeAAiACAAYwBsAGEAcwBzAE4AYQBtAGUAPQAiAHMAaQB6AGUALQA5ACIAIAAvAD4ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgADwALwBBAGMAdABpAG8AbgA%2BAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAA8AG4AYQB2AD4ACgAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAA8AEwAaQBzAHQATQBlAG4AdQAgAGMAbABvAHMAZQBNAGUAbgB1AD0AewBjAGwAbwBzAGUATQBlAG4AdQB9ACAALwA%2BAAoAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAA8AC8AbgBhAHYAPgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgADwALwBkAGkAdgA%2BAAoAIAAgACAAIAAgACAAIAAgACAAIAA8AC8AZABpAHYAPgAKACAAIAAgACAAIAAgACAAIAA8AC8AZABpAHYAPgAKACAAIAAgACAAIAAgACAAIAA8AGwAYQBiAGUAbAAKACAAIAAgACAAIAAgACAAIAAgACAAaAB0AG0AbABGAG8AcgA9ACIAYgB1AHIAZwBlAHIAIgAKACAAIAAgACAAIAAgACAAIAAgACAAYwBsAGEAcwBzAE4AYQBtAGUAPQAiAGEAYgBzAG8AbAB1AHQAZQAgAHoALQAwACAAcwBpAHoAZQAtAGYAdQBsAGwAIABiAGcALQBiAGwAYQBjAGsALwA1ADAAIABtAGQAOgBoAGkAZABkAGUAbgAiAAoAIAAgACAAIAAgACAAIAAgAC8APgAKACAAIAAgACAAIAAgADwALwBkAGkAdgA%2BAAoAIAAgACAAIAA8AC8APgAKACAAIAApADsACgB9ADsACgA%3D

### Expected result

Label should not have been highlighted, as this is not against W3C rules:

![image](https://github.com/user-attachments/assets/fc80dc43-85ec-4ab8-a661-3ea2270a33ef)
label works the same way on the button

https://validator.w3.org/nu/#textarea

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:
Could you provide a more minimal repro? There's a lot of code in that playground.
> Could you provide a more minimal repro? There's a lot of code in that playground.

https://biomejs.dev/playground/?code=ZQB4AHAAbwByAHQAIABjAG8AbgBzAHQAIABNAGUAbgB1ACAAPQAgACgAKQAgAD0APgAgAHsACgAgACAAcgBlAHQAdQByAG4AIAAoAAoAIAAgACAAIAA8AD4ACgAgACAAIAAgACAAIAAgACAAPABiAHUAdAB0AG8AbgAgAHQAeQBwAGUAPQAiAGIAdQB0AHQAbwBuACIAIABpAGQAPQAiAGIAdQByAGcAZQByACIAPgAKACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAGIAdQB0AHQAbwBuAAoAIAAgACAAIAAgACAAIAAgADwALwBiAHUAdAB0AG8AbgA%2BAAoAIAAgACAAIAAgACAAIAAgADwAbABhAGIAZQBsAAoAIAAgACAAIAAgACAAIAAgACAAIABoAHQAbQBsAEYAbwByAD0AIgBiAHUAcgBnAGUAcgAiAAoAIAAgACAAIAAgACAAIAAgACAAIABjAGwAYQBzAHMATgBhAG0AZQA9ACIAYQBiAHMAbwBsAHUAdABlACAAegAtADAAIABzAGkAegBlAC0AZgB1AGwAbAAgAGIAZwAtAGIAbABhAGMAawAvADUAMAAgAG0AZAA6AGgAaQBkAGQAZQBuACIACgAgACAAIAAgACAAIAAgACAALwA%2BAAoAIAAgACAAIAA8AC8APgAKACAAIAApADsACgB9ADsACgA%3D
You're right, labeling a button shouldn't cause the rule to trigger.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7fe0d4e1e1b..dec1598d5f80 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -296,6 +296,8 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
 
 - Fixed a panic related to bogus import statements in `useExhaustiveDependencies` ([#4568](https://github.com/biomejs/biome/issues/4568)) Contributed by @dyc3
 
+- [noLabelWithoutControl](https://biomejs.dev/linter/rules/no-label-without-control/) detects button tags as input ([#4511])(https://github.com/biomejs/biome/issues/4511). Contributed by @unvalley
+
 ### Parser
 
 #### Bug fixes
diff --git a/crates/biome_js_analyze/src/lint/a11y/no_label_without_control.rs b/crates/biome_js_analyze/src/lint/a11y/no_label_without_control.rs
index bae591e668ad..bbe686756897 100644
--- a/crates/biome_js_analyze/src/lint/a11y/no_label_without_control.rs
+++ b/crates/biome_js_analyze/src/lint/a11y/no_label_without_control.rs
@@ -13,7 +13,7 @@ use serde::{Deserialize, Serialize};
 declare_lint_rule! {
     /// Enforce that a label element or component has a text label and an associated input.
     ///
-    /// An "input" is considered one of the following elements: `input`, `meter`, `output`, `progress`, `select` or `textarea`.
+    /// An "input" is considered one of the following elements: `input`, `meter`, `output`, `progress`, `select`, `textarea` or `button`.
     ///
     /// There are two supported ways to associate a label with an input:
     /// - Wrapping an input in a label element.
@@ -270,8 +270,9 @@ pub struct NoLabelWithoutControlState {
 
 const DEFAULT_LABEL_ATTRIBUTES: [&str; 3] = ["aria-label", "aria-labelledby", "alt"];
 const DEFAULT_LABEL_COMPONENTS: [&str; 1] = ["label"];
-const DEFAULT_INPUT_COMPONENTS: [&str; 6] =
-    ["input", "meter", "output", "progress", "select", "textarea"];
+const DEFAULT_INPUT_COMPONENTS: [&str; 7] = [
+    "input", "meter", "output", "progress", "select", "textarea", "button",
+];
 
 /// Returns whether the passed `AnyJsxTag` have a `for` or `htmlFor` attribute
 fn has_for_attribute(jsx_tag: &AnyJsxTag) -> bool {


Test patch:
diff --git a/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx b/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx
index 74e6c226d3fe..77df356a02ae 100644
--- a/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx
+++ b/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx
@@ -30,3 +30,12 @@
 <label>foo<textarea /></label>;
 
 <label htmlFor="three">{label}</label>;
+
+// Allow Button #4511
+<label for="btn_id"><button id="btn_id">Button</button></label>;
+<label htmlFor="btn_id"><button id="btn_id">Button</button></label>;
+<label>A label<button /></label>;
+<>
+	<button type="button" id="burger">Menu</button>
+	<label htmlFor="burger">Menu</label>;
+</>
diff --git a/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx.snap b/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx.snap
index ca4f933e39eb..f9ebdaea42ae 100644
--- a/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx.snap
+++ b/crates/biome_js_analyze/tests/specs/a11y/noLabelWithoutControl/valid.jsx.snap
@@ -37,4 +37,13 @@ expression: valid.jsx
 
 <label htmlFor="three">{label}</label>;
 
+// Allow Button #4511
+<label for="btn_id"><button id="btn_id">Button</button></label>;
+<label htmlFor="btn_id"><button id="btn_id">Button</button></label>;
+<label>A label<button /></label>;
+<>
+	<button type="button" id="burger">Menu</button>
+	<label htmlFor="burger">Menu</label>;
+</>
+
 ```