disclosure.rs

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