1use gpui::prelude::*;
4use gpui::{div, px, App, ClickEvent, ElementId, IntoElement, Window};
5
6use crate::devtools::Probed;
7use crate::icon::{Glyph, IconName};
8use crate::input::ClickHandler;
9use crate::style::icon_size;
10use crate::theme::{theme, Size};
11
12#[derive(IntoElement)]
14pub struct CloseButton {
15 id: ElementId,
16 size: Size,
17 on_click: Option<ClickHandler>,
18}
19
20impl CloseButton {
21 pub fn new(id: impl Into<ElementId>) -> Self {
22 CloseButton {
23 id: id.into(),
24 size: Size::Md,
25 on_click: None,
26 }
27 }
28
29 pub fn size(mut self, size: Size) -> Self {
30 self.size = size;
31 self
32 }
33
34 pub fn on_click(
35 mut self,
36 handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
37 ) -> Self {
38 self.on_click = Some(Box::new(handler));
39 self
40 }
41}
42
43impl RenderOnce for CloseButton {
44 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
45 let t = theme(cx);
46 let dim = icon_size(self.size);
47 let hover_bg = t.surface_hover().hsla();
48 let hover_fg = t.text().hsla();
49
50 let mut el = div()
51 .id(self.id)
52 .w(px(dim))
53 .h(px(dim))
54 .flex()
55 .items_center()
56 .justify_center()
57 .rounded(px(t.radius(Size::Sm)))
58 .text_color(t.dimmed().hsla())
59 .text_size(px(dim * 0.5))
60 .hover(move |s| s.bg(hover_bg).text_color(hover_fg))
61 .child(Glyph::from(IconName::X));
62 if let Some(handler) = self.on_click {
63 el = el.on_click(handler);
64 }
65 el.probe("CloseButton")
66 }
67}