freya_components/hooks/
use_form.rs1use std::{
4 collections::HashMap,
5 fmt::Display,
6 hash::Hash,
7};
8
9use dioxus::prelude::*;
10
11use crate::{
12 ButtonProps,
13 InputMode,
14 InputProps,
15};
16
17type SubmitCallback<Id> = Box<dyn Fn(&HashMap<Id, String>)>;
18
19#[derive(Clone)]
24pub struct UseForm<Id: Hash + Eq + 'static> {
25 data: Signal<HashMap<Id, String>>,
26 onsubmit: Signal<SubmitCallback<Id>>,
27}
28
29impl<Id: Clone + Hash + Eq + Display> UseForm<Id> {
30 pub fn input(&self, id: Id) -> InputProps {
32 let value = self.data.read().get(&id).cloned().unwrap_or_default();
33 let placeholder = id.to_string();
34 let mut data = self.data;
35 InputProps {
36 onchange: EventHandler::new(move |txt| {
37 data.write().insert(id.clone(), txt);
38 }),
39 theme: None,
40 mode: InputMode::default(),
41 value: dioxus_core::prelude::SuperInto::super_into(value),
42 placeholder: dioxus_core::prelude::SuperInto::super_into(Some(placeholder)),
43 auto_focus: false,
44 onvalidate: None,
45 width: "150".to_string(),
46 }
47 }
48
49 pub fn submit(&self) -> ButtonProps {
51 let submit = self.onsubmit;
52 let data = self.data;
53 ButtonProps {
54 theme: None,
55 onpress: Some(EventHandler::new(move |_| {
56 (submit.peek())(&data.read());
57 })),
58 children: Ok(VNode::placeholder()),
59 onclick: None,
60 }
61 }
62}
63
64pub fn use_form<Id: Hash + Eq + Clone>(
66 onsubmit: impl Fn(&HashMap<Id, String>) + 'static,
67) -> UseForm<Id> {
68 use_hook(|| UseForm {
69 data: Signal::new(HashMap::default()),
70 onsubmit: Signal::new(Box::new(onsubmit)),
71 })
72}