Skip to main content

orbital_base_components/data/avatar_group/
base.rs

1use leptos::prelude::*;
2
3#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4pub enum AvatarGroupLayout {
5    #[default]
6    Spread,
7    Stack,
8}
9
10impl AvatarGroupLayout {
11    pub fn as_str(&self) -> &'static str {
12        match self {
13            Self::Spread => "spread",
14            Self::Stack => "stack",
15        }
16    }
17}
18
19#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
20pub enum AvatarGroupSize {
21    Tiny,
22    #[default]
23    S24,
24    S28,
25    S32,
26    S40,
27    S56,
28    S96,
29}
30
31impl AvatarGroupSize {
32    pub fn as_str(&self) -> &'static str {
33        match self {
34            Self::Tiny => "tiny",
35            Self::S24 => "24",
36            Self::S28 => "28",
37            Self::S32 => "32",
38            Self::S40 => "40",
39            Self::S56 => "56",
40            Self::S96 => "96",
41        }
42    }
43
44    pub fn px(&self) -> u8 {
45        match self {
46            Self::Tiny => 4,
47            Self::S24 => 24,
48            Self::S28 => 28,
49            Self::S32 => 32,
50            Self::S40 => 40,
51            Self::S56 => 56,
52            Self::S96 => 96,
53        }
54    }
55}
56
57#[component]
58pub fn BaseAvatarGroup(
59    #[prop(optional, into)] class: MaybeProp<String>,
60    #[prop(optional, into)] layout: Signal<AvatarGroupLayout>,
61    #[prop(optional, into)] size: Signal<AvatarGroupSize>,
62    #[prop(optional, into)] overflow: MaybeProp<u32>,
63    children: Children,
64) -> impl IntoView {
65    view! {
66        <span
67            class=move || {
68                let mut parts = vec![
69                    "orbital-avatar-group".to_string(),
70                    format!("orbital-avatar-group--{}", layout.get().as_str()),
71                    format!("orbital-avatar-group--size-{}", size.get().as_str()),
72                ];
73                if let Some(extra) = class.get() {
74                    if !extra.is_empty() {
75                        parts.push(extra);
76                    }
77                }
78                parts.join(" ")
79            }
80            style=move || format!("--orbital-avatar-group-size: {}px;", size.get().px())
81        >
82            {children()}
83            {move || {
84                overflow.get().filter(|n| *n > 0).map(|n| {
85                    view! {
86                        <span class="orbital-avatar-group__overflow" aria-label=format!("{n} more")>
87                            {format!("+{n}")}
88                        </span>
89                    }
90                })
91            }}
92        </span>
93    }
94}