leptos_shadcn_textarea/
default.rs

1use leptos::{ev::Event, prelude::*};
2use leptos_style::Style;
3use leptos::wasm_bindgen::JsCast;
4
5const TEXTAREA_CLASS: &str = "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50";
6
7#[component]
8pub fn Textarea(
9    #[prop(into, optional)] value: MaybeProp<String>,
10    #[prop(into, optional)] on_change: Option<Callback<String>>,
11    #[prop(into, optional)] placeholder: MaybeProp<String>,
12    #[prop(into, optional)] disabled: Signal<bool>,
13    #[prop(into, optional)] input_type: MaybeProp<String>,
14    #[prop(into, optional)] class: MaybeProp<String>,
15    #[prop(into, optional)] id: MaybeProp<String>,
16    #[prop(into, optional)] style: Signal<Style>,
17) -> impl IntoView {
18    let handle_input = {
19        let on_change = on_change.clone();
20        move |event: Event| {
21            if let Some(callback) = &on_change {
22                let target = event.target().unwrap();
23                let input = target.unchecked_into::<web_sys::HtmlInputElement>();
24                callback.run(input.value());
25            }
26        }
27    };
28
29    let computed_class = Signal::derive(move || {
30        format!("{} {}", TEXTAREA_CLASS, class.get().unwrap_or_default())
31    });
32
33    view! {
34        <textarea
35            placeholder=move || placeholder.get().unwrap_or_default()
36            disabled=move || disabled.get()
37            class=move || computed_class.get()
38            id=move || id.get().unwrap_or_default()
39            style=move || style.get().to_string()
40            on:input=handle_input
41        >
42            {value.get().unwrap_or_default()}
43        </textarea>
44    }
45}