input.rs (2034B)
1 use yew::prelude::*; 2 3 #[derive(Debug, PartialEq, Clone, Properties)] 4 pub struct InputProps { 5 pub on_submit: Callback<String>, 6 } 7 8 pub struct InputState { 9 value: Option<String>, 10 } 11 12 pub struct Input { 13 on_input: Callback<InputData>, 14 on_submit: Callback<KeyboardEvent>, 15 state: InputState, 16 props: InputProps, 17 } 18 19 #[allow(clippy::large_enum_variant)] 20 pub enum Msg { 21 ValueChange(InputData), 22 ValueSubmit(KeyboardEvent), 23 } 24 25 impl Component for Input { 26 type Message = Msg; 27 type Properties = InputProps; 28 29 fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self { 30 let state = InputState { value: None }; 31 Self { 32 props, 33 on_input: link.callback(Msg::ValueChange), 34 on_submit: link.callback(Msg::ValueSubmit), 35 state, 36 } 37 } 38 39 fn update(&mut self, msg: Self::Message) -> bool { 40 match msg { 41 Msg::ValueChange(data) => { 42 self.state.value = Some(data.value); 43 true 44 } 45 Msg::ValueSubmit(data) => { 46 if data.key() == "Enter" { 47 self.props 48 .on_submit 49 .emit(self.state.value.as_deref().unwrap_or("").to_owned()); 50 self.state.value = None; 51 return true; 52 } 53 false 54 } 55 } 56 } 57 58 fn change(&mut self, _props: Self::Properties) -> bool { 59 false 60 } 61 62 fn view(&self) -> Html { 63 html! { 64 <div class="message-input"> 65 <div class="encryption-bg"> 66 <span class="material-icons">{"lock_open"}</span> 67 </div> 68 <textarea autofocus=true 69 placeholder={ "Input Text..." } 70 value=&self.state.value.as_deref().unwrap_or("") 71 oninput=&self.on_input 72 onkeypress=&self.on_submit 73 /> 74 </div> 75 } 76 } 77 }