thaw/src/input/mod.rs

98 lines
2.8 KiB
Rust
Raw Normal View History

2023-04-06 17:27:54 +08:00
mod theme;
2023-10-07 21:41:03 +08:00
2023-05-30 23:00:30 +08:00
use crate::{
theme::{use_theme, Theme},
2023-10-11 21:25:11 +08:00
utils::{maybe_rw_signal::MaybeRwSignal, mount_style::mount_style},
2023-05-30 23:00:30 +08:00
};
2023-04-03 17:31:50 +08:00
use leptos::*;
2023-05-30 23:00:30 +08:00
pub use theme::InputTheme;
2023-04-03 17:31:50 +08:00
2023-06-19 21:53:39 +08:00
#[derive(Default, Clone)]
2023-10-08 14:01:24 +08:00
pub enum InputVariant {
2023-06-19 21:53:39 +08:00
#[default]
2023-10-16 21:15:43 +08:00
Text,
Password,
2023-06-19 21:53:39 +08:00
}
2023-10-08 14:01:24 +08:00
impl InputVariant {
2023-06-19 21:53:39 +08:00
pub fn as_str(&self) -> &'static str {
match self {
2023-10-16 21:15:43 +08:00
InputVariant::Text => "text",
InputVariant::Password => "password",
2023-06-19 21:53:39 +08:00
}
}
}
#[slot]
pub struct InputSuffix {
children: Children,
}
2023-04-03 17:31:50 +08:00
#[component]
pub fn Input(
2023-10-11 21:25:11 +08:00
#[prop(optional, into)] value: MaybeRwSignal<String>,
2023-10-15 12:23:26 +08:00
#[prop(optional, into)] allow_value: Option<Callback<String, bool>>,
2023-10-08 14:01:24 +08:00
#[prop(optional, into)] variant: MaybeSignal<InputVariant>,
2023-10-15 12:23:26 +08:00
#[prop(optional, into)] placeholder: MaybeSignal<String>,
#[prop(optional, into)] on_focus: Option<Callback<ev::FocusEvent>>,
#[prop(optional, into)] on_blur: Option<Callback<ev::FocusEvent>>,
#[prop(optional)] input_suffix: Option<InputSuffix>,
2023-04-03 17:31:50 +08:00
) -> impl IntoView {
2023-08-29 09:11:22 +08:00
let theme = use_theme(Theme::light);
2023-10-07 21:41:03 +08:00
mount_style("input", include_str!("./input.css"));
2023-05-30 23:00:30 +08:00
2023-10-15 12:23:26 +08:00
let on_input = move |ev| {
let input_value = event_target_value(&ev);
if let Some(allow_value) = allow_value.as_ref() {
if !allow_value.call(input_value.clone()) {
return;
}
}
value.set(input_value);
};
let on_internal_focus = move |ev| {
if let Some(on_focus) = on_focus.as_ref() {
on_focus.call(ev);
}
};
let on_internal_blur = move |ev| {
if let Some(on_blur) = on_blur.as_ref() {
on_blur.call(ev);
}
};
2023-05-30 23:00:30 +08:00
2023-08-29 09:11:22 +08:00
let css_vars = create_memo(move |_| {
2023-04-06 17:27:54 +08:00
let mut css_vars = String::new();
let theme = theme.get();
let border_color_hover = theme.common.color_primary.clone();
css_vars.push_str(&format!("--border-color-hover: {border_color_hover};"));
let border_radius = theme.common.border_radius.clone();
css_vars.push_str(&format!("--border-radius: {border_radius};"));
css_vars
});
2023-04-03 17:31:50 +08:00
view! {
<div class="melt-input" style=move || css_vars.get()>
2023-10-08 09:28:13 +08:00
<input
2023-10-08 14:01:24 +08:00
type=move || variant.get().as_str()
2023-10-08 09:28:13 +08:00
prop:value=move || value.get()
2023-10-15 12:23:26 +08:00
on:input=on_input
on:focus=on_internal_focus
on:blur=on_internal_blur
2023-10-08 09:28:13 +08:00
class="melt-input__input-el"
2023-10-15 12:23:26 +08:00
placeholder=move || placeholder.get()
2023-10-08 09:28:13 +08:00
/>
{
if let Some(suffix) = input_suffix {
view! {
<div class="melt-input__suffix">
{(suffix.children)()}
</div>
}.into()
} else {
None
}
}
2023-04-03 17:31:50 +08:00
</div>
}
}