mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
refactor: tab
This commit is contained in:
parent
938342ab1f
commit
e8942dc212
11 changed files with 95 additions and 93 deletions
|
@ -82,8 +82,8 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
|||
<Route path="/spin-button" view=SpinButtonMdPage/>
|
||||
<Route path="/spinner" view=SpinnerMdPage/>
|
||||
<Route path="/switch" view=SwitchMdPage/>
|
||||
<Route path="/tab-list" view=TabListMdPage/>
|
||||
<Route path="/table" view=TableMdPage/>
|
||||
<Route path="/tabs" view=TabsMdPage/>
|
||||
<Route path="/tag" view=TagMdPage/>
|
||||
<Route path="/text" view=TextMdPage/>
|
||||
<Route path="/time-picker" view=TimePickerMdPage/>
|
||||
|
|
|
@ -175,6 +175,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/spinner".into(),
|
||||
label: "Spinner".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/tab-list".into(),
|
||||
label: "Tab List".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/tag".into(),
|
||||
label: "Tag".into(),
|
||||
|
@ -251,10 +255,6 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
|||
value: "/components/loading-bar".into(),
|
||||
label: "Loading Bar".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/tabs".into(),
|
||||
label: "Tabs".into(),
|
||||
},
|
||||
MenuItemOption {
|
||||
value: "/components/alert".into(),
|
||||
label: "Alert".into(),
|
||||
|
|
|
@ -6,10 +6,16 @@ let selected_value = RwSignal::new(String::new());
|
|||
view! {
|
||||
<TabList selected_value>
|
||||
<Tab value="apple">
|
||||
"🍎 Apple"
|
||||
"Apple"
|
||||
</Tab>
|
||||
<Tab value="pear">
|
||||
"🍐 Pear"
|
||||
"Pear"
|
||||
</Tab>
|
||||
<Tab value="item1">
|
||||
"Item 1"
|
||||
</Tab>
|
||||
<Tab value="item2">
|
||||
"Item 2"
|
||||
</Tab>
|
||||
</TabList>
|
||||
}
|
|
@ -64,8 +64,8 @@ pub fn include_md(_token_stream: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
"SpinButtonMdPage" => "../docs/spin_button/mod.md",
|
||||
"SpinnerMdPage" => "../docs/spinner/mod.md",
|
||||
"SwitchMdPage" => "../docs/switch/mod.md",
|
||||
"TabListMdPage" => "../docs/tab_list/mod.md",
|
||||
"TableMdPage" => "../docs/table/mod.md",
|
||||
"TabsMdPage" => "../docs/tabs/mod.md",
|
||||
"TagMdPage" => "../docs/tag/mod.md",
|
||||
"TimePickerMdPage" => "../docs/time_picker/mod.md",
|
||||
"TextMdPage" => "../docs/text/mod.md",
|
||||
|
|
|
@ -38,7 +38,7 @@ mod spin_button;
|
|||
mod spinner;
|
||||
mod switch;
|
||||
mod table;
|
||||
mod tabs;
|
||||
mod tab_list;
|
||||
mod tag;
|
||||
mod text;
|
||||
mod theme;
|
||||
|
@ -84,7 +84,7 @@ pub use spin_button::*;
|
|||
pub use spinner::*;
|
||||
pub use switch::*;
|
||||
pub use table::*;
|
||||
pub use tabs::*;
|
||||
pub use tab_list::*;
|
||||
pub use tag::*;
|
||||
pub use text::*;
|
||||
pub use thaw_utils::{create_component_ref, ComponentRef, SignalWatch};
|
||||
|
|
77
thaw/src/tab_list/tab.rs
Normal file
77
thaw/src/tab_list/tab.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
use super::{TabListInjection, TabRegisterData};
|
||||
use leptos::*;
|
||||
use std::ops::Deref;
|
||||
use thaw_utils::{class_list, mount_style};
|
||||
|
||||
#[component]
|
||||
pub fn Tab(
|
||||
#[prop(optional, into)] class: MaybeProp<String>,
|
||||
#[prop(into)] value: String,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("tab", include_str!("./tab.css"));
|
||||
|
||||
let tab_ref = NodeRef::<html::Button>::new();
|
||||
let tab_list = TabListInjection::use_();
|
||||
let value = StoredValue::new(value);
|
||||
tab_list.register(TabRegisterData {
|
||||
value: value.get_value(),
|
||||
tab_ref,
|
||||
});
|
||||
on_cleanup(move || {
|
||||
value.with_value(|v| tab_list.unregister(v));
|
||||
});
|
||||
|
||||
let selected = Memo::new(move |_| {
|
||||
tab_list
|
||||
.selected_value
|
||||
.with(|selected_value| value.with_value(|value| value == selected_value))
|
||||
});
|
||||
|
||||
let on_select = move |_| {
|
||||
tab_list.registered_tabs.with_untracked(|registered_tabs| {
|
||||
if let Some(previous_selected_tab) = tab_list
|
||||
.selected_value
|
||||
.with_untracked(|selected_value| registered_tabs.get(selected_value))
|
||||
{
|
||||
let tab_el = tab_ref.get_untracked().unwrap();
|
||||
let selected_tab_rect = tab_el.get_bounding_client_rect();
|
||||
let previous_selected_tab_rect = previous_selected_tab
|
||||
.tab_ref
|
||||
.get_untracked()
|
||||
.unwrap()
|
||||
.get_bounding_client_rect();
|
||||
|
||||
let offset = previous_selected_tab_rect.x() - selected_tab_rect.x();
|
||||
let scale = previous_selected_tab_rect.width() / selected_tab_rect.width();
|
||||
|
||||
let style = tab_el.deref().style();
|
||||
let _ =
|
||||
style.set_property("--thaw-tab__indicator--offset", &format!("{offset:.0}px"));
|
||||
let _ = style.set_property("--thaw-tab__indicator--scale", &format!("{scale:.2}"));
|
||||
|
||||
request_animation_frame(move || {
|
||||
let _ = style.set_property("--thaw-tab__indicator--offset", "0px");
|
||||
let _ = style.set_property("--thaw-tab__indicator--scale", "1");
|
||||
});
|
||||
}
|
||||
});
|
||||
tab_list.on_select(value.get_value());
|
||||
};
|
||||
|
||||
view! {
|
||||
<button
|
||||
class=class_list![
|
||||
"thaw-tab", ("thaw-tab--selected", move || selected.get()), class
|
||||
]
|
||||
role="tab"
|
||||
aria-selected=move || if selected.get() { "true" } else { "false" }
|
||||
ref=tab_ref
|
||||
on:click=on_select
|
||||
>
|
||||
<span class="thaw-tab__content">
|
||||
{children()}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
use super::{TabListInjection, TabRegisterData};
|
||||
use leptos::*;
|
||||
use std::ops::Deref;
|
||||
use thaw_utils::{class_list, mount_style};
|
||||
|
||||
#[component]
|
||||
pub fn Tab(
|
||||
#[prop(optional, into)] class: MaybeProp<String>,
|
||||
#[prop(into)] value: String,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
mount_style("tab", include_str!("./tab.css"));
|
||||
|
||||
let tab_ref = NodeRef::<html::Button>::new();
|
||||
let tab_list = TabListInjection::use_();
|
||||
let value = StoredValue::new(value);
|
||||
tab_list.register(TabRegisterData {
|
||||
value: value.get_value(),
|
||||
tab_ref,
|
||||
});
|
||||
on_cleanup(move || {
|
||||
value.with_value(|v| tab_list.unregister(v));
|
||||
});
|
||||
|
||||
let selected = Memo::new(move |_| {
|
||||
tab_list
|
||||
.selected_value
|
||||
.with(|selected_value| value.with_value(|value| value == selected_value))
|
||||
});
|
||||
|
||||
Effect::new(move |_| {
|
||||
let selected = selected.get();
|
||||
if selected {
|
||||
tab_list.registered_tabs.with_untracked(|registered_tabs| {
|
||||
if let Some(previous_selected_tab) = tab_list
|
||||
.previous_selected_value
|
||||
.with_value(|selected_value| registered_tabs.get(selected_value))
|
||||
{
|
||||
let tab_el = tab_ref.get_untracked().unwrap();
|
||||
let selected_tab_rect = tab_el.get_bounding_client_rect();
|
||||
let previous_selected_tab_rect = previous_selected_tab
|
||||
.tab_ref
|
||||
.get_untracked()
|
||||
.unwrap()
|
||||
.get_bounding_client_rect();
|
||||
|
||||
let offset = previous_selected_tab_rect.x() - selected_tab_rect.x();
|
||||
let scale = previous_selected_tab_rect.width() / selected_tab_rect.width();
|
||||
|
||||
let style = tab_el.deref().style();
|
||||
let _ = style
|
||||
.set_property("--thaw-tab__indicator--offset", &format!("{offset:.0}px"));
|
||||
let _ =
|
||||
style.set_property("--thaw-tab__indicator--scale", &format!("{scale:.2}"));
|
||||
|
||||
// let _ = style.get_property_value("offsetWidth");
|
||||
|
||||
// let _ = style.set_property("--thaw-tab__indicator--offset", "0px");
|
||||
// let _ = style.set_property("--thaw-tab__indicator--scale", "1");
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
selected
|
||||
});
|
||||
|
||||
view! {
|
||||
<button
|
||||
class=class_list![
|
||||
"thaw-tab", ("thaw-tab--selected", move || selected.get()), class
|
||||
]
|
||||
role="tab"
|
||||
aria-selected=move || if selected.get() { "true" } else { "false" }
|
||||
ref=tab_ref
|
||||
style="--thaw-tab__indicator--offset: 0px; --thaw-tab__indicator--scale: 1"
|
||||
on:click=move |_| tab_list.on_select(value.get_value())
|
||||
>
|
||||
<span class="thaw-tab__content">
|
||||
{children()}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
}
|
|
@ -57,6 +57,7 @@ pub struct CommonTheme {
|
|||
pub spacing_horizontal_m_nudge: String,
|
||||
pub spacing_horizontal_m: String,
|
||||
pub spacing_horizontal_l: String,
|
||||
pub spacing_vertical_none: String,
|
||||
pub spacing_vertical_s: String,
|
||||
pub spacing_vertical_m_nudge: String,
|
||||
pub spacing_vertical_m: String,
|
||||
|
@ -137,6 +138,7 @@ impl CommonTheme {
|
|||
spacing_horizontal_m_nudge: "10px".into(),
|
||||
spacing_horizontal_m: "12px".into(),
|
||||
spacing_horizontal_l: "16px".into(),
|
||||
spacing_vertical_none: "0".into(),
|
||||
spacing_vertical_s: "8px".into(),
|
||||
spacing_vertical_m_nudge: "10px".into(),
|
||||
spacing_vertical_m: "12px".into(),
|
||||
|
|
Loading…
Add table
Reference in a new issue