use crate::core::px;
use crate::view::interactivity::ClickHandler;
use crate::view::prelude::*;
use std::rc::Rc;
pub struct TreeItem {
label: String,
depth: usize,
expanded: Option<bool>,
selected: bool,
id: Option<String>,
on_click: Option<ClickHandler>,
}
impl TreeItem {
pub fn new(label: impl Into<String>) -> Self {
Self { label: label.into(), depth: 0, expanded: None, selected: false, id: None, on_click: None }
}
pub fn depth(mut self, depth: usize) -> Self {
self.depth = depth;
self
}
pub fn expanded(mut self, expanded: Option<bool>) -> Self {
self.expanded = expanded;
self
}
pub fn selected(mut self, selected: bool) -> Self {
self.selected = selected;
self
}
pub fn id(mut self, id: impl Into<String>) -> Self {
self.id = Some(id.into());
self
}
pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut EventContext) + 'static) -> Self {
self.on_click = Some(Rc::new(handler));
self
}
}
impl IntoElement for TreeItem {
fn into_element(self) -> AnyElement {
let marker = match self.expanded {
Some(true) => "v",
Some(false) => ">",
None => " ",
};
let handler = self.on_click.clone();
div()
.flex_row()
.items_center()
.gap_1()
.w_full()
.h(px(24.0))
.flex_shrink_0()
.pl_for_depth(self.depth)
.text_sm()
.text_color(if self.selected { Token::Text } else { Token::TextMuted })
.when(self.selected, |row| row.bg(Token::Selection))
.hover(|style| style.bg(Token::Hover))
.when_some(self.id, |row, id| row.id(id))
.when_some(handler, |row, handler| row.on_click(move |event, cx| handler(event, cx)))
.child(div().w(px(12.0)).text_xs().child(marker))
.child(self.label)
.into_element()
}
}
trait DepthPadding {
fn pl_for_depth(self, depth: usize) -> Self;
}
impl DepthPadding for Div {
fn pl_for_depth(mut self, depth: usize) -> Self {
self.style().padding.left = Some(px(8.0 + depth as f32 * 12.0));
self
}
}