kayrx_ui/widget/input/
input_number.rs1use web_sys::HtmlInputElement;
2use crate::fabric::prelude::*;
3
4pub struct InputNumber {
5 link: ComponentLink<Self>,
6 oninput: Callback<Option<f64>>,
7 value: String,
8 node_ref: NodeRef,
9 disabled: bool,
10}
11pub enum Msg {
12 Input(String),
13}
14
15#[derive(Clone, Properties)]
16pub struct Props {
17 #[prop_or_else(Callback::noop)]
18 pub oninput: Callback<Option<f64>>,
19 #[prop_or_default]
20 pub value: Option<f64>,
21 #[prop_or_default]
22 pub disabled: bool,
23}
24impl Component for InputNumber {
25 type Message = Msg;
26 type Properties = Props;
27
28 fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
29 InputNumber {
30 link,
31 oninput: props.oninput,
32 value: props.value.map_or("".into(), |v| v.to_string()),
33 disabled: props.disabled,
34 node_ref: NodeRef::default(),
35 }
36 }
37
38 fn update(&mut self, msg: Self::Message) -> ShouldRender {
39 match msg {
40 Msg::Input(v) => {
41 let old = if let Ok(fv) = self.value.parse::<f64>() {
42 Some(fv)
43 } else {
44 None
45 };
46 let res = if v.len() == 0 {
47 self.value = "".into();
48 None
49 } else if let Ok(fv) = v.parse::<f64>() {
50 self.value = v.clone().into();
51 Some(fv)
52 } else {
53 old
54 };
55
56 if old != res {
57 self.oninput.emit(res);
58 }
59 if self.value != v {
60 if let Some(el) = self.node_ref.cast::<HtmlInputElement>() {
61 if el.value() != self.value {
62 el.set_value(&self.value);
63 }
64 }
65 }
66 }
67 }
68 false
69 }
70
71 fn change(&mut self, props: Self::Properties) -> ShouldRender {
72 self.value = props.value.map_or("".into(), |v| v.to_string());
73 self.oninput = props.oninput;
74 true
75 }
76
77 fn view(&self) -> Html {
78 html! {
79 <div class="bow-input-number">
80 <input ref=self.node_ref.clone()
81 value=&self.value
82 disabled=self.disabled
83 oninput=self.link.callback(|v: InputData| Msg::Input(v.value))>
84 </input>
85 </div>
86 }
87 }
88}