flams_web_utils/components/
spinner.rs

1use 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    /// An optional label for the Spinner.
36    #[prop(optional, into)]
37    label: MaybeProp<String>,
38    /// The size of the spinner.
39    #[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}