disclosure.rs

 1use std::rc::Rc;
 2
 3use gpui::ClickEvent;
 4
 5use crate::prelude::*;
 6use crate::{Color, Icon, IconButton, IconSize, ToggleState, Toggleable};
 7
 8#[derive(IntoElement)]
 9pub struct Disclosure {
10    state: ToggleState,
11    on_toggle: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
12}
13
14impl Disclosure {
15    pub fn new(state: ToggleState) -> Self {
16        Self {
17            state,
18            on_toggle: None,
19        }
20    }
21
22    pub fn from_toggleable(toggleable: Toggleable) -> Option<Self> {
23        match toggleable {
24            Toggleable::Toggleable(state) => Some(Self::new(state)),
25            Toggleable::NotToggleable => None,
26        }
27    }
28
29    pub fn on_toggle(
30        mut self,
31        handler: impl Into<Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>>,
32    ) -> Self {
33        self.on_toggle = handler.into();
34        self
35    }
36}
37
38impl RenderOnce for Disclosure {
39    type Rendered = IconButton;
40
41    fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
42        IconButton::new(
43            "toggle",
44            match self.state {
45                ToggleState::Toggled => Icon::ChevronDown,
46                ToggleState::NotToggled => Icon::ChevronRight,
47            },
48        )
49        .color(Color::Muted)
50        .size(IconSize::Small)
51        .when_some(self.on_toggle, move |this, on_toggle| {
52            this.on_click(move |event, cx| on_toggle(event, cx))
53        })
54    }
55}