mod person;
mod variant;
use yew::{classes, function_component, html, AttrValue, Children, Classes, Html, Properties};
use yew_hooks::{use_async_with_options, UseAsyncOptions};
use zu_util::image_future::ImageFuture;
use zu_util::{name, prop::ToAttr};
use crate::styles::shape_variant::ShapeVariant;
pub use person::Person;
#[derive(Debug, Clone, PartialEq, Properties)]
pub struct Props {
#[prop_or_default]
pub alt: AttrValue,
#[prop_or_default]
pub aria_label: AttrValue,
#[prop_or_default]
pub children: Children,
#[prop_or_default]
pub classes: Classes,
#[prop_or(false)]
pub color_default: bool,
#[prop_or(AttrValue::from("div"))]
pub component: AttrValue,
#[prop_or_default]
pub img_prop_cross_origin: AttrValue,
#[prop_or_default]
pub img_prop_referencer_policy: AttrValue,
#[prop_or_default]
pub sizes: AttrValue,
#[prop_or_default]
pub src: AttrValue,
#[prop_or_default]
pub src_set: AttrValue,
#[prop_or_default]
pub style: AttrValue,
#[prop_or_default]
pub variant: ShapeVariant,
}
#[function_component(Avatar)]
pub fn avatar(props: &Props) -> Html {
let has_image = !props.src.is_empty() || !props.src_set.is_empty();
let use_loaded = {
let image_src = props.src.to_string();
let image_src_set = props.src_set.to_string();
use_async_with_options(
async move { ImageFuture::new(&image_src, Some(&image_src_set)).await },
UseAsyncOptions::enable_auto(),
)
};
let has_image_no_failing = has_image && use_loaded.data.is_some();
let root_cls = classes!(
"ZuAvatar-root",
variant::css_class(props.variant),
if has_image_no_failing {
""
} else {
"ZuAvatar-colorDefault"
},
props.classes.clone(),
);
let style = [
if props.alt.is_empty() {
String::new()
} else {
format!("background-color: {};", name::to_color(props.alt.as_str()))
}
.as_str(),
props.style.as_str(),
]
.join(";");
let abbr_name: String = if props.alt.is_empty() {
String::new()
} else {
name::abbreviate_first(props.alt.as_str())
};
let children = if !props.children.is_empty() {
html! {for props.children.iter()}
} else if has_image_no_failing {
html! {<img class="ZuAvatar-img"
aria-label={props.aria_label.to_attr()}
src={props.src.to_attr()}
src-set={props.src_set.to_attr()}
alt={props.alt.to_attr()}
sizes={props.sizes.to_attr()} />}
} else if !abbr_name.is_empty() {
html! {abbr_name}
} else {
html! {<Person classes="ZuAvatar-fallback" />}
};
html! {
<@{props.component.to_string()} class={root_cls} style={style}>
{children}
</@>
}
}