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