ZIm/crates/ui/src/components/indicator.rs
Danilo Leal 2cde6da5ff
Redesign and clean up all icons across Zed (#35856)
- [x] Clean up unused and old icons
- [x] Swap SVG for all in-use icons with the redesigned version
- [x] Document guidelines

Release Notes:

- N/A
2025-08-08 15:34:36 -03:00

177 lines
5.9 KiB
Rust

use super::AnyIcon;
use crate::prelude::*;
#[derive(Default)]
enum IndicatorKind {
#[default]
Dot,
Bar,
Icon(AnyIcon),
}
#[derive(IntoElement, RegisterComponent)]
pub struct Indicator {
kind: IndicatorKind,
border_color: Option<Color>,
pub color: Color,
}
impl Indicator {
pub fn dot() -> Self {
Self {
kind: IndicatorKind::Dot,
border_color: None,
color: Color::Default,
}
}
pub fn bar() -> Self {
Self {
kind: IndicatorKind::Bar,
border_color: None,
color: Color::Default,
}
}
pub fn icon(icon: impl Into<AnyIcon>) -> Self {
Self {
kind: IndicatorKind::Icon(icon.into()),
border_color: None,
color: Color::Default,
}
}
pub fn color(mut self, color: Color) -> Self {
self.color = color;
self
}
pub fn border_color(mut self, color: Color) -> Self {
self.border_color = Some(color);
self
}
}
impl RenderOnce for Indicator {
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
let container = div().flex_none();
let container = if let Some(border_color) = self.border_color {
if matches!(self.kind, IndicatorKind::Dot | IndicatorKind::Bar) {
container.border_1().border_color(border_color.color(cx))
} else {
container
}
} else {
container
};
match self.kind {
IndicatorKind::Icon(icon) => container
.child(icon.map(|icon| icon.custom_size(rems_from_px(8.)).color(self.color))),
IndicatorKind::Dot => container
.w_1p5()
.h_1p5()
.rounded_full()
.bg(self.color.color(cx)),
IndicatorKind::Bar => container
.w_full()
.h_1p5()
.rounded_t_sm()
.bg(self.color.color(cx)),
}
}
}
impl Component for Indicator {
fn scope() -> ComponentScope {
ComponentScope::Status
}
fn description() -> Option<&'static str> {
Some(
"Visual indicators used to represent status, notifications, or draw attention to specific elements.",
)
}
fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
Some(
v_flex()
.gap_6()
.children(vec![
example_group_with_title(
"Dot Indicators",
vec![
single_example("Default", Indicator::dot().into_any_element()),
single_example(
"Success",
Indicator::dot().color(Color::Success).into_any_element(),
),
single_example(
"Warning",
Indicator::dot().color(Color::Warning).into_any_element(),
),
single_example(
"Error",
Indicator::dot().color(Color::Error).into_any_element(),
),
single_example(
"With Border",
Indicator::dot()
.color(Color::Accent)
.border_color(Color::Default)
.into_any_element(),
),
],
),
example_group_with_title(
"Bar Indicators",
vec![
single_example("Default", Indicator::bar().into_any_element()),
single_example(
"Success",
Indicator::bar().color(Color::Success).into_any_element(),
),
single_example(
"Warning",
Indicator::bar().color(Color::Warning).into_any_element(),
),
single_example(
"Error",
Indicator::bar().color(Color::Error).into_any_element(),
),
],
),
example_group_with_title(
"Icon Indicators",
vec![
single_example(
"Default",
Indicator::icon(Icon::new(IconName::Circle)).into_any_element(),
),
single_example(
"Success",
Indicator::icon(Icon::new(IconName::Check))
.color(Color::Success)
.into_any_element(),
),
single_example(
"Warning",
Indicator::icon(Icon::new(IconName::Warning))
.color(Color::Warning)
.into_any_element(),
),
single_example(
"Error",
Indicator::icon(Icon::new(IconName::Close))
.color(Color::Error)
.into_any_element(),
),
],
),
])
.into_any_element(),
)
}
}