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