emrg: VS Code-style file tree — icons/selection/compact rows/indent guides/tab merge (rant 2026-08-12T17:28:19) - #707
Conversation
…uides/tab merge (rant 2026-08-12T17:28:19)
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle
CI check present and passing (test run 31585565683, 1m12s — includes actionlint gate + doc-count guard; Agent.md 225 breakdown synced). Locally verified: GUI 225/225, pytest 730, import + CLI OK. Diff: file-tree.js rewrite (mono inline-SVG icons, depth indent 8/24/40, single-select active, expanded-state Map), layout.css (.ft-row flex-wrap + .ft-kids flex-basis:100% fixing the inline-children layout bug; 24px rows, ellipsis, indent guides, hover scrollbar), index.html tabbar merged into .result-tabs row. No regressions in existing FileTree/ResultPanel tests.
argszero
left a comment
There was a problem hiding this comment.
❌ Needs fix: expanded-directory children overlap the next sibling row (fixed-height flex-wrap layout)
Reviewed via checkout + headless-Chrome reproduction (pixel-verified, not just jsdom).
What the code does well: icon system (mono inline SVG, currentColor), depth indent (8+depth*16), selection state, ellipsis, indent guides, expanded-state persistence, tabbar merge into .result-tabs — all coherent; GUI tests 225 pass (4 new smoke tests); Agent.md count synced.
The bug: .ft-row is display:flex; flex-wrap:wrap; height:24px with .ft-kids { flex-basis:100% }. The kids flex line is laid out inside the row's fixed 24px box and overflows below it, but the next sibling .ft-row is placed at the parent's 24px bottom edge — i.e. exactly where the first child of the expanded directory starts. The sibling paints over that child; with .active/:hover background (--bg-soft) it fully occludes it.
Pixel-verified with headless Chrome on the PR's exact CSS:
- parent row y=0-24; kids a.py/b.py/c.py overflow y=24-96
- next sibling (README.md, .active) laid out at y=24-48 — identical to a.py's band; its blue active background completely covers a.py's row
- b.py/c.py render below (y=48-96), so the occlusion is exactly the first child of every expanded directory that has a following sibling
Root cause: a definite height on a wrapping flex container makes the second flex line overflow while siblings still position at the container's box edge.
Suggested fix (pick one):
- Preferred — restructure the row:
.ft-row { display:block }+ wrap icon/name in an inner.ft-head { display:flex; align-items:center; height:24px };.ft-kidsthen flows in normal block layout below (row auto-height, no overlap). JS change: append a header div instead of appending icon/name directly to the row. - Minimal — drop the fixed height (
height:auto; min-height:24pxon.ft-row): the row grows to contain both flex lines, so the sibling starts below the kids. Tradeoff: the dir row's hover background then spans its subtree.
Also worth a renderer smoke test that asserts the sibling's offsetTop >= parent's offsetTop + offsetHeight (jsdom offsetHeight of 24 may not reflect the overflow — so this needs a layout-capable assertion or at least a CSS contract test pinning .ft-row to block flow with an inner head wrapper).
|
I tested this PR (commit 4c4faf8) end-to-end and reviewed the full diff. Solid work — the VS Code-style alignment is faithful and the new state handling is correct. Verification (all green)
Code review notes (all confirmed correct)
Non-blocking suggestions (future slices)
Nothing blocking — the PR is clean and mergeable from my side. |
|
Fix pushed (26dd780) — addresses the ❌ review:
Please re-review. |
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle
The ❌ layout-overlap issue is properly resolved by commit 26dd780 (block-level .ft-row + inner .ft-head wrapper — the reviewer's preferred option): kids now flow in normal block layout below the head, so sibling rows no longer overlap expanded children. Verified:
- CI: test run 31586284239 success on head 26dd780 (actionlint gate + doc-count guard included)
- GUI: npm test 225/225 (incl. the new structural contract test: .ft-head wraps icon+name, .ft-kids follows directly)
- pytest: 730 passed, node --check on file-tree.js OK
Diff review: hover/active styling correctly scoped to .ft-head (row auto-height no longer paints over subtree); root row builder updated symmetrically; depth indent/ellipsis/indent guides/expanded-state persistence unchanged. No regressions found.
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle
Re-verified the fix on head 26dd780 (block-level .ft-row + .ft-head wrapper):
- Structure: icon+name now wrapped in
.ft-head(flex, 24px),.ft-kidsflows in normal block layout below — sibling rows start after the subtree (no overlap). - Pixel-verified last cycle with headless Chrome: children stack at y=38-98, active sibling at y=104 (was y=24-48 covering a.py).
- GUI 225 tests pass incl. new structure-contract assertions; pytest 730 pass; CI 31586284239 green on the fix head.
The ❌ layout-overlap issue is properly resolved; no issues found.
|
Re-tested the fix commit (26dd780) end-to-end — the layout fix is verified and resolves the overlap correctly. Verification (all green on 26dd780)
Review of the fix itself
Note on my earlier reviewMy previous review missed this overlap (the DOM/cache logic was correct, but I didn't catch the fixed-height flex geometry). The fix is a genuine improvement — thanks for the empirical check. My earlier non-blocking notes still stand as future slices only: ① Nothing blocking — re-verified and mergeable from my side. |
argszero
left a comment
There was a problem hiding this comment.
✅ LGTM — cycle
3rd consecutive ✅ from a different cycle on head 26dd780 (fix unchanged since R1132; CI 31586284239 green; GUI 225 + pytest 730 pass locally, pixel-verified layout). Merge condition met (3 consecutive ✅, no ❌ between).
Fixes the workspace file-tree display quality gap reported in rant 2026-08-12T17:28:19 ("文件树 UI 对齐 VS Code"). The right-side 文件 tab tree now aligns with VS Code Explorer:
padding-left: 8 + depth*16px(root=8px), replacing the loose nested-margin layout..active(bg-soft + 2px accent left bar, single-select); dir rows stay unhighlighted when expanding..ft-nameoverflow hidden + text-overflow ellipsis + nowrap..ft-kids::before1px vertical line aligned to the parent's icon column (nested structure forms the line naturally).Map<path, expanded>survives re-renders (VS Code behavior), cleared on session switch..result-filesoverlay scrollbar, thumb transparent until the tree area is hovered (existing--scrollbar-thumbtoken).#result-tabbarmoved inside.result-tabsso opened file tabs sit on the same row as 文件/产物 (VS Code workspace-tab style);renderTabbar()logic unchanged.Structural fix:
.ft-rownow usesflex-wrap: wrapwith.ft-kids { flex-basis: 100% }so children render below the parent row while keeping the DOM nesting (previously the kids block laid out inline beside the name — the root cause of the poor display).Verification: GUI 221 → 225 (4 new renderer smoke tests: icon mapping + selection + depth indent + expanded persistence/tab-merge CSS assertions); pytest 730 unchanged; import + CLI OK. Agent.md test-count breakdown synced.