patternfly_yew/components/
spinner.rs

1//! Spinner indicator
2use yew::prelude::*;
3
4/// Size of the [`Spinner`] component
5#[derive(Clone, Default, Debug, PartialEq)]
6pub enum SpinnerSize {
7    #[default]
8    None,
9    Sm,
10    Md,
11    Lg,
12    Xl,
13    Custom(String),
14}
15
16impl SpinnerSize {
17    pub fn as_classes(&self) -> Vec<&'static str> {
18        match self {
19            Self::None => Vec::new(),
20            Self::Sm => vec!["pf-m-sm"],
21            Self::Md => vec!["pf-m-md"],
22            Self::Lg => vec!["pf-m-lg"],
23            Self::Xl => vec!["pf-m-xl"],
24            Self::Custom(_) => Vec::new(),
25        }
26    }
27}
28
29/// Properties for [`Spinner`]
30#[derive(PartialEq, Properties)]
31pub struct SpinnerProperties {
32    #[prop_or_default]
33    pub size: SpinnerSize,
34    #[prop_or(String::from("Loading..."))]
35    pub aria_label: String,
36}
37
38/// Spinner component
39///
40/// > A **spinner** is used to indicate to users that an action is in progress. For actions that may take a long time, use a progress bar instead.
41///
42/// See: <https://www.patternfly.org/components/spinner>
43///
44/// ## Properties
45///
46/// Defined by [`SpinnerProperties`].
47pub struct Spinner;
48
49impl Component for Spinner {
50    type Message = ();
51    type Properties = SpinnerProperties;
52
53    fn create(_: &Context<Self>) -> Self {
54        Self {}
55    }
56
57    fn view(&self, ctx: &Context<Self>) -> Html {
58        let mut classes = Classes::from("pf-v5-c-spinner");
59        classes.extend(ctx.props().size.as_classes());
60
61        let style = if let SpinnerSize::Custom(diameter) = &ctx.props().size {
62            format!("--pf-v5-c-spinner--diameter: {};", diameter)
63        } else {
64            String::new()
65        };
66
67        html! (
68            <svg
69                class={classes}
70                role="progressbar"
71                viewBox="0 0 100 100"
72                aria-label={ ctx.props().aria_label.clone() }
73                { style }
74            >
75                <circle class="pf-v5-c-spinner__path" cx="50" cy="50" r="45" fill="none" />
76            </svg>
77        )
78    }
79}