diff --git a/CHANGELOG.md b/CHANGELOG.md index da0fcc62b..b642629e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- Keep imported Figma instances linked to their remapped source components so later component edits update existing instances. (#385) - Restore native copy, cut, and paste shortcuts in desktop text inputs while preserving design clipboard handling on the canvas. - Complete translated app, accessibility, font, color, collaboration, import, connection-test, and browser fallback text across all supported locales, and keep the document language synchronized with the selected locale. diff --git a/packages/core/src/kiwi/fig/import.ts b/packages/core/src/kiwi/fig/import.ts index d510f20c9..8e6780def 100644 --- a/packages/core/src/kiwi/fig/import.ts +++ b/packages/core/src/kiwi/fig/import.ts @@ -358,11 +358,13 @@ function importVariableBindings( } function remapComponentIds(graph: SceneGraph, guidToNodeId: Map): void { - for (const node of graph.getAllNodes()) { - if (node.type !== 'INSTANCE' || !node.componentId) continue - const remapped = guidToNodeId.get(node.componentId) - if (remapped) node.componentId = remapped - } + graph.preserveSourceMetadataDuring(() => { + for (const node of graph.getAllNodes()) { + if (node.type !== 'INSTANCE' || !node.componentId) continue + const remapped = guidToNodeId.get(node.componentId) + if (remapped) graph.updateNode(node.id, { componentId: remapped }) + } + }) } function applyVariantPropSpecs(graph: SceneGraph): void { diff --git a/tests/engine/io/fig/import/component-props.test.ts b/tests/engine/io/fig/import/component-props.test.ts index 21c5a8a83..7069132e3 100644 --- a/tests/engine/io/fig/import/component-props.test.ts +++ b/tests/engine/io/fig/import/component-props.test.ts @@ -97,6 +97,9 @@ describe('Figma component property import', () => { (node) => node.name === 'Menu item instance' ) expect(instance?.componentPropertyAssignments).toEqual({ '3:1': 'Profile Item' }) + if (!component || !instance) throw new Error('Expected imported component and instance') + expect(graph.getInstances(component.id).map((node) => node.id)).toContain(instance.id) + expect(graph.instanceIndex.get('1:1')?.has(instance.id)).toBeFalsy() const unpopulated = importNodeChanges(nodeChanges, [], undefined, { populate: 'none' }) const unpopulatedInstance = Array.from(unpopulated.getAllNodes()).find(