top bar drag standardization: auto carve-out + the overlay DOM law (owner ruling)
The chains-overlay TopBar had dead drag zones (counts, around search, close gap) — cause: app-region subtraction resolves by DOM ORDER, not z-index; the graph chrome's lh-no-drag column came later in the DOM and punched holes through the overlay's drag band despite sitting visually underneath (z-40 vs z-10). Two laws, per the owner's standardization ruling: - AUTO CARVE-OUT (globals.css): inside any .lh-drag band, every native interactive element (button/input/textarea/select/a/summary/ [contenteditable]) is automatically a no-drag island — draggable anywhere that is not a clickable element becomes structural. Manual lh-no-drag is only for clickable non-natives. - THE OVERLAY DOM LAW: a surface containing a TopBar that covers other content must be the LAST child of its container — ChainTableOverlay moved after the chrome column (verified live: last child, after the column; auto-carve rule compiled; search/close/sidebar-toggle all still click).
This commit is contained in:
+22
-14
@@ -1555,19 +1555,7 @@ export function GraphView() {
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* The chain table overlay (chains-overlay plan, 2026-09-29):
|
||||
ABSOLUTE INSIDE the graph area (the session-overlay idiom —
|
||||
never a body portal) so the app chrome stays sharp and
|
||||
reachable; the overlay itself is read-only toward the graph
|
||||
and owns its selection + the custom practice dialog. */}
|
||||
<ChainTableOverlay
|
||||
open={chainsOpen && !isEmpty}
|
||||
nodes={snapshot?.nodes ?? []}
|
||||
edges={snapshot?.edges ?? []}
|
||||
sessions={snapshot?.sessions ?? {}}
|
||||
fileSources={snapshot?.fileSources ?? {}}
|
||||
onClose={() => setChainsOpen(false)}
|
||||
/>
|
||||
|
||||
|
||||
{/* Legend + filters: search box and per-state toggle rows. */}
|
||||
{/* Top-right controls — separate floating containers (owner,
|
||||
@@ -1734,6 +1722,26 @@ export function GraphView() {
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* The chain table overlay (chains-overlay plan, 2026-09-29):
|
||||
ABSOLUTE INSIDE the graph area (the session-overlay idiom —
|
||||
never a body portal) so the app chrome stays sharp and
|
||||
reachable; the overlay itself is read-only toward the graph
|
||||
and owns its selection + the custom practice dialog.
|
||||
LAST CHILD OF THE ROOT, DELIBERATELY (owner, 2026-09-29
|
||||
night): app-region subtraction resolves by DOM order, not
|
||||
z-index — mounted earlier, the chrome's lh-no-drag column
|
||||
punched dead zones through the overlay's TopBar drag band
|
||||
(over the counts, around the search field). A full-bleed
|
||||
surface covering a drag band must paint AFTER everything it
|
||||
covers. (DeleteNodeDialog is body-portaled — DOM-irrelevant
|
||||
here.) */}
|
||||
<ChainTableOverlay
|
||||
open={chainsOpen && !isEmpty}
|
||||
nodes={snapshot?.nodes ?? []}
|
||||
edges={snapshot?.edges ?? []}
|
||||
sessions={snapshot?.sessions ?? {}}
|
||||
fileSources={snapshot?.fileSources ?? {}}
|
||||
onClose={() => setChainsOpen(false)}
|
||||
/> </div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user