use dioxus::prelude::*;
#[derive(Clone, PartialEq, Props)]
pub struct CardProps {
#[props(default)]
pub header: Option<Element>,
#[props(default)]
pub body: Option<Element>,
#[props(default)]
pub footer: Option<Element>,
#[props(default)]
pub href: Option<String>,
#[props(default)]
pub target: Option<String>,
#[props(default)]
pub class: String,
#[props(default)]
pub header_class: String,
#[props(default)]
pub body_class: String,
#[props(default)]
pub footer_class: String,
#[props(extends = GlobalAttributes)]
attributes: Vec<Attribute>,
#[props(default)]
pub children: Element,
}
fn card_class(class: &str) -> String {
if class.is_empty() {
"card".to_string()
} else {
format!("card {class}")
}
}
#[component]
pub fn Card(props: CardProps) -> Element {
let full_class = card_class(&props.class);
let header_class = if props.header_class.is_empty() {
"card-header".to_string()
} else {
format!("card-header {}", props.header_class)
};
let body_class = if props.body_class.is_empty() {
"card-body".to_string()
} else {
format!("card-body {}", props.body_class)
};
let footer_class = if props.footer_class.is_empty() {
"card-footer".to_string()
} else {
format!("card-footer {}", props.footer_class)
};
let inner = rsx! {
if let Some(header) = props.header {
div { class: "{header_class}", {header} }
}
if let Some(body) = props.body {
div { class: "{body_class}", {body} }
}
{props.children}
if let Some(footer) = props.footer {
div { class: "{footer_class}", {footer} }
}
};
if let Some(href) = props.href.clone() {
let target = props.target.clone();
return rsx! {
a { class: "{full_class}", href: "{href}", target: target,
..props.attributes,
{inner}
}
};
}
rsx! {
div { class: "{full_class}",
..props.attributes,
{inner}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn card_class_base() {
assert_eq!(card_class(""), "card");
}
#[test]
fn card_class_with_extra() {
assert_eq!(
card_class("h-100 text-decoration-none text-reset"),
"card h-100 text-decoration-none text-reset"
);
}
}