use dioxus::prelude::*;
use crate::types::{Color, Size};
#[derive(Clone, PartialEq, Props)]
pub struct PlaceholderProps {
#[props(default = 100)]
pub width: u8,
#[props(default)]
pub color: Option<Color>,
#[props(default)]
pub size: Size,
#[props(default)]
pub wave: bool,
#[props(default)]
pub glow: bool,
#[props(default = "span".to_string())]
pub tag: String,
#[props(default)]
pub class: String,
}
#[component]
pub fn Placeholder(props: PlaceholderProps) -> Element {
let col = format!("col-{}", props.width.min(12));
let color_class = match &props.color {
Some(c) => format!(" bg-{c}"),
None => String::new(),
};
let size_class = match props.size {
Size::Sm => " placeholder-sm",
Size::Lg => " placeholder-lg",
Size::Md => "",
};
let full_class = if props.class.is_empty() {
format!("placeholder {col}{color_class}{size_class}")
} else {
format!("placeholder {col}{color_class}{size_class} {}", props.class)
};
let animation = if props.wave {
"placeholder-wave"
} else if props.glow {
"placeholder-glow"
} else {
""
};
if animation.is_empty() {
rsx! {
span { class: "{full_class}", "aria-hidden": "true" }
}
} else {
rsx! {
p { class: "{animation}",
span { class: "{full_class}", "aria-hidden": "true" }
}
}
}
}
#[derive(Clone, PartialEq, Props)]
pub struct PlaceholderParagraphProps {
#[props(default = 3)]
pub lines: usize,
#[props(default)]
pub wave: bool,
#[props(default)]
pub glow: bool,
#[props(default)]
pub class: String,
}
#[component]
pub fn PlaceholderParagraph(props: PlaceholderParagraphProps) -> Element {
let animation = if props.wave {
" placeholder-wave"
} else if props.glow {
" placeholder-glow"
} else {
""
};
let full_class = if props.class.is_empty() {
animation.trim().to_string()
} else {
format!("{} {}", animation.trim(), props.class)
};
let widths = [7, 9, 6, 8, 5, 10, 7, 4, 11, 6];
rsx! {
p { class: "{full_class}",
for i in 0..props.lines {
{
let w = widths[i % widths.len()];
let cls = format!("placeholder col-{w}");
rsx! {
span {
class: "{cls}",
"aria-hidden": "true",
}
" "
}
}
}
}
}
}