nova_forms/components/
input.rs1use crate::{Datatype, QueryString, FieldWiring};
2use leptos::*;
3
4#[component]
7pub fn Input<T>(
8 #[prop(into)] label: TextProp,
10 #[prop(into)] bind: QueryString,
12 #[prop(optional, into)] placeholder: Option<T>,
14 #[prop(optional, into)] value: MaybeProp<T>,
16 #[prop(optional, into)] change: Option<Callback<Result<T, T::Error>, ()>>,
18 #[prop(optional, into)] error: MaybeProp<TextProp>,
20) -> impl IntoView
21where
22 T: Datatype,
23{
24 let FieldWiring {
25 qs,
26 raw_value,
27 error,
28 set_raw_value,
29 render_mode,
30 ..
31 } = FieldWiring::wire(bind, value, change, error);
32
33 let node_ref = NodeRef::new();
35 node_ref.on_load(move |element| {
36 let element: &web_sys::HtmlInputElement = &*element;
37 let value = element.value();
38 if !value.is_empty() {
39 set_raw_value.call(value);
40 }
41 });
42
43 let input_elem = T::attributes()
59 .into_iter()
60 .fold(html::input(), |el, (name, value)| el.attr(name, value))
61 .attr("id", qs.to_string())
62 .attr("name", qs.to_string())
63 .attr("placeholder", placeholder.as_ref().map(T::to_string))
64 .prop("value", move || raw_value.get())
65 .node_ref(node_ref)
66 .on(ev::input, move |ev| {
67 set_raw_value.call(event_target_value(&ev));
68 });
69
70 view! {
71 <div
72 class="field"
73 class:error=move || error.get().is_some()
74 class:ok=move || error.get().is_none()
75 >
76 {move || {
77 if render_mode.get() {
78 view!{
79 <span class="label">{label.clone()}</span>
80 <span class="value">{raw_value.get()}</span>
81 }.into_view()
82 } else {
83 view! {
84 <label for=qs.to_string()>{label.clone()}</label>
85 {input_elem.clone()}
86 {move || {
87 if let Some(error) = error.get() {
88 view! { <span class="error-message">{error}</span> }
89 .into_view()
90 } else {
91 View::default()
92 }
93 }}
94 }.into_view()
95 }
96 }}
97 </div>
98 }
99}