vizia_core/views/
collapsible.rs
1use crate::{icons::ICON_CHEVRON_DOWN, prelude::*};
2
3pub enum CollapsibleEvent {
5 ToggleOpen,
6}
7
8#[derive(Lens)]
24pub struct Collapsible {
25 is_open: bool,
26}
27
28impl Collapsible {
29 pub fn new(
31 cx: &mut Context,
32 header: impl Fn(&mut Context),
33 content: impl Fn(&mut Context),
34 ) -> Handle<Self> {
35 Self { is_open: false }
36 .build(cx, |cx| {
37 HStack::new(cx, |cx| {
39 header(cx);
40 Svg::new(cx, ICON_CHEVRON_DOWN)
41 .class("expand-icon")
42 .on_press(|cx| cx.emit(CollapsibleEvent::ToggleOpen));
43 })
44 .class("header")
45 .on_press(|cx| cx.emit(CollapsibleEvent::ToggleOpen));
46
47 VStack::new(cx, |cx| {
49 content(cx);
50 })
51 .class("content");
52 })
53 .toggle_class("open", Collapsible::is_open)
54 }
55}
56
57impl View for Collapsible {
58 fn element(&self) -> Option<&'static str> {
59 Some("collapsible")
60 }
61
62 fn event(&mut self, _cx: &mut EventContext, event: &mut Event) {
63 event.map(|collapsible_event, _| match collapsible_event {
64 CollapsibleEvent::ToggleOpen => {
65 self.is_open = !self.is_open;
66 }
67 });
68 }
69}
70
71impl Handle<'_, Collapsible> {
72 pub fn open(self, open: impl Res<bool>) -> Self {
74 self.bind(open, |handle, open| {
75 let open = open.get(&handle);
76 handle.modify(|collapsible| collapsible.is_open = open);
77 })
78 }
79}