dashboard: connect tree-prefix vertical bars across taller rows (#388)
The container-row tree-prefix used text box-drawing glyphs (├ └ │) positioned with `top: 0.6em` — a single text-line tall. Once rows grew past one line (5em square icon + multi-line body), the `│` columns of consecutive siblings no longer touched, leaving visible breaks in the tree. Replace the text-glyph string with structured DOM: one `.tree-lane` per depth column. Continuation lanes (`.lane-line`) paint a 1px border-left spanning the full row height + the `.containers` gap below, so adjacent siblings' bars visually merge into one unbroken vertical. The row's own joint lane is `├` (branch — bar continues below) or `└` (last — bar stops at icon midline), with a horizontal stub at 3.1em (row padding-top + icon half-height) reaching to the icon edge. Joint y / stub width are derived from the 5em icon + 0.6em row padding-top + 0.8em row padding-left so they meet the icon cleanly.
This commit is contained in:
parent
47403595f1
commit
7743c07380
2 changed files with 89 additions and 20 deletions
|
|
@ -649,16 +649,29 @@ window.marked = marked;
|
|||
}
|
||||
return out;
|
||||
}
|
||||
function treePrefix({ depth, ancestorIsLast, isLast }) {
|
||||
if (depth === 0) return '';
|
||||
let s = '';
|
||||
// Ancestor at depth 0 (root) doesn't get a vertical-line column —
|
||||
// roots are separated visually as top-level rows already.
|
||||
// Builds the .tree-prefix DOM for a row at the given depth. Each
|
||||
// lane is its own positioned child so CSS can paint full-height
|
||||
// vertical bars that bridge the gap between sibling rows — text
|
||||
// box-drawing glyphs only paint one text-line tall, which left
|
||||
// visible breaks between rows once we grew taller-than-one-line
|
||||
// container cards (#388). Ancestor lanes are either continuation
|
||||
// (vertical bar top→bottom+gap) or blank; the joint at this row's
|
||||
// own depth is ├ (branch — vertical continues below) or └ (last —
|
||||
// vertical stops at the row's icon midline). CSS at
|
||||
// `.container-row .tree-prefix` paints the bars + horizontal stub.
|
||||
function treePrefixDom({ depth, ancestorIsLast, isLast }) {
|
||||
if (depth === 0) return null;
|
||||
const prefix = el('span', { class: 'tree-prefix', 'aria-hidden': 'true' });
|
||||
// Ancestor columns (depth 1..depth-1). Skip depth 0 (root has no
|
||||
// continuation column — top-level rows are separated visually as
|
||||
// top-level rows already).
|
||||
for (let d = 1; d < depth; d++) {
|
||||
s += ancestorIsLast[d] ? ' ' : '│ ';
|
||||
const cls = ancestorIsLast[d] ? 'tree-lane lane-blank' : 'tree-lane lane-line';
|
||||
prefix.append(el('span', { class: cls }));
|
||||
}
|
||||
s += isLast ? '└─ ' : '├─ ';
|
||||
return s;
|
||||
const jointCls = 'tree-lane lane-joint ' + (isLast ? 'lane-joint-last' : 'lane-joint-branch');
|
||||
prefix.append(el('span', { class: jointCls }));
|
||||
return prefix;
|
||||
}
|
||||
|
||||
function renderContainers(s) {
|
||||
|
|
@ -731,10 +744,8 @@ window.marked = marked;
|
|||
// legacy flat layout (every container at depth 0) is bit-
|
||||
// identical to today's render — no glyph, no indent.
|
||||
if (node.depth > 0) li.dataset.depth = String(node.depth);
|
||||
const prefix = treePrefix(node);
|
||||
if (prefix) {
|
||||
li.prepend(el('span', { class: 'tree-prefix', 'aria-hidden': 'true' }, prefix));
|
||||
}
|
||||
const prefix = treePrefixDom(node);
|
||||
if (prefix) li.prepend(prefix);
|
||||
|
||||
// Full-height square agent icon, left of the card body. The
|
||||
// icon is an <img> absolutely positioned inside a wrapper div:
|
||||
|
|
|
|||
Loading…
Reference in a new issue