Skip to main content

ui/components/icon/
decorated_icon.rs

1use gpui::{AnyElement, IntoElement, Point};
2
3use crate::{IconDecoration, IconDecorationKind, prelude::*};
4
5#[derive(IntoElement, RegisterComponent)]
6pub struct DecoratedIcon {
7    icon: Icon,
8    decoration: Option<IconDecoration>,
9}
10
11impl DecoratedIcon {
12    pub fn new(icon: Icon, decoration: Option<IconDecoration>) -> Self {
13        Self { icon, decoration }
14    }
15}
16
17impl RenderOnce for DecoratedIcon {
18    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
19        div()
20            .relative()
21            .size(self.icon.size)
22            .child(self.icon)
23            .children(self.decoration)
24    }
25}
26
27impl Component for DecoratedIcon {
28    fn scope() -> ComponentScope {
29        ComponentScope::Images
30    }
31
32    fn description() -> Option<&'static str> {
33        Some(
34            "An icon with an optional decoration overlay (like an X, triangle, or dot) that can be positioned relative to the icon",
35        )
36    }
37
38    fn preview(_window: &mut Window, cx: &mut App) -> Option<AnyElement> {
39        let decoration_x = IconDecoration::new(
40            IconDecorationKind::X,
41            cx.theme().colors().surface_background,
42            cx,
43        )
44        .color(cx.theme().status().error)
45        .position(Point {
46            x: px(-2.),
47            y: px(-2.),
48        });
49
50        let decoration_triangle = IconDecoration::new(
51            IconDecorationKind::Triangle,
52            cx.theme().colors().surface_background,
53            cx,
54        )
55        .color(cx.theme().status().error)
56        .position(Point {
57            x: px(-2.),
58            y: px(-2.),
59        });
60
61        let decoration_dot = IconDecoration::new(
62            IconDecorationKind::Dot,
63            cx.theme().colors().surface_background,
64            cx,
65        )
66        .color(cx.theme().status().error)
67        .position(Point {
68            x: px(-2.),
69            y: px(-2.),
70        });
71
72        Some(
73            v_flex()
74                .gap_6()
75                .children(vec![example_group_with_title(
76                    "Decorations",
77                    vec![
78                        single_example(
79                            "No Decoration",
80                            DecoratedIcon::new(Icon::new(IconName::FileDoc), None)
81                                .into_any_element(),
82                        ),
83                        single_example(
84                            "X Decoration",
85                            DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_x))
86                                .into_any_element(),
87                        ),
88                        single_example(
89                            "Triangle Decoration",
90                            DecoratedIcon::new(
91                                Icon::new(IconName::FileDoc),
92                                Some(decoration_triangle),
93                            )
94                            .into_any_element(),
95                        ),
96                        single_example(
97                            "Dot Decoration",
98                            DecoratedIcon::new(Icon::new(IconName::FileDoc), Some(decoration_dot))
99                                .into_any_element(),
100                        ),
101                    ],
102                )])
103                .into_any_element(),
104        )
105    }
106}