mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34:15 -05:00
feat: functional optimization
This commit is contained in:
parent
4c16a51d14
commit
6b9b05b59e
18 changed files with 129 additions and 192 deletions
|
@ -34,6 +34,7 @@ icondata = { version = "0.1.0", features = [
|
||||||
] }
|
] }
|
||||||
icondata_core = "0.0.2"
|
icondata_core = "0.0.2"
|
||||||
uuid = { version = "1.5.0", features = ["v4"] }
|
uuid = { version = "1.5.0", features = ["v4"] }
|
||||||
|
cfg-if = "1.0.0"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["demo"]
|
members = ["demo"]
|
||||||
|
|
|
@ -95,12 +95,12 @@ pub fn Button(
|
||||||
"--thaw-background-color-active: {};",
|
"--thaw-background-color-active: {};",
|
||||||
theme.button.color_text_active
|
theme.button.color_text_active
|
||||||
));
|
));
|
||||||
css_vars.push_str(&format!("--thaw-ripple-color: #0000;"));
|
css_vars.push_str("--thaw-ripple-color: #0000;");
|
||||||
} else {
|
} else {
|
||||||
css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};"));
|
css_vars.push_str(&format!("--thaw-font-color-hover: {bg_color};"));
|
||||||
css_vars.push_str("--thaw-border-color: #555a;");
|
css_vars.push_str("--thaw-border-color: #555a;");
|
||||||
css_vars.push_str("--thaw-border-color-hover: #555;");
|
css_vars.push_str("--thaw-border-color-hover: #555;");
|
||||||
css_vars.push_str(&format!("--thaw-ripple-color: #0000;"));
|
css_vars.push_str("--thaw-ripple-color: #0000;");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,23 +6,14 @@ pub fn CheckboxGroup(
|
||||||
#[prop(optional, into)] value: RwSignal<HashSet<String>>,
|
#[prop(optional, into)] value: RwSignal<HashSet<String>>,
|
||||||
children: Children,
|
children: Children,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let injection_key = CheckboxGroupInjectionKey::new(value.into());
|
provide_context(CheckboxGroupInjection(value));
|
||||||
provide_context(injection_key);
|
|
||||||
|
|
||||||
children()
|
children()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct CheckboxGroupInjectionKey {
|
pub(crate) struct CheckboxGroupInjection(pub RwSignal<HashSet<String>>);
|
||||||
pub value: RwSignal<HashSet<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CheckboxGroupInjectionKey {
|
pub(crate) fn use_checkbox_group() -> CheckboxGroupInjection {
|
||||||
pub fn new(value: RwSignal<HashSet<String>>) -> Self {
|
expect_context()
|
||||||
Self { value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn use_checkbox_group() -> CheckboxGroupInjectionKey {
|
|
||||||
expect_context::<CheckboxGroupInjectionKey>()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,13 @@ pub fn CheckboxItem(
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let checkbox_group = use_checkbox_group();
|
let checkbox_group = use_checkbox_group();
|
||||||
let checked = checkbox_group
|
let checked = checkbox_group
|
||||||
.value
|
.0
|
||||||
.with_untracked(|checkbox_group| checkbox_group.contains(&key));
|
.with_untracked(|checkbox_group| checkbox_group.contains(&key));
|
||||||
let checked = create_rw_signal(checked);
|
let checked = create_rw_signal(checked);
|
||||||
let item_key = store_value(key);
|
let item_key = store_value(key);
|
||||||
|
|
||||||
_ = checked.watch(move |checked| {
|
_ = checked.watch(move |checked| {
|
||||||
checkbox_group.value.update(move |checkbox_group| {
|
checkbox_group.0.update(move |checkbox_group| {
|
||||||
if *checked {
|
if *checked {
|
||||||
checkbox_group.insert(item_key.get_value());
|
checkbox_group.insert(item_key.get_value());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub fn Grid(
|
||||||
#[prop(optional, into)] y_gap: MaybeSignal<i32>,
|
#[prop(optional, into)] y_gap: MaybeSignal<i32>,
|
||||||
children: Children,
|
children: Children,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let grid_injection_key = GridInjectionKey::new(x_gap);
|
let grid_injection_key = GridInjection::new(x_gap);
|
||||||
provide_context(grid_injection_key);
|
provide_context(grid_injection_key);
|
||||||
|
|
||||||
let style = create_memo(move |_| {
|
let style = create_memo(move |_| {
|
||||||
|
@ -31,16 +31,16 @@ pub fn Grid(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GridInjectionKey {
|
pub(crate) struct GridInjection {
|
||||||
x_gap: MaybeSignal<i32>,
|
x_gap: MaybeSignal<i32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GridInjectionKey {
|
impl GridInjection {
|
||||||
pub fn new(x_gap: MaybeSignal<i32>) -> Self {
|
pub fn new(x_gap: MaybeSignal<i32>) -> Self {
|
||||||
Self { x_gap }
|
Self { x_gap }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_grid() -> GridInjectionKey {
|
pub(crate) fn use_grid() -> GridInjection {
|
||||||
expect_context::<GridInjectionKey>()
|
expect_context()
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub fn LoadingBarProvider(children: Children) -> impl IntoView {
|
||||||
pub struct LoadingBarInjection {
|
pub struct LoadingBarInjection {
|
||||||
loading_bar_ref: ComponentRef<LoadingBarRef>,
|
loading_bar_ref: ComponentRef<LoadingBarRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Copy for LoadingBarInjection {}
|
impl Copy for LoadingBarInjection {}
|
||||||
|
|
||||||
impl LoadingBarInjection {
|
impl LoadingBarInjection {
|
||||||
|
|
|
@ -99,7 +99,7 @@ pub(crate) fn LoadingBar(#[prop(optional)] comp_ref: ComponentRef<LoadingBarRef>
|
||||||
view! {
|
view! {
|
||||||
<div
|
<div
|
||||||
class="thaw-loading-bar-container"
|
class="thaw-loading-bar-container"
|
||||||
style=move || (!loading.get()).then(|| "display: none;")
|
style=move || (!loading.get()).then_some("display: none;")
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="thaw-loading-bar"
|
class="thaw-loading-bar"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{use_menu, MenuInjectionKey};
|
use super::use_menu;
|
||||||
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme};
|
use crate::{theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
|
||||||
|
@ -12,7 +12,10 @@ pub fn MenuItem(
|
||||||
let menu = use_menu();
|
let menu = use_menu();
|
||||||
let click_key = key.clone();
|
let click_key = key.clone();
|
||||||
let on_click = move |_| {
|
let on_click = move |_| {
|
||||||
menu.set(MenuInjectionKey::new(click_key.get()));
|
let click_key = click_key.get();
|
||||||
|
if menu.0.with(|key| key != &click_key) {
|
||||||
|
menu.0.set(click_key);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let css_vars = create_memo(move |_| {
|
let css_vars = create_memo(move |_| {
|
||||||
|
@ -33,7 +36,7 @@ pub fn MenuItem(
|
||||||
<div class="thaw-menu-item">
|
<div class="thaw-menu-item">
|
||||||
<div
|
<div
|
||||||
class="thaw-menu-item__content"
|
class="thaw-menu-item__content"
|
||||||
class=("thaw-menu-item__content--selected", move || menu.get().value == key.get())
|
class=("thaw-menu-item__content--selected", move || menu.0.get() == key.get())
|
||||||
on:click=on_click
|
on:click=on_click
|
||||||
style=move || css_vars.get()
|
style=move || css_vars.get()
|
||||||
>
|
>
|
||||||
|
|
|
@ -9,37 +9,13 @@ pub use theme::MenuTheme;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Menu(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView {
|
pub fn Menu(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView {
|
||||||
let menu_injection_key = create_rw_signal(MenuInjectionKey::new(value.get_untracked()));
|
provide_context(MenuInjection(value));
|
||||||
create_effect(move |_| {
|
|
||||||
let selected_key = value.get();
|
|
||||||
let key = menu_injection_key.get_untracked();
|
|
||||||
if selected_key != key.value {
|
|
||||||
menu_injection_key.set(MenuInjectionKey::new(selected_key));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
create_effect(move |_| {
|
|
||||||
let selected_key = value.get_untracked();
|
|
||||||
let key = menu_injection_key.get();
|
|
||||||
if selected_key != key.value {
|
|
||||||
value.set(key.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
provide_context(menu_injection_key);
|
|
||||||
view! { <div class="thaw-menu">{children()}</div> }
|
view! { <div class="thaw-menu">{children()}</div> }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MenuInjectionKey {
|
pub(crate) struct MenuInjection(pub RwSignal<String>);
|
||||||
value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MenuInjectionKey {
|
pub(crate) fn use_menu() -> MenuInjection {
|
||||||
pub fn new(value: String) -> Self {
|
expect_context()
|
||||||
Self { value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn use_menu() -> RwSignal<MenuInjectionKey> {
|
|
||||||
expect_context::<RwSignal<MenuInjectionKey>>()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
use crate::{theme::use_theme, Icon, Theme};
|
|
||||||
use icondata::*;
|
|
||||||
use leptos::*;
|
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
|
||||||
pub enum MessageVariant {
|
|
||||||
#[default]
|
|
||||||
Success,
|
|
||||||
Warning,
|
|
||||||
Error,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MessageVariant {
|
|
||||||
fn icon(&self) -> Icon {
|
|
||||||
match self {
|
|
||||||
MessageVariant::Success => icondata::Icon::Ai(AiCloseCircleFilled),
|
|
||||||
MessageVariant::Warning => icondata::Icon::Ai(AiExclamationCircleFilled),
|
|
||||||
MessageVariant::Error => icondata::Icon::Ai(AiCheckCircleFilled),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn theme_color(&self, theme: &Theme) -> String {
|
|
||||||
match self {
|
|
||||||
MessageVariant::Success => theme.common.color_success.clone(),
|
|
||||||
MessageVariant::Warning => theme.common.color_warning.clone(),
|
|
||||||
MessageVariant::Error => theme.common.color_error.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
|
||||||
pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView {
|
|
||||||
let theme = use_theme(Theme::light);
|
|
||||||
let css_vars = create_memo(move |_| {
|
|
||||||
let mut css_vars = String::new();
|
|
||||||
theme.with(|theme| {
|
|
||||||
css_vars.push_str(&format!(
|
|
||||||
"--thaw-background-color: {}",
|
|
||||||
theme.message.background_color
|
|
||||||
))
|
|
||||||
});
|
|
||||||
css_vars
|
|
||||||
});
|
|
||||||
let style = theme.with_untracked(|theme| format!("color: {};", variant.theme_color(theme)));
|
|
||||||
view! {
|
|
||||||
<div class="thaw-message-wrapper">
|
|
||||||
<div class="thaw-message" style=move || css_vars.get()>
|
|
||||||
<div class="thaw-message__icon">
|
|
||||||
<Icon icon=variant.icon() style/>
|
|
||||||
</div>
|
|
||||||
<div class="thaw-message__content">{content}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{message::Message, message_provider::MessageType};
|
use super::{message_provider::MessageType, Message};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use super::{message::MessageVariant, message_environment::MessageEnvironment};
|
use super::{message_environment::MessageEnvironment, MessageVariant};
|
||||||
use crate::{mount_style, teleport::Teleport};
|
use crate::{mount_style, teleport::Teleport};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
|
@ -1,8 +1,60 @@
|
||||||
mod message;
|
|
||||||
mod message_environment;
|
mod message_environment;
|
||||||
mod message_provider;
|
mod message_provider;
|
||||||
mod theme;
|
mod theme;
|
||||||
|
|
||||||
pub use message::*;
|
use crate::{theme::use_theme, Icon, Theme};
|
||||||
|
use icondata::*;
|
||||||
|
use leptos::*;
|
||||||
pub use message_provider::*;
|
pub use message_provider::*;
|
||||||
pub use theme::MessageTheme;
|
pub use theme::MessageTheme;
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub enum MessageVariant {
|
||||||
|
#[default]
|
||||||
|
Success,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MessageVariant {
|
||||||
|
fn icon(&self) -> Icon {
|
||||||
|
match self {
|
||||||
|
MessageVariant::Success => icondata::Icon::Ai(AiCloseCircleFilled),
|
||||||
|
MessageVariant::Warning => icondata::Icon::Ai(AiExclamationCircleFilled),
|
||||||
|
MessageVariant::Error => icondata::Icon::Ai(AiCheckCircleFilled),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn theme_color(&self, theme: &Theme) -> String {
|
||||||
|
match self {
|
||||||
|
MessageVariant::Success => theme.common.color_success.clone(),
|
||||||
|
MessageVariant::Warning => theme.common.color_warning.clone(),
|
||||||
|
MessageVariant::Error => theme.common.color_error.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub(crate) fn Message(variant: MessageVariant, content: String) -> impl IntoView {
|
||||||
|
let theme = use_theme(Theme::light);
|
||||||
|
let css_vars = create_memo(move |_| {
|
||||||
|
let mut css_vars = String::new();
|
||||||
|
theme.with(|theme| {
|
||||||
|
css_vars.push_str(&format!(
|
||||||
|
"--thaw-background-color: {}",
|
||||||
|
theme.message.background_color
|
||||||
|
))
|
||||||
|
});
|
||||||
|
css_vars
|
||||||
|
});
|
||||||
|
let style = theme.with_untracked(|theme| format!("color: {};", variant.theme_color(theme)));
|
||||||
|
view! {
|
||||||
|
<div class="thaw-message-wrapper">
|
||||||
|
<div class="thaw-message" style=move || css_vars.get()>
|
||||||
|
<div class="thaw-message__icon">
|
||||||
|
<Icon icon=variant.icon() style/>
|
||||||
|
</div>
|
||||||
|
<div class="thaw-message__content">{content}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,24 +21,7 @@ pub fn Tabbar(
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
provide_context(TabbarInjection(value));
|
||||||
let tabbar_injection_key = create_rw_signal(TabbarInjectionKey::new(value.get()));
|
|
||||||
create_effect(move |_| {
|
|
||||||
let selected_key = value.get();
|
|
||||||
let key = tabbar_injection_key.get_untracked();
|
|
||||||
if selected_key != key.value {
|
|
||||||
tabbar_injection_key.set(TabbarInjectionKey::new(selected_key));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
create_effect(move |_| {
|
|
||||||
let selected_key = value.get_untracked();
|
|
||||||
let key = tabbar_injection_key.get();
|
|
||||||
if selected_key != key.value {
|
|
||||||
value.set(key.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
provide_context(tabbar_injection_key);
|
|
||||||
view! {
|
view! {
|
||||||
<div class="thaw-tabbar" style=move || css_vars.get()>
|
<div class="thaw-tabbar" style=move || css_vars.get()>
|
||||||
{children()}
|
{children()}
|
||||||
|
@ -47,16 +30,8 @@ pub fn Tabbar(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TabbarInjectionKey {
|
pub(crate) struct TabbarInjection(pub RwSignal<String>);
|
||||||
value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TabbarInjectionKey {
|
pub(crate) fn use_tabbar() -> TabbarInjection {
|
||||||
pub fn new(value: String) -> Self {
|
expect_context()
|
||||||
Self { value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn use_tabbar() -> RwSignal<TabbarInjectionKey> {
|
|
||||||
use_context::<RwSignal<TabbarInjectionKey>>().expect("TabbarInjectionKey not exist")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{use_tabbar, TabbarInjectionKey};
|
use super::use_tabbar;
|
||||||
use crate::components::*;
|
use crate::components::*;
|
||||||
use crate::utils::StoredMaybeSignal;
|
use crate::utils::StoredMaybeSignal;
|
||||||
use crate::{icon::*, theme::use_theme, utils::mount_style::mount_style, Theme};
|
use crate::{icon::*, theme::use_theme, utils::mount_style::mount_style, Theme};
|
||||||
|
@ -15,7 +15,10 @@ pub fn TabbarItem(
|
||||||
let tabbar = use_tabbar();
|
let tabbar = use_tabbar();
|
||||||
let key: StoredMaybeSignal<_> = key.into();
|
let key: StoredMaybeSignal<_> = key.into();
|
||||||
let on_click = move |_| {
|
let on_click = move |_| {
|
||||||
tabbar.set(TabbarInjectionKey::new(key.get()));
|
let click_key = key.get();
|
||||||
|
if tabbar.0.with(|key| key != &click_key) {
|
||||||
|
tabbar.0.set(click_key);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let css_vars = create_memo(move |_| {
|
let css_vars = create_memo(move |_| {
|
||||||
|
@ -30,7 +33,7 @@ pub fn TabbarItem(
|
||||||
view! {
|
view! {
|
||||||
<div
|
<div
|
||||||
class="thaw-tabbar-item"
|
class="thaw-tabbar-item"
|
||||||
class=("thaw-tabbar-item--selected", move || tabbar.get().value == key.get())
|
class=("thaw-tabbar-item--selected", move || tabbar.0.get() == key.get())
|
||||||
on:click=on_click
|
on:click=on_click
|
||||||
style=move || css_vars.get()
|
style=move || css_vars.get()
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::utils::mount_style::mount_style;
|
use crate::utils::mount_style::mount_style;
|
||||||
use leptos::*;
|
use cfg_if::cfg_if;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use web_sys::Element;
|
|
||||||
|
|
||||||
pub struct ToastOptions {
|
pub struct ToastOptions {
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
@ -10,26 +9,20 @@ pub struct ToastOptions {
|
||||||
|
|
||||||
pub fn show_toast(options: ToastOptions) {
|
pub fn show_toast(options: ToastOptions) {
|
||||||
mount_style("toast", include_str!("./toast.css"));
|
mount_style("toast", include_str!("./toast.css"));
|
||||||
|
cfg_if! { if #[cfg(target_arch = "wasm32")] {
|
||||||
let parent = Element::from(document().body().expect("body element not to exist"));
|
use leptos::{leptos_dom::Mountable, *};
|
||||||
let children = view! { <div class="thaw-toast">{options.message}</div> };
|
let mount = document().body().expect("body element not to exist");
|
||||||
let node = children.into_view();
|
let children = view! { <div class="thaw-toast">{options.message}</div> };
|
||||||
|
let node = children.into_view();
|
||||||
#[cfg(target_arch = "wasm32")]
|
|
||||||
{
|
|
||||||
use leptos::leptos_dom::Mountable;
|
|
||||||
let node = node.get_mountable_node();
|
let node = node.get_mountable_node();
|
||||||
parent.append_child(&node).unwrap();
|
_ = mount.append_child(&node);
|
||||||
set_timeout(
|
set_timeout(
|
||||||
move || {
|
move || {
|
||||||
_ = parent.remove_child(&node);
|
_ = mount.remove_child(&node);
|
||||||
},
|
},
|
||||||
options.duration,
|
options.duration,
|
||||||
);
|
);
|
||||||
}
|
} else {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
_ = options;
|
||||||
{
|
}}
|
||||||
_ = parent;
|
|
||||||
_ = node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub use tab::*;
|
||||||
pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView {
|
pub fn Tabs(#[prop(optional, into)] value: RwSignal<String>, children: Children) -> impl IntoView {
|
||||||
mount_style("tabs", include_str!("./tabs.css"));
|
mount_style("tabs", include_str!("./tabs.css"));
|
||||||
let tab_options_vec = create_rw_signal(vec![]);
|
let tab_options_vec = create_rw_signal(vec![]);
|
||||||
provide_context(TabsInjectionKey {
|
provide_context(TabsInjection {
|
||||||
active_key: value,
|
active_key: value,
|
||||||
tab_options_vec,
|
tab_options_vec,
|
||||||
});
|
});
|
||||||
|
@ -106,12 +106,12 @@ pub(crate) struct TabsLabelLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TabsInjectionKey {
|
pub(crate) struct TabsInjection {
|
||||||
active_key: RwSignal<String>,
|
active_key: RwSignal<String>,
|
||||||
tab_options_vec: RwSignal<Vec<TabOption>>,
|
tab_options_vec: RwSignal<Vec<TabOption>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TabsInjectionKey {
|
impl TabsInjection {
|
||||||
pub fn get_key(&self) -> String {
|
pub fn get_key(&self) -> String {
|
||||||
self.active_key.get()
|
self.active_key.get()
|
||||||
}
|
}
|
||||||
|
@ -123,6 +123,6 @@ impl TabsInjectionKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_tabs() -> TabsInjectionKey {
|
pub(crate) fn use_tabs() -> TabsInjection {
|
||||||
use_context::<TabsInjectionKey>().expect("TabsInjectionKey not exist")
|
expect_context()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,30 @@
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use web_sys::Element;
|
|
||||||
|
|
||||||
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
|
/// https://github.com/solidjs/solid/blob/main/packages/solid/web/src/index.ts#L56
|
||||||
#[component]
|
#[component]
|
||||||
pub fn Teleport(#[prop(optional)] to: Option<&'static str>, children: Children) -> impl IntoView {
|
pub fn Teleport(
|
||||||
let parent = if let Some(to) = to {
|
#[prop(into, optional)] mount: Option<web_sys::Element>,
|
||||||
document()
|
children: Children,
|
||||||
.query_selector(to)
|
) -> impl IntoView {
|
||||||
.expect("element not to exist")
|
cfg_if! { if #[cfg(target_arch = "wasm32")] {
|
||||||
.expect("element not to exist")
|
use leptos::{
|
||||||
} else {
|
wasm_bindgen::JsCast,
|
||||||
Element::from(document().body().expect("body element not to exist"))
|
leptos_dom::Mountable
|
||||||
};
|
};
|
||||||
|
let mount = mount.unwrap_or_else(|| {
|
||||||
#[cfg(target_arch = "wasm32")]
|
document()
|
||||||
{
|
.body()
|
||||||
use leptos::leptos_dom::Mountable;
|
.expect("body element not to exist")
|
||||||
|
.unchecked_into()
|
||||||
|
});
|
||||||
let node = children().into_view();
|
let node = children().into_view();
|
||||||
let node = node.get_mountable_node();
|
let node = node.get_mountable_node();
|
||||||
parent.append_child(&node).unwrap();
|
_ = mount.append_child(&node);
|
||||||
on_cleanup(move || {
|
on_cleanup(move || {
|
||||||
_ = parent.remove_child(&node);
|
_ = mount.remove_child(&node);
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
_ = mount;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
{
|
|
||||||
_ = parent;
|
|
||||||
_ = children;
|
_ = children;
|
||||||
}
|
}}
|
||||||
|
|
||||||
view! { <></> }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue