use super::*;
#[component]
pub fn euv_collapse(node: VirtualNode<EuvCollapseProps>) -> VirtualNode {
let EuvCollapseProps {
items,
open_keys,
allow_multiple,
}: EuvCollapseProps = node.try_get_props().unwrap_or_default();
let children: VirtualNode = node.get_children().into();
let mut sections: Vec<VirtualNode> = Vec::with_capacity(items.len() + 1);
sections.extend(
items
.into_iter()
.map(|item: EuvCollapseItem| collapse_section(open_keys, allow_multiple, item)),
);
sections.push(children);
sections.into()
}
fn collapse_section(
open_keys: Signal<Vec<String>>,
allow_multiple: bool,
item: EuvCollapseItem,
) -> VirtualNode {
let key: &'static str = item.key;
html! {
div {
key: key
class: c_euv_collapse_item()
button {
class: c_euv_collapse_header()
class: if { open_keys.get().iter().any(|entry: &String| entry == key) } {
c_euv_collapse_header_active()
} else {
c_euv_collapse_header()
}
onclick: on_collapse_toggle(open_keys, key, allow_multiple)
{
item.title
}
}
div {
class: c_euv_collapse_body()
class: if { open_keys.get().iter().any(|entry: &String| entry == key) } {
c_euv_collapse_body_open()
} else {
c_euv_collapse_body_closed()
}
}
}
}
}
fn on_collapse_toggle(
open_keys: Signal<Vec<String>>,
key: &'static str,
allow_multiple: bool,
) -> Option<Rc<dyn Fn(Event)>> {
Some(Rc::new(move |_: Event| {
let mut keys: Vec<String> = open_keys.get();
let is_open: bool = keys.iter().any(|entry: &String| entry == key);
if allow_multiple {
if let Some(index) = keys.iter().position(|entry: &String| entry == key) {
keys.remove(index);
} else {
keys.push(key.to_string());
}
} else {
keys = if is_open {
Vec::new()
} else {
vec![key.to_string()]
};
}
open_keys.set(keys);
}))
}