From 01353e7ca7645365ff0cd45aca078317842e9e65 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Mon, 31 Aug 2026 23:52:01 +0300 Subject: [PATCH] fix(scene-graph): preserve text instance overrides --- packages/core/src/figma-api/proxy.ts | 6 +++++- .../api/create/instance-fill-override.test.ts | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/core/src/figma-api/proxy.ts b/packages/core/src/figma-api/proxy.ts index 81b53f5da..97b031044 100644 --- a/packages/core/src/figma-api/proxy.ts +++ b/packages/core/src/figma-api/proxy.ts @@ -1,3 +1,4 @@ +import { recordInstanceOverride } from '@open-pencil/scene-graph' import type { SceneGraph, SceneNode, @@ -137,7 +138,10 @@ export class FigmaNodeProxy { private _update(changes: Partial): void { assertNodeEditable(this[INTERNAL_GRAPH], this[INTERNAL_ID]) - this[INTERNAL_GRAPH].updateNode(this[INTERNAL_ID], changes) + const graph = this[INTERNAL_GRAPH] + const id = this[INTERNAL_ID] + graph.updateNode(id, changes) + recordInstanceOverride(graph, id, Object.keys(changes)) } private _raw(): SceneNode { diff --git a/tests/engine/figma/api/create/instance-fill-override.test.ts b/tests/engine/figma/api/create/instance-fill-override.test.ts index 8d4e51422..aa24a70f3 100644 --- a/tests/engine/figma/api/create/instance-fill-override.test.ts +++ b/tests/engine/figma/api/create/instance-fill-override.test.ts @@ -20,6 +20,24 @@ describe('setting fills on an instance descendant', () => { expect(raw?.overrides[`${vector.id}:fills`]).toBe(true) }) + test('preserves text edits on an instance descendant during resync', () => { + const api = createAPI() + const component = api.createComponent() + const text = api.createText() + text.characters = 'Default' + component.appendChild(text) + + const instance = component.createInstance() + const instanceText = instance.children[0] + if (!instanceText) throw new Error('instance text not found') + instanceText.characters = 'Custom' + + expect(api.graph.getNode(instance.id)?.overrides[`${instanceText.id}:text`]).toBe(true) + text.characters = 'Updated default' + api.graph.syncInstances(component.id) + + expect(instanceText.characters).toBe('Custom') + }) test('does not record an override for a node with no instance ancestor', () => { const api = createAPI() const frame = api.createFrame()