feat(stammbaum): highlight the selected person's bloodline (#703) #704

Merged
marcel merged 13 commits from feat/issue-703-stammbaum-lineage-highlight into main 2026-05-31 20:11:07 +02:00
Showing only changes of commit da3067150d - Show all commits

View File

@@ -965,6 +965,15 @@ describe('StammbaumTree lineage highlight (#703)', () => {
}
const DIM = String(DIMMED_OPACITY);
// Connector groups render as direct <svg> children; the node content groups
// (also .lineage-fade) are nested inside g[role="button"], so the child
// combinator scopes cleanly to connectors.
function dimmedConnectorCount(): number {
return Array.from(document.querySelectorAll('svg > g.lineage-fade')).filter(
(g) => g.getAttribute('opacity') === DIM
).length;
}
it('renders every node at full strength when nothing is selected (AC1)', () => {
render(StammbaumTree, {
nodes: NODES,
@@ -1047,4 +1056,33 @@ describe('StammbaumTree lineage highlight (#703)', () => {
});
for (const n of NODES) expect(nodeOpacity(n.displayName)).toBeNull();
});
it('leaves every connector at full strength when nothing is selected (AC5)', () => {
render(StammbaumTree, {
nodes: NODES,
edges: EDGES,
selectedId: null,
panZoom: { x: 0, y: 0, z: 1 },
showGutter: false,
onSelect: () => {}
});
expect(dimmedConnectorCount()).toBe(0);
});
it('dims exactly the connector feeding the collateral child at the render layer (AC5)', () => {
render(StammbaumTree, {
nodes: NODES,
edges: EDGES,
selectedId: 'vater',
panZoom: { x: 0, y: 0, z: 1 },
showGutter: false,
onSelect: () => {}
});
// Every connector among the bloodline + spouses stays full strength; only
// the vertical joining the active parent pair (Grossvater+Grossmutter) to
// the dimmed collateral child (Tante) renders at DIMMED_OPACITY. This proves
// the <g opacity> render wiring — not just the isConnectorActive predicate —
// and exercises the shared parent-pair per-child path.
expect(dimmedConnectorCount()).toBe(1);
});
});