From 02b12224cca04d1597b759838597bbbfdd437c08 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Wed, 4 Mar 2026 23:48:52 +0300 Subject: [PATCH] Fix override resolution for sibling instances of the same component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit findNodeByComponentId used root-matching which returned the first child when multiple siblings shared the same component root. This caused all symbolOverride guidPaths targeting different siblings (e.g., 3 _stepper instances inside a Stepper component) to resolve to the first sibling. Fix: separate into 3 passes — exact componentId match first, then unambiguous root match (only when exactly one child shares the root), then deep recursion. --- packages/core/src/kiwi/instance-overrides.ts | 31 ++++++++++++++++---- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/packages/core/src/kiwi/instance-overrides.ts b/packages/core/src/kiwi/instance-overrides.ts index a70a2e89e..c4f94206c 100644 --- a/packages/core/src/kiwi/instance-overrides.ts +++ b/packages/core/src/kiwi/instance-overrides.ts @@ -143,15 +143,35 @@ export function populateAndApplyOverrides( } function findNodeByComponentId(parentId: string, componentId: string): string | null { - const targetRoot = preComputedRoot.get(componentId) ?? getComponentRoot(componentId) const parent = graph.getNode(parentId) if (!parent) return null + + // Pass 1: exact componentId match on direct children for (const childId of parent.childIds) { const child = graph.getNode(childId) - if (!child) continue - if (child.componentId === componentId) return childId - const childRoot = preComputedRoot.get(childId) ?? (child.componentId ? getComponentRoot(child.componentId) : null) - if (childRoot && childRoot === targetRoot) return childId + if (child?.componentId === componentId) return childId + } + + // Pass 2: root match — but only if exactly one child shares the root + // (multiple siblings with the same root are ambiguous) + const targetRoot = preComputedRoot.get(componentId) ?? getComponentRoot(componentId) + if (targetRoot) { + let rootMatch: string | null = null + let ambiguous = false + for (const childId of parent.childIds) { + const child = graph.getNode(childId) + if (!child?.componentId) continue + const childRoot = preComputedRoot.get(childId) ?? getComponentRoot(child.componentId) + if (childRoot === targetRoot) { + if (rootMatch) { ambiguous = true; break } + rootMatch = childId + } + } + if (rootMatch && !ambiguous) return rootMatch + } + + // Pass 3: recurse into children + for (const childId of parent.childIds) { const deep = findNodeByComponentId(childId, componentId) if (deep) return deep } @@ -474,6 +494,7 @@ export function populateAndApplyOverrides( if (!guids?.length) continue const targetId = resolveOverrideTarget(nodeId, guids) + if (!targetId) continue overriddenNodes.add(targetId)