1use gpui::prelude::*;
8use gpui::{div, px, App, IntoElement, SharedString, Window};
9
10use crate::theme::{theme, ColorName, Size};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum IconName {
15 Check,
16 Close,
17 Minus,
18 Plus,
19 ChevronDown,
20 ChevronUp,
21 ChevronLeft,
22 ChevronRight,
23 Search,
24 Dot,
25 Info,
26 Warning,
27 Star,
28 Copy,
29 Menu,
30 Ellipsis,
31 ArrowRight,
32 ArrowLeft,
33}
34
35impl IconName {
36 pub fn glyph(self) -> &'static str {
38 match self {
39 IconName::Check => "\u{2713}",
40 IconName::Close => "\u{00d7}",
41 IconName::Minus => "\u{2212}",
42 IconName::Plus => "+",
43 IconName::ChevronDown => "\u{25be}",
44 IconName::ChevronUp => "\u{25b4}",
45 IconName::ChevronLeft => "\u{25c2}",
46 IconName::ChevronRight => "\u{25b8}",
47 IconName::Search => "\u{2315}",
48 IconName::Dot => "\u{2022}",
49 IconName::Info => "\u{2139}",
50 IconName::Warning => "\u{26a0}",
51 IconName::Star => "\u{2605}",
52 IconName::Copy => "\u{29c9}",
53 IconName::Menu => "\u{2630}",
54 IconName::Ellipsis => "\u{2026}",
55 IconName::ArrowRight => "\u{2192}",
56 IconName::ArrowLeft => "\u{2190}",
57 }
58 }
59}
60
61#[derive(IntoElement)]
65pub struct Icon {
66 name: IconName,
67 size: Size,
68 color: Option<ColorName>,
69}
70
71impl Icon {
72 pub fn new(name: IconName) -> Self {
73 Icon {
74 name,
75 size: Size::Md,
76 color: None,
77 }
78 }
79
80 pub fn size(mut self, size: Size) -> Self {
81 self.size = size;
82 self
83 }
84
85 pub fn color(mut self, color: ColorName) -> Self {
87 self.color = Some(color);
88 self
89 }
90
91 fn glyph_px(&self) -> f32 {
92 match self.size {
93 Size::Xs => 14.0,
94 Size::Sm => 16.0,
95 Size::Md => 20.0,
96 Size::Lg => 26.0,
97 Size::Xl => 32.0,
98 }
99 }
100}
101
102impl RenderOnce for Icon {
103 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
104 let t = theme(cx);
105 let tint = self.color.map(|c| t.color(c, t.primary_shade()).hsla());
106 let mut el = div()
107 .flex()
108 .items_center()
109 .justify_center()
110 .text_size(px(self.glyph_px()))
111 .child(SharedString::new_static(self.name.glyph()));
112 if let Some(tint) = tint {
113 el = el.text_color(tint);
114 }
115 el
116 }
117}