Skip to main content

orbital_base_components/form/
bind.rs

1use leptos::prelude::*;
2use reactive_stores::Field;
3
4/// Two-way value handle for **form controls only**.
5///
6/// Accepts store fields, standalone signals, or plain initial values (preview ergonomics).
7#[derive(Clone)]
8pub enum FormBind<T: 'static> {
9    Signal(RwSignal<T>),
10    Field(Field<T>),
11}
12
13impl<T: Send + Sync + 'static> FormBind<T> {
14    pub fn get(&self) -> T
15    where
16        T: Clone,
17    {
18        match self {
19            Self::Signal(signal) => signal.get(),
20            Self::Field(field) => field.get(),
21        }
22    }
23
24    pub fn get_untracked(&self) -> T
25    where
26        T: Clone,
27    {
28        match self {
29            Self::Signal(signal) => signal.get_untracked(),
30            Self::Field(field) => field.get_untracked(),
31        }
32    }
33
34    pub fn set(&self, value: T) {
35        match self {
36            Self::Signal(signal) => signal.set(value),
37            Self::Field(field) => field.set(value),
38        }
39    }
40
41    pub fn update(&self, f: impl FnOnce(&mut T))
42    where
43        T: Clone,
44    {
45        match self {
46            Self::Signal(signal) => signal.update(f),
47            Self::Field(field) => field.update(f),
48        }
49    }
50}
51
52impl<T> From<RwSignal<T>> for FormBind<T> {
53    fn from(signal: RwSignal<T>) -> Self {
54        Self::Signal(signal)
55    }
56}
57
58impl<T> From<Field<T>> for FormBind<T> {
59    fn from(field: Field<T>) -> Self {
60        Self::Field(field)
61    }
62}
63
64impl<T: Send + Sync + 'static> From<T> for FormBind<T> {
65    fn from(value: T) -> Self {
66        Self::Signal(RwSignal::new(value))
67    }
68}
69
70impl<T: Default + Send + Sync + 'static> Default for FormBind<T> {
71    fn default() -> Self {
72        Self::Signal(RwSignal::new(T::default()))
73    }
74}