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}