Preserve focus inside grid editors

This commit is contained in:
2026-07-29 11:02:30 +02:00
parent 096ba8aa1c
commit 1b2ca84258
3 changed files with 33 additions and 1 deletions
@@ -27,6 +27,7 @@ import {
deviceFieldKeys, deviceFieldKeys,
formatPhaseTypeLabel, formatPhaseTypeLabel,
formatValue, formatValue,
isGridEditorControlTarget,
} from "../utils/circuit-grid-model"; } from "../utils/circuit-grid-model";
import { import {
buildCircuitDeviceRowInsertSnapshot, buildCircuitDeviceRowInsertSnapshot,
@@ -3398,6 +3399,9 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
setCircuitReorderIntent(null); setCircuitReorderIntent(null);
}} }}
onClick={(event) => { onClick={(event) => {
if (isGridEditorControlTarget(event.target)) {
return;
}
if (cell.editable) { if (cell.editable) {
handleRowSelectionClick(row, column.key, { handleRowSelectionClick(row, column.key, {
ctrlKey: event.ctrlKey, ctrlKey: event.ctrlKey,
@@ -3406,7 +3410,10 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
}); });
} }
}} }}
onDoubleClick={() => { onDoubleClick={(event) => {
if (isGridEditorControlTarget(event.target)) {
return;
}
if (cell.editable) { if (cell.editable) {
startEdit({ rowKey: row.rowKey, cellKey: column.key }, "selectExisting"); startEdit({ rowKey: row.rowKey, cellKey: column.key }, "selectExisting");
} }
+12
View File
@@ -230,6 +230,18 @@ export function formatPhaseTypeLabel(value: string): string {
return value; return value;
} }
export function isGridEditorControlTarget(target: unknown): boolean {
if (
target === null ||
typeof target !== "object" ||
!("closest" in target) ||
typeof target.closest !== "function"
) {
return false;
}
return Boolean(target.closest("input, select, textarea"));
}
export function parseNumeric(cellKey: CellKey, draft: string): number | undefined { export function parseNumeric(cellKey: CellKey, draft: string): number | undefined {
const trimmed = draft.trim(); const trimmed = draft.trim();
if (trimmed === "") { if (trimmed === "") {
+13
View File
@@ -5,6 +5,7 @@ import {
buildCircuitEditPatch, buildCircuitEditPatch,
buildDeviceRowEditPatch, buildDeviceRowEditPatch,
formatValue, formatValue,
isGridEditorControlTarget,
getBlockSortValue, getBlockSortValue,
getCellKind, getCellKind,
getCircuitValue, getCircuitValue,
@@ -50,6 +51,18 @@ const circuit: CircuitTreeCircuitDto = {
}; };
describe("circuit grid model", () => { describe("circuit grid model", () => {
it("does not route clicks from active editor controls back to the grid cell", () => {
const inputTarget = {
closest: (selector: string) =>
selector === "input, select, textarea" ? {} : null,
};
const cellTarget = { closest: () => null };
assert.equal(isGridEditorControlTarget(inputTarget), true);
assert.equal(isGridEditorControlTarget(cellTarget), false);
assert.equal(isGridEditorControlTarget(null), false);
});
it("keeps the equipment identifier locked as the first column", () => { it("keeps the equipment identifier locked as the first column", () => {
assert.equal(allColumns[0].key, "equipmentIdentifier"); assert.equal(allColumns[0].key, "equipmentIdentifier");
assert.equal(allColumns[0].locked, true); assert.equal(allColumns[0].locked, true);