diff --git a/demo/src/app.rs b/demo/src/app.rs index 6d37601..d9e138d 100644 --- a/demo/src/app.rs +++ b/demo/src/app.rs @@ -83,6 +83,7 @@ fn TheRouter() -> impl IntoView { + diff --git a/demo/src/pages/button/mod.rs b/demo/src/pages/button/mod.rs index 63bb7b8..ee3077c 100644 --- a/demo/src/pages/button/mod.rs +++ b/demo/src/pages/button/mod.rs @@ -193,7 +193,7 @@ pub fn ButtonPage() -> impl IntoView { } #[component] -pub fn LoadingButton() -> impl IntoView { +fn LoadingButton() -> impl IntoView { let loading = create_rw_signal(false); let on_click = move |_| { loading.set(true); diff --git a/demo/src/pages/components.rs b/demo/src/pages/components.rs index e7bc4b8..5936ea0 100644 --- a/demo/src/pages/components.rs +++ b/demo/src/pages/components.rs @@ -205,6 +205,10 @@ pub(crate) fn gen_menu_data() -> Vec { value: "modal".into(), label: "Modal".into(), }, + MenuItemOption { + value: "progress".into(), + label: "Progress".into(), + }, MenuItemOption { value: "skeleton".into(), label: "Skeleton".into(), diff --git a/demo/src/pages/input/mod.rs b/demo/src/pages/input/mod.rs index 7bf408f..83cffaf 100644 --- a/demo/src/pages/input/mod.rs +++ b/demo/src/pages/input/mod.rs @@ -1,7 +1,7 @@ use crate::components::{Demo, DemoCode}; use leptos::*; -use thaw::*; use prisms::highlight_str; +use thaw::*; #[component] pub fn InputPage() -> impl IntoView { @@ -43,6 +43,72 @@ pub fn InputPage() -> impl IntoView { "" +

"Input Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"value""RwSignal"r#""""#"Set the input value"
"variant""MaybeSignal""InputVariant::Text""Button's variant."
"placeholder""MaybeSignal"r#""""#"Placeholder of input."
"allow_value""Option>""None""Check the incoming value, if it returns false, input will not be accepted."
"on_focus""Option>""None""Callback triggered when the input is focussed on."
"on_blur""Option>""None""Callback triggered when the input is blurred."
+

"Input Slots"

+ + + + + + + + + + + + + + + +
"Name""Default""Description"
"InputSuffix""None""Input content."
} } diff --git a/demo/src/pages/input_number/mod.rs b/demo/src/pages/input_number/mod.rs index fd7b939..c718057 100644 --- a/demo/src/pages/input_number/mod.rs +++ b/demo/src/pages/input_number/mod.rs @@ -1,7 +1,7 @@ use crate::components::{Demo, DemoCode}; use leptos::*; -use thaw::*; use prisms::highlight_str; +use thaw::*; #[component] pub fn InputNumberPage() -> impl IntoView { @@ -36,6 +36,41 @@ pub fn InputNumberPage() -> impl IntoView { "" +

"InputNumber Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"value""RwSignal""T::default()""Set the input value."
"placeholder""MaybeSignal"r#""""#"Placeholder of input number."
"step""MaybeSignal""The number which the current value is increased or decreased on key or button press."
+

"T impl"

+

+ "T: Add + Sub + Default + Clone + FromStr + ToString + 'static" +

} } diff --git a/demo/src/pages/layout/mod.rs b/demo/src/pages/layout/mod.rs index ce01259..784271e 100644 --- a/demo/src/pages/layout/mod.rs +++ b/demo/src/pages/layout/mod.rs @@ -57,6 +57,105 @@ pub fn LayoutPage() -> impl IntoView { "" +

"Layout Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"style""MaybeSignal"r#""""#"Layout's style."
"position""LayoutPosition""LayoutPosition::Static""static position will make it css position set to static. absolute position will make it css position set to absolute and left, right, top, bottom to 0. absolute position is very useful when you want to make content scroll in a fixed container or make the whole page's layout in a fixed position. You may need to change the style of the component to make it display as you expect."
"has_sider""MaybeSignal""false""Whether the component has sider inside. If so it must be true."
"children""Children""Layout's content."
+

"Layout Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"style""MaybeSignal"r#""""#"Layout's style."
"position""LayoutPosition""LayoutPosition::Static""static position will make it css position set to static. absolute position will make it css position set to absolute and left, right, top, bottom to 0. absolute position is very useful when you want to make content scroll in a fixed container or make the whole page's layout in a fixed position. You may need to change the style of the component to make it display as you expect."
"has_sider""MaybeSignal""false""Whether the component has sider inside. If so it must be true."
"children""Children""Layout's content."
+

"LayoutHeader, LayoutSider Props"

+ + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"style""MaybeSignal"r#""""#"LayoutHeader's style."
"children""Children""LayoutHeader's content."
} } diff --git a/demo/src/pages/loading_bar/mod.rs b/demo/src/pages/loading_bar/mod.rs index 29859f0..acbf671 100644 --- a/demo/src/pages/loading_bar/mod.rs +++ b/demo/src/pages/loading_bar/mod.rs @@ -57,6 +57,33 @@ pub fn LoadingBarPage() -> impl IntoView { "" +

"LoadingBar Injection Methods"

+ + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Description"
"start""fn(&self)""Callback function for loading bar to start loading."
"finish""fn(&self)""The callback function when the loading bar finishes loading."
"error""fn(&self)""Callback function for loading bar error."
} } diff --git a/demo/src/pages/menu/mod.rs b/demo/src/pages/menu/mod.rs index 37cda9c..d77ffa7 100644 --- a/demo/src/pages/menu/mod.rs +++ b/demo/src/pages/menu/mod.rs @@ -1,7 +1,7 @@ use crate::components::{Demo, DemoCode}; use leptos::*; -use thaw::*; use prisms::highlight_str; +use thaw::*; #[component] pub fn MenuPage() -> impl IntoView { @@ -32,6 +32,81 @@ pub fn MenuPage() -> impl IntoView { "" +

"Menu Props"

+ + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"value""MaybeSignal"r#""""#"The selected item key of the menu."
"children""Children""Menu's content."
+

"MenuGroup Props"

+ + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"label""String""The label of the menu group."
"children""Children""MenuGroup's content."
+

"MenuItem Props"

+ + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"label""MaybeSignal"r#""""#"The label of the menu item."
"key""MaybeSignal"r#""""#"The indentifier of the menu item."
} } diff --git a/demo/src/pages/message/mod.rs b/demo/src/pages/message/mod.rs index e5780bd..149ca03 100644 --- a/demo/src/pages/message/mod.rs +++ b/demo/src/pages/message/mod.rs @@ -1,7 +1,7 @@ use crate::components::{Demo, DemoCode}; use leptos::*; -use thaw::*; use prisms::highlight_str; +use thaw::*; #[component] pub fn MessagePage() -> impl IntoView { @@ -72,6 +72,23 @@ pub fn MessagePage() -> impl IntoView { "" +

"MessageProvider Injection Methods"

+ + + + + + + + + + + + + + + +
"Name""Type""Description"
"create""fn(&self, content: String, variant: MessageVariant, options: MessageOptions)""The label of the menu item."
} } diff --git a/demo/src/pages/mod.rs b/demo/src/pages/mod.rs index dd26b40..2ccca25 100644 --- a/demo/src/pages/mod.rs +++ b/demo/src/pages/mod.rs @@ -23,6 +23,7 @@ mod message; mod mobile; mod modal; mod nav_bar; +mod progress; mod radio; mod select; mod skeleton; @@ -61,6 +62,7 @@ pub use message::*; pub use mobile::*; pub use modal::*; pub use nav_bar::*; +pub use progress::*; pub use radio::*; pub use select::*; pub use skeleton::*; diff --git a/demo/src/pages/modal/mod.rs b/demo/src/pages/modal/mod.rs index 228ce4c..45a7e1b 100644 --- a/demo/src/pages/modal/mod.rs +++ b/demo/src/pages/modal/mod.rs @@ -1,7 +1,7 @@ use crate::components::{Demo, DemoCode}; use leptos::*; -use thaw::*; use prisms::highlight_str; +use thaw::*; #[component] pub fn ModalPage() -> impl IntoView { @@ -34,6 +34,55 @@ pub fn ModalPage() -> impl IntoView { "" +

"Modal Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"show""MaybeSignal""Whether to show modal."
"title""MaybeSignal"r#""""#"Modal title."
"children""Children""Modal's content."
+

"Modal Slots"

+ + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"ModalFooter""None""Footer content."
} } diff --git a/demo/src/pages/nav_bar/mod.rs b/demo/src/pages/nav_bar/mod.rs index 61253c5..01aaad1 100644 --- a/demo/src/pages/nav_bar/mod.rs +++ b/demo/src/pages/nav_bar/mod.rs @@ -3,8 +3,9 @@ use crate::{ pages::MobilePage, }; use leptos::*; -use thaw::mobile::NavBar; use prisms::highlight_str; +use thaw::mobile::NavBar; +use thaw::Table; #[component] pub fn NavBarPage() -> impl IntoView { @@ -43,6 +44,55 @@ pub fn NavBarPage() -> impl IntoView { "" +

"NavBar Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"title""MaybeSignal"r#""""#"NavBar title."
"left_arrow""MaybeSignal""Whether to show left arrow."
"left_text""MaybeSignal"r#""""#"NavBar left text."
"on_click_left""MaybeSignal"r#""""#"NavBar left click."
"right_text""MaybeSignal"r#""""#"NavBar right text."
"on_click_right""MaybeSignal"r#""""#"NavBar right click."
diff --git a/demo/src/pages/progress/mod.rs b/demo/src/pages/progress/mod.rs new file mode 100644 index 0000000..9d7eb10 --- /dev/null +++ b/demo/src/pages/progress/mod.rs @@ -0,0 +1,100 @@ +use crate::components::{Demo, DemoCode}; +use leptos::*; +use prisms::highlight_str; +use thaw::*; + +#[component] +pub fn ProgressPage() -> impl IntoView { + let percentage = create_rw_signal(0.0f32); + view! { +
+

"Progress"

+ + + + + + + + + + + + + + + + + + + + + + + + + + } + "#, + "rust" + ) + > + + "" + + +

"Progress Props"

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
"Name""Type""Default""Description"
"percentage""MaybeSignal""0""Percentage value."
"variant""MaybeSignal""ProgressVariant::Primary""Progress variant."
"show_indicator""MaybeSignal""true""Whether to display indicators."
"indicator_placement""MaybeSignal""ProgressIndicatorPlacement::Outside""Indicator placement."
+
+ } +} diff --git a/src/progress/mod.rs b/src/progress/mod.rs index 45c23fa..7a09c10 100644 --- a/src/progress/mod.rs +++ b/src/progress/mod.rs @@ -1,32 +1,117 @@ -use crate::utils::{mount_style, StoredMaybeSignal}; +mod theme; + +use crate::{use_theme, utils::mount_style, Theme}; use leptos::*; +pub use theme::ProgressTheme; + +#[derive(Default, Clone, PartialEq)] +pub enum ProgressIndicatorPlacement { + #[default] + Outside, + Inside, +} + +impl Copy for ProgressIndicatorPlacement {} + +impl ProgressIndicatorPlacement { + pub fn as_str(&self) -> &'static str { + match self { + ProgressIndicatorPlacement::Outside => "outside", + ProgressIndicatorPlacement::Inside => "inside", + } + } +} + +#[derive(Default, Clone)] +pub enum ProgressVariant { + #[default] + Primary, + Success, + Warning, + Error, +} + +impl ProgressVariant { + fn theme_background_color(&self, theme: &Theme) -> String { + match self { + Self::Primary => theme.common.color_primary.clone(), + Self::Success => theme.common.color_success.clone(), + Self::Warning => theme.common.color_warning.clone(), + Self::Error => theme.common.color_error.clone(), + } + } +} #[component] pub fn Progress( - #[prop(optional, into)] left_tip: MaybeSignal, - #[prop(optional, into)] right_tip: MaybeSignal, - percentage: ReadSignal, + #[prop(into, optional)] percentage: MaybeSignal, + #[prop(into, optional)] variant: MaybeSignal, + #[prop(into, default = MaybeSignal::Static(true))] show_indicator: MaybeSignal, + #[prop(into, optional)] indicator_placement: MaybeSignal, ) -> impl IntoView { mount_style("progress", include_str!("./progress.css")); - let style = move || format!("width: {}%", percentage.get()); - let left_tip: StoredMaybeSignal<_> = left_tip.into(); - let right_tip: StoredMaybeSignal<_> = right_tip.into(); + 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.progress.background_color + )); + css_vars.push_str(&format!( + "--thaw-inner-background-color: {};", + variant.get().theme_background_color(theme) + )); + }); + css_vars + }); + let style = move || { + let percentage = percentage.get(); + let percentage = if percentage < 0.0 { + 0.0 + } else if percentage > 100.0 { + 100.0 + } else { + percentage + }; + format!("width: {}%;", percentage) + }; + + let class = move || { + let mut class = String::from("thaw-progress__progress"); + + class.push_str(&format!( + " thaw-progress__progress--indicator-{}", + indicator_placement.get().as_str() + )); + + class + }; view! { -
- - {move || left_tip.get()} - - - - - - - - {move || right_tip.get()} - +
+
+
+ +
+ { + move || { + format!("{}%", percentage.get()) + } + } +
+
+
+
+ +
+ { + move || { + format!("{}%", percentage.get()) + } + } +
+
} } diff --git a/src/progress/progress.css b/src/progress/progress.css index c928599..f14a8f1 100644 --- a/src/progress/progress.css +++ b/src/progress/progress.css @@ -3,45 +3,37 @@ display: flex; justify-content: center; align-items: center; - height: 24px; - padding: 0 8px; -} - -.thaw-progress__tip-right, -.thaw-progress__tip-left { - display: inline-block; - margin: 0 10px; - width: 48px; - text-align: center; - font-size: 12px; - color: #777; } .thaw-progress__progress { flex: 1; - height: 3px; - background: #f2f2f2; - border-radius: 2px; - /* cursor: pointer; */ + position: relative; + height: 8px; + line-height: 8px; + background: var(--thaw-background-color); + border-radius: 4px; +} + +.thaw-progress__progress--indicator-inside { + height: 16px; + line-height: 16px; + font-size: 12px; + border-radius: 8px; } .thaw-progress__progress-inner { - position: relative; - top: -14px; - display: inline-block; - background: red; + position: absolute; + background: var(--thaw-inner-background-color); height: 100%; + border-radius: inherit; transition: width 0.1s; } -.thaw-progress__progress-circle { - display: inline-block; - position: absolute; - right: -3px; - top: -4px; - width: 10px; - height: 10px; - border-radius: 50%; - background: #fff; - box-shadow: 0 0 3px 2px #4443; +.thaw-progress__indicator--outside { + padding: 0 8px; +} + +.thaw-progress__indicator--inside { + text-align: right; + margin: 0 12px; } diff --git a/src/progress/theme.rs b/src/progress/theme.rs new file mode 100644 index 0000000..4c78aa1 --- /dev/null +++ b/src/progress/theme.rs @@ -0,0 +1,20 @@ +use crate::theme::ThemeMethod; + +#[derive(Clone)] +pub struct ProgressTheme { + pub background_color: String, +} + +impl ThemeMethod for ProgressTheme { + fn light() -> Self { + Self { + background_color: "#ebebeb".into(), + } + } + + fn dark() -> Self { + Self { + background_color: "#ffffff1f".into(), + } + } +} diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 8efbbe9..5fdf504 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -4,8 +4,8 @@ use self::common::CommonTheme; use crate::{ mobile::{NavBarTheme, TabbarTheme}, AlertTheme, AutoCompleteTheme, AvatarTheme, BreadcrumbTheme, ButtonTheme, ColorPickerTheme, - InputTheme, MenuTheme, MessageTheme, SelectTheme, SkeletionTheme, SliderTheme, SwitchTheme, - TableTheme, TagTheme, UploadTheme, + InputTheme, MenuTheme, MessageTheme, ProgressTheme, SelectTheme, SkeletionTheme, SliderTheme, + SwitchTheme, TableTheme, TagTheme, UploadTheme, }; use leptos::*; @@ -36,6 +36,7 @@ pub struct Theme { pub auto_complete: AutoCompleteTheme, pub color_picker: ColorPickerTheme, pub breadcrumb: BreadcrumbTheme, + pub progress: ProgressTheme, } impl Theme { @@ -61,6 +62,7 @@ impl Theme { auto_complete: AutoCompleteTheme::light(), color_picker: ColorPickerTheme::light(), breadcrumb: BreadcrumbTheme::light(), + progress: ProgressTheme::light(), } } pub fn dark() -> Self { @@ -85,6 +87,7 @@ impl Theme { auto_complete: AutoCompleteTheme::dark(), color_picker: ColorPickerTheme::dark(), breadcrumb: BreadcrumbTheme::dark(), + progress: ProgressTheme::dark(), } } }