thaw-ui / thaw

An easy to use leptos component library
https://thawui.vercel.app
MIT License
206 stars 21 forks source link

Added parser and formatter props to input and input_number components #209

Closed mmannes closed 2 days ago

mmannes commented 1 week ago

This PR tries to resolve issue https://github.com/thaw-ui/thaw/issues/129 by adding optional callbacks to Input and InputNumber components. The parser callback converts user input to the desired signal format, while the formatter callback presents the signal value to the user. You can check it working in the Docs.

Following the suggested implementation I've added the parser to the onchange event. There was the need to clone the parser in order to be consumed by two closures. Please, feel free to give advice on how to avoid the cloning.

Thank you!

luoxiaozero commented 1 week ago

Thank you for your contribution.

It looks good. Wouldn't it be nice to change InputNumber's formatter type to Callback<T, String> and parser type to Callback<String, T>?

Please, feel free to give advice on how to avoid the cloning.

Implementing Copy for OptionalProp solves this problem.

impl<T: Copy> Copy for OptionalProp<T> {}
mmannes commented 6 days ago

I tried using callbacks with generic types, but InputNumber calls the Input component under the hood, which lacks a generic type. Next, I attempted to implement a generic type for the Input component but haven't found a solution yet. The easier approach would be to avoid using the Input component inside InputNumber, but I don't consider this an elegant alternative, so I'll continue exploring other options...

luoxiaozero commented 6 days ago

I don't think you need to implement generics for Input, just:

fn InputNumber(parser, formatter) {
   let parser = parser.map(|parser| {
        Callback::new(move |v| parser.call(v).to_string())
   });
   let formatter = formatter.map(|formatter| {
        Callback::new(move |v| formatter.call(v.parse::<T>()))
   });
   view! {
      <Input parser formatter/>
   }
}
mmannes commented 6 days ago

Oh, is it okay to create a new callback? I thought it might introduce too much overhead. I was considering the possibility of using other Rust types with Input, such as std::net::IpAddr, in a similar manner to how InputNumber can hold an i32 or f64.

Anyway, I am happy with your suggestion; it is simpler, and we can move forward. I'll make the changes tonight.

Thank you for your kindness in helping me out.

mmannes commented 4 days ago

The suggested changes have been made. Let me know if you have any other suggestions.

luoxiaozero commented 2 days ago

Thank you!