ymc/text_inputs/textfield.rs
1#![allow(unused_variables)]
2#![allow(dead_code)]
3
4use super::set_on_input_handler;
5use crate::text_inputs::{
6 // validity_state::ValidityStateJS,
7 TextFieldType, ValidityState, ValidityTransform,
8};
9use crate::{to_option, to_option_string};
10use gloo::events::EventListener;
11use wasm_bindgen::prelude::*;
12use wasm_bindgen::JsCast;
13use web_sys::Node;
14use web_sys::ValidityState as NativeValidityState;
15use yew::prelude::*;
16
17
18/// The `textfield` component
19///
20/// [Documentation](https://github.com/material-components/material-components-web-components/tree/master/packages/textfield)
21pub struct TextField {
22 props: TextFieldProps,
23 node_ref: NodeRef,
24 // validity_transform_closure:
25 // Option<Closure<dyn Fn(String, NativeValidityState) -> ValidityStateJS>>,
26 input_listener: Option<EventListener>,
27}
28
29/// Props for [`TextField`]
30///
31/// Documentation:
32///
33/// - [Properties](https://github.com/material-components/material-components-web-components/tree/master/packages/textfield#propertiesattributes)
34#[derive(Properties, Clone)]
35pub struct TextFieldProps {
36 #[prop_or_default]
37 pub open: bool,
38 #[prop_or_default]
39 pub value: String,
40 #[prop_or(TextFieldType::Text)]
41 pub field_type: TextFieldType,
42 #[prop_or_default]
43 pub label: String,
44 #[prop_or_default]
45 pub placeholder: String,
46 #[prop_or_default]
47 pub prefix: String,
48 #[prop_or_default]
49 pub suffix: String,
50 #[prop_or_default]
51 pub icon: String,
52 #[prop_or_default]
53 pub icon_trailing: String,
54 #[prop_or_default]
55 pub disabled: bool,
56 #[prop_or_default]
57 pub char_counter: bool,
58 #[prop_or_default]
59 pub outlined: bool,
60 #[prop_or_default]
61 pub helper: String,
62 #[prop_or_default]
63 pub helper_persistent: bool,
64 #[prop_or_default]
65 pub required: bool,
66 #[prop_or_default]
67 pub max_length: String,
68 #[prop_or_default]
69 pub validation_message: String,
70 #[prop_or_default]
71 pub pattern: String,
72 /// Type: `number | string` so I'll leave it as a string
73 #[prop_or_default]
74 pub min: String,
75 /// Type: `number | string` so I'll leave it as a string
76 #[prop_or_default]
77 pub max: String,
78 // What you doing...
79 #[prop_or_default]
80 pub size: Option<i64>,
81 // ...step size
82 #[prop_or_default]
83 pub step: Option<i64>,
84 #[prop_or_default]
85 pub auto_validate: bool,
86 // #[prop_or_default]
87 // pub validity_transform: Option<ValidityTransform>,
88 #[prop_or_default]
89 pub validate_on_initial_render: bool,
90 #[prop_or_default]
91 pub oninput: Callback<InputData>,
92 #[prop_or_default]
93 pub name: String,
94}
95
96impl Component for TextField {
97 type Message = ();
98 type Properties = TextFieldProps;
99
100 fn create(props: Self::Properties, _: ComponentLink<Self>) -> Self {
101 // TextField::ensure_loaded();
102 Self {
103 props,
104 node_ref: NodeRef::default(),
105 // validity_transform_closure: None,
106 input_listener: None,
107 }
108 }
109
110 fn update(&mut self, _msg: Self::Message) -> ShouldRender {
111 false
112 }
113
114 fn change(&mut self, props: Self::Properties) -> bool {
115 self.props = props;
116 true
117 }
118
119 fn view(&self) -> Html {
120 // open=self.props.open
121 // label?=to_option_string(&self.props.label)
122 // placeholder?=to_option_string(&self.props.placeholder)
123 // prefix?=to_option_string(&self.props.prefix)
124 // suffix?=to_option_string(&self.props.suffix)
125 // icon?=to_option_string(&self.props.icon)
126 // iconTrailing?=to_option_string(&self.props.icon_trailing)
127 // disabled=self.props.disabled
128 // charCounter?=to_option(self.props.char_counter)
129 // outlined?=to_option(self.props.outlined)
130 // helper?=to_option_string(&self.props.helper)
131 // helperPersistent?=to_option(self.props.helper_persistent)
132 // required=self.props.required
133 // maxLength?=to_option_string(&self.props.max_length)
134 // validationMessage?=to_option_string(&self.props.validation_message)
135 // pattern?=to_option_string(&self.props.pattern)
136 // min?=to_option_string(&self.props.min)
137 // max?=to_option_string(&self.props.max)
138 // size?=self.props.size //.map_or("null".to_string(), |v| v.to_string())
139 // step?=self.props.step //.map_or("null".to_string(), |v| v.to_string())
140 // autoValidate?=to_option(self.props.auto_validate)
141 // validateOnInitialRender?=to_option(self.props.validate_on_initial_render)
142 // name?=to_option_string(&self.props.name)
143 // ref=self.node_ref.clone()
144
145 html! {
146 <label class="mdc-text-field mdc-text-field--filled">
147 <span class="mdc-text-field__ripple"></span>
148 <span class="mdc-floating-label" id="my-label-id">{ "Hint text" }</span>
149 <input class="mdc-text-field__input" type="text" aria-labelledby="my-label-id"/>
150 <span class="mdc-line-ripple"></span>
151 </label>
152 }
153 }
154
155 fn rendered(&mut self, first_render: bool) {
156 // if first_render {
157 // self.input_listener = Some(set_on_input_handler(
158 // &self.node_ref,
159 // self.props.oninput.clone(),
160 // |(input_event, detail)| {
161 // InputData {
162 // value: detail
163 // .unchecked_into::<TextFieldInputEvent>()
164 // .target()
165 // .value(),
166 // event: input_event,
167 // }
168 // },
169 // ));
170
171 // let element = self.node_ref.cast::<TextField>().unwrap();
172 // element.set_type(&JsValue::from(&self.props.field_type.to_string()));
173 // element.set_value(&JsValue::from(&self.props.value));
174
175 // let this = self.node_ref.cast::<TextField>().unwrap();
176 // if let Some(transform) = self.props.validity_transform.clone() {
177 // self.validity_transform_closure = Some(Closure::wrap(Box::new(
178 // move |s: String, v: NativeValidityState| -> ValidityStateJS {
179 // transform.0(s, v).into()
180 // },
181 // )
182 // as Box<dyn Fn(String, NativeValidityState) -> ValidityStateJS>));
183 // this.set_validity_transform(&self.validity_transform_closure.as_ref().unwrap());
184 // }
185 // }
186 }
187}
188
189impl TextField {
190 pub fn validity_transform<F: Fn(String, NativeValidityState) -> ValidityState + 'static>(
191 func: F,
192 ) -> ValidityTransform {
193 ValidityTransform::new(func)
194 }
195}
196