indicator.rs

  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}
 86
 87impl ComponentPreview for Indicator {
 88    fn description() -> impl Into<Option<&'static str>> {
 89        "An indicator visually represents a status or state."
 90    }
 91
 92    fn examples(_window: &mut Window, _: &mut App) -> Vec<ComponentExampleGroup<Self>> {
 93        vec![
 94            example_group_with_title(
 95                "Types",
 96                vec![
 97                    single_example("Dot", Indicator::dot().color(Color::Info)),
 98                    single_example("Bar", Indicator::bar().color(Color::Player(2))),
 99                    single_example(
100                        "Icon",
101                        Indicator::icon(Icon::new(IconName::Check).color(Color::Success)),
102                    ),
103                ],
104            ),
105            example_group_with_title(
106                "Examples",
107                vec![
108                    single_example("Info", Indicator::dot().color(Color::Info)),
109                    single_example("Success", Indicator::dot().color(Color::Success)),
110                    single_example("Warning", Indicator::dot().color(Color::Warning)),
111                    single_example("Error", Indicator::dot().color(Color::Error)),
112                ],
113            ),
114        ]
115    }
116}