Skip to main content

orbital_base_components/form/
field_injection.rs

1use leptos::prelude::*;
2use uuid::Uuid;
3
4use super::field_validation::FieldValidationState;
5
6#[derive(Clone)]
7pub struct FieldInjection {
8    pub(crate) id: StoredValue<String>,
9    pub(crate) name: MaybeProp<String>,
10    pub(crate) label: MaybeProp<String>,
11    pub(crate) validation_state: RwSignal<Option<FieldValidationState>>,
12}
13
14impl FieldInjection {
15    pub fn new(
16        id: StoredValue<String>,
17        name: MaybeProp<String>,
18        label: MaybeProp<String>,
19        validation_state: RwSignal<Option<FieldValidationState>>,
20    ) -> Self {
21        Self {
22            id,
23            name,
24            label,
25            validation_state,
26        }
27    }
28
29    pub fn use_context() -> Option<Self> {
30        use_context()
31    }
32
33    pub fn id(&self) -> Option<String> {
34        if self.label.with(|l| l.is_some()) {
35            Some(self.id.get_value())
36        } else {
37            None
38        }
39    }
40
41    pub fn name(&self) -> Option<String> {
42        self.name.get()
43    }
44
45    pub fn use_id_and_name(
46        id: MaybeProp<String>,
47        name: MaybeProp<String>,
48    ) -> (Signal<Option<String>>, Signal<Option<String>>) {
49        let field_injection = Self::use_context();
50        let id = Signal::derive(move || {
51            if let Some(id) = id.get() {
52                return Some(id);
53            }
54            field_injection.as_ref()?.id()
55        });
56
57        let field_injection = Self::use_context();
58        let name = Signal::derive(move || {
59            if let Some(name) = name.get() {
60                return Some(name);
61            }
62            field_injection.as_ref()?.name()
63        });
64
65        (id, name)
66    }
67
68    pub fn update_validation_state(&self, state: Result<(), FieldValidationState>) {
69        let state = state.err();
70        self.validation_state.try_maybe_update(|validation_state| {
71            if validation_state == &state {
72                (false, ())
73            } else {
74                *validation_state = state;
75                (true, ())
76            }
77        });
78    }
79}
80
81pub fn new_field_id() -> String {
82    Uuid::new_v4().to_string()
83}