dioxus_element_plug/components/
skeleton.rs1use dioxus::prelude::*;
2
3#[derive(Props, Clone, PartialEq)]
5pub struct SkeletonProps {
6 #[props(default)]
8 pub children: Option<Element>,
9
10 #[props(default = false)]
12 pub animated: bool,
13
14 #[props(default = 1)]
16 pub count: u32,
17
18 #[props(default = 3)]
20 pub rows: u32,
21
22 #[props(default = true)]
24 pub loading: bool,
25
26 #[props(default)]
28 pub class: Option<String>,
29
30 #[props(default)]
32 pub style: Option<String>,
33}
34
35#[component]
45pub fn Skeleton(props: SkeletonProps) -> Element {
46 if !props.loading {
47 return rsx! { {props.children} };
48 }
49
50 let mut class_names = vec!["el-skeleton".to_string()];
51
52 if props.animated {
53 class_names.push("is-animated".to_string());
54 }
55
56 if let Some(ref custom_class) = props.class {
57 class_names.push(custom_class.clone());
58 }
59
60 let class_string = class_names.join(" ");
61 let style_string = props.style.clone().unwrap_or_default();
62
63 let items: Vec<u32> = (0..props.count).collect();
64 let rows: Vec<(u32, String)> = (0..props.rows)
65 .map(|idx| {
66 let width = if idx == props.rows - 1 { "50%" } else { "100%" };
67 (idx, width.to_string())
68 })
69 .collect();
70
71 rsx! {
72 div {
73 class: "{class_string}",
74 style: "{style_string}",
75 for _item in items.iter() {
76 div {
77 class: "el-skeleton__item",
78 for (_idx, width) in rows.iter() {
79 div {
80 class: "el-skeleton__paragraph",
81 style: "width: {width}; height: 16px; margin-top: 12px; background: var(--el-fill-color-light); border-radius: 4px;",
82 }
83 }
84 }
85 }
86 }
87 }
88}
89