vizia_core/views/avatar.rs
1use crate::prelude::*;
2
3/// Enum which represents the geometric variants of an avatar view.
4#[derive(Debug, Default, Clone, Copy, Data, PartialEq)]
5pub enum AvatarVariant {
6 #[default]
7 /// Represents a circular avatar shape.
8 Circle,
9 /// Represents a square avatar shape.
10 Square,
11 /// Represents a rounded rectangle avatar shape.
12 Rounded,
13}
14
15/// An avatar view is used to visually represent a person or entity and can contain text, an icon, or an image.
16///
17/// # Example
18/// ```
19/// # use vizia_core::prelude::*;
20/// # let cx = &mut Context::default();
21/// Avatar::new(cx, |cx|{
22/// Svg::new(cx, ICON_USER);
23/// });
24/// ```
25pub struct Avatar {}
26
27impl Avatar {
28 /// Creates a new avatar with the given content.
29 ///
30 /// ```
31 /// # use vizia_core::prelude::*;
32 /// # let cx = &mut Context::default();
33 /// Avatar::new(cx, |cx|{
34 /// Svg::new(cx, ICON_USER);
35 /// });
36 /// ```
37 pub fn new<F>(cx: &mut Context, content: F) -> Handle<Self>
38 where
39 F: FnOnce(&mut Context),
40 {
41 Self {}.build(cx, content).class("circle")
42 }
43}
44
45impl View for Avatar {
46 fn element(&self) -> Option<&'static str> {
47 Some("avatar")
48 }
49}
50
51impl Handle<'_, Avatar> {
52 /// Selects the geometric variant of the Avatar. Accepts a value of, or lens to, an [AvatarVariant].
53 ///
54 /// ```
55 /// # use vizia_core::prelude::*;
56 /// # let cx = &mut Context::default();
57 /// Avatar::new(cx, |cx|{
58 /// Svg::new(cx, ICON_USER);
59 /// })
60 /// .variant(AvatarVariant::Rounded);
61 /// ```
62 pub fn variant<U: Into<AvatarVariant>>(self, variant: impl Res<U>) -> Self {
63 self.bind(variant, |handle, val| {
64 let var: AvatarVariant = val.get(&handle).into();
65 match var {
66 AvatarVariant::Circle => {
67 handle
68 .toggle_class("circle", true)
69 .toggle_class("square", false)
70 .toggle_class("rounded", false);
71 }
72
73 AvatarVariant::Square => {
74 handle
75 .toggle_class("circle", false)
76 .toggle_class("square", true)
77 .toggle_class("rounded", false);
78 }
79
80 AvatarVariant::Rounded => {
81 handle
82 .toggle_class("circle", false)
83 .toggle_class("square", false)
84 .toggle_class("rounded", true);
85 }
86 }
87 })
88 }
89
90 /// Adds a badge to the Avatar.
91 ///
92 /// ```
93 /// # use vizia_core::prelude::*;
94 /// # let cx = &mut Context::default();
95 /// Avatar::new(cx, |cx|{
96 /// Svg::new(cx, ICON_USER);
97 /// })
98 /// .badge(|cx| Badge::empty(cx).class("error"));
99 /// ```
100 pub fn badge<F>(mut self, content: F) -> Self
101 where
102 F: FnOnce(&mut Context) -> Handle<'_, Badge>,
103 {
104 let entity = self.entity();
105
106 self.context().with_current(entity, |cx| {
107 (content)(cx).placement(BadgePlacement::default());
108 });
109
110 self
111 }
112}
113
114/// The [AvatarGroup] view can be used to group a series of avatars together.
115pub struct AvatarGroup {}
116
117impl AvatarGroup {
118 /// Create a new [AvatarGroup]. The content should be a series of [Avatar] views.
119 pub fn new<F>(cx: &mut Context, content: F) -> Handle<Self>
120 where
121 F: FnOnce(&mut Context),
122 {
123 Self {}.build(cx, content).size(Auto).gap(Pixels(-20.0)).layout_type(LayoutType::Row)
124 }
125}
126
127impl View for AvatarGroup {
128 fn element(&self) -> Option<&'static str> {
129 Some("avatar-group")
130 }
131}