input.rs

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