flams_web_utils/components/
spinner.rs1use leptos::{either::Either, prelude::*};
2
3use crate::inject_css;
4
5#[derive(Default, Clone)]
6pub enum SpinnerSize {
7 ExtraTiny,
8 Tiny,
9 ExtraSmall,
10 Small,
11 #[default]
12 Medium,
13 Large,
14 ExtraLarge,
15 Huge,
16}
17
18impl SpinnerSize {
19 pub const fn as_str(&self) -> &'static str {
20 match self {
21 Self::ExtraTiny => "extra-tiny",
22 Self::Tiny => "tiny",
23 Self::ExtraSmall => "extra-small",
24 Self::Small => "small",
25 Self::Medium => "medium",
26 Self::Large => "large",
27 Self::ExtraLarge => "extra-large",
28 Self::Huge => "huge",
29 }
30 }
31}
32
33#[component]
34pub fn Spinner(
35 #[prop(optional, into)]
37 label: MaybeProp<String>,
38 #[prop(optional, into)]
40 size: Signal<SpinnerSize>,
41 #[prop(optional)] children: Option<Children>,
42) -> impl IntoView {
43 inject_css("flams-spinner", include_str!("./spinner.css"));
44
45 let cls = format!("thaw-spinner thaw-spinner--{}", size.get().as_str());
46
47 view! {
48 <div
49 class=cls
50 role="progressbar"
51 >
52 <span class="thaw-spinner__spinner">
53 <span class="thaw-spinner__spinner-tail"></span>
54 </span>
55 {children.map_or_else(
56 || Either::Left({
57 move || label.get().map(|label|
58 view! {
59 <label class="thaw-spinner__label">
60 {label}
61 </label>
62 }
63 )
64 }),
65 |children| Either::Right(view! {
66 <label class="thaw-spinner__label">
67 {children()}
68 </label>
69 })
70 )}
71 </div>
72 }
73}