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 Eye,
34 EyeOff,
35}
36
37impl IconName {
38 pub fn glyph(self) -> &'static str {
40 match self {
41 IconName::Check => "\u{2713}",
42 IconName::Close => "\u{00d7}",
43 IconName::Minus => "\u{2212}",
44 IconName::Plus => "+",
45 IconName::ChevronDown => "\u{25be}",
46 IconName::ChevronUp => "\u{25b4}",
47 IconName::ChevronLeft => "\u{25c2}",
48 IconName::ChevronRight => "\u{25b8}",
49 IconName::Search => "\u{2315}",
50 IconName::Dot => "\u{2022}",
51 IconName::Info => "\u{2139}",
52 IconName::Warning => "\u{26a0}",
53 IconName::Star => "\u{2605}",
54 IconName::Copy => "\u{29c9}",
55 IconName::Menu => "\u{2630}",
56 IconName::Ellipsis => "\u{2026}",
57 IconName::ArrowRight => "\u{2192}",
58 IconName::ArrowLeft => "\u{2190}",
59 IconName::Eye => "\u{25ce}",
60 IconName::EyeOff => "\u{2298}",
61 }
62 }
63}
64
65#[derive(IntoElement)]
69pub struct Icon {
70 name: IconName,
71 size: Size,
72 color: Option<ColorName>,
73}
74
75impl Icon {
76 pub fn new(name: IconName) -> Self {
77 Icon {
78 name,
79 size: Size::Md,
80 color: None,
81 }
82 }
83
84 pub fn size(mut self, size: Size) -> Self {
85 self.size = size;
86 self
87 }
88
89 pub fn color(mut self, color: ColorName) -> Self {
91 self.color = Some(color);
92 self
93 }
94
95 fn glyph_px(&self) -> f32 {
96 match self.size {
97 Size::Xs => 14.0,
98 Size::Sm => 16.0,
99 Size::Md => 20.0,
100 Size::Lg => 26.0,
101 Size::Xl => 32.0,
102 }
103 }
104}
105
106impl RenderOnce for Icon {
107 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
108 let t = theme(cx);
109 let tint = self.color.map(|c| t.color(c, t.primary_shade()).hsla());
110 let mut el = div()
111 .flex()
112 .items_center()
113 .justify_center()
114 .text_size(px(self.glyph_px()))
115 .child(SharedString::new_static(self.name.glyph()));
116 if let Some(tint) = tint {
117 el = el.text_color(tint);
118 }
119 el
120 }
121}