1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use *;
use ;
use component_doc;
use inject_style;
use presence_badge_styles;
/// Availability dot on an avatar or by itself.
///
/// `PresenceBadge` shows availability as a colored dot using Orbital status tokens (`--orb-color-status-success-fg`, `--orb-color-status-warning-fg`, `--orb-color-status-danger-fg`). Set `status` to `Available`, `Away`, `Busy`, `Offline`, `OutOfOffice`, or `Unknown`. Wrap an [`Avatar`](crate::Avatar) as a child to anchor the dot at the bottom-right — common in people lists and messaging UI.
///
/// For inline text labels use [`Badge`](crate::Badge); for numeric overlays use [`CounterBadge`](crate::CounterBadge).
///
/// # When to use
///
/// - Contact lists and chat headers where a person glyph needs an availability signal - Status legends that explain dot colors - Standalone dots when no avatar host is needed
///
/// # Examples
///
/// ## Default presence dot
/// Standalone presence indicator for status legends.
/// <!-- default -->
/// <!-- preview -->
/// ```rust
/// use crate::{PresenceBadge, PresenceStatus};
/// view! {
/// <div data-testid="presence-badge-preview" style="display: inline-flex; min-width: 32px; min-height: 32px; align-items: center; justify-content: center;">
/// <PresenceBadge status=PresenceStatus::Available />
/// </div>
/// }
/// ```
///
/// ## On avatar
/// Presence dot anchored to an avatar host — common in contact lists and chat.
/// <!-- preview -->
/// ```rust
/// use crate::{Avatar, AvatarConfig, PresenceBadge, PresenceStatus};
/// view! {
/// <div data-testid="presence-badge-avatar">
/// <PresenceBadge status=PresenceStatus::Available>
/// <Avatar config=AvatarConfig::colored("Jane Doe") />
/// </PresenceBadge>
/// </div>
/// }
/// ```
///
/// ## Status matrix
/// Supported availability states side by side, including out-of-office and unknown.
/// <!-- preview -->
/// ```rust
/// use crate::{Avatar, AvatarConfig, AvatarColor, Flex, FlexAlign, FlexGap, PresenceBadge, PresenceStatus};
/// view! {
/// <div data-testid="presence-badge-statuses">
/// <Flex gap=FlexGap::Medium align=FlexAlign::Center>
/// <div data-testid="presence-available">
/// <PresenceBadge status=PresenceStatus::Available>
/// <Avatar config=AvatarConfig::with_color("Ava", AvatarColor::Crimson) />
/// </PresenceBadge>
/// </div>
/// <div data-testid="presence-away">
/// <PresenceBadge status=PresenceStatus::Away>
/// <Avatar config=AvatarConfig::with_color("Ben", AvatarColor::Azure) />
/// </PresenceBadge>
/// </div>
/// <div data-testid="presence-busy">
/// <PresenceBadge status=PresenceStatus::Busy>
/// <Avatar config=AvatarConfig::with_color("Cal", AvatarColor::Tangerine) />
/// </PresenceBadge>
/// </div>
/// <div data-testid="presence-offline">
/// <PresenceBadge status=PresenceStatus::Offline>
/// <Avatar config=AvatarConfig::with_color("Dee", AvatarColor::Ash) />
/// </PresenceBadge>
/// </div>
/// <div data-testid="presence-out-of-office">
/// <PresenceBadge status=PresenceStatus::OutOfOffice>
/// <Avatar config=AvatarConfig::with_color("Eve", AvatarColor::Plum) />
/// </PresenceBadge>
/// </div>
/// <div data-testid="presence-unknown">
/// <PresenceBadge status=PresenceStatus::Unknown>
/// <Avatar config=AvatarConfig::with_color("Fin", AvatarColor::Marigold) />
/// </PresenceBadge>
/// </div>
/// </Flex>
/// </div>
/// }
/// ```