Compare commits

..

No commits in common. "4f9d423a5cebd7befd1571f13fb62d12745b753c" and "08821aaaaf8638ca038be0aacf562ff0ae63e6ae" have entirely different histories.

2 changed files with 18 additions and 52 deletions

View file

@ -1,64 +1,39 @@
use leptos::*; use leptos::*;
use std::sync::Arc;
#[component] #[component]
pub fn EditableCell( pub fn EditableCell(
value: String, value: String,
on_input: impl Fn(String) + 'static, on_input: impl Fn(String) + 'static,
key: Arc<String>, #[prop(optional)] key: Option<String>, // Optional `key` prop
focused_cell: ReadSignal<Option<String>>,
set_focused_cell: WriteSignal<Option<String>>,
) -> impl IntoView { ) -> impl IntoView {
let (input_value, set_input_value) = create_signal(value.clone()); let (input_value, set_input_value) = create_signal(value.clone());
let input_ref = NodeRef::<html::Input>::new(); let (has_focus, set_has_focus) = create_signal(false); // Track focus state locally
// Handle input event
let handle_input = move |e: web_sys::Event| { let handle_input = move |e: web_sys::Event| {
let new_value = event_target_value(&e); let new_value = event_target_value(&e);
set_input_value.set(new_value.clone()); set_input_value.set(new_value.clone());
on_input(new_value); on_input(new_value);
}; };
let handle_focus = { let handle_focus = move |_: web_sys::FocusEvent| {
let key = Arc::clone(&key); set_has_focus.set(true);
move |_| {
set_focused_cell.set(Some(key.to_string()));
}
}; };
let handle_blur = move |_| { let handle_blur = move |_: web_sys::FocusEvent| {
set_focused_cell.set(None); set_has_focus.set(false);
}; };
create_effect({ // Use key to force updates only when necessary
let key = Arc::clone(&key); let _key = key.unwrap_or_default();
move |_| {
if let Some(ref current_key) = focused_cell.get() {
if current_key == key.as_str() {
if let Some(input) = input_ref.get() {
if web_sys::window()
.unwrap()
.document()
.unwrap()
.active_element()
.map_or(true, |el| !el.is_same_node(Some(input.as_ref())))
{
let _ = input.focus();
}
}
}
}
}
});
view! { view! {
<input <input
type="text" type="text"
prop:value={input_value} value={input_value.get()}
on:input=handle_input on:input=handle_input
on:focus=handle_focus on:focus=handle_focus
on:blur=handle_blur on:blur=handle_blur
node_ref=input_ref class={if has_focus.get() { "focused" } else { "not-focused" }}
/> />
} }
} }

View file

@ -21,9 +21,6 @@ pub fn ItemsList(
items: ReadSignal<Vec<Item>>, items: ReadSignal<Vec<Item>>,
set_items: WriteSignal<Vec<Item>>, set_items: WriteSignal<Vec<Item>>,
) -> impl IntoView { ) -> impl IntoView {
// State to track the currently focused cell
let (focused_cell, set_focused_cell) = create_signal(None::<String>);
// State to manage dynamic property names // State to manage dynamic property names
let (custom_properties, set_custom_properties) = create_signal(Vec::<String>::new()); let (custom_properties, set_custom_properties) = create_signal(Vec::<String>::new());
@ -163,9 +160,7 @@ pub fn ItemsList(
<EditableCell <EditableCell
value=item.name.clone() value=item.name.clone()
on_input=move |value| update_item(index, "name", value) on_input=move |value| update_item(index, "name", value)
key=Arc::new(format!("name-{}", index)) key=format!("name-{}", index)
focused_cell=focused_cell
set_focused_cell=set_focused_cell.clone()
/> />
<ul> <ul>
{move || { {move || {
@ -205,9 +200,7 @@ pub fn ItemsList(
<EditableCell <EditableCell
value=item.description.clone() value=item.description.clone()
on_input=move |value| update_item(index, "description", value) on_input=move |value| update_item(index, "description", value)
key=Arc::new(format!("description-{}", index)) key=format!("description-{}", index)
focused_cell=focused_cell
set_focused_cell=set_focused_cell.clone()
/> />
}.into_view(), }.into_view(),
"Tags" => view! { "Tags" => view! {
@ -247,9 +240,7 @@ pub fn ItemsList(
<EditableCell <EditableCell
value=item.custom_properties.get(&property_clone).cloned().unwrap_or_default() value=item.custom_properties.get(&property_clone).cloned().unwrap_or_default()
on_input=move |value| update_item(index, &property_clone_for_closure, value) on_input=move |value| update_item(index, &property_clone_for_closure, value)
key=Arc::new(format!("custom-{}-{}", property_clone, index)) key=format!("custom-{}-{}", property_clone, index)
focused_cell=focused_cell
set_focused_cell=set_focused_cell.clone()
/> />
</td> </td>
} }