use std::path::PathBuf;
use dioxus::prelude::*;
use dioxus_swdir_tree_core::{SelectionMode, TreeNode};
use crate::event::DirectoryTreeEvent;
use crate::style as s;
#[derive(Props, Clone, PartialEq)]
pub(crate) struct TreeRowProps {
pub node: TreeNode,
pub depth: u32,
pub on_event: EventHandler<DirectoryTreeEvent>,
}
#[component]
pub(crate) fn TreeRow(props: TreeRowProps) -> Element {
let TreeRowProps {
node,
depth,
on_event,
} = props;
let path: PathBuf = node.path.clone();
let is_dir = node.is_dir;
let is_expanded = node.is_expanded;
let is_loaded = node.is_loaded;
let has_error = node.error.is_some();
let is_selected = node.is_selected;
let indent_px = depth * 16;
let mut classes = s::CLASS_ROW.to_string();
if is_selected {
classes.push(' ');
classes.push_str(s::CLASS_ROW_SELECTED);
}
if has_error {
classes.push(' ');
classes.push_str(s::CLASS_ROW_ERROR);
}
let caret: &str = if !is_dir {
" " } else if is_expanded && !is_loaded {
"…" } else if is_expanded {
"▾"
} else {
"▸"
};
let icon: &str = if has_error {
"⚠"
} else if !is_dir {
"📄"
} else if is_expanded {
"📂"
} else {
"📁"
};
let label = node.file_name().to_string_lossy().into_owned();
let error_title: String = node
.error
.as_ref()
.map(|e| e.message().to_string())
.unwrap_or_default();
let caret_path = path.clone();
let on_caret_click = move |evt: MouseEvent| {
evt.stop_propagation();
on_event.call(DirectoryTreeEvent::Toggled(caret_path.clone()));
};
let row_path = path.clone();
let on_row_click = move |_evt: MouseEvent| {
on_event.call(DirectoryTreeEvent::Selected {
path: row_path.clone(),
is_dir,
mode: SelectionMode::Replace,
});
};
rsx! {
div {
class: "{classes}",
style: "padding-left: {indent_px}px;",
title: "{error_title}",
onclick: on_row_click,
span {
class: s::CLASS_CARET,
onclick: on_caret_click,
"{caret}"
}
span {
class: s::CLASS_ICON,
"{icon}"
}
span {
class: s::CLASS_LABEL,
"{label}"
}
}
}
}