Skip to main content

orbital_base_components/collection/state/
mod.rs

1mod cascade;
2mod expansion;
3mod focus;
4mod keyboard;
5mod registry;
6mod selection;
7
8pub use cascade::{
9    apply_cascade, checkbox_state, shift_range_in_visible, typeahead_match, CollectionCheckboxState,
10};
11pub use expansion::{CollectionExpansionState, ExpansionTrigger};
12pub use focus::{CollectionFocusState, CollectionItemDomRegistry};
13pub use keyboard::{collection_keyboard_action, CollectionKeyboardAction};
14pub use registry::{CollectionRegistry, CollectionRegistryEntry};
15pub use selection::{CollectionSelectionMode, CollectionSelectionState};
16
17use leptos::{ev, prelude::*};
18use std::collections::HashSet;
19
20use crate::signals::SignalModel;
21use crate::Handler;
22
23/// DOM/role-agnostic collection behavior state shared by Tree and Navigation.
24#[derive(Clone)]
25pub struct CollectionState {
26    pub expansion: CollectionExpansionState,
27    pub selection: CollectionSelectionState,
28    pub focus: CollectionFocusState,
29    pub registry: CollectionRegistry,
30    pub dom_registry: CollectionItemDomRegistry,
31    pub disabled_items: SignalModel<HashSet<String>>,
32    pub disabled_items_focusable: Signal<bool>,
33    pub on_item_click: Option<Handler<(String, ev::MouseEvent)>>,
34}
35
36impl CollectionState {
37    pub fn is_item_disabled(&self, item_id: &str) -> bool {
38        self.disabled_items.with(|items| items.contains(item_id))
39    }
40
41    pub fn is_item_open(&self, item_id: &str) -> bool {
42        self.expansion.is_open(item_id)
43    }
44
45    pub fn is_item_selected(&self, item_id: &str) -> bool {
46        self.selection.is_selected(item_id)
47    }
48
49    pub fn visible_ordered_ids(&self) -> Vec<String> {
50        let expansion = self.expansion.clone();
51        self.registry
52            .visible_ordered_ids(move |id| expansion.is_open(id))
53    }
54}
55
56#[derive(Clone)]
57pub struct CollectionStateInjection(pub CollectionState);
58
59impl CollectionStateInjection {
60    pub fn expect_context() -> CollectionState {
61        expect_context::<Self>().0
62    }
63
64    pub fn use_context() -> Option<CollectionState> {
65        use_context::<Self>().map(|injection| injection.0)
66    }
67}