Numput component: custom number <input /> with relative value changes

This commit is contained in:
YK 2025-09-20 11:02:11 +03:00
parent 94befe3cd1
commit c54ca148f5
2 changed files with 39 additions and 0 deletions

View File

@ -5,6 +5,7 @@ use crate::prelude::*;
pub mod header; pub mod header;
pub mod sidebar; pub mod sidebar;
pub mod numput;
#[component] #[component]
pub fn Dash () -> impl IntoView { pub fn Dash () -> impl IntoView {

38
src/components/numput.rs Normal file
View File

@ -0,0 +1,38 @@
use std::{ fmt::Debug, str::FromStr, ops::{ Sub, Add }};
use leptos::{ logging, prelude::*, tachys::html::property::IntoProperty };
use num_format::{Locale, ToFormattedString};
use num_traits::{ SaturatingSub, SaturatingAdd };
use crate::prelude::*;
#[component]
pub fn Numput <T, U, 'a> (
field: U,
#[prop(optional)]
class: &'a str,
) -> impl IntoView
where T: ToString + FromStr + Clone + Debug + SaturatingSub<Output = T> + SaturatingAdd<Output = T> + Copy + Sync + ToFormattedString,
U: Get<Value = T> + Set<Value = T> + GetUntracked<Value = T> + With<Value = T> + IntoProperty + Copy + Clone + Send + Sync + 'static,
{
let change = move |ev: Targeted<Event, HtmlInputElement>| {
let old = field.get_untracked();
let new = ev.target().value().replace(",", "");
if let Some(t) = new.strip_prefix("+") && let Ok(v) = t.parse::<T>() {
field.set(old.saturating_add(&v))
} else if let Some(t) = new.strip_prefix("-") && let Ok(v) = t.parse::<T>() {
field.set(old.saturating_sub(&v))
} else if let Ok(v) = new.parse::<T>() {
field.set(v);
} else {
ev.target().set_value(&old.to_string());
}
};
let class = format!("{} numput", class);
view! {
<input pattern="[0-9+=\\-]*" type="text" class=class on:change:target=change prop:value={move || field.with(|f| f.to_formatted_string(&Locale::en))} />
}
}