icon_button.rs

 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}