mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-08 19:03:09 -05:00
feature: spinner (#48)
* feature: spinner * feat: modify the spinner style --------- Co-authored-by: Cristobal Andrada <kandrelczyk@gmail.com> Co-authored-by: luoxiao <luoxiaozero@163.com>
This commit is contained in:
parent
08936c92ff
commit
d94c8ed4c6
10 changed files with 201 additions and 1 deletions
|
@ -53,6 +53,7 @@ fn TheRouter(is_routing: RwSignal<bool>) -> impl IntoView {
|
||||||
<Route path="/tabs" view=TabsPage/>
|
<Route path="/tabs" view=TabsPage/>
|
||||||
<Route path="/select" view=SelectPage/>
|
<Route path="/select" view=SelectPage/>
|
||||||
<Route path="/space" view=SpacePage/>
|
<Route path="/space" view=SpacePage/>
|
||||||
|
<Route path="/spinner" view=SpinnerPage/>
|
||||||
<Route path="/table" view=TablePage/>
|
<Route path="/table" view=TablePage/>
|
||||||
<Route path="/color-picker" view=ColorPickerPage/>
|
<Route path="/color-picker" view=ColorPickerPage/>
|
||||||
<Route path="/alert" view=AlertPage/>
|
<Route path="/alert" view=AlertPage/>
|
||||||
|
|
|
@ -221,6 +221,10 @@ pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||||
value: "progress".into(),
|
value: "progress".into(),
|
||||||
label: "Progress".into(),
|
label: "Progress".into(),
|
||||||
},
|
},
|
||||||
|
MenuItemOption {
|
||||||
|
value: "spinner".into(),
|
||||||
|
label: "Spinner".into(),
|
||||||
|
},
|
||||||
MenuItemOption {
|
MenuItemOption {
|
||||||
value: "skeleton".into(),
|
value: "skeleton".into(),
|
||||||
label: "Skeleton".into(),
|
label: "Skeleton".into(),
|
||||||
|
|
|
@ -30,6 +30,7 @@ mod select;
|
||||||
mod skeleton;
|
mod skeleton;
|
||||||
mod slider;
|
mod slider;
|
||||||
mod space;
|
mod space;
|
||||||
|
mod spinner;
|
||||||
mod switch;
|
mod switch;
|
||||||
mod tabbar;
|
mod tabbar;
|
||||||
mod table;
|
mod table;
|
||||||
|
@ -73,6 +74,7 @@ pub use select::*;
|
||||||
pub use skeleton::*;
|
pub use skeleton::*;
|
||||||
pub use slider::*;
|
pub use slider::*;
|
||||||
pub use space::*;
|
pub use space::*;
|
||||||
|
pub use spinner::*;
|
||||||
pub use switch::*;
|
pub use switch::*;
|
||||||
pub use tabbar::*;
|
pub use tabbar::*;
|
||||||
pub use table::*;
|
pub use table::*;
|
||||||
|
|
83
demo/src/pages/spinner/mod.rs
Normal file
83
demo/src/pages/spinner/mod.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
use crate::components::{Demo, DemoCode};
|
||||||
|
use leptos::*;
|
||||||
|
use prisms::highlight_str;
|
||||||
|
use thaw::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn SpinnerPage() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div style="width: 896px; margin: 0 auto;">
|
||||||
|
<h1>"Spinner"</h1>
|
||||||
|
<Demo>
|
||||||
|
<Space>
|
||||||
|
<Spinner/>
|
||||||
|
</Space>
|
||||||
|
<DemoCode slot>
|
||||||
|
|
||||||
|
{highlight_str!(
|
||||||
|
r#"
|
||||||
|
<Spinner/>
|
||||||
|
"#,
|
||||||
|
"rust"
|
||||||
|
)}
|
||||||
|
|
||||||
|
</DemoCode>
|
||||||
|
</Demo>
|
||||||
|
<h3>"size"</h3>
|
||||||
|
<Demo>
|
||||||
|
<Space>
|
||||||
|
<Spinner size=SpinnerSize::Tiny/>
|
||||||
|
<Spinner size=SpinnerSize::Small/>
|
||||||
|
<Spinner size=SpinnerSize::Medium/>
|
||||||
|
<Spinner size=SpinnerSize::Large/>
|
||||||
|
</Space>
|
||||||
|
<DemoCode slot>
|
||||||
|
|
||||||
|
{highlight_str!(
|
||||||
|
r#"
|
||||||
|
<Spinner size=SpinnerSize::Tiny/>
|
||||||
|
<Spinner size=SpinnerSize::Small/>
|
||||||
|
<Spinner size=SpinnerSize::Medium/>
|
||||||
|
<Spinner size=SpinnerSize::Large/>
|
||||||
|
"#,
|
||||||
|
"rust"
|
||||||
|
)}
|
||||||
|
|
||||||
|
</DemoCode>
|
||||||
|
</Demo>
|
||||||
|
<h3>"Spinner Props"</h3>
|
||||||
|
<Table single_column=true>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>"Name"</th>
|
||||||
|
<th>"Type"</th>
|
||||||
|
<th>"Default"</th>
|
||||||
|
<th>"Description"</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>"class"</td>
|
||||||
|
<td>
|
||||||
|
<Text code=true>"MaybeSignal<String>"</Text>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Text code=true>"Default::default()"</Text>
|
||||||
|
</td>
|
||||||
|
<td>"Additional classes for the spinner element."</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>"size"</td>
|
||||||
|
<td>
|
||||||
|
<Text code=true>"MaybeSignal<SpinnerSize>"</Text>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<Text code=true>"SpinnerSize::Medium"</Text>
|
||||||
|
</td>
|
||||||
|
<td>"Spinner size."</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ mod select;
|
||||||
mod skeleton;
|
mod skeleton;
|
||||||
mod slider;
|
mod slider;
|
||||||
mod space;
|
mod space;
|
||||||
|
mod spinner;
|
||||||
mod switch;
|
mod switch;
|
||||||
mod table;
|
mod table;
|
||||||
mod tabs;
|
mod tabs;
|
||||||
|
@ -69,6 +70,7 @@ pub use select::*;
|
||||||
pub use skeleton::*;
|
pub use skeleton::*;
|
||||||
pub use slider::*;
|
pub use slider::*;
|
||||||
pub use space::*;
|
pub use space::*;
|
||||||
|
pub use spinner::*;
|
||||||
pub use switch::*;
|
pub use switch::*;
|
||||||
pub use table::*;
|
pub use table::*;
|
||||||
pub use tabs::*;
|
pub use tabs::*;
|
||||||
|
|
66
src/spinner/mod.rs
Normal file
66
src/spinner/mod.rs
Normal file
|
@ -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<String>,
|
||||||
|
#[prop(optional, into)] size: MaybeSignal<SpinnerSize>,
|
||||||
|
) -> 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! {
|
||||||
|
<div
|
||||||
|
class=ssr_class
|
||||||
|
use:dyn_classes=class
|
||||||
|
class="thaw-spinner"
|
||||||
|
style=move || css_vars.get()
|
||||||
|
></div>
|
||||||
|
}
|
||||||
|
}
|
17
src/spinner/spinner.css
Normal file
17
src/spinner/spinner.css
Normal file
|
@ -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); }
|
||||||
|
}
|
20
src/spinner/theme.rs
Normal file
20
src/spinner/theme.rs
Normal file
|
@ -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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,8 @@
|
||||||
border-radius: 25px;
|
border-radius: 25px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.05);
|
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 {
|
.thaw-switch__button {
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
mobile::{NavBarTheme, TabbarTheme},
|
mobile::{NavBarTheme, TabbarTheme},
|
||||||
AlertTheme, AutoCompleteTheme, AvatarTheme, BreadcrumbTheme, ButtonTheme, CalendarTheme,
|
AlertTheme, AutoCompleteTheme, AvatarTheme, BreadcrumbTheme, ButtonTheme, CalendarTheme,
|
||||||
ColorPickerTheme, InputTheme, MenuTheme, MessageTheme, ProgressTheme, SelectTheme,
|
ColorPickerTheme, InputTheme, MenuTheme, MessageTheme, ProgressTheme, SelectTheme,
|
||||||
SkeletionTheme, SliderTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme,
|
SkeletionTheme, SliderTheme, SpinnerTheme, SwitchTheme, TableTheme, TagTheme, TimePickerTheme,
|
||||||
TypographyTheme, UploadTheme,
|
TypographyTheme, UploadTheme,
|
||||||
};
|
};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
@ -31,6 +31,7 @@ pub struct Theme {
|
||||||
pub select: SelectTheme,
|
pub select: SelectTheme,
|
||||||
pub slider: SliderTheme,
|
pub slider: SliderTheme,
|
||||||
pub switch: SwitchTheme,
|
pub switch: SwitchTheme,
|
||||||
|
pub spinner: SpinnerTheme,
|
||||||
pub upload: UploadTheme,
|
pub upload: UploadTheme,
|
||||||
pub nav_bar: NavBarTheme,
|
pub nav_bar: NavBarTheme,
|
||||||
pub tabbar: TabbarTheme,
|
pub tabbar: TabbarTheme,
|
||||||
|
@ -60,6 +61,7 @@ impl Theme {
|
||||||
select: SelectTheme::light(),
|
select: SelectTheme::light(),
|
||||||
slider: SliderTheme::light(),
|
slider: SliderTheme::light(),
|
||||||
switch: SwitchTheme::light(),
|
switch: SwitchTheme::light(),
|
||||||
|
spinner: SpinnerTheme::light(),
|
||||||
upload: UploadTheme::light(),
|
upload: UploadTheme::light(),
|
||||||
nav_bar: NavBarTheme::light(),
|
nav_bar: NavBarTheme::light(),
|
||||||
tabbar: TabbarTheme::light(),
|
tabbar: TabbarTheme::light(),
|
||||||
|
@ -88,6 +90,7 @@ impl Theme {
|
||||||
select: SelectTheme::dark(),
|
select: SelectTheme::dark(),
|
||||||
slider: SliderTheme::dark(),
|
slider: SliderTheme::dark(),
|
||||||
switch: SwitchTheme::dark(),
|
switch: SwitchTheme::dark(),
|
||||||
|
spinner: SpinnerTheme::dark(),
|
||||||
upload: UploadTheme::dark(),
|
upload: UploadTheme::dark(),
|
||||||
nav_bar: NavBarTheme::dark(),
|
nav_bar: NavBarTheme::dark(),
|
||||||
tabbar: TabbarTheme::dark(),
|
tabbar: TabbarTheme::dark(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue