Skip to main content

guise/
closebutton.rs

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