Empty-graph chrome: Import Notes stays, search + settings wait for nodes
Owner ruling on the empty graph (honesty principle — dead controls are lies): the top-chrome actions row now gates per control. - Import Notes renders ALWAYS (graph enabled) — the one action that works on an empty graph, the entry point itself. It used to hide with everything else, leaving the empty state a dead end with no entry. - Search + settings render only when the snapshot has nodes, and their appear-once mount carries a deliberate 200ms fade (graph-chrome-fade-in, globals.css — the settings-pop register, reduced-motion appears instantly). Computed animationName verified live. - The row's body is now the exported pure GraphChromeRow (the DeleteNodeBody pattern) — the no-match note's truth (visibleIds + snapshot) stays upstream, computed by the wrapper. - The empty-state placeholder copy is LEFT AS-IS (SCOPE rule: it already has copy — icon, title, and the session-mapping paragraph). Pins (tests/render-graph-chrome.test.tsx): empty → Import Notes present, search/settings absent, no fade carriers; populated → all three, exactly two fade carriers; the no-match note follows its upstream truth. SSR of GraphChromeRow both ways. Live-verified on :3001 with scratch data: empty graph → Import Notes only + placeholder intact; a real import through the button (file input via DataTransfer) → nodes land, search + settings fade in (computed chrome-fade-in on both carriers); wipe → reload → back to Import Notes only (the reverse path). Scratch graph restored byte-identical. 932/932, tsc/lint/build green.
This commit is contained in:
@@ -438,6 +438,30 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Graph chrome fade-in (empty-graph chrome wave, owner 2026-09-25): the
|
||||
search + settings controls appear ONCE, as the first nodes land —
|
||||
Import Notes always renders (the empty graph's entry point), the other
|
||||
two mount only when the snapshot has nodes. Same understated register
|
||||
as settings-pop (a plain fade); reduced-motion appears instantly. */
|
||||
@keyframes chrome-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.graph-chrome-fade-in {
|
||||
animation: chrome-fade-in 200ms ease-out;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.graph-chrome-fade-in {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ─────────────────────────────────────────────────────────────────────────
|
||||
Electron merged chrome (owner, 2026-09-17). The system title bar is
|
||||
hidden (titleBarStyle: "hiddenInset" in electron/main.cjs); the app's
|
||||
|
||||
Reference in New Issue
Block a user