yew_bootstrap/component/
spinner.rs

1use yew::prelude::*;
2
3use crate::util::Color;
4
5/// # Spinner component
6/// Used alongside [crate::util::Color] to create Spinner components
7///
8/// See [SpinnerProps] for a listing of properties
9///
10/// ## Example
11/// ```rust
12/// use yew::prelude::*;
13/// use yew_bootstrap::component::Spinner;
14/// use yew_bootstrap::util::Color;
15/// fn test() -> Html {
16///     html!{
17///         <Spinner style={Color::Primary}>
18///             {"Visually hidden text"}
19///         </Spinner>
20///     }
21/// }
22/// ```
23pub struct Spinner {}
24
25/// # Properties of [Spinner]
26#[derive(Properties, Clone, PartialEq)]
27pub struct SpinnerProps {
28    /// CSS class
29    #[prop_or_default]
30    pub class: String,
31
32    /// Inner components (visually hidden text)
33    #[prop_or_default]
34    pub children: Children,
35
36    /// Color style, default [Color::Primary]
37    #[prop_or(Color::Primary)]
38    pub style: Color,
39
40    /// Grow style, default false
41    #[prop_or_default]
42    pub grow: bool,
43
44    /// Small size style, default false
45    #[prop_or_default]
46    pub small: bool,
47}
48
49impl Component for Spinner {
50    type Message = ();
51    type Properties = SpinnerProps;
52
53    fn create(_ctx: &Context<Self>) -> Self {
54        Self {}
55    }
56
57    fn view(&self, ctx: &Context<Self>) -> Html {
58        let props = ctx.props();
59        let mut classes = Classes::new();
60
61        if props.grow {
62            classes.push("spinner-grow");
63            if props.small {
64                classes.push("spinner-grow-sm");
65            }
66        } else {
67            classes.push("spinner-border");
68            if props.small {
69                classes.push("spinner-border-sm");
70            }
71        }
72
73        classes.push(format!("text-{}", props.style));
74        classes.push(props.class.clone());
75
76        html! {
77            <div class={classes} role="status">
78                <span class="visually-hidden">
79                    { for props.children.iter() }
80                </span>
81            </div>
82        }
83    }
84}