mirror of
https://github.com/adoyle0/thaw.git
synced 2025-03-13 14:09:49 -04:00
Pref/class (#58)
* feat: add class_list macro * fix: ssr mode class_list * pref: replace with class_list
This commit is contained in:
parent
0b69e94181
commit
5ab09bb281
35 changed files with 316 additions and 304 deletions
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Icon, Theme,
|
||||
};
|
||||
use icondata::AiIcon;
|
||||
|
@ -86,14 +84,8 @@ pub fn Alert(
|
|||
.into()
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class:thaw-alert=true
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<div class=class_list!["thaw-alert", move || class.get()] style=move || css_vars.get()>
|
||||
<Icon icon class="thaw-alert__icon"/>
|
||||
<div>
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
mod theme;
|
||||
|
||||
use crate::utils::{dyn_classes, ssr_class};
|
||||
use crate::{
|
||||
components::{Binder, Follower, FollowerPlacement, FollowerWidth},
|
||||
use_theme,
|
||||
utils::{mount_style, StoredMaybeSignal},
|
||||
utils::{class_list::class_list, mount_style, StoredMaybeSignal},
|
||||
ComponentRef, Input, InputPrefix, InputRef, InputSuffix, Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -126,13 +125,10 @@ pub fn AutoComplete(
|
|||
comp_ref.load(AutoCompleteRef { input_ref });
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<Binder target_ref=auto_complete_ref>
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class:thaw-auto-complete=true
|
||||
class=class_list!["thaw-auto-complete", move || class.get()]
|
||||
ref=auto_complete_ref
|
||||
on:keydown=on_keydown
|
||||
>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -35,14 +33,8 @@ pub fn Avatar(
|
|||
});
|
||||
mount_style("avatar", include_str!("./avatar.css"));
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<span
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class:thaw-avatar=true
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<span class=class_list!["thaw-avatar", move || class.get()] style=move || css_vars.get()>
|
||||
{move || {
|
||||
let src = src.get();
|
||||
(!src.is_empty()).then(|| view! { <img src=src/> })
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -59,18 +56,13 @@ pub fn Badge(
|
|||
value.to_string()
|
||||
}
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class="thaw-badge" style=move || css_vars.get()>
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-badge__sup"
|
||||
class=("thaw-badge__sup--value", move || !dot.get() && !value.get().is_empty())
|
||||
class=("thaw-badge__sup--dot", move || dot.get())
|
||||
>
|
||||
{move || value.get()}
|
||||
</div>
|
||||
<div class=class_list![
|
||||
"thaw-badge__sup", ("thaw-badge__sup--value", move || ! dot.get() && ! value.get()
|
||||
.is_empty()), ("thaw-badge__sup--dot", move || dot.get()), move || class.get()
|
||||
]>{move || value.get()}</div>
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
use super::use_breadcrumb_separator;
|
||||
use crate::utils::class_list::class_list;
|
||||
use leptos::*;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::ssr_class;
|
||||
|
||||
#[component]
|
||||
pub fn BreadcrumbItem(
|
||||
#[prop(optional, into)] class: MaybeSignal<String>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let breadcrumb_separator = use_breadcrumb_separator();
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<li class="thaw-breadcrumb-item">
|
||||
<span class=ssr_class use:dyn_classes=class class="thaw-breadcrumb-item__link">
|
||||
{children()}
|
||||
</span>
|
||||
<span class=class_list![
|
||||
"thaw-breadcrumb-item__link", move || class.get()
|
||||
]>{children()}</span>
|
||||
<span class="thaw-breadcrumb-item__separator">
|
||||
{move || breadcrumb_separator.0.get()}
|
||||
</span>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
mod breadcrumb_item;
|
||||
mod theme;
|
||||
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
pub use breadcrumb_item::BreadcrumbItem;
|
||||
|
@ -37,13 +36,11 @@ pub fn Breadcrumb(
|
|||
});
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<Provider value=BreadcrumbSeparatorInjection(separator)>
|
||||
<nav
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-breadcrumb"
|
||||
class=class_list!["thaw-breadcrumb", move || class.get()]
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<ul>{children()}</ul>
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
mod button_group;
|
||||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::{OptionComp, Wave, WaveRef},
|
||||
icon::*,
|
||||
theme::*,
|
||||
utils::{mount_style, ssr_class, ComponentRef},
|
||||
utils::{class_list::class_list, mount_style, ComponentRef},
|
||||
};
|
||||
pub use button_group::ButtonGroup;
|
||||
use leptos::*;
|
||||
|
@ -222,18 +220,17 @@ pub fn Button(
|
|||
callback.call(event);
|
||||
};
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<button
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class:thaw-button=true
|
||||
class=("thaw-button--solid", move || variant.get() == ButtonVariant::Solid)
|
||||
class=("thaw-button--text", move || variant.get() == ButtonVariant::Text)
|
||||
class=("thaw-button--link", move || variant.get() == ButtonVariant::Link)
|
||||
class=("thaw-button--round", move || round.get())
|
||||
class=("thaw-button--circle", move || circle.get())
|
||||
class=("thaw-button--disabled", move || disabled.get())
|
||||
class=class_list![
|
||||
"thaw-button", ("thaw-button--solid", move || variant.get() ==
|
||||
ButtonVariant::Solid), ("thaw-button--text", move || variant.get() ==
|
||||
ButtonVariant::Text), ("thaw-button--link", move || variant.get() ==
|
||||
ButtonVariant::Link), ("thaw-button--round", move || round.get()),
|
||||
("thaw-button--circle", move || circle.get()), ("thaw-button--disabled", move ||
|
||||
disabled.get()), move || class.get()
|
||||
]
|
||||
|
||||
style=move || format!("{}{}", css_vars.get(), style.get())
|
||||
disabled=move || disabled.get()
|
||||
on:click=on_click
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
chrono::{Datelike, Days, Local, NaiveDate},
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Button, ButtonGroup, ButtonVariant, Theme,
|
||||
};
|
||||
use chrono::{Month, Months};
|
||||
|
@ -117,14 +115,9 @@ pub fn Calendar(
|
|||
*date = *date + Months::new(1);
|
||||
});
|
||||
};
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-calendar"
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<div class=class_list!["thaw-calendar", move || class.get()] style=move || css_vars.get()>
|
||||
<div class="thaw-calendar__header">
|
||||
<span class="thaw-calendar__header-title">
|
||||
|
||||
|
@ -132,7 +125,8 @@ pub fn Calendar(
|
|||
show_date
|
||||
.with(|date| {
|
||||
format!(
|
||||
"{} {}", Month::try_from(date.month() as u8).unwrap().name(),
|
||||
"{} {}",
|
||||
Month::try_from(date.month() as u8).unwrap().name(),
|
||||
date.year(),
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::*,
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -59,9 +57,8 @@ pub fn Card(
|
|||
let header = store_value(card_header);
|
||||
let header_extra = store_value(card_header_extra);
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-card" style=move || css_vars.get()>
|
||||
<div class=class_list!["thaw-card", move || class.get()] style=move || css_vars.get()>
|
||||
<If cond=is_header>
|
||||
<Then slot>
|
||||
<div class="thaw-card__header">
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
mod checkbox_group;
|
||||
mod checkbox_item;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::*,
|
||||
icon::*,
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
pub use checkbox_group::CheckboxGroup;
|
||||
|
@ -35,13 +33,13 @@ pub fn Checkbox(
|
|||
css_vars
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class:thaw-checkbox=true
|
||||
class=("thaw-checkbox--checked", move || value.get())
|
||||
class=class_list![
|
||||
"thaw-checkbox", ("thaw-checkbox--checked", move || value.get()), move || class
|
||||
.get()
|
||||
]
|
||||
|
||||
style=move || css_vars.get()
|
||||
on:click=move |_| value.set(!value.get_untracked())
|
||||
>
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
mod color;
|
||||
mod theme;
|
||||
|
||||
use crate::components::{Binder, Follower, FollowerPlacement};
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::{Binder, Follower, FollowerPlacement},
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
pub use color::*;
|
||||
|
@ -98,13 +97,10 @@ pub fn ColorPicker(
|
|||
on_cleanup(move || timer.remove());
|
||||
}
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<Binder target_ref=trigger_ref>
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-color-picker-trigger"
|
||||
class=class_list!["thaw-color-picker-trigger", move || class.get()]
|
||||
on:click=show_popover
|
||||
ref=trigger_ref
|
||||
>
|
||||
|
@ -189,8 +185,9 @@ fn ColorPanel(hue: ReadSignal<u16>, sv: RwSignal<(f64, f64)>) -> impl IntoView {
|
|||
class="thaw-color-picker-popover__handle"
|
||||
style=move || {
|
||||
format!(
|
||||
"left: calc({}% - 6px); bottom: calc({}% - 6px)", sv.get().0 * 100.0, sv
|
||||
.get().1 * 100.0,
|
||||
"left: calc({}% - 6px); bottom: calc({}% - 6px)",
|
||||
sv.get().0 * 100.0,
|
||||
sv.get().1 * 100.0,
|
||||
)
|
||||
}
|
||||
>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
use leptos::*;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::{mount_style, ssr_class};
|
||||
use crate::utils::{class_list::class_list, mount_style};
|
||||
|
||||
#[component]
|
||||
pub fn Divider(#[prop(optional, into)] class: MaybeSignal<String>) -> impl IntoView {
|
||||
mount_style("divider", include_str!("./divider.css"));
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-divider">
|
||||
<div class=class_list!["thaw-divider", move || class.get()]>
|
||||
<div class="thaw-divider__line"></div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use super::use_grid;
|
||||
use crate::utils::class_list::class_list;
|
||||
use leptos::*;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::ssr_class;
|
||||
|
||||
#[component]
|
||||
pub fn GridItem(
|
||||
#[prop(default = MaybeSignal::Static(1u16), into)] column: MaybeSignal<u16>,
|
||||
|
@ -37,9 +34,9 @@ pub fn GridItem(
|
|||
|
||||
style
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-grid-item" style=move || style.get()>
|
||||
<div class=class_list!["thaw-grid-item", move || class.get()] style=move || style.get()>
|
||||
{children()}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
mod grid_item;
|
||||
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::ssr_class;
|
||||
|
||||
use crate::utils::class_list::class_list;
|
||||
pub use grid_item::*;
|
||||
use leptos::*;
|
||||
|
||||
|
@ -24,10 +22,9 @@ pub fn Grid(
|
|||
style
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<Provider value=GridInjection::new(x_gap)>
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-grid" style=move || style.get()>
|
||||
<div class=class_list!["thaw-grid", move || class.get()] style=move || style.get()>
|
||||
{children()}
|
||||
</div>
|
||||
</Provider>
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
use leptos::*;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::ssr_class;
|
||||
|
||||
#[component]
|
||||
pub fn Image(
|
||||
#[prop(optional, into)] src: MaybeSignal<String>,
|
||||
|
@ -35,11 +31,9 @@ pub fn Image(
|
|||
style
|
||||
};
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<img
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class=move || class.get()
|
||||
src=move || src.get()
|
||||
alt=move || alt.get()
|
||||
style=style
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::{use_theme, Theme},
|
||||
utils::{mount_style, ssr_class, ComponentRef},
|
||||
utils::{class_list::class_list, mount_style, ComponentRef},
|
||||
};
|
||||
use leptos::*;
|
||||
pub use theme::InputTheme;
|
||||
|
@ -127,15 +125,14 @@ pub fn Input(
|
|||
comp_ref.load(InputRef { input_ref });
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-input"
|
||||
class=("thaw-input--focus", move || is_focus.get())
|
||||
class=("thaw-input--disabled", move || disabled.get())
|
||||
class=("thaw-input--invalid", move || invalid.get())
|
||||
class=class_list![
|
||||
"thaw-input", ("thaw-input--focus", move || is_focus.get()),
|
||||
("thaw-input--disabled", move || disabled.get()), ("thaw-input--invalid", move ||
|
||||
invalid.get()), move || class.get()
|
||||
]
|
||||
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
{if let Some(prefix) = input_prefix.and_then(|prefix| prefix.if_.then_some(prefix)) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -22,14 +20,9 @@ pub fn MenuGroup(
|
|||
});
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-menu-group"
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<div class=class_list!["thaw-menu-group", move || class.get()] style=move || css_vars.get()>
|
||||
{label}
|
||||
</div>
|
||||
{children()}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use super::use_menu;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -40,14 +37,15 @@ pub fn MenuItem(
|
|||
});
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class="thaw-menu-item">
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-menu-item__content"
|
||||
class=("thaw-menu-item__content--selected", move || menu.0.get() == key.get())
|
||||
class=class_list![
|
||||
"thaw-menu-item__content", ("thaw-menu-item__content--selected", move || menu.0
|
||||
.get() == key.get()), move || class.get()
|
||||
]
|
||||
|
||||
on:click=on_click
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
|
|
|
@ -2,9 +2,7 @@ mod menu_group;
|
|||
mod menu_item;
|
||||
mod theme;
|
||||
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::ssr_class;
|
||||
|
||||
use crate::utils::class_list::class_list;
|
||||
use leptos::*;
|
||||
pub use menu_group::MenuGroup;
|
||||
pub use menu_item::*;
|
||||
|
@ -16,12 +14,9 @@ pub fn Menu(
|
|||
#[prop(optional, into)] class: MaybeSignal<String>,
|
||||
children: Children,
|
||||
) -> impl IntoView {
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<Provider value=MenuInjection(value)>
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-menu">
|
||||
{children()}
|
||||
</div>
|
||||
<div class=class_list!["thaw-menu", move || class.get()]>{children()}</div>
|
||||
</Provider>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::*,
|
||||
icon::*,
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class, StoredMaybeSignal},
|
||||
utils::{class_list::class_list, mount_style, StoredMaybeSignal},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -48,14 +46,8 @@ pub fn NavBar(
|
|||
}
|
||||
};
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-nav-bar"
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
<div class=class_list!["thaw-nav-bar", move || class.get()] style=move || css_vars.get()>
|
||||
<If cond=MaybeSignal::derive(move || left_arrow.get() || !left_text.get().is_empty())>
|
||||
<Then slot>
|
||||
<div class="thaw-nav-bar__left" on:click=on_click_left>
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
mod theme;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::{
|
||||
components::{Binder, Follower, FollowerPlacement},
|
||||
use_theme,
|
||||
utils::{add_event_listener, dyn_classes, mount_style, ssr_class},
|
||||
utils::{add_event_listener, class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::{leptos_dom::helpers::TimeoutHandle, *};
|
||||
use std::time::Duration;
|
||||
pub use theme::PopoverTheme;
|
||||
|
||||
#[slot]
|
||||
|
@ -108,13 +107,10 @@ pub fn Popover(
|
|||
});
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<Binder target_ref>
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-popover-trigger"
|
||||
class=class_list!["thaw-popover-trigger", move || class.get()]
|
||||
ref=target_ref
|
||||
on:mouseenter=on_mouse_enter
|
||||
on:mouseleave=on_mouse_leave
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -26,13 +24,12 @@ pub fn Radio(
|
|||
css_vars
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-radio"
|
||||
class=("thaw-radio--checked", move || value.get())
|
||||
class=class_list![
|
||||
"thaw-radio", ("thaw-radio--checked", move || value.get()), move || class.get()
|
||||
]
|
||||
|
||||
style=move || css_vars.get()
|
||||
on:click=move |_| value.set(!value.get_untracked())
|
||||
>
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
mod theme;
|
||||
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::{Binder, Follower, FollowerPlacement, FollowerWidth},
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -108,13 +107,11 @@ where
|
|||
.map_or(String::new(), |v| v.label.clone()),
|
||||
None => String::new(),
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<Binder target_ref=trigger_ref>
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-select"
|
||||
class=class_list!["thaw-select", move || class.get()]
|
||||
ref=trigger_ref
|
||||
on:click=show_menu
|
||||
style=move || css_vars.get()
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
mod slider_label;
|
||||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
components::OptionComp,
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -118,12 +116,9 @@ pub fn Slider(
|
|||
});
|
||||
on_cleanup(move || on_mouse_move.remove());
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-slider"
|
||||
class=class_list!["thaw-slider", move || class.get()]
|
||||
style=move || css_vars.get()
|
||||
on:click=on_mouse_click
|
||||
>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::{mount_style, ssr_class};
|
||||
use crate::utils::{class_list::class_list, mount_style};
|
||||
use leptos::*;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -30,12 +28,9 @@ pub fn Space(
|
|||
SpaceGap::WH(width, height) => format!("{width}px {height}px"),
|
||||
};
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-space"
|
||||
class=class_list!["thaw-space", move || class.get()]
|
||||
style:gap=gap
|
||||
style:flex-direction=if vertical { "column" } else { "row" }
|
||||
>
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
||||
pub use theme::SpinnerTheme;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
|
@ -54,12 +51,9 @@ pub fn Spinner(
|
|||
css_vars
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-spinner"
|
||||
class=class_list!["thaw-spinner", move || class.get()]
|
||||
style=move || css_vars.get()
|
||||
></div>
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -31,13 +29,13 @@ pub fn Switch(
|
|||
});
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-switch"
|
||||
class=("thaw-switch--active", move || value.get())
|
||||
class=class_list![
|
||||
"thaw-switch", ("thaw-switch--active", move || value.get()), move || class.get()
|
||||
]
|
||||
|
||||
style=move || css_vars.get()
|
||||
on:click=move |_| value.set(!value.get_untracked())
|
||||
>
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -43,14 +41,14 @@ pub fn Table(
|
|||
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<table
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-table"
|
||||
class=("thaw-table--single-row", move || single_row.get())
|
||||
class=("thaw-table--single-column", move || single_column.get())
|
||||
class=class_list![
|
||||
"thaw-table", ("thaw-table--single-row", move || single_row.get()),
|
||||
("thaw-table--single-column", move || single_column.get()), move || class.get()
|
||||
]
|
||||
|
||||
style=move || format!("{}{}", css_vars.get(), style.get())
|
||||
>
|
||||
{children()}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod tab;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -61,9 +59,9 @@ fn TabsInner(
|
|||
let label_list_ref = create_node_ref::<html::Div>();
|
||||
|
||||
let children = children();
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-tabs" style=move || css_vars.get()>
|
||||
<div class=class_list!["thaw-tabs", move || class.get()] style=move || css_vars.get()>
|
||||
<div class="thaw-tabs__label-list" ref=label_list_ref>
|
||||
<For
|
||||
each=move || tab_options_vec.get()
|
||||
|
@ -74,10 +72,12 @@ fn TabsInner(
|
|||
create_effect({
|
||||
let key = key.clone();
|
||||
move |_| {
|
||||
let Some(label) = label_ref.get() else { return;
|
||||
};
|
||||
let Some(label_list) = label_list_ref.get() else { return;
|
||||
};
|
||||
let Some(label) = label_ref.get() else {
|
||||
return;
|
||||
};
|
||||
let Some(label_list) = label_list_ref.get() else {
|
||||
return;
|
||||
};
|
||||
if key.clone() == value.get() {
|
||||
request_animation_frame(move || {
|
||||
let list_rect = label_list.get_bounding_client_rect();
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use super::use_tabs;
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::utils::{mount_style, ssr_class};
|
||||
use crate::utils::{class_list::class_list, mount_style};
|
||||
use leptos::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
|
@ -23,15 +21,10 @@ pub fn Tab(
|
|||
key: key.clone(),
|
||||
label,
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-tab"
|
||||
class=("thaw-tab--hidden", move || key != tabs.get_key())
|
||||
>
|
||||
{children()}
|
||||
</div>
|
||||
<div class=class_list![
|
||||
"thaw-tab", ("thaw-tab--hidden", move || key != tabs.get_key()), move || class.get()
|
||||
]>{children()}</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
mod theme;
|
||||
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
theme::use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -73,9 +71,9 @@ pub fn Tag(
|
|||
});
|
||||
css_vars
|
||||
});
|
||||
let ssr_class = ssr_class(&class);
|
||||
|
||||
view! {
|
||||
<div class=ssr_class use:dyn_classes=class class="thaw-tag" style=move || css_vars.get()>
|
||||
<div class=class_list!["thaw-tag", move || class.get()] style=move || css_vars.get()>
|
||||
<span class="thaw-tag__content">{children()}</span>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use crate::utils::dyn_classes;
|
||||
use crate::{
|
||||
use_theme,
|
||||
utils::{mount_style, ssr_class},
|
||||
utils::{class_list::class_list, mount_style},
|
||||
Theme,
|
||||
};
|
||||
use leptos::*;
|
||||
|
@ -26,13 +24,10 @@ pub fn Text(
|
|||
css_vars
|
||||
});
|
||||
|
||||
let ssr_class = ssr_class(&class);
|
||||
if code {
|
||||
view! {
|
||||
<code
|
||||
class=ssr_class
|
||||
use:dyn_classes=class
|
||||
class="thaw-text thaw-text--code"
|
||||
class=class_list!["thaw-text thaw-text--code", move || class.get()]
|
||||
style=move || css_vars.get()
|
||||
>
|
||||
{children()}
|
||||
|
@ -40,11 +35,7 @@ pub fn Text(
|
|||
}
|
||||
.into_any()
|
||||
} else {
|
||||
view! {
|
||||
<span class=ssr_class use:dyn_classes=class class="thaw-text">
|
||||
{children()}
|
||||
</span>
|
||||
}
|
||||
view! { <span class=class_list!["thaw-text", move || class.get()]>{children()}</span> }
|
||||
.into_any()
|
||||
}
|
||||
}
|
||||
|
|
186
src/utils/class_list.rs
Normal file
186
src/utils/class_list.rs
Normal file
|
@ -0,0 +1,186 @@
|
|||
#[cfg(not(feature = "ssr"))]
|
||||
use leptos::create_render_effect;
|
||||
use leptos::{Attribute, IntoAttribute, Oco, RwSignal, SignalUpdate, SignalWith};
|
||||
use std::{collections::HashSet, rc::Rc};
|
||||
|
||||
pub struct ClassList(RwSignal<HashSet<Oco<'static, str>>>);
|
||||
|
||||
impl ClassList {
|
||||
pub fn new() -> Self {
|
||||
Self(RwSignal::new(HashSet::new()))
|
||||
}
|
||||
|
||||
pub fn add(self, value: impl IntoClass) -> Self {
|
||||
let class = value.into_class();
|
||||
match class {
|
||||
Class::String(name) => {
|
||||
self.0.update(move |set| {
|
||||
set.insert(name);
|
||||
});
|
||||
}
|
||||
Class::FnString(f) => {
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
let name = f();
|
||||
self.0.update(|set| {
|
||||
set.insert(name);
|
||||
});
|
||||
}
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
create_render_effect(move |old_name| {
|
||||
let name = f();
|
||||
if let Some(old_name) = old_name {
|
||||
if old_name != name {
|
||||
self.0.update(|set| {
|
||||
set.remove(&old_name);
|
||||
set.insert(name.clone());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.0.update(|set| {
|
||||
set.insert(name.clone());
|
||||
});
|
||||
}
|
||||
name
|
||||
});
|
||||
}
|
||||
Class::Fn(name, f) => {
|
||||
#[cfg(feature = "ssr")]
|
||||
{
|
||||
let new = f();
|
||||
self.0.update(|set| {
|
||||
if new {
|
||||
set.insert(name);
|
||||
}
|
||||
});
|
||||
}
|
||||
#[cfg(not(feature = "ssr"))]
|
||||
create_render_effect(move |old| {
|
||||
let name = name.clone();
|
||||
let new = f();
|
||||
if old.is_none() {
|
||||
if new {
|
||||
self.0.update(|set| {
|
||||
set.insert(name);
|
||||
});
|
||||
}
|
||||
} else if old.as_ref() != Some(&new) {
|
||||
self.0.update(|set| {
|
||||
if new {
|
||||
set.insert(name);
|
||||
} else {
|
||||
set.remove(&name);
|
||||
}
|
||||
});
|
||||
}
|
||||
new
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoAttribute for ClassList {
|
||||
fn into_attribute(self) -> Attribute {
|
||||
Attribute::Fn(Rc::new(move || {
|
||||
self.0.with(|set| {
|
||||
let mut class = String::new();
|
||||
set.iter().enumerate().for_each(|(index, name)| {
|
||||
if name.is_empty() {
|
||||
return;
|
||||
}
|
||||
if index != 0 {
|
||||
class.push(' ');
|
||||
}
|
||||
class.push_str(name)
|
||||
});
|
||||
class.into_attribute()
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn into_attribute_boxed(self: Box<Self>) -> Attribute {
|
||||
self.into_attribute()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Class {
|
||||
String(Oco<'static, str>),
|
||||
FnString(Box<dyn Fn() -> Oco<'static, str>>),
|
||||
Fn(Oco<'static, str>, Box<dyn Fn() -> bool>),
|
||||
}
|
||||
|
||||
pub trait IntoClass {
|
||||
fn into_class(self) -> Class;
|
||||
}
|
||||
|
||||
impl IntoClass for String {
|
||||
fn into_class(self) -> Class {
|
||||
Class::String(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoClass for &'static str {
|
||||
fn into_class(self) -> Class {
|
||||
Class::String(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, U> IntoClass for T
|
||||
where
|
||||
T: Fn() -> U + 'static,
|
||||
U: ToString,
|
||||
{
|
||||
fn into_class(self) -> Class {
|
||||
Class::FnString(Box::new(move || (self)().to_string().into()))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoClass for (&'static str, T)
|
||||
where
|
||||
T: Fn() -> bool + 'static,
|
||||
{
|
||||
fn into_class(self) -> Class {
|
||||
Class::Fn(self.0.into(), Box::new(self.1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoClass for (String, T)
|
||||
where
|
||||
T: Fn() -> bool + 'static,
|
||||
{
|
||||
fn into_class(self) -> Class {
|
||||
Class::Fn(self.0.into(), Box::new(self.1))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! class_list {
|
||||
($($name:expr),+) => {
|
||||
{
|
||||
use crate::utils::class_list::ClassList;
|
||||
ClassList::new()$(.add($name))+
|
||||
}
|
||||
};
|
||||
}
|
||||
pub(crate) use class_list;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use leptos::{create_runtime, Attribute, IntoAttribute};
|
||||
|
||||
#[test]
|
||||
fn macro_class_list() {
|
||||
let rt = create_runtime();
|
||||
let class_list = class_list!("aa", ("bb", || true), move || "cc");
|
||||
if let Attribute::Fn(f) = class_list.into_attribute() {
|
||||
if let Attribute::String(class) = f() {
|
||||
assert!(class.contains("aa"));
|
||||
assert!(class.contains("bb"));
|
||||
assert!(class.contains("cc"));
|
||||
}
|
||||
}
|
||||
rt.dispose();
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
use cfg_if::cfg_if;
|
||||
use leptos::{html::AnyElement, HtmlElement, MaybeSignal};
|
||||
|
||||
pub fn dyn_classes(el: HtmlElement<AnyElement>, classes_signal: MaybeSignal<String>) {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "ssr")] {
|
||||
let _ = el;
|
||||
let _ = classes_signal;
|
||||
} else {
|
||||
use leptos::SignalGet;
|
||||
let _ = el.dyn_classes(move || {
|
||||
let classes = classes_signal.get();
|
||||
if classes.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
classes
|
||||
.split_ascii_whitespace()
|
||||
.map(|class| class.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn ssr_class(class: &MaybeSignal<String>) -> String {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "ssr")] {
|
||||
use leptos::SignalGetUntracked;
|
||||
class.get_untracked()
|
||||
} else {
|
||||
let _ = class;
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// mod callback;
|
||||
pub(crate) mod class_list;
|
||||
mod component_ref;
|
||||
mod dyn_classes;
|
||||
mod event_listener;
|
||||
mod mount_style;
|
||||
mod signal;
|
||||
|
@ -9,7 +9,6 @@ mod time;
|
|||
|
||||
// pub use callback::AsyncCallback;
|
||||
pub use component_ref::{create_component_ref, ComponentRef};
|
||||
pub(crate) use dyn_classes::*;
|
||||
pub(crate) use event_listener::*;
|
||||
pub(crate) use mount_style::mount_style;
|
||||
pub use signal::SignalWatch;
|
||||
|
|
Loading…
Add table
Reference in a new issue