1use gpui::{FontWeight, *};
2use ui::prelude::*;
3
4#[derive(IntoElement)]
5pub struct JuicyButton {
6 base: Div,
7 label: SharedString,
8 keybinding: Option<AnyElement>,
9 on_click: Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
10}
11
12impl JuicyButton {
13 pub fn new(label: impl Into<SharedString>) -> Self {
14 Self {
15 base: div(),
16 label: label.into(),
17 keybinding: None,
18 on_click: None,
19 }
20 }
21
22 pub fn keybinding(mut self, keybinding: Option<impl IntoElement>) -> Self {
23 if let Some(kb) = keybinding {
24 self.keybinding = Some(kb.into_any_element());
25 }
26 self
27 }
28}
29
30impl Clickable for JuicyButton {
31 fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self {
32 self.on_click = Some(Box::new(handler));
33 self
34 }
35
36 fn cursor_style(mut self, style: gpui::CursorStyle) -> Self {
37 self.base = self.base.cursor(style);
38 self
39 }
40}
41
42impl RenderOnce for JuicyButton {
43 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
44 let mut children = vec![
45 h_flex()
46 .flex_1()
47 .items_center()
48 .justify_center()
49 .child(
50 div()
51 .text_size(px(14.))
52 .font_weight(FontWeight::MEDIUM)
53 .text_color(cx.theme().colors().text)
54 .child(self.label),
55 )
56 .into_any_element(),
57 ];
58
59 if let Some(keybinding) = self.keybinding {
60 children.push(
61 div()
62 .flex_none()
63 .bg(gpui::white().opacity(0.2))
64 .rounded_md()
65 .px_1()
66 .child(keybinding)
67 .into_any_element(),
68 );
69 }
70
71 self.base
72 .id("juicy-button")
73 .w_full()
74 .h(rems(2.))
75 .px(rems(1.5))
76 .rounded(px(6.))
77 .bg(cx.theme().colors().icon.opacity(0.12))
78 .shadow_hairline()
79 .hover(|style| {
80 style.bg(cx.theme().colors().icon.opacity(0.12)) // Darker blue on hover
81 })
82 .active(|style| {
83 style
84 .bg(rgb(0x1e40af)) // Even darker on active
85 .shadow_md()
86 })
87 .cursor_pointer()
88 .flex()
89 .items_center()
90 .justify_between()
91 .when_some(self.on_click, |div, on_click| div.on_click(on_click))
92 .children(children)
93 }
94}