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