vertigo_forms/input/
input_with_button.rs

1use vertigo::{AttrGroup, Value, bind, component, computed_tuple, dom, transaction};
2
3/// Input connected to provided `Value<String>`.
4///
5/// ```
6/// use vertigo::{dom, Value};
7/// use vertigo_forms::InputWithButton;
8///
9/// let my_value = Value::<String>::default();
10///
11/// dom! {
12///     <InputWithButton value={my_value} params={} />
13/// };
14/// ```
15///
16/// ```
17/// use vertigo::{css, dom, Value};
18/// use vertigo_forms::{InputWithButton, InputWithButtonParams};
19///
20/// let my_value = Value::new("Initial text".to_string());
21///
22/// dom! {
23///     <InputWithButton
24///         value={my_value}
25///         params={InputWithButtonParams {
26///                 button_label: "Load".to_string(),
27///                 ..Default::default()
28///         }}
29///         input:css={css!("width: 300px;")}
30///     />
31/// };
32/// ```
33#[component]
34pub fn InputWithButton(
35    value: Value<String>,
36    params: InputWithButtonParams,
37    input: AttrGroup,
38    button: AttrGroup,
39) {
40    let temp_value = Value::<Option<String>>::default();
41    let display_value =
42        computed_tuple!(value, temp_value).map(|(value, temp_value)| temp_value.unwrap_or(value));
43
44    let on_input = bind!(temp_value, |new_value: String| {
45        temp_value.set(Some(new_value));
46    });
47
48    let on_click = bind!(value, temp_value, |_| {
49        transaction(|ctx| {
50            let new_value = temp_value.get(ctx);
51            if let Some(new_value) = new_value {
52                value.set(new_value);
53            }
54            temp_value.set(None);
55        })
56    });
57
58    dom! {
59        <input value={display_value} {on_input} {..input}/>
60        <button {on_click} {..button}>{params.button_label}</button>
61    }
62}
63
64#[derive(Clone)]
65pub struct InputWithButtonParams {
66    pub button_label: String,
67}
68
69impl Default for InputWithButtonParams {
70    fn default() -> Self {
71        Self {
72            button_label: "OK".to_string(),
73        }
74    }
75}