#![allow(unused)]
use crate::countries::COUNTRY_CODES;
use leptos::{ev::MouseEvent, prelude::*, *};
#[component]
pub fn Input(
#[prop(default = "text")]
r#type: &'static str,
#[prop(default = "")]
label: &'static str,
#[prop(default = "")]
name: &'static str,
#[prop(default = false)]
required: bool,
#[prop(default = "")]
error_message: &'static str,
#[prop(default = "")]
input_class: &'static str,
#[prop(default = "")]
field_class: &'static str,
#[prop(default = "")]
label_class: &'static str,
#[prop(default = "")]
class: &'static str,
#[prop(default = "")]
error_class: &'static str,
#[prop(default = "")]
icon_class: &'static str,
handle: (ReadSignal<String>, WriteSignal<String>),
valid_handle: (ReadSignal<bool>, WriteSignal<bool>),
validate_function: fn(String) -> bool,
#[prop(
default = "cursor-pointer right-4 top-1 text-2xl text-gray-600 toggle-button fa fa-eye"
)]
eye_active: &'static str,
#[prop(
default = "cursor-pointer right-4 top-1 text-2xl text-gray-600 toggle-button fa fa-eye-slash"
)]
eye_disabled: &'static str,
#[prop(default = "")]
id: &'static str,
#[prop(default = "")]
placeholder: &'static str,
#[prop(default = "")]
aria_label: &'static str,
#[prop(default = "true")]
aria_required: &'static str,
#[prop(default = "true")]
aria_invalid: &'static str,
#[prop(default = "")]
aria_describedby: &'static str,
#[prop(default = "")]
accept: &'static str,
#[prop(default = "")]
alt: &'static str,
#[prop(default = "")]
autocapitalize: &'static str,
#[prop(default = "")]
autocomplete: &'static str,
#[prop(default = "")]
capture: &'static str,
#[prop(default = false)]
checked: bool,
#[prop(default = "")]
dirname: &'static str,
#[prop(default = false)]
disabled: bool,
#[prop(default = "")]
form: &'static str,
#[prop(default = "")]
formaction: &'static str,
#[prop(default = "")]
formenctype: &'static str,
#[prop(default = "")]
formmethod: &'static str,
#[prop(default = false)]
formnovalidate: bool,
#[prop(default = "")]
formtarget: &'static str,
#[prop(default = None)]
height: Option<u32>,
#[prop(default = "")]
list: &'static str,
#[prop(default = "")]
max: &'static str,
#[prop(default = None)]
maxlength: Option<usize>,
#[prop(default = "")]
min: &'static str,
#[prop(default = None)]
minlength: Option<usize>,
#[prop(default = false)]
multiple: bool,
#[prop(default = ".*")]
pattern: &'static str,
#[prop(default = false)]
readonly: bool,
#[prop(default = None)]
size: Option<u32>,
#[prop(default = "")]
src: &'static str,
#[prop(default = "")]
step: &'static str,
#[prop(default = "")]
value: &'static str,
#[prop(default = None)]
width: Option<u32>,
) -> impl IntoView {
let (eye_active_handle, set_eye_active_handle) = signal(false);
let (password_type, set_password_type) = signal("password".to_string());
let valid = valid_handle;
let input_ref: NodeRef<html::Input> = NodeRef::new();
let onchange = {
move |ev: web_sys::Event| {
let input_value = input_ref.get().expect("<input> should be mounted").value();
handle.1.set(input_value.clone());
valid.1.set(validate_function(input_value));
}
};
let on_toggle_password = {
move |ev: MouseEvent| {
if eye_active_handle.get() {
set_password_type.set("password".to_string());
} else {
set_password_type.set("text".to_string());
}
set_eye_active_handle.set(!eye_active_handle.get());
}
};
let tag = {
move || {
match r#type {
"password" => Some(view! {
<>
<input
r#type={password_type.get()}
class={input_class}
id={id}
name={name}
value={handle.0.get()}
placeholder={placeholder}
aria-label={aria_label}
aria-required={aria_required}
aria-invalid={aria_invalid}
aria-describedby={aria_describedby}
on:input={onchange}
required={required}
node_ref={input_ref}
autocomplete={autocomplete}
autocapitalize={autocapitalize}
readonly={readonly}
minlength={minlength.map(|v| v.to_string())}
maxlength={maxlength.map(|v| v.to_string())}
pattern={pattern}
size={size.map(|v| v.to_string())}
disabled={disabled}
list={list}
step={step}
min={min}
max={max}
accept={accept}
/>
<span
class={if eye_active_handle.get() { eye_active } else { eye_disabled }}
on:click={on_toggle_password}
/>
</>
}.into_any()),
"tel" => Some(view! {
<>
<select class={field_class} on:change={onchange}>
<For
each=move || COUNTRY_CODES
key=|country| *country
let:country
>
{move || {
let (code, emoji, _, name, _, _) = country;
view! {
<option value={code} selected={*code == handle.0.get()}>{ format!("{} {} {}", emoji, name, code) }</option>
}
}}
</For>
</select>
<input
r#type={"tel"}
class={input_class}
id={id}
name={name}
value={handle.0.get()}
placeholder={placeholder}
aria-label={aria_label}
aria-required={aria_required}
aria-invalid={aria_invalid}
aria-describedby={aria_describedby}
on:input={onchange}
required={required}
node_ref={input_ref}
autocomplete={autocomplete}
autocapitalize={autocapitalize}
readonly={readonly}
minlength={minlength.map(|v| v.to_string())}
maxlength={maxlength.map(|v| v.to_string())}
pattern={pattern}
size={size.map(|v| v.to_string())}
disabled={disabled}
list={list}
step={step}
min={min}
max={max}
accept={accept}
/>
</>
}.into_any()),
_ => Some(view! {
<>
<input
r#type={r#type.to_string()}
class={input_class}
id={id}
name={name}
value={handle.0.get()}
placeholder={placeholder}
aria-label={aria_label}
aria-required={aria_required}
aria-invalid={aria_invalid}
aria-describedby={aria_describedby}
on:input={onchange}
required={required}
node_ref={input_ref}
autocomplete={autocomplete}
autocapitalize={autocapitalize}
readonly={readonly}
minlength={minlength.map(|v| v.to_string())}
maxlength={maxlength.map(|v| v.to_string())}
pattern={pattern}
size={size.map(|v| v.to_string())}
disabled={disabled}
list={list}
step={step}
min={min}
max={max}
accept={accept}
/>
</>
}.into_any()),
}
}
};
view! {
<div class={class}>
<label class={label_class} for={id}>{label}</label>
<div class={field_class}>
{tag}
<span class={icon_class} />
</div>
{move ||
if !valid.0.get() {
Some(view! {
<div class={error_class} id={aria_describedby}>
{error_message}
</div>
})
} else {
None
}
}
</div>
}
}