1use crate::{AnyIcon, prelude::*};
2
3#[derive(Default)]
4enum IndicatorKind {
5 #[default]
6 Dot,
7 Bar,
8 Icon(AnyIcon),
9}
10
11#[derive(IntoElement)]
12pub struct Indicator {
13 kind: IndicatorKind,
14 border_color: Option<Color>,
15 pub color: Color,
16}
17
18impl Indicator {
19 pub fn dot() -> Self {
20 Self {
21 kind: IndicatorKind::Dot,
22 border_color: None,
23 color: Color::Default,
24 }
25 }
26
27 pub fn bar() -> Self {
28 Self {
29 kind: IndicatorKind::Bar,
30 border_color: None,
31
32 color: Color::Default,
33 }
34 }
35
36 pub fn icon(icon: impl Into<AnyIcon>) -> Self {
37 Self {
38 kind: IndicatorKind::Icon(icon.into()),
39 border_color: None,
40
41 color: Color::Default,
42 }
43 }
44
45 pub fn color(mut self, color: Color) -> Self {
46 self.color = color;
47 self
48 }
49
50 pub fn border_color(mut self, color: Color) -> Self {
51 self.border_color = Some(color);
52 self
53 }
54}
55
56impl RenderOnce for Indicator {
57 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
58 let container = div().flex_none();
59 let container = if let Some(border_color) = self.border_color {
60 if matches!(self.kind, IndicatorKind::Dot | IndicatorKind::Bar) {
61 container.border_1().border_color(border_color.color(cx))
62 } else {
63 container
64 }
65 } else {
66 container
67 };
68
69 match self.kind {
70 IndicatorKind::Icon(icon) => container
71 .child(icon.map(|icon| icon.custom_size(rems_from_px(8.)).color(self.color))),
72 IndicatorKind::Dot => container
73 .w_1p5()
74 .h_1p5()
75 .rounded_full()
76 .bg(self.color.color(cx)),
77 IndicatorKind::Bar => container
78 .w_full()
79 .h_1p5()
80 .rounded_t_sm()
81 .bg(self.color.color(cx)),
82 }
83 }
84}