flams_web_utils/components/
spinner.rs

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