1use std::sync::Arc;
2
3use crate::theme::theme;
4use crate::Theme;
5use gpui2::elements::svg;
6use gpui2::style::StyleHelpers;
7use gpui2::{Element, ViewContext};
8use gpui2::{Hsla, IntoElement};
9
10#[derive(Default, PartialEq, Copy, Clone)]
11pub enum IconColor {
12 #[default]
13 Default,
14 Muted,
15 Disabled,
16 Placeholder,
17 Accent,
18 Error,
19 Warning,
20 Success,
21 Info,
22}
23
24impl IconColor {
25 pub fn color(self, theme: Arc<Theme>) -> Hsla {
26 match self {
27 IconColor::Default => theme.lowest.base.default.foreground,
28 IconColor::Muted => theme.lowest.variant.default.foreground,
29 IconColor::Disabled => theme.lowest.base.disabled.foreground,
30 IconColor::Placeholder => theme.lowest.base.disabled.foreground,
31 IconColor::Accent => theme.lowest.accent.default.foreground,
32 IconColor::Error => theme.lowest.negative.default.foreground,
33 IconColor::Warning => theme.lowest.warning.default.foreground,
34 IconColor::Success => theme.lowest.positive.default.foreground,
35 IconColor::Info => theme.lowest.accent.default.foreground,
36 }
37 }
38}
39
40#[derive(Default, PartialEq, Copy, Clone)]
41pub enum IconAsset {
42 Ai,
43 ArrowLeft,
44 ArrowRight,
45 ArrowUpRight,
46 AudioOff,
47 AudioOn,
48 Bolt,
49 ChevronDown,
50 ChevronLeft,
51 ChevronRight,
52 ChevronUp,
53 Close,
54 ExclamationTriangle,
55 File,
56 FileDoc,
57 FileGit,
58 FileLock,
59 FileRust,
60 FileToml,
61 FileTree,
62 Folder,
63 FolderOpen,
64 FolderX,
65 #[default]
66 Hash,
67 InlayHint,
68 MagicWand,
69 MagnifyingGlass,
70 MessageBubbles,
71 Mic,
72 MicMute,
73 Plus,
74 Screen,
75 Split,
76 Terminal,
77 XCircle,
78 Copilot,
79 Envelope,
80}
81
82impl IconAsset {
83 pub fn path(self) -> &'static str {
84 match self {
85 IconAsset::Ai => "icons/ai.svg",
86 IconAsset::ArrowLeft => "icons/arrow_left.svg",
87 IconAsset::ArrowRight => "icons/arrow_right.svg",
88 IconAsset::ArrowUpRight => "icons/arrow_up_right.svg",
89 IconAsset::AudioOff => "icons/speaker-off.svg",
90 IconAsset::AudioOn => "icons/speaker-loud.svg",
91 IconAsset::Bolt => "icons/bolt.svg",
92 IconAsset::ChevronDown => "icons/chevron_down.svg",
93 IconAsset::ChevronLeft => "icons/chevron_left.svg",
94 IconAsset::ChevronRight => "icons/chevron_right.svg",
95 IconAsset::ChevronUp => "icons/chevron_up.svg",
96 IconAsset::Close => "icons/x.svg",
97 IconAsset::ExclamationTriangle => "icons/warning.svg",
98 IconAsset::File => "icons/file_icons/file.svg",
99 IconAsset::FileDoc => "icons/file_icons/book.svg",
100 IconAsset::FileGit => "icons/file_icons/git.svg",
101 IconAsset::FileLock => "icons/file_icons/lock.svg",
102 IconAsset::FileRust => "icons/file_icons/rust.svg",
103 IconAsset::FileToml => "icons/file_icons/toml.svg",
104 IconAsset::FileTree => "icons/project.svg",
105 IconAsset::Folder => "icons/file_icons/folder.svg",
106 IconAsset::FolderOpen => "icons/file_icons/folder_open.svg",
107 IconAsset::FolderX => "icons/stop_sharing.svg",
108 IconAsset::Hash => "icons/hash.svg",
109 IconAsset::InlayHint => "icons/inlay_hint.svg",
110 IconAsset::MagicWand => "icons/magic-wand.svg",
111 IconAsset::MagnifyingGlass => "icons/magnifying_glass.svg",
112 IconAsset::MessageBubbles => "icons/conversations.svg",
113 IconAsset::Mic => "icons/mic.svg",
114 IconAsset::MicMute => "icons/mic-mute.svg",
115 IconAsset::Plus => "icons/plus.svg",
116 IconAsset::Screen => "icons/desktop.svg",
117 IconAsset::Split => "icons/split.svg",
118 IconAsset::Terminal => "icons/terminal.svg",
119 IconAsset::XCircle => "icons/error.svg",
120 IconAsset::Copilot => "icons/copilot.svg",
121 IconAsset::Envelope => "icons/feedback.svg",
122 }
123 }
124}
125
126#[derive(Element, Clone)]
127pub struct Icon {
128 asset: IconAsset,
129 color: IconColor,
130}
131
132pub fn icon(asset: IconAsset) -> Icon {
133 Icon {
134 asset,
135 color: IconColor::default(),
136 }
137}
138
139impl Icon {
140 pub fn color(mut self, color: IconColor) -> Self {
141 self.color = color;
142 self
143 }
144
145 fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
146 let theme = theme(cx);
147 let fill = self.color.color(theme);
148
149 svg()
150 .flex_none()
151 .path(self.asset.path())
152 .size_4()
153 .fill(fill)
154 }
155}