diff --git a/demo/src/app.rs b/demo/src/app.rs index 81ad58e..16310cd 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -53,6 +53,7 @@ fn TheRouter(is_routing: RwSignal) -> impl IntoView { + diff --git a/demo/src/pages/components.rs b/demo/src/pages/components.rs index 6c92faf..a83bd2a 100644 --- a/demo/src/pages/components.rs +++ b/demo/src/pages/components.rs @@ -221,6 +221,10 @@ pub(crate) fn gen_menu_data() -> Vec { value: "progress".into(), label: "Progress".into(), }, + MenuItemOption { + value: "spinner".into(), + label: "Spinner".into(), + }, MenuItemOption { value: "skeleton".into(), label: "Skeleton".into(), diff --git a/demo/src/pages/mod.rs b/demo/src/pages/mod.rs index 27aea7f..1e0c7c0 100644 --- a/demo/src/pages/mod.rs +++ b/demo/src/pages/mod.rs @@ -30,6 +30,7 @@ mod select; mod skeleton; mod slider; mod space; +mod spinner; mod switch; mod tabbar; mod table; @@ -73,6 +74,7 @@ pub use select::*; pub use skeleton::*; pub use slider::*; pub use space::*; +pub use spinner::*; pub use switch::*; pub use tabbar::*; pub use table::*; diff --git a/demo/src/pages/spinner/mod.rs b/demo/src/pages/spinner/mod.rs new file mode 100644 index 0000000..06d18b5 --- /dev/null +++ b/demo/src/pages/spinner/mod.rs @@ -0,0 +1,83 @@ +use crate::components::{Demo, DemoCode}; +use leptos::*; +use prisms::highlight_str; +use thaw::*; + +#[component] +pub fn SpinnerPage() -> impl IntoView { + view! { +
+

"Spinner"

+ + + + + + + {highlight_str!( + r#" + + "#, + "rust" + )} + + + +

"size"

+ + + + + + + + + + {highlight_str!( + r#" + + + + + "#, + "rust" + )} + + + +

"Spinner Props"

+ + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"class" + "MaybeSignal" + + "Default::default()" + "Additional classes for the spinner element."
"size" + "MaybeSignal" + + "SpinnerSize::Medium" + "Spinner size."
+
+ } +} diff --git a/src/lib.rs b/src/lib.rs index 9df80bb..b8baca3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,6 +29,7 @@ mod select; mod skeleton; mod slider; mod space; +mod spinner; mod switch; mod table; mod tabs; @@ -69,6 +70,7 @@ pub use select::*; pub use skeleton::*; pub use slider::*; pub use space::*; +pub use spinner::*; pub use switch::*; pub use table::*; pub use tabs::*; diff --git a/src/spinner/mod.rs b/src/spinner/mod.rs new file mode 100644 index 0000000..50192c6 --- /dev/null +++ b/src/spinner/mod.rs @@ -0,0 +1,66 @@ +mod theme; + +#[cfg(not(feature = "ssr"))] +use crate::utils::dyn_classes; +use crate::{ + theme::use_theme, + utils::{mount_style, ssr_class}, + Theme, +}; +use leptos::*; + +pub use theme::SpinnerTheme; + +#[derive(Default, Clone)] +pub enum SpinnerSize { + Tiny, + Small, + #[default] + Medium, + Large, +} + +impl SpinnerSize { + fn theme_height(&self, theme: &Theme) -> String { + match self { + SpinnerSize::Tiny => theme.common.height_tiny.clone(), + SpinnerSize::Small => theme.common.height_small.clone(), + SpinnerSize::Medium => theme.common.height_medium.clone(), + SpinnerSize::Large => theme.common.height_large.clone(), + } + } +} + +#[component] +pub fn Spinner( + #[prop(optional, into)] class: MaybeSignal, + #[prop(optional, into)] size: MaybeSignal, +) -> impl IntoView { + mount_style("spinner", include_str!("./spinner.css")); + 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-height: {};", + size.get().theme_height(theme) + )); + css_vars.push_str(&format!( + "--thaw-background-color: {};", + &theme.spinner.background_color + )); + css_vars.push_str(&format!("--thaw-color: {};", &theme.common.color_primary)); + }); + css_vars + }); + + let ssr_class = ssr_class(&class); + view! { +
+ } +} diff --git a/src/spinner/spinner.css b/src/spinner/spinner.css new file mode 100644 index 0000000..79ab833 --- /dev/null +++ b/src/spinner/spinner.css @@ -0,0 +1,17 @@ +.thaw-spinner { + border-color: var(--thaw-color); + border-left-color: var(--thaw-background-color); + border-style: solid; + border-radius: 100px; + border-width: 2px; + width: var(--thaw-height); + height: var(--thaw-height); + outline: 1px solid transparent; + animation: 1s linear 0s infinite normal none running spin; + box-sizing: border-box; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} diff --git a/src/spinner/theme.rs b/src/spinner/theme.rs new file mode 100644 index 0000000..e7e7bb2 --- /dev/null +++ b/src/spinner/theme.rs @@ -0,0 +1,20 @@ +use crate::theme::ThemeMethod; + +#[derive(Clone)] +pub struct SpinnerTheme { + pub background_color: String, +} + +impl ThemeMethod for SpinnerTheme { + fn light() -> Self { + Self { + background_color: "#0000000a".into(), + } + } + + fn dark() -> Self { + Self { + background_color: "#2b2f31".into(), + } + } +} diff --git a/src/switch/switch.css b/src/switch/switch.css index 6b22080..2cc75f7 100644 --- a/src/switch/switch.css +++ b/src/switch/switch.css @@ -8,6 +8,8 @@ border-radius: 25px; cursor: pointer; box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.05); + transition: all 0.4s ease; + box-sizing: content-box; } .thaw-switch__button { diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 058dd6f..df40770 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -5,7 +5,7 @@ use crate::{ mobile::{NavBarTheme, TabbarTheme}, AlertTheme, AutoCompleteTheme, AvatarTheme, BreadcrumbTheme, ButtonTheme, CalendarTheme, ColorPickerTheme, InputTheme, MenuTheme, MessageTheme, ProgressTheme, SelectTheme, - SkeletionTheme, SliderTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, + SkeletionTheme, SliderTheme, SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme, TypographyTheme, UploadTheme, }; use leptos::*; @@ -31,6 +31,7 @@ pub struct Theme { pub select: SelectTheme, pub slider: SliderTheme, pub switch: SwitchTheme, + pub spinner: SpinnerTheme, pub upload: UploadTheme, pub nav_bar: NavBarTheme, pub tabbar: TabbarTheme, @@ -60,6 +61,7 @@ impl Theme { select: SelectTheme::light(), slider: SliderTheme::light(), switch: SwitchTheme::light(), + spinner: SpinnerTheme::light(), upload: UploadTheme::light(), nav_bar: NavBarTheme::light(), tabbar: TabbarTheme::light(), @@ -88,6 +90,7 @@ impl Theme { select: SelectTheme::dark(), slider: SliderTheme::dark(), switch: SwitchTheme::dark(), + spinner: SpinnerTheme::dark(), upload: UploadTheme::dark(), nav_bar: NavBarTheme::dark(), tabbar: TabbarTheme::dark(),