fix: allow uniquely named lists to work with multientry component

This commit is contained in:
alphafetus committed 2026-02-04 22:01:44 -05:00
1 parent 4bf0cdcb39
commit 956c653e28
4 files changed
+31 -10

No files matched your search

+9 -1
View File
@@ -26,7 +26,14 @@ pub enum InputType {
}
impl InputType {
pub fn into_view(self, data_map: RwSignal<HashMap<String, ValueType>>) -> impl IntoView {
/// Converts an `InputType` into an `impl IntoView`. A name must be specified in the case that
/// the component is a checkbox/radio list, which requires a unique name to function properly.
/// Many times, the name will be the same as the data member.
pub fn into_view(
self,
data_map: RwSignal<HashMap<String, ValueType>>,
name: String,
) -> impl IntoView {
view! {
{match self {
InputType::Text(member, label, placeholder, required) =>
@@ -56,6 +63,7 @@ impl InputType {
view! {
<CheckboxList
label = label.clone()
name = name.clone()
items = options.clone()
data_member = member.clone()
data_map = data_map
+5 -1
View File
@@ -103,6 +103,10 @@ pub fn Checkbox(
/// ```
#[component]
pub fn CheckboxList(
/// The name that this list should use. This doesn't need to be specified all the time, but is
/// for use in elements that may treat this list as a sub-input (components like the [`MultiEntry`]
/// do this)
#[prop(optional, into)] name: Signal<String>,
/// The data member that this list should edit/display from the `data_map`.
#[prop(into)] data_member: Signal<String>,
/// A [`Signal`] allowing access to a data store.
@@ -160,7 +164,7 @@ pub fn CheckboxList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item
name=data_member
name=move || format!("{}_{}", name.get(), data_member.get())
disabled=disabled
/>
}
+2 -1
View File
@@ -151,6 +151,7 @@ pub fn RadioList(
#[prop(optional, into)] label: String,
#[prop(optional, into)] required: Signal<bool>,
#[prop(optional, into)] other_prompt: Signal<String>,
#[prop(optional, into)] name: Signal<String>
) -> impl IntoView {
//#region Value Logic
@@ -262,7 +263,7 @@ pub fn RadioList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item
name=data_member
name=move || format!("{}_{}", name.get(), data_member.get())
disabled=disabled
/>
}
+15 -7
View File
@@ -125,13 +125,17 @@ pub fn MultiEntry(
>
<For
each=move || data_list.get()
// Entries MUST be given a unique ID. This is absolutely ridiculous.
// Entries MUST be given a unique ID.
key=|entry| get_uuid_from_map(&entry.as_map().unwrap().unwrap())
children=move |mut entry_map| {
let map_signal = RwSignal::new(
entry_map.as_map().ok().flatten().unwrap_or_default(),
);
let unique_id = Memo::new(move |_| {
get_uuid_from_map(&map_signal.get()).unwrap_or_default()
});
Effect::new(move |_| {
let child_map = map_signal.get();
let mut list = data_list.get_untracked();
@@ -139,7 +143,7 @@ pub fn MultiEntry(
update_parent_list(list);
});
view! { <Entry data_map=map_signal schema=schema /> }
view! { <Entry data_map=map_signal schema=schema id=unique_id /> }
}
/>
</Show>
@@ -181,19 +185,23 @@ fn Entry(
/// The data map that contains all information. Data is found within this map using the `member`
/// props. This map should be unique to this entry; in other words, it should be contained and
/// passed down from within the entry list in the parent `MultiEntry` component.
#[prop()]
data_map: RwSignal<HashMap<String, ValueType>>,
#[prop()] data_map: RwSignal<HashMap<String, ValueType>>,
/// The schema of this entry. Should contain all information about what inputs to use and what
/// data members those inputs modify.
#[prop(into)]
schema: Signal<Vec<InputType>>,
#[prop(into)] schema: Signal<Vec<InputType>>,
/// The unique ID for this entry.
#[prop(into)] id: Signal<String>,
) -> impl IntoView {
view! {
<div class="flex flex-col flex-1 p-2 rounded-sm transition-shadow shadow-sm hover:shadow-lg/30">
{schema
.get()
.iter()
.map(|input_type| { input_type.clone().into_view(data_map.clone()) })
.map(|input_type|
input_type
.clone()
.into_view(data_map.clone(), id.get())
)
.collect_view()}
</div>
}