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
use crate::prelude::*;

/// Enum which represents the geometric variants of an avatar view.
#[derive(Debug, Default, Clone, Copy, Data, PartialEq)]
pub enum AvatarVariant {
    #[default]
    Circle,
    Square,
    Rounded,
}

/// An avatar is used to visually represent a person or entity and can contain text, an icon, or an image.
///
/// # Example
/// ```
/// # use vizia_core::prelude::*;
/// # let cx = &mut Context::default();
/// Avatar::new(cx, |cx|{
///     Svg::new(cx, ICON_USER);
/// });
/// ```
pub struct Avatar {}

impl Avatar {
    pub fn new<F>(cx: &mut Context, content: F) -> Handle<Self>
    where
        F: FnOnce(&mut Context),
    {
        Self {}.build(cx, content).class("circle")
    }
}

impl View for Avatar {
    fn element(&self) -> Option<&'static str> {
        Some("avatar")
    }
}

impl<'a> Handle<'a, Avatar> {
    /// Selects the style variant for the Avatar.
    pub fn variant<U: Into<AvatarVariant>>(mut self, variant: impl Res<U>) -> Self {
        let entity = self.entity();
        variant.set_or_bind(self.context(), entity, |cx, val| {
            let var: AvatarVariant = val.get(cx).into();
            match var {
                AvatarVariant::Circle => {
                    cx.toggle_class("circle", true);
                    cx.toggle_class("square", false);
                    cx.toggle_class("rounded", false);
                }

                AvatarVariant::Square => {
                    cx.toggle_class("circle", false);
                    cx.toggle_class("square", true);
                    cx.toggle_class("rounded", false);
                }

                AvatarVariant::Rounded => {
                    cx.toggle_class("circle", false);
                    cx.toggle_class("square", false);
                    cx.toggle_class("rounded", true);
                }
            }
        });

        self
    }

    /// Adds a badge to the Avatar.
    pub fn badge<F>(mut self, content: F) -> Self
    where
        F: FnOnce(&mut Context) -> Handle<'_, Badge>,
    {
        let entity = self.entity();

        self.context().with_current(entity, |cx| {
            (content)(cx).placement(BadgePlacement::default());
        });

        self
    }
}