From 9d9675ccd6af1aa2879ee3a361af8dc9f3fed135 Mon Sep 17 00:00:00 2001 From: Connor Shea Date: Fri, 31 Oct 2025 19:27:35 -0600 Subject: [PATCH 1/2] fix(linter): Improve diagnostic for react/button-has-type. Fixes #15147. Previously, the diagnostic message did not change based on the options configured for the rule. Disclaimer: Fully written by GitHub Copilot w/ Claude Sonnet 4.5. I only made minor edits. --- .../src/rules/react/button_has_type.rs | 41 +++++++++++++++++-- .../src/snapshots/react_button_has_type.snap | 12 +++--- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/crates/oxc_linter/src/rules/react/button_has_type.rs b/crates/oxc_linter/src/rules/react/button_has_type.rs index 0ec17e3933bab..95053906cb43c 100644 --- a/crates/oxc_linter/src/rules/react/button_has_type.rs +++ b/crates/oxc_linter/src/rules/react/button_has_type.rs @@ -23,9 +23,11 @@ fn missing_type_prop(span: Span) -> OxcDiagnostic { .with_label(span) } -fn invalid_type_prop(span: Span) -> OxcDiagnostic { +fn invalid_type_prop(span: Span, allowed_types: &str) -> OxcDiagnostic { OxcDiagnostic::warn("`button` elements must have a valid `type` attribute.") - .with_help("Change the `type` attribute to one of the allowed values: `button`, `submit`, or `reset`.") + .with_help(format!( + "Change the `type` attribute to one of the allowed values: {allowed_types}." + )) .with_label(span) } @@ -95,7 +97,11 @@ impl Rule for ButtonHasType { }, |button_type_prop| { if !self.is_valid_button_type_prop(button_type_prop) { - ctx.diagnostic(invalid_type_prop(button_type_prop.span())); + let allowed_types = self.allowed_types_message(); + ctx.diagnostic(invalid_type_prop( + button_type_prop.span(), + &allowed_types, + )); } }, ); @@ -130,7 +136,11 @@ impl Rule for ButtonHasType { |type_prop| { if !self.is_valid_button_type_prop_expression(&type_prop.value) { - ctx.diagnostic(invalid_type_prop(type_prop.span)); + let allowed_types = self.allowed_types_message(); + ctx.diagnostic(invalid_type_prop( + type_prop.span, + &allowed_types, + )); } }, ); @@ -165,6 +175,29 @@ impl Rule for ButtonHasType { } impl ButtonHasType { + fn allowed_types_message(&self) -> String { + let mut types = Vec::new(); + if self.button { + types.push("`button`"); + } + if self.submit { + types.push("`submit`"); + } + if self.reset { + types.push("`reset`"); + } + + match types.len() { + 0 => String::new(), + 1 => types[0].to_string(), + 2 => format!("{} or {}", types[0], types[1]), + _ => { + let last = types.pop().unwrap(); + format!("{}, or {}", types.join(", "), last) + } + } + } + fn is_valid_button_type_prop(&self, item: &JSXAttributeItem) -> bool { match get_prop_value(item) { Some(JSXAttributeValue::ExpressionContainer(container)) => { diff --git a/crates/oxc_linter/src/snapshots/react_button_has_type.snap b/crates/oxc_linter/src/snapshots/react_button_has_type.snap index 909314b508ac1..7a9fc93739db8 100644 --- a/crates/oxc_linter/src/snapshots/react_button_has_type.snap +++ b/crates/oxc_linter/src/snapshots/react_button_has_type.snap @@ -55,7 +55,7 @@ source: crates/oxc_linter/src/tester.rs 1 │