Repository: biomejs/biome (language: rust)

Issue:
🐛 `useButtonType` warning when `type` is provided
### Environment information

[playground link](https://biomejs.dev/playground/?code=UgBlAGEAYwB0AC4AYwByAGUAYQB0AGUARQBsAGUAbQBlAG4AdAAoACIAYgB1AHQAdABvAG4AIgAsACAAewAgAHQAeQBwAGUAOgAgACIAYgB1AHQAdABvAG4AIgAgAH0ALAAgACIAZgBvAG8AIgApAAoACgBSAGUAYQBjAHQALgBjAHIAZQBhAHQAZQBFAGwAZQBtAGUAbgB0ACgAIgBiAHUAdAB0AG8AbgAiACwAIAB7ACAAdAB5AHAAZQA6ACAAIgBzAHUAYgBtAGkAdAAiACAAfQAsACAAIgBmAG8AbwAiACkACgA%3D)

```block
CLI:
  Version:                      1.9.2
  Color support:                true

Platform:
  CPU Architecture:             aarch64
  OS:                           linux

Environment:
  BIOME_LOG_PATH:               unset
  BIOME_LOG_PREFIX_NAME:        unset
  BIOME_CONFIG_PATH:            unset
  NO_COLOR:                     unset
  TERM:                         "xterm-ghostty"
  JS_RUNTIME_VERSION:           unset
  JS_RUNTIME_NAME:              unset
  NODE_PACKAGE_MANAGER:         unset

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    true
  VCS disabled:                 false

Workspace:
  Open Documents:               0
```


### What happened?

```ts
React.createElement("button", { type: "button" }, "foo")
// Provide a valid type prop for the button element.biomelint/a11y/useButtonType
```

### Expected result

no `element.biomelint/a11y/useButtonType` warning when `type` is provided

### Code of Conduct

- [X] I agree to follow Biome's Code of Conduct


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d44abfcfa206..4c5c600807ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -47,6 +47,16 @@ our [guidelines for writing a good changelog entry](https://github.com/biomejs/b
 
   Contributed by @Conaclos
 
+- [useButtonType](https://biomejs.dev/linter/rules/use-button-type/) no longer reports dynamically created button with a valid type ([#4072](https://github.com/biomejs/biome/issues/4072)).
+
+  The following code is no longer reported:
+
+  ```js
+  React.createElement("button", { type: "button" }, "foo")
+  ```
+
+  Contributed by @Conaclos
+
 ### Parser
 
 ## v1.9.2 (2024-09-19)
diff --git a/crates/biome_js_analyze/src/lint/a11y/use_button_type.rs b/crates/biome_js_analyze/src/lint/a11y/use_button_type.rs
index 86afee7fa7a8..8ed0e5b415b2 100644
--- a/crates/biome_js_analyze/src/lint/a11y/use_button_type.rs
+++ b/crates/biome_js_analyze/src/lint/a11y/use_button_type.rs
@@ -113,52 +113,36 @@ impl Rule for UseButtonType {
                 let model = ctx.model();
                 let react_create_element =
                     ReactCreateElementCall::from_call_expression(call_expression, model)?;
-
                 // first argument needs to be a string
                 let first_argument = react_create_element
                     .element_type
                     .as_any_js_expression()?
-                    .as_any_js_literal_expression()?
-                    .as_js_string_literal_expression()?;
-
-                if first_argument.inner_string_text().ok()?.text() == "button" {
-                    return if let Some(props) = react_create_element.props.as_ref() {
-                        let type_member = react_create_element.find_prop_by_name("type");
-                        if let Some(member) = type_member {
-                            let property_value = member.value().ok()?;
-                            let Some(value) = property_value
-                                .as_any_js_literal_expression()?
-                                .as_js_string_literal_expression()
-                            else {
-                                return Some(UseButtonTypeState {
-                                    range: property_value.range(),
-                                    missing_prop: false,
-                                });
-                            };
-
-                            if !ALLOWED_BUTTON_TYPES.contains(&&*value.inner_string_text().ok()?) {
-                                return Some(UseButtonTypeState {
-                                    range: value.range(),
-                                    missing_prop: false,
-                                });
-                            }
-                        }
-
-                        // if we are here, it means that we haven't found the property "type" and
-                        // we have to return a diagnostic
-                        Some(UseButtonTypeState {
-                            range: props.range(),
-                            missing_prop: false,
-                        })
-                    } else {
-                        Some(UseButtonTypeState {
-                            range: first_argument.range(),
-                            missing_prop: true,
-                        })
-                    };
+                    .as_static_value()?;
+                if first_argument.text() != "button" {
+                    return None;
+                }
+                let Some(props) = react_create_element.props.as_ref() else {
+                    return Some(UseButtonTypeState {
+                        range: first_argument.range(),
+                        missing_prop: true,
+                    });
+                };
+                let Some(member) = react_create_element.find_prop_by_name("type") else {
+                    // We haven't found the property `type`
+                    return Some(UseButtonTypeState {
+                        range: props.range(),
+                        missing_prop: false,
+                    });
+                };
+                let property_value = member.value().ok()?.as_static_value()?;
+                if ALLOWED_BUTTON_TYPES.contains(&property_value.text()) {
+                    None
+                } else {
+                    Some(UseButtonTypeState {
+                        range: property_value.range(),
+                        missing_prop: false,
+                    })
                 }
-
-                None
             }
         }
     }
diff --git a/crates/biome_js_analyze/src/react.rs b/crates/biome_js_analyze/src/react.rs
index e3e88bcaaa21..711803870248 100644
--- a/crates/biome_js_analyze/src/react.rs
+++ b/crates/biome_js_analyze/src/react.rs
@@ -105,14 +105,7 @@ impl ReactApiCall for ReactCreateElementCall {
                 let AnyJsObjectMember::JsPropertyObjectMember(property) = member.ok()? else {
                     return None;
                 };
-                let property_name = property.name().ok()?;
-
-                let property_name = property_name.as_js_literal_member_name()?;
-                if property_name.name().ok()? == prop_name {
-                    Some(property)
-                } else {
-                    None
-                }
+                (property.name().ok()?.name()? == prop_name).then_some(property)
             })
         })
     }


Test patch:
diff --git a/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js b/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js
index e8a3fd5e7439..57de7c8ca36c 100644
--- a/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js
+++ b/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js
@@ -12,6 +12,5 @@ React.createElement('button', {
 React.createElement('button', {});
 
 // valid
-React.createElement('button', {
-    "type": foo
-});
+React.createElement('button', { "type": foo });
+React.createElement("button", { type: "button" }, "foo")
\ No newline at end of file
diff --git a/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js.snap b/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js.snap
index 17513d42f18f..e780b3e8b1d8 100644
--- a/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js.snap
+++ b/crates/biome_js_analyze/tests/specs/a11y/useButtonType/inObject.js.snap
@@ -18,10 +18,8 @@ React.createElement('button', {
 React.createElement('button', {});
 
 // valid
-React.createElement('button', {
-    "type": foo
-});
-
+React.createElement('button', { "type": foo });
+React.createElement("button", { type: "button" }, "foo")
 ```
 
 # Diagnostics
@@ -121,5 +119,3 @@ inObject.js:12:31 lint/a11y/useButtonType ━━━━━━━━━━━━
   
 
 ```
-
-