orbital_base_components/form/
field_injection.rs1use 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}