orbital_base_components/tree/state/
mod.rs1pub use crate::collection::state::{
4 checkbox_state, collection_keyboard_action, CollectionCheckboxState, CollectionExpansionState,
5 CollectionFocusState, CollectionItemDomRegistry, CollectionKeyboardAction, CollectionRegistry,
6 CollectionRegistryEntry, CollectionSelectionMode, CollectionSelectionState, CollectionState,
7 ExpansionTrigger,
8};
9
10pub type TreeCheckboxState = CollectionCheckboxState;
11pub type TreeExpansionState = CollectionExpansionState;
12pub type TreeFocusState = CollectionFocusState;
13pub type TreeItemDomRegistry = CollectionItemDomRegistry;
14pub type TreeKeyboardAction = CollectionKeyboardAction;
15pub type TreeItemRegistry = CollectionRegistry;
16pub type TreeRegistryEntry = CollectionRegistryEntry;
17pub type TreeSelectionMode = CollectionSelectionMode;
18pub type TreeSelectionState = CollectionSelectionState;
19
20pub fn tree_keyboard_action(event: &leptos::ev::KeyboardEvent) -> TreeKeyboardAction {
21 collection_keyboard_action(event)
22}
23
24use leptos::{ev, prelude::*};
25use std::collections::HashSet;
26
27use crate::signals::SignalModel;
28use crate::tree::dnd::TreeDragState;
29use crate::tree::types::TreeSize;
30use crate::Handler;
31
32#[derive(Clone)]
34pub struct TreeState {
35 pub expansion: TreeExpansionState,
36 pub selection: TreeSelectionState,
37 pub focus: TreeFocusState,
38 pub registry: TreeItemRegistry,
39 pub dom_registry: TreeItemDomRegistry,
40 pub size: Signal<TreeSize>,
41 pub disabled_items: SignalModel<HashSet<String>>,
42 pub disabled_items_focusable: Signal<bool>,
43 pub editable: Signal<bool>,
44 pub editable_items: SignalModel<HashSet<String>>,
45 pub reorderable: Signal<bool>,
46 pub on_item_click: Option<Handler<(String, ev::MouseEvent)>>,
47 pub on_label_change: Option<Handler<(String, String)>>,
48 pub on_reorder: Option<Handler<(String, String, usize)>>,
49 pub drag_state: TreeDragState,
50}
51
52impl TreeState {
53 pub fn from_collection(collection: CollectionState, tree_fields: TreeStateFields) -> Self {
54 Self {
55 expansion: collection.expansion,
56 selection: collection.selection,
57 focus: collection.focus,
58 registry: collection.registry,
59 dom_registry: collection.dom_registry,
60 disabled_items: collection.disabled_items,
61 disabled_items_focusable: collection.disabled_items_focusable,
62 on_item_click: collection.on_item_click,
63 size: tree_fields.size,
64 editable: tree_fields.editable,
65 editable_items: tree_fields.editable_items,
66 reorderable: tree_fields.reorderable,
67 on_label_change: tree_fields.on_label_change,
68 on_reorder: tree_fields.on_reorder,
69 drag_state: tree_fields.drag_state,
70 }
71 }
72
73 pub fn collection(&self) -> CollectionState {
74 CollectionState {
75 expansion: self.expansion.clone(),
76 selection: self.selection.clone(),
77 focus: self.focus.clone(),
78 registry: self.registry.clone(),
79 dom_registry: self.dom_registry.clone(),
80 disabled_items: self.disabled_items.clone(),
81 disabled_items_focusable: self.disabled_items_focusable,
82 on_item_click: self.on_item_click.clone(),
83 }
84 }
85
86 pub fn is_item_disabled(&self, item_id: &str) -> bool {
87 self.disabled_items.with(|items| items.contains(item_id))
88 }
89
90 pub fn is_item_editable(&self, item_id: &str) -> bool {
91 if !self.editable.get() {
92 return false;
93 }
94 self.editable_items
95 .with(|items| items.is_empty() || items.contains(item_id))
96 }
97
98 pub fn is_item_open(&self, item_id: &str) -> bool {
99 self.expansion.is_open(item_id)
100 }
101
102 pub fn is_item_selected(&self, item_id: &str) -> bool {
103 self.selection.is_selected(item_id)
104 }
105
106 pub fn visible_ordered_ids(&self) -> Vec<String> {
107 let expansion = self.expansion.clone();
108 self.registry
109 .visible_ordered_ids(move |id| expansion.is_open(id))
110 }
111}
112
113#[derive(Clone)]
114pub struct TreeStateFields {
115 pub size: Signal<TreeSize>,
116 pub editable: Signal<bool>,
117 pub editable_items: SignalModel<HashSet<String>>,
118 pub reorderable: Signal<bool>,
119 pub on_label_change: Option<Handler<(String, String)>>,
120 pub on_reorder: Option<Handler<(String, String, usize)>>,
121 pub drag_state: TreeDragState,
122}
123
124#[derive(Clone)]
125pub struct TreeStateInjection(pub TreeState);
126
127impl TreeStateInjection {
128 pub fn expect_context() -> TreeState {
129 expect_context::<Self>().0
130 }
131
132 pub fn use_context() -> Option<TreeState> {
133 use_context::<Self>().map(|injection| injection.0)
134 }
135}