Skip to main content

guise/
themeicon.rs

1//! `ThemeIcon` — a colored, rounded container for a single icon.
2
3use gpui::prelude::*;
4use gpui::{div, px, App, IntoElement, Window};
5
6use crate::devtools::Probed;
7use crate::icon::Glyph;
8use crate::style::{surface, Variant};
9use crate::theme::{theme, ColorName, Size};
10
11/// A decorative colored icon chip.
12#[derive(IntoElement)]
13pub struct ThemeIcon {
14  icon: Glyph,
15  variant: Variant,
16  color: ColorName,
17  size: Size,
18  radius: Option<Size>,
19}
20
21impl ThemeIcon {
22  pub fn new(icon: impl Into<Glyph>) -> Self {
23    ThemeIcon {
24      icon: icon.into(),
25      variant: Variant::Filled,
26      color: ColorName::Blue,
27      size: Size::Md,
28      radius: None,
29    }
30  }
31
32  pub fn variant(mut self, variant: Variant) -> Self {
33    self.variant = variant;
34    self
35  }
36
37  pub fn color(mut self, color: ColorName) -> Self {
38    self.color = color;
39    self
40  }
41
42  pub fn size(mut self, size: Size) -> Self {
43    self.size = size;
44    self
45  }
46
47  pub fn radius(mut self, radius: Size) -> Self {
48    self.radius = Some(radius);
49    self
50  }
51
52  fn dimension(&self) -> f32 {
53    match self.size {
54      Size::Xs => 16.0,
55      Size::Sm => 22.0,
56      Size::Md => 28.0,
57      Size::Lg => 38.0,
58      Size::Xl => 52.0,
59    }
60  }
61}
62
63impl RenderOnce for ThemeIcon {
64  fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
65    let t = theme(cx);
66    let s = surface(t, self.color, self.variant);
67    let dim = self.dimension();
68    let radius = t.radius(self.radius.unwrap_or(t.default_radius));
69
70    let mut el = div()
71      .w(px(dim))
72      .h(px(dim))
73      .flex()
74      .items_center()
75      .justify_center()
76      .rounded(px(radius))
77      .bg(s.bg)
78      .text_color(s.fg)
79      .text_size(px(dim * 0.52))
80      .child(self.icon);
81    if let Some(border) = s.border {
82      el = el.border_1().border_color(border);
83    }
84    el.probe("ThemeIcon")
85  }
86}