From 05322530343a6f09efc6ec49845fde3e065db3e0 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Tue, 28 Apr 2026 15:44:22 +0100 Subject: [PATCH] fix(base): commit cell edit on click-outside, not just on Enter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CellNumber/CellText/CellEmail/CellUrl all commit their draft via onBlur. The grid-container's document mousedown handler was clearing editingCell synchronously when the user clicked outside, which made React unmount the input before the native blur event reached its onBlur listener — so the edit was silently dropped, and pressing Enter was the only way to save. Trigger blur() on the active element first; the cell's onBlur runs, commits, and clears editingCell as part of its normal flow. The trailing setEditingCell(null) is now a safety net for the case where the active element wasn't a cell editor (no double-commit risk because each cell guards with committedRef). --- .../base/components/grid/grid-container.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/apps/client/src/features/base/components/grid/grid-container.tsx b/apps/client/src/features/base/components/grid/grid-container.tsx index f9aa001db..8617239ab 100644 --- a/apps/client/src/features/base/components/grid/grid-container.tsx +++ b/apps/client/src/features/base/components/grid/grid-container.tsx @@ -121,6 +121,19 @@ export function GridContainer({ } else { setActivePropertyMenu(null); } + // Blur the focused element BEFORE clearing editingCell. Cell + // editors (CellNumber, CellText, CellEmail, CellUrl) commit + // their draft via onBlur — if we set editingCell to null first, + // React unmounts the input before the native blur event reaches + // its onBlur listener, so the user's edit is silently dropped + // (and pressing Enter is the only way to save). Triggering blur + // here lets the cell's onBlur run, commit, and clear editingCell + // itself; the setEditingCell(null) below is a no-op safety net + // for cases where the active element wasn't a cell editor. + const active = document.activeElement as HTMLElement | null; + if (active && active !== document.body && typeof active.blur === "function") { + active.blur(); + } setEditingCell(null); }; document.addEventListener("mousedown", handleMouseDown);