Skip to main content

leptos_forms_rs/components/
input.rs

1use crate::core::FieldType;
2use leptos::prelude::*;
3use leptos::wasm_bindgen::JsCast;
4
5/// Unified Input component that handles different field types
6#[component]
7pub fn Input(
8    name: String,
9    #[prop(optional)] value: Option<String>,
10    #[prop(optional)] field_type: Option<FieldType>,
11    #[prop(optional)] placeholder: Option<String>,
12    #[prop(optional)] required: Option<bool>,
13    #[prop(optional)] disabled: Option<bool>,
14    #[prop(optional)] _error: Option<String>,
15    #[prop(optional)] _has_error: Option<bool>,
16    #[prop(optional)] on_change: Option<Callback<String>>,
17    #[prop(optional)] class: Option<String>,
18) -> impl IntoView {
19    let input_type = field_type
20        .map(|ft| match ft {
21            FieldType::Text => "text",
22            FieldType::Email => "email",
23            FieldType::Password => "password",
24            FieldType::Number(_) => "number",
25            FieldType::Boolean => "checkbox",
26            FieldType::Select(_) => "select",
27            FieldType::MultiSelect(_) => "select",
28            FieldType::Date => "date",
29            FieldType::DateTime => "datetime-local",
30            FieldType::File(_) => "file",
31            FieldType::Array(_) => "text", // Default to text for arrays
32            FieldType::Nested(_) => "text",
33            FieldType::RichText | FieldType::Markdown | FieldType::Code => "text", // Default to text for nested forms
34        })
35        .unwrap_or("text");
36
37    let is_required = required.unwrap_or(false);
38    let is_disabled = disabled.unwrap_or(false);
39    let input_class = class.unwrap_or_else(|| "form-input".to_string());
40
41    view! {
42        <div class="input-wrapper">
43            <input
44                type=input_type
45                name=name.clone()
46                value=value
47                placeholder=placeholder
48                required=is_required
49                disabled=is_disabled
50                class=input_class
51                on:input=move |ev| {
52                    if let Some(on_change_callback) = on_change {
53                        if let Some(target) = ev.target() {
54                            if let Some(input) = target.dyn_ref::<web_sys::HtmlInputElement>() {
55                                let value = input.value();
56                                on_change_callback.run(value);
57                            }
58                        }
59                    }
60                }
61            />
62            // Error display will be added later when we fix the view macro issue
63        </div>
64    }
65}