From 9da8b03de2bd5f791ed3893ae4d485ce00347be5 Mon Sep 17 00:00:00 2001 From: ryan <ryannganga13325@gmail.com> Date: Tue, 24 Dec 2024 14:27:32 +0300 Subject: [PATCH] feat(maintain focus on cells): maintain focus while typing in cells; in progress --- src/components/editable_cell.rs | 16 +++++++++++++++ src/components/items_list.rs | 36 ++++++++++++++++----------------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/components/editable_cell.rs b/src/components/editable_cell.rs index 72d6c1e..2604931 100644 --- a/src/components/editable_cell.rs +++ b/src/components/editable_cell.rs @@ -4,8 +4,10 @@ use leptos::*; pub fn EditableCell( value: String, on_input: impl Fn(String) + 'static, + #[prop(optional)] key: Option<String>, // Optional `key` prop ) -> impl IntoView { let (input_value, set_input_value) = create_signal(value.clone()); + let (has_focus, set_has_focus) = create_signal(false); // Track focus state locally let handle_input = move |e: web_sys::Event| { let new_value = event_target_value(&e); @@ -13,11 +15,25 @@ pub fn EditableCell( on_input(new_value); }; + let handle_focus = move |_: web_sys::FocusEvent| { + set_has_focus.set(true); + }; + + let handle_blur = move |_: web_sys::FocusEvent| { + set_has_focus.set(false); + }; + + // Use key to force updates only when necessary + let _key = key.unwrap_or_default(); + view! { <input type="text" value={input_value.get()} on:input=handle_input + on:focus=handle_focus + on:blur=handle_blur + class={if has_focus.get() { "focused" } else { "not-focused" }} /> } } diff --git a/src/components/items_list.rs b/src/components/items_list.rs index 4759a36..b6f8d5e 100644 --- a/src/components/items_list.rs +++ b/src/components/items_list.rs @@ -89,7 +89,7 @@ pub fn ItemsList( name: String::new(), description: String::new(), tags: vec![], - reviews:vec![], + reviews: vec![], wikidata_id: None, }); }); @@ -121,15 +121,15 @@ pub fn ItemsList( <tr> // Editable Name Field with Wikidata Integration <td> - <EditableCell - value=item.name.clone() - on_input=move |value| update_item(index, "name", value) - /> + <EditableCell + value=item.name.clone() + on_input=move |value| update_item(index, "name", value) + key=format!("name-{}", index) // Unique key per cell + /> <ul> {move || { let suggestions = wikidata_suggestions.get().to_vec(); suggestions.into_iter().map(|suggestion| { - // Clone all necessary fields upfront let label_for_click = suggestion.label.clone(); let label_for_display = suggestion.label.clone(); let description_for_click = suggestion.description.clone().unwrap_or_default(); @@ -146,34 +146,34 @@ pub fn ItemsList( <li on:click=move |_| { set_items.update(|items| { if let Some(item) = items.get_mut(index) { - item.description = description_for_click.clone(); // Update description - item.tags.extend(tags.clone()); // Add tags + item.description = description_for_click.clone(); + item.tags.extend(tags.clone()); item.wikidata_id = Some(id.clone()); - item.name = label_for_click.clone(); // Use the cloned version for updating + item.name = label_for_click.clone(); } }); }> - { format!("{} - {}", label_for_display, description_for_display) } // Use the cloned version for display + { format!("{} - {}", label_for_display, description_for_display) } </li> - } - - }).collect::<Vec<_>>() + } + }).collect::<Vec<_>>() }} </ul> </td> // Editable Description Field <td> - <EditableCell - value=item.description.clone() - on_input=move |value| update_item(index, "description", value) - /> + <EditableCell + value=item.description.clone() + on_input=move |value| update_item(index, "description", value) + key=format!("description-{}", index) + /> </td> // Tag Editor <td> <TagEditor tags=item.tags.clone() on_add=move |key, value| add_tag(index, key, value) - on_remove=Arc::new (Mutex:: new (move |tag_index:usize| remove_tag(index, tag_index))) + on_remove=Arc::new(Mutex::new(move |tag_index: usize| remove_tag(index, tag_index))) /> </td> // Actions