jinya_ui/widgets/form/
input.rs1use yew::prelude::*;
2use yew::{Callback, Component, ComponentLink, Html};
3
4pub fn get_css<'a>() -> &'a str {
5 "
7.jinya-input__color-container {
8 width: 100%;
9}
10
11.jinya-input__color-container--default {
12 --state-color: var(--primary-color);
13}
14
15.jinya-input__color-container--negative {
16 --state-color: var(--negative-color);
17}
18
19.jinya-input__color-container--positive {
20 --state-color: var(--positive-color);
21}
22
23.jinya-input__color-container--disabled {
24 --state-color: var(--disabled-border-color);
25}
26
27.jinya-input__container {
28 display: inline-block;
29 border: 2px solid var(--state-color);
30 border-radius: 5px;
31 padding: 0.5rem 0.75rem 0.25rem;
32 position: relative;
33 margin-top: 0.75rem;
34 width: 100%;
35 box-sizing: border-box;
36}
37
38.jinya-input__input {
39 font-size: var(--font-size-16);
40 color: var(--state-color);
41 background: var(--white);
42 border: none;
43 padding: 0;
44 width: 100%;
45 outline: none;
46 font-family: var(--font-family);
47}
48
49.jinya-input__input:disabled {
50 cursor: not-allowed;
51}
52
53.jinya-input__input:invalid {
54 outline: none;
55 box-shadow: none;
56 border: none;
57}
58
59.jinya-input__label {
60 display: block;
61 font-size: var(--font-size-12);
62 color: var(--state-color);
63 position: absolute;
64 top: -0.75rem;
65 background: var(--white);
66 padding-left: 0.25rem;
67 padding-right: 0.25rem;
68 box-sizing: border-box;
69 left: 0.5rem;
70 z-index: 0;
71}
72
73.jinya-input__validation-message {
74 display: block;
75 font-size: var(--font-size-12);
76 color: var(--state-color);
77}
78"
79}
80
81#[derive(Clone, PartialEq)]
82pub enum InputState {
83 Default,
84 Negative,
85 Positive,
86}
87
88pub struct Input {
89 link: ComponentLink<Self>,
90 label: String,
91 on_input: Callback<String>,
92 state: InputState,
93 value: String,
94 input_type: String,
95 validation_message: String,
96 placeholder: String,
97 disabled: bool,
98}
99
100#[derive(Clone, PartialEq, Properties)]
101pub struct InputProps {
102 pub label: String,
103 pub on_input: Callback<String>,
104 #[prop_or(InputState::Default)]
105 pub state: InputState,
106 pub value: String,
107 #[prop_or("text".to_string())]
108 pub input_type: String,
109 #[prop_or("".to_string())]
110 pub validation_message: String,
111 #[prop_or("".to_string())]
112 pub placeholder: String,
113 #[prop_or(false)]
114 pub disabled: bool,
115}
116
117pub enum Msg {
118 Input(String),
119}
120
121impl Default for InputState {
122 fn default() -> Self {
123 InputState::Default
124 }
125}
126
127impl Input {
128 fn get_input_container_class(&self) -> String {
129 let class = match self.state {
130 InputState::Default => {
131 "jinya-input__color-container jinya-input__color-container--default"
132 }
133 InputState::Negative => {
134 "jinya-input__color-container jinya-input__color-container--negative"
135 }
136 InputState::Positive => {
137 "jinya-input__color-container jinya-input__color-container--positive"
138 }
139 }
140 .to_string();
141
142 if self.disabled {
143 "jinya-input__color-container jinya-input__color-container--disabled".to_string()
144 } else {
145 class
146 }
147 }
148}
149
150impl Component for Input {
151 type Message = Msg;
152 type Properties = InputProps;
153
154 fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
155 Input {
156 link,
157 label: props.label,
158 on_input: props.on_input,
159 state: props.state,
160 value: props.value,
161 input_type: props.input_type,
162 validation_message: props.validation_message,
163 placeholder: props.placeholder,
164 disabled: props.disabled,
165 }
166 }
167
168 fn update(&mut self, msg: Self::Message) -> bool {
169 match msg {
170 Msg::Input(value) => {
171 self.on_input.emit(value);
172 }
173 }
174
175 false
176 }
177
178 fn change(&mut self, _props: Self::Properties) -> bool {
179 self.label = _props.label;
180 self.on_input = _props.on_input;
181 self.state = _props.state;
182 self.value = _props.value;
183 self.validation_message = _props.validation_message;
184 self.input_type = _props.input_type;
185 self.placeholder = _props.placeholder;
186 self.disabled = _props.disabled;
187
188 true
189 }
190
191 fn view(&self) -> Html {
192 let id = super::super::super::id_generator::generate_id();
193 html! {
194 <div class=self.get_input_container_class()>
195 <div class="jinya-input__container">
196 <label for=id class="jinya-input__label">{&self.label}</label>
197 <input
198 id=id
199 type=self.input_type
200 disabled=self.disabled
201 placeholder=self.placeholder
202 oninput=self.link.callback(|e: InputData| Msg::Input(e.value))
203 value=self.value class="jinya-input__input"
204 />
205 </div>
206 <span class="jinya-input__validation-message">{&self.validation_message}</span>
207 </div>
208 }
209 }
210}