refactor(stammbaum): carry child id on the connector centre object (#703)

The shared parent-pair child loop read group.childIds[i] while iterating
the filtered childCenters, so a child without a position would desync the
id from the centre — and that index now also drives the active-connector
lookup. Ride the id on the mapped {id,x,y} centre so the two never drift;
a positionless child drops out of both together.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-31 19:17:34 +02:00
parent da3067150d
commit 7cc2ddc6ad

View File

@@ -106,8 +106,11 @@ const parentLinks = $derived.by<ParentLinks>(() => {
{@const aCenter = nodeCenter(group.parentA)}
{@const bCenter = nodeCenter(group.parentB)}
{@const childCenters = group.childIds
.map((id) => nodeCenter(id))
.filter((c): c is { x: number; y: number } => c !== null)}
.map((id) => {
const c = nodeCenter(id);
return c ? { id, x: c.x, y: c.y } : null;
})
.filter((c): c is { id: string; x: number; y: number } => c !== null)}
{#if aCenter && bCenter && childCenters.length > 0}
{@const midX = (aCenter.x + bCenter.x) / 2}
{@const parentBottomY = aCenter.y + NODE_H / 2}
@@ -138,13 +141,14 @@ const parentLinks = $derived.by<ParentLinks>(() => {
/>
{/if}
</g>
{#each childCenters as cc, i (group.childIds[i])}
{#each childCenters as cc (cc.id)}
<!-- Each vertical joins the parent pair to one child: active only when
both parents and that child are active, so the same bar can stay lit
to the lineage child while dimming to a collateral sibling. -->
to the lineage child while dimming to a collateral sibling. The child
id rides on the centre object, so it never desyncs from the filtered
centres (a child without a position drops out of both together). -->
{@const childActive =
isConnectorActive(group.parentA, group.childIds[i]) &&
isConnectorActive(group.parentB, group.childIds[i])}
isConnectorActive(group.parentA, cc.id) && isConnectorActive(group.parentB, cc.id)}
<g class="lineage-fade" opacity={connectorOpacity(childActive)}>
<line
x1={cc.x}