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