input.rs

  1use crate::prelude::*;
  2use crate::theme;
  3
  4#[derive(Default, PartialEq)]
  5pub enum InputVariant {
  6    #[default]
  7    Ghost,
  8    Filled,
  9}
 10
 11#[derive(Element)]
 12pub struct Input {
 13    placeholder: &'static str,
 14    value: String,
 15    state: InteractionState,
 16    variant: InputVariant,
 17}
 18
 19impl Input {
 20    pub fn new(placeholder: &'static str) -> Self {
 21        Self {
 22            placeholder,
 23            value: "".to_string(),
 24            state: InteractionState::default(),
 25            variant: InputVariant::default(),
 26        }
 27    }
 28
 29    pub fn value(mut self, value: String) -> Self {
 30        self.value = value;
 31        self
 32    }
 33
 34    pub fn state(mut self, state: InteractionState) -> Self {
 35        self.state = state;
 36        self
 37    }
 38
 39    pub fn variant(mut self, variant: InputVariant) -> Self {
 40        self.variant = variant;
 41        self
 42    }
 43
 44    fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
 45        let theme = theme(cx);
 46
 47        let text_el;
 48        let text_color;
 49        let background_color_default;
 50        let background_color_active;
 51
 52        let mut border_color_default = theme.middle.base.default.border;
 53        let mut border_color_hover = theme.middle.base.hovered.border;
 54        let mut border_color_active = theme.middle.base.pressed.border;
 55        let border_color_focus = theme.middle.base.pressed.background;
 56
 57        match self.variant {
 58            InputVariant::Ghost => {
 59                background_color_default = theme.middle.base.default.background;
 60                background_color_active = theme.middle.base.active.background;
 61            }
 62            InputVariant::Filled => {
 63                background_color_default = theme.middle.on.default.background;
 64                background_color_active = theme.middle.on.active.background;
 65            }
 66        };
 67
 68        if self.state == InteractionState::Focused {
 69            border_color_default = theme.players[0].cursor;
 70            border_color_hover = theme.players[0].cursor;
 71            border_color_active = theme.players[0].cursor;
 72        }
 73
 74        if self.state == InteractionState::Focused || self.state == InteractionState::Active {
 75            text_el = self.value.clone();
 76            text_color = theme.lowest.base.default.foreground;
 77        } else {
 78            text_el = self.placeholder.to_string().clone();
 79            text_color = theme.lowest.base.disabled.foreground;
 80        }
 81
 82        div()
 83            .h_7()
 84            .px_2()
 85            .border()
 86            .border_color(border_color_default)
 87            .fill(background_color_default)
 88            .hover()
 89            .border_color(border_color_hover)
 90            .active()
 91            .border_color(border_color_active)
 92            .fill(background_color_active)
 93            .flex()
 94            .items_center()
 95            .child(
 96                div()
 97                    .flex()
 98                    .items_center()
 99                    .text_sm()
100                    .text_color(text_color)
101                    .child(text_el)
102                    .child(div().text_color(theme.players[0].cursor).child("|")),
103            )
104    }
105}