Skip to main content

orbital_base_components/feedback/presence_badge/
base.rs

1use leptos::prelude::*;
2
3#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
4pub enum PresenceStatus {
5    #[default]
6    Available,
7    Away,
8    Busy,
9    Offline,
10    OutOfOffice,
11    Unknown,
12}
13
14impl PresenceStatus {
15    pub fn as_str(&self) -> &'static str {
16        match self {
17            Self::Available => "available",
18            Self::Away => "away",
19            Self::Busy => "busy",
20            Self::Offline => "offline",
21            Self::OutOfOffice => "out-of-office",
22            Self::Unknown => "unknown",
23        }
24    }
25
26    pub fn aria_label(&self) -> &'static str {
27        match self {
28            Self::Available => "Available",
29            Self::Away => "Away",
30            Self::Busy => "Busy",
31            Self::Offline => "Offline",
32            Self::OutOfOffice => "Out of office",
33            Self::Unknown => "Unknown",
34        }
35    }
36}
37
38#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
39pub enum PresenceBadgeSize {
40    ExtraSmall,
41    Small,
42    #[default]
43    Medium,
44    Large,
45    ExtraLarge,
46}
47
48impl PresenceBadgeSize {
49    pub fn as_str(&self) -> &'static str {
50        match self {
51            Self::ExtraSmall => "extra-small",
52            Self::Small => "small",
53            Self::Medium => "medium",
54            Self::Large => "large",
55            Self::ExtraLarge => "extra-large",
56        }
57    }
58}
59
60#[component]
61pub fn BasePresenceBadge(
62    #[prop(optional, into)] class: MaybeProp<String>,
63    #[prop(optional, into)] status: Signal<PresenceStatus>,
64    #[prop(optional, into)] size: Signal<PresenceBadgeSize>,
65    #[prop(optional)] children: Option<Children>,
66) -> impl IntoView {
67    let standalone = children.is_none();
68
69    view! {
70        <span
71            class=move || {
72                let mut parts = vec![
73                    "orbital-presence-badge".to_string(),
74                    format!("orbital-presence-badge--{}", status.get().as_str()),
75                    format!("orbital-presence-badge--{}", size.get().as_str()),
76                ];
77                if standalone {
78                    parts.push("orbital-presence-badge--standalone".to_string());
79                }
80                if let Some(extra) = class.get() {
81                    if !extra.is_empty() {
82                        parts.push(extra);
83                    }
84                }
85                parts.join(" ")
86            }
87        >
88            {children.map(|c| c())}
89            <span
90                class=move || {
91                    format!(
92                        "orbital-presence-badge__indicator orbital-presence-badge__indicator--{}",
93                        status.get().as_str()
94                    )
95                }
96                role="img"
97                aria-label=move || status.get().aria_label()
98            />
99        </span>
100    }
101}