fix: add hydration effect to selectable lists

This commit is contained in:
alphafetus committed 2026-01-13 15:52:15 -05:00
1 parent c693ed9190
commit c1f0c0cb81
3 files changed
+34 -21

No files matched your search

+26 -13
View File
@@ -23,24 +23,37 @@ fn value_type_to_vec(value_type: &ValueType) -> Vec<String> {
}
pub fn use_selectable_list(
data_member: String,
data_member: Signal<String>,
data_map: RwSignal<HashMap<String, ValueType>>,
required: Signal<bool>
) -> ListController {
//#region Central List Logic
// Get default values from the data map. This will only run once, when the input is created
// and mounted to the DOM.
let temp_map = data_map.get_untracked();
let origin_value_type = temp_map.get(&data_member)
.unwrap_or(&ValueType::List(None));
let origin_list = value_type_to_vec(origin_value_type);
// "Raw" selected values - just strings, no ValueTyping
let selected_list = RwSignal::new(origin_list);
let selected_list = RwSignal::new(Vec::new());
let hydrated = RwSignal::new(false);
let dirty = RwSignal::new(false);
// Hydration effect - runs only once, to hydrate data.
Effect::new(move || {
if hydrated.get() {
return;
}
// React to data_map changes
let map = data_map.get();
let key = data_member.get();
let list = map
.get(&key)
.unwrap_or(&ValueType::List(None));
selected_list.set(value_type_to_vec(list));
hydrated.set(true);
});
Effect::new({
let data_member = data_member.clone();
move || {
// Convert selected strings into ValueTypes
let typed_list = selected_list.with(|list|
@@ -51,7 +64,7 @@ pub fn use_selectable_list(
// Update the map
data_map.update(|map| {
map.insert(data_member.clone(), ValueType::List(Some(typed_list)));
map.insert(data_member.get(), ValueType::List(Some(typed_list)));
});
}
});
@@ -69,11 +82,11 @@ pub fn use_selectable_list(
ValidationState::Valid
}
});
let dirty = RwSignal::new(false);
let show_errors = Signal::derive(move || dirty.get() && matches!(error.get(), ValidationState::Invalid(_)));
let validator = RwSignal::new(InputState::new(
data_member.clone(),
data_member.get(),
error.clone(),
dirty.clone()
));