disclosure.rs

 1use std::sync::Arc;
 2
 3use gpui::ClickEvent;
 4
 5use crate::{prelude::*, Color, IconButton, IconButtonShape, IconName, IconSize};
 6
 7#[derive(IntoElement)]
 8pub struct Disclosure {
 9    id: ElementId,
10    is_open: bool,
11    selected: bool,
12    on_toggle: Option<Arc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
13}
14
15impl Disclosure {
16    pub fn new(id: impl Into<ElementId>, is_open: bool) -> Self {
17        Self {
18            id: id.into(),
19            is_open,
20            selected: false,
21            on_toggle: None,
22        }
23    }
24
25    pub fn on_toggle(
26        mut self,
27        handler: impl Into<Option<Arc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>>,
28    ) -> Self {
29        self.on_toggle = handler.into();
30        self
31    }
32}
33
34impl Selectable for Disclosure {
35    fn selected(mut self, selected: bool) -> Self {
36        self.selected = selected;
37        self
38    }
39}
40
41impl Clickable for Disclosure {
42    fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut WindowContext) + 'static) -> Self {
43        self.on_toggle = Some(Arc::new(handler));
44        self
45    }
46}
47
48impl RenderOnce for Disclosure {
49    fn render(self, _cx: &mut WindowContext) -> impl IntoElement {
50        IconButton::new(
51            self.id,
52            match self.is_open {
53                true => IconName::ChevronDown,
54                false => IconName::ChevronRight,
55            },
56        )
57        .shape(IconButtonShape::Square)
58        .icon_color(Color::Muted)
59        .icon_size(IconSize::Small)
60        .selected(self.selected)
61        .when_some(self.on_toggle, move |this, on_toggle| {
62            this.on_click(move |event, cx| on_toggle(event, cx))
63        })
64    }
65}