orbital_base_components/tab_list/
mod.rs1mod tab;
2
3pub use tab::BaseTab;
4
5use leptos::{context::Provider, prelude::*};
6use std::collections::HashMap;
7
8#[component]
9pub fn BaseTabList(
10 #[prop(optional, into)] class: MaybeProp<String>,
11 #[prop(optional, into)] selected_value: Option<RwSignal<String>>,
12 children: Children,
13) -> impl IntoView {
14 let selected_value = selected_value.unwrap_or_else(|| RwSignal::new(String::new()));
15 let registered_tabs = RwSignal::new(HashMap::new());
16
17 let root_class = Memo::new(move |_| {
18 let extra = class.get().unwrap_or_default();
19 if extra.is_empty() {
20 "orbital-tab-list".to_string()
21 } else {
22 format!("orbital-tab-list {extra}")
23 }
24 });
25
26 view! {
27 <Provider value=TabListInjection {
28 previous_selected_value: StoredValue::new(selected_value.get_untracked()),
29 selected_value,
30 registered_tabs,
31 }>
32 <div class=root_class role="tablist">
33 {children()}
34 </div>
35 </Provider>
36 }
37}
38
39#[derive(Clone, Copy)]
40pub(crate) struct TabListInjection {
41 pub previous_selected_value: StoredValue<String>,
42 pub selected_value: RwSignal<String>,
43 pub registered_tabs: RwSignal<HashMap<String, TabRegisterData>>,
44}
45
46impl TabListInjection {
47 pub fn expect_context() -> Self {
48 expect_context()
49 }
50
51 pub fn register(&self, data: TabRegisterData) {
52 self.registered_tabs.update(|map| {
53 map.insert(data.value.clone(), data);
54 });
55 }
56
57 pub fn unregister(&self, value: &String) {
58 self.registered_tabs.update(|map| {
59 map.remove(value);
60 });
61 }
62
63 pub fn on_select(&self, value: String) {
64 self.previous_selected_value
65 .set_value(self.selected_value.get_untracked());
66 self.selected_value.set(value);
67 }
68}
69
70pub(crate) struct TabRegisterData {
71 pub value: String,
72 pub tab_ref: NodeRef<leptos::html::Button>,
73}