leptos_shadcn_input_otp/
lib.rs

1use leptos::prelude::*;
2use leptos::wasm_bindgen::JsCast;
3use web_sys::HtmlInputElement;
4
5#[component]
6pub fn InputOtp(
7    #[prop(into, optional)] length: MaybeProp<usize>,
8    #[prop(into, optional)] value: RwSignal<String>,
9    #[prop(into, optional)] on_change: Option<Callback<String>>,
10    #[prop(into, optional)] class: MaybeProp<String>,
11) -> impl IntoView {
12    let len = length.get().unwrap_or(6);
13
14    let handle_input = {
15        let value = value.clone();
16        let on_change = on_change.clone();
17        Callback::new(move |new_val: String| {
18            value.set(new_val.clone());
19            if let Some(cb) = &on_change { cb.run(new_val); }
20        })
21    };
22
23    let classes = Signal::derive(move || class.get().unwrap_or_default());
24
25    view! {
26        <div class=classes>
27            <input
28                value=move || value.get()
29                on:input=move |ev| {
30                    let target: HtmlInputElement = ev.target().unwrap().unchecked_into();
31                    let mut v = target.value();
32                    v.truncate(len);
33                    handle_input.run(v);
34                }
35            />
36        </div>
37    }
38}
39
40pub mod prelude { pub use super::InputOtp; }
41
42#[cfg(test)]
43mod tests;