yew_bs/components/
spinners.rs1use yew::prelude::*;
2use crate::components::common::{Variant, Size};
3#[derive(Clone, Copy, PartialEq, Debug)]
4pub enum SpinnerType {
5 Border,
6 Grow,
7}
8impl SpinnerType {
9 pub fn as_str(&self) -> &'static str {
10 match self {
11 SpinnerType::Border => "border",
12 SpinnerType::Grow => "grow",
13 }
14 }
15}
16#[derive(Properties, PartialEq)]
18pub struct SpinnerProps {
19 #[prop_or(SpinnerType::Border)]
21 pub spinner_type: SpinnerType,
22 #[prop_or(Variant::Primary)]
24 pub variant: Variant,
25 #[prop_or_default]
27 pub size: Option<Size>,
28 #[prop_or_default]
30 pub label: Option<AttrValue>,
31 #[prop_or_default]
33 pub centered: bool,
34 #[prop_or_default]
36 pub class: Option<AttrValue>,
37 #[prop_or_default]
39 pub node_ref: NodeRef,
40}
41#[function_component(Spinner)]
43pub fn spinner(props: &SpinnerProps) -> Html {
44 let mut classes = Classes::new();
45 classes.push("spinner");
46 classes.push(format!("spinner-{}", props.spinner_type.as_str()));
47 if props.variant != Variant::Primary {
48 classes.push(format!("text-{}", props.variant.as_str()));
49 }
50 if let Some(size) = &props.size {
51 match size {
52 Size::Small => {
53 classes.push(format!("spinner-{}-sm", props.spinner_type.as_str()))
54 }
55 Size::Large => {}
56 Size::Medium => {}
57 }
58 }
59 if let Some(class) = &props.class {
60 classes.push(class.to_string());
61 }
62 let container_classes = if props.centered {
63 classes!("d-flex", "justify-content-center")
64 } else {
65 Classes::new()
66 };
67 let default_label = match props.spinner_type {
68 SpinnerType::Border => "Loading...",
69 SpinnerType::Grow => "Loading...",
70 };
71 let label_attr = if let Some(label) = &props.label {
72 label.clone()
73 } else {
74 AttrValue::from(default_label)
75 };
76 html! {
77 if props.centered { < div class = { container_classes } > < div class = { classes
78 } role = "status" ref = { props.node_ref.clone() } > < span class =
79 "visually-hidden" > { & label_attr } </ span > </ div > </ div > } else { < div
80 class = { classes } role = "status" ref = { props.node_ref.clone() } > < span
81 class = "visually-hidden" > { & label_attr } </ span > </ div > }
82 }
83}