Skip to main content

orbital_base_components/tree/
root.rs

1use leptos::{context::Provider, prelude::*};
2use std::collections::HashSet;
3
4use crate::collection::primitives::BaseCollectionRoot;
5
6use super::dnd::TreeDragState;
7use super::state::{
8    TreeExpansionState, TreeFocusState, TreeItemDomRegistry, TreeItemRegistry, TreeSelectionState,
9    TreeState, TreeStateInjection,
10};
11use super::types::{BaseTreeConfig, SubtreeInjection};
12use crate::signals::SignalModel;
13
14#[component]
15pub fn BaseTreeRoot(
16    #[prop(optional, into)] class: MaybeProp<String>,
17    #[prop(into)] tree_state: TreeState,
18    children: Children,
19) -> impl IntoView {
20    let size = tree_state.size;
21    let collection_state = tree_state.collection();
22    let tree_state_for_provider = tree_state.clone();
23
24    view! {
25        <BaseCollectionRoot
26            role="tree"
27            base_class="orbital-tree"
28            class=Signal::derive(move || {
29                let mut parts = vec![format!("orbital-tree--{}", size.get().as_str())];
30                if let Some(extra) = class.get() {
31                    if !extra.is_empty() {
32                        parts.push(extra);
33                    }
34                }
35                parts.join(" ")
36            })
37            collection_state=collection_state
38        >
39            <Provider value=TreeStateInjection(tree_state_for_provider)>
40                <Provider value=SubtreeInjection { level: 1, parent_id: None }>{children()}</Provider>
41            </Provider>
42        </BaseCollectionRoot>
43    }
44}
45
46/// Simple tree root for legacy callers.
47#[component]
48pub fn BaseTree(
49    #[prop(optional, into)] class: MaybeProp<String>,
50    #[prop(optional, into)] config: BaseTreeConfig,
51    children: Children,
52) -> impl IntoView {
53    let BaseTreeConfig {
54        open_items,
55        size,
56        selected_items,
57        selection_mode,
58        disabled_items,
59        disabled_items_focusable,
60        editable,
61        reorderable,
62    } = config;
63
64    let tree_state = TreeState {
65        expansion: TreeExpansionState::new(open_items),
66        selection: TreeSelectionState::new(selection_mode, selected_items),
67        focus: TreeFocusState::new(),
68        registry: TreeItemRegistry::new(),
69        dom_registry: TreeItemDomRegistry::new(),
70        size,
71        disabled_items,
72        disabled_items_focusable,
73        editable,
74        editable_items: SignalModel::new(HashSet::new()),
75        reorderable,
76        on_item_click: None,
77        on_label_change: None,
78        on_reorder: None,
79        drag_state: TreeDragState::new(),
80    };
81
82    view! {
83        <BaseTreeRoot class=class tree_state=tree_state>{children()}</BaseTreeRoot>
84    }
85}