1use gpui2::elements::div;
2use gpui2::style::{StyleHelpers, Styleable};
3use gpui2::{Element, IntoElement, ParentElement, ViewContext};
4
5use crate::{icon, theme, IconColor};
6use crate::{prelude::*, IconAsset};
7
8#[derive(Element)]
9pub struct IconButton {
10 icon: IconAsset,
11 color: IconColor,
12 variant: ButtonVariant,
13 state: InteractionState,
14}
15
16pub fn icon_button() -> IconButton {
17 IconButton {
18 icon: IconAsset::default(),
19 color: IconColor::default(),
20 variant: ButtonVariant::default(),
21 state: InteractionState::default(),
22 }
23}
24
25impl IconButton {
26 pub fn new(icon: IconAsset) -> Self {
27 Self {
28 icon,
29 color: IconColor::default(),
30 variant: ButtonVariant::default(),
31 state: InteractionState::default(),
32 }
33 }
34
35 pub fn icon(mut self, icon: IconAsset) -> Self {
36 self.icon = icon;
37 self
38 }
39
40 pub fn color(mut self, color: IconColor) -> Self {
41 self.color = color;
42 self
43 }
44
45 pub fn variant(mut self, variant: ButtonVariant) -> Self {
46 self.variant = variant;
47 self
48 }
49
50 pub fn state(mut self, state: InteractionState) -> Self {
51 self.state = state;
52 self
53 }
54
55 fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
56 let theme = theme(cx);
57
58 let icon_color = match (self.state, self.color) {
59 (InteractionState::Disabled, _) => IconColor::Disabled,
60 _ => self.color,
61 };
62
63 let mut div = div();
64 if self.variant == ButtonVariant::Filled {
65 div = div.fill(theme.highest.on.default.background);
66 }
67
68 div.w_7()
69 .h_6()
70 .flex()
71 .items_center()
72 .justify_center()
73 .rounded_md()
74 .hover()
75 .fill(theme.highest.base.hovered.background)
76 .active()
77 .fill(theme.highest.base.pressed.background)
78 .child(icon(self.icon).color(icon_color))
79 }
80}