1use gpui::{ClickEvent, ElementId, IntoElement, ParentElement, Styled};
2use ui::prelude::*;
3
4#[derive(IntoElement)]
5pub struct NewThreadButton {
6 id: ElementId,
7 label: SharedString,
8 icon: IconName,
9 keybinding: Option<ui::KeyBinding>,
10 on_click: Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
11}
12
13impl NewThreadButton {
14 fn new(id: impl Into<ElementId>, label: impl Into<SharedString>, icon: IconName) -> Self {
15 Self {
16 id: id.into(),
17 label: label.into(),
18 icon,
19 keybinding: None,
20 on_click: None,
21 }
22 }
23
24 fn keybinding(mut self, keybinding: Option<ui::KeyBinding>) -> Self {
25 self.keybinding = keybinding;
26 self
27 }
28
29 fn on_click<F>(mut self, handler: F) -> Self
30 where
31 F: Fn(&mut Window, &mut App) + 'static,
32 {
33 self.on_click = Some(Box::new(
34 move |_: &ClickEvent, window: &mut Window, cx: &mut App| handler(window, cx),
35 ));
36 self
37 }
38}
39
40impl RenderOnce for NewThreadButton {
41 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
42 h_flex()
43 .id(self.id)
44 .w_full()
45 .py_1p5()
46 .px_2()
47 .gap_1()
48 .justify_between()
49 .rounded_md()
50 .border_1()
51 .border_color(cx.theme().colors().border.opacity(0.4))
52 .bg(cx.theme().colors().element_active.opacity(0.2))
53 .hover(|style| {
54 style
55 .bg(cx.theme().colors().element_hover)
56 .border_color(cx.theme().colors().border)
57 })
58 .child(
59 h_flex()
60 .gap_1p5()
61 .child(
62 Icon::new(self.icon)
63 .size(IconSize::XSmall)
64 .color(Color::Muted),
65 )
66 .child(Label::new(self.label).size(LabelSize::Small)),
67 )
68 .when_some(self.keybinding, |this, keybinding| {
69 this.child(keybinding.size(rems_from_px(10.)))
70 })
71 .when_some(self.on_click, |this, on_click| {
72 this.on_click(move |event, window, cx| on_click(event, window, cx))
73 })
74 }
75}