button: Add Support for on_hover event (#1341)

This commit is contained in:
Floyd Wang 2025-10-09 18:43:50 +08:00 committed by GitHub
parent ca9d5b77e2
commit 7a8be9a628
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 43 additions and 15 deletions

View file

@ -1,13 +1,13 @@
use gpui::{
prelude::FluentBuilder, px, Action, App, AppContext as _, ClickEvent, Context, Entity,
Focusable, InteractiveElement, IntoElement, ParentElement as _, Render, Styled as _, Window,
Action, App, AppContext as _, ClickEvent, Context, Entity, Focusable, InteractiveElement,
IntoElement, ParentElement as _, Render, Styled as _, Window, prelude::FluentBuilder, px,
};
use gpui_component::{
ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _, Theme,
button::{Button, ButtonCustomVariant, ButtonGroup, ButtonVariants as _, DropdownButton},
checkbox::Checkbox,
h_flex, v_flex, ActiveTheme, Disableable as _, Icon, IconName, Selectable as _, Sizable as _,
Theme,
h_flex, v_flex,
};
use serde::Deserialize;
@ -43,8 +43,12 @@ impl ButtonStory {
})
}
fn on_click(ev: &ClickEvent, _window: &mut Window, _cx: &mut App) {
println!("Button clicked! {:?}", ev);
fn on_click(ev: &ClickEvent, _: &mut Window, _: &mut App) {
println!("Button clicked {:?}", ev);
}
fn on_hover(hovered: &bool, _: &mut Window, _: &mut App) {
println!("Button hovered {:?}", hovered);
}
}
@ -159,7 +163,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-2")
@ -168,7 +173,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-4")
@ -178,7 +184,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-4-warning")
@ -188,7 +195,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-4-success")
@ -198,7 +206,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-5-info")
@ -208,7 +217,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-5-ghost")
@ -218,7 +228,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-5-link")
@ -228,7 +239,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
)
.child(
Button::new("button-5-text")
@ -238,7 +250,8 @@ impl Render for ButtonStory {
.selected(selected)
.loading(loading)
.when(compact, |this| this.compact())
.on_click(Self::on_click),
.on_click(Self::on_click)
.on_hover(Self::on_hover),
),
)
.child(

View file

@ -201,6 +201,7 @@ pub struct Button {
Option<(Rc<Box<dyn Action>>, Option<SharedString>)>,
)>,
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
on_hover: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
pub(crate) stop_propagation: bool,
loading: bool,
loading_icon: Option<Icon>,
@ -236,6 +237,7 @@ impl Button {
size: Size::Medium,
tooltip: None,
on_click: None,
on_hover: None,
stop_propagation: true,
loading: false,
compact: false,
@ -325,6 +327,12 @@ impl Button {
self
}
/// Add hover handler, the bool parameter indicates whether the mouse is hovering.
pub fn on_hover(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self {
self.on_hover = Some(Rc::new(handler));
self
}
pub fn stop_propagation(mut self, val: bool) -> Self {
self.stop_propagation = val;
self
@ -526,6 +534,11 @@ impl RenderOnce for Button {
(on_click)(event, window, cx);
})
})
.when_some(self.on_hover.filter(|_| clickable), |this, on_hover| {
this.on_hover(move |hovered, window, cx| {
(on_hover)(hovered, window, cx);
})
})
.when(self.disabled, |this| {
let disabled_style = style.disabled(self.outline, cx);
this.bg(disabled_style.bg)

View file

@ -601,6 +601,7 @@ mod tests {
// Test for not on a char boundary
let mut rope = Rope::from("中文");
rope.replace(0..1, "New");
// autocorrect-disable
assert_eq!(rope.to_string(), "New文");
let mut rope = Rope::from("中文");
rope.replace(0..2, "New");
@ -608,6 +609,7 @@ mod tests {
let mut rope = Rope::from("中文");
rope.replace(0..3, "New");
assert_eq!(rope.to_string(), "New文");
// autocorrect-enable
let mut rope = Rope::from("中文");
rope.replace(1..4, "New");
assert_eq!(rope.to_string(), "New");