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}