Contain circuit editor scrolling
This commit is contained in:
@@ -281,6 +281,13 @@ Tasks:
|
|||||||
- review sensible default columns and responsive behavior for typical browser widths
|
- review sensible default columns and responsive behavior for typical browser widths
|
||||||
- redesign column filtering with clearer controls, active-filter indicators and an easy reset action
|
- redesign column filtering with clearer controls, active-filter indicators and an easy reset action
|
||||||
|
|
||||||
|
Implemented layout foundation:
|
||||||
|
|
||||||
|
- table scrolling is contained inside the editor so sticky headers remain visible
|
||||||
|
- the toolbar remains reachable while the page scrolls
|
||||||
|
- programmatic grid focus preserves the viewport during undo/redo reloads
|
||||||
|
- wide tables no longer expand the surrounding browser layout
|
||||||
|
|
||||||
Acceptance criteria:
|
Acceptance criteria:
|
||||||
|
|
||||||
- users retain column context anywhere in a long list
|
- users retain column context anywhere in a long list
|
||||||
|
|||||||
+16
-2
@@ -44,12 +44,19 @@ body {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar {
|
.editor-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
position: relative;
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 12;
|
||||||
|
padding: 0.35rem 0;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 0 rgba(196, 205, 220, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button {
|
.editor-toolbar button {
|
||||||
@@ -137,13 +144,20 @@ body {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
border: 1px solid #d9dee8;
|
border: 1px solid #d9dee8;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
max-height: max(28rem, calc(100vh - 12rem));
|
||||||
|
scrollbar-gutter: stable;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tree-editor-layout {
|
.tree-editor-layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 320px 1fr;
|
grid-template-columns: minmax(240px, 320px) minmax(0, 1fr);
|
||||||
gap: 0.75rem;
|
gap: 0.75rem;
|
||||||
min-height: 560px;
|
min-height: 560px;
|
||||||
|
min-width: 0;
|
||||||
|
align-items: start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-device-sidebar {
|
.project-device-sidebar {
|
||||||
|
|||||||
@@ -482,7 +482,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
setAnchorRowKey(null);
|
setAnchorRowKey(null);
|
||||||
}
|
}
|
||||||
setSelectedCell({ rowKey: row.rowKey, cellKey });
|
setSelectedCell({ rowKey: row.rowKey, cellKey });
|
||||||
requestAnimationFrame(() => containerRef.current?.focus());
|
focusGridWithoutScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Captures semantic identity for post-reload focus restoration.
|
// Captures semantic identity for post-reload focus restoration.
|
||||||
@@ -556,7 +556,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
}
|
}
|
||||||
await loadTree({ showLoading: false });
|
await loadTree({ showLoading: false });
|
||||||
if (!intent) {
|
if (!intent) {
|
||||||
requestAnimationFrame(() => containerRef.current?.focus());
|
focusGridWithoutScroll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -779,7 +779,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
if (resolved) {
|
if (resolved) {
|
||||||
setSelectedCell(resolved);
|
setSelectedCell(resolved);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(() => containerRef.current?.focus());
|
focusGridWithoutScroll();
|
||||||
}, [data, editableCells, visibleRows]);
|
}, [data, editableCells, visibleRows]);
|
||||||
|
|
||||||
// Restores multi-selected device rows after operations that rebuild row keys.
|
// Restores multi-selected device rows after operations that rebuild row keys.
|
||||||
@@ -870,6 +870,10 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
return row?.cells.find((cell) => cell.cellKey === cellKey);
|
return row?.cells.find((cell) => cell.cellKey === cellKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function focusGridWithoutScroll() {
|
||||||
|
requestAnimationFrame(() => containerRef.current?.focus({ preventScroll: true }));
|
||||||
|
}
|
||||||
|
|
||||||
// Opens edit session for selected cell.
|
// Opens edit session for selected cell.
|
||||||
// Enter/F2/double-click use selectExisting; type-to-edit uses replaceWithTypedChar.
|
// Enter/F2/double-click use selectExisting; type-to-edit uses replaceWithTypedChar.
|
||||||
function startEdit(cell: SelectedCell, mode: StartEditMode, typedChar?: string) {
|
function startEdit(cell: SelectedCell, mode: StartEditMode, typedChar?: string) {
|
||||||
@@ -1169,7 +1173,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
}
|
}
|
||||||
setEditingCell(null);
|
setEditingCell(null);
|
||||||
setSelectedCell({ rowKey: editingCell.rowKey, cellKey: editingCell.cellKey });
|
setSelectedCell({ rowKey: editingCell.rowKey, cellKey: editingCell.cellKey });
|
||||||
requestAnimationFrame(() => containerRef.current?.focus());
|
focusGridWithoutScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleAddReserveCircuit(sectionId: string, afterCircuitId?: string) {
|
async function handleAddReserveCircuit(sectionId: string, afterCircuitId?: string) {
|
||||||
@@ -3164,7 +3168,7 @@ export function CircuitTreeEditor(props: { projectId: string; circuitListId: str
|
|||||||
const active = document.activeElement as HTMLElement | null;
|
const active = document.activeElement as HTMLElement | null;
|
||||||
if (!active || !containerRef.current?.contains(active)) {
|
if (!active || !containerRef.current?.contains(active)) {
|
||||||
setEditingCell(null);
|
setEditingCell(null);
|
||||||
requestAnimationFrame(() => containerRef.current?.focus());
|
focusGridWithoutScroll();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user