dioxus_swdir_tree/
view.rs1use dioxus::prelude::*;
4use dioxus_swdir_tree_core::keyboard::{self, Modifiers as CoreMods, TreeKey};
5use dioxus_swdir_tree_core::{DirectoryTree, DragMsg};
6
7use crate::event::DirectoryTreeEvent;
8use crate::row::{ArcTheme, TreeRow, default_theme};
9use crate::style as s;
10
11#[component]
24pub fn DirectoryTreeView(
25 tree: Signal<DirectoryTree>,
26 on_event: EventHandler<DirectoryTreeEvent>,
27 #[props(optional)] theme: Option<ArcTheme>,
28) -> Element {
29 let theme = theme.unwrap_or_else(default_theme);
30
31 let t = tree.read();
32 let rows: Vec<(dioxus_swdir_tree_core::TreeNode, u32)> = t
33 .visible_rows()
34 .into_iter()
35 .map(|(node, depth)| (node.clone(), depth))
36 .collect();
37 let drag = t.drag_state().cloned();
38 let drag_active = drag.is_some();
39 drop(t);
40
41 #[cfg(feature = "default-style")]
42 let default_style_css = Some(s::DEFAULT_CSS);
43 #[cfg(not(feature = "default-style"))]
44 let default_style_css: Option<&str> = None;
45
46 let on_keydown = move |evt: KeyboardEvent| {
47 let tree_key = match evt.key() {
48 Key::ArrowUp => TreeKey::Up,
49 Key::ArrowDown => TreeKey::Down,
50 Key::Home => TreeKey::Home,
51 Key::End => TreeKey::End,
52 Key::Enter => TreeKey::Enter,
53 Key::ArrowLeft => TreeKey::Left,
54 Key::ArrowRight => TreeKey::Right,
55 Key::Escape => TreeKey::Escape,
56 Key::Character(ref s) if s == " " => TreeKey::Space,
57 _ => return,
58 };
59 let mods = CoreMods {
60 shift: evt.modifiers().shift(),
61 ctrl: evt.modifiers().ctrl(),
62 };
63 if let Some(event) = keyboard::handle_key(&tree.read(), tree_key, mods) {
64 evt.prevent_default();
65 on_event.call(event);
66 }
67 };
68
69 let on_container_mouseup = move |_evt: MouseEvent| {
70 if drag_active {
71 on_event.call(DirectoryTreeEvent::Drag(DragMsg::Cancelled));
72 }
73 };
74
75 rsx! {
76 if let Some(css) = default_style_css {
77 style { "{css}" }
78 }
79
80 if let Some(ref d) = drag {
81 div {
82 style: "
83 position: fixed; bottom: 1rem; left: 50%;
84 transform: translateX(-50%);
85 background: rgba(0,0,0,0.75); color: #fff;
86 padding: 0.2rem 0.6rem; border-radius: 4px;
87 font-size: 0.75rem; pointer-events: none; z-index: 999;
88 ",
89 "Dragging {d.sources.len()} item(s)"
90 }
91 }
92
93 div {
94 class: s::CLASS_TREE,
95 tabindex: "0",
96 onkeydown: on_keydown,
97 onmouseup: on_container_mouseup,
98
99 for (node, depth) in rows {
100 TreeRow {
101 key: "{node.path.display()}",
102 node,
103 depth,
104 on_event,
105 drag: drag.clone(),
106 theme: theme.clone(),
107 }
108 }
109 }
110 }
111}