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