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}