fix(EditableCell): improve seamless input handling and focus management

- Resolved issues with input handling to ensure smoother updates on focus and blur.
- Introduced `commit_input` to properly commit input values on blur or enter.
- Added logging to aid debugging and track input events.
This commit is contained in:
ryan 2025-01-06 15:33:26 +03:00
parent 4f9d423a5c
commit 0e15699b13

View file

@ -1,5 +1,6 @@
use leptos::*; use leptos::*;
use std::sync::Arc; use std::sync::Arc;
use leptos::logging::log;
#[component] #[component]
pub fn EditableCell( pub fn EditableCell(
@ -9,44 +10,44 @@ pub fn EditableCell(
focused_cell: ReadSignal<Option<String>>, focused_cell: ReadSignal<Option<String>>,
set_focused_cell: WriteSignal<Option<String>>, set_focused_cell: WriteSignal<Option<String>>,
) -> impl IntoView { ) -> impl IntoView {
let (input_value, set_input_value) = create_signal(value.clone()); let input_ref = create_node_ref::<html::Input>();
let input_ref = NodeRef::<html::Input>::new(); let (local_value, set_local_value) = create_signal(value.clone());
// Handle input event // 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()); log!("Input event: {}", new_value);
on_input(new_value); set_local_value.set(new_value);
}; };
// Commit the input value on blur or enter
let commit_input = move || {
let value = local_value.get();
log!("Committing input: {}", value);
on_input(value);
};
// Focus handling
let handle_focus = { let handle_focus = {
let key = Arc::clone(&key); let key = Arc::clone(&key);
move |_| { move |_| {
log!("Focus gained for key: {}", key);
set_focused_cell.set(Some(key.to_string())); set_focused_cell.set(Some(key.to_string()));
} }
}; };
let handle_blur = move |_| { let handle_blur = move |_| {
log!("Focus lost");
set_focused_cell.set(None); set_focused_cell.set(None);
commit_input();
}; };
create_effect({ // Update input field value when focused cell changes
let key = Arc::clone(&key); create_effect(move |_| {
move |_| { if focused_cell.get().as_deref() == Some(key.as_str()) {
if let Some(ref current_key) = focused_cell.get() { log!("Setting focus for key: {}", key);
if current_key == key.as_str() { if let Some(input) = input_ref.get() {
if let Some(input) = input_ref.get() { let _ = input.focus();
if web_sys::window()
.unwrap()
.document()
.unwrap()
.active_element()
.map_or(true, |el| !el.is_same_node(Some(input.as_ref())))
{
let _ = input.focus();
}
}
}
} }
} }
}); });
@ -54,11 +55,11 @@ pub fn EditableCell(
view! { view! {
<input <input
type="text" type="text"
prop:value={input_value} value=move || local_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 node_ref=input_ref
/> />
} }
} }