diff --git a/packages/scene-graph/src/index.ts b/packages/scene-graph/src/index.ts index 8ddeee242..0b0015bb3 100644 --- a/packages/scene-graph/src/index.ts +++ b/packages/scene-graph/src/index.ts @@ -381,7 +381,15 @@ export class SceneGraph { const node = this.nodes.get(id) if (!node) return + let entries = Object.entries(changes) as Array<[string, unknown]> + changes = Object.fromEntries( + entries.filter(([, value]) => value !== undefined) + ) as Partial changes = styleDetachmentChanges(node, changes) + entries = Object.entries(changes) as Array<[string, unknown]> + changes = Object.fromEntries( + entries.filter(([, value]) => value !== undefined) + ) as Partial // Only clear absPosCache when layout-affecting properties change. // Fills, strokes, effects, plugin data changes do NOT affect absolute position. @@ -408,10 +416,6 @@ export class SceneGraph { const glyphChanged = Object.keys(changes).some((k) => GLYPH_AFFECTING_KEYS.has(k)) if (node.figmaDerivedTextGlyphs && glyphChanged) node.figmaDerivedTextGlyphs = null } - const entries = Object.entries(changes) as Array<[string, unknown]> - changes = Object.fromEntries( - entries.filter(([, value]) => value !== undefined) - ) as Partial if (this.sourceMetadataPreservationDepth === 0) { markSourceFieldsEdited(node, Object.keys(changes)) } diff --git a/packages/scene-graph/src/preview.ts b/packages/scene-graph/src/preview.ts index 9c68fc8a2..04d2d9c6d 100644 --- a/packages/scene-graph/src/preview.ts +++ b/packages/scene-graph/src/preview.ts @@ -50,6 +50,11 @@ export function updateNodePreview( ): Partial | null { const node = graph.nodes.get(id) if (!node) return null + changes = Object.fromEntries( + (Object.entries(changes) as Array<[string, unknown]>).filter( + ([, value]) => value !== undefined + ) + ) as Partial if ((Object.keys(changes) as (keyof SceneNode)[]).every((key) => node[key] === changes[key])) { return null } diff --git a/packages/scene-graph/src/text-picture.ts b/packages/scene-graph/src/text-picture.ts index 2e8f3f5a6..323ad81ba 100644 --- a/packages/scene-graph/src/text-picture.ts +++ b/packages/scene-graph/src/text-picture.ts @@ -24,6 +24,7 @@ export const GLYPH_AFFECTING_KEYS: ReadonlySet = new Set([ 'fontFamily', 'fontWeight', 'italic', + 'textDirection', 'lineHeight', 'letterSpacing', 'textCase', diff --git a/tests/engine/scene-graph/basic/text-picture-keys.test.ts b/tests/engine/scene-graph/basic/text-picture-keys.test.ts index f2cf4e47d..ed5a00816 100644 --- a/tests/engine/scene-graph/basic/text-picture-keys.test.ts +++ b/tests/engine/scene-graph/basic/text-picture-keys.test.ts @@ -35,6 +35,7 @@ describe('text rendering invalidation keys', () => { 'fontFamily', 'fontWeight', 'italic', + 'textDirection', 'lineHeight', 'letterSpacing', 'textCase', @@ -49,7 +50,6 @@ describe('text rendering invalidation keys', () => { 'height', 'fills', 'textAlignHorizontal', - 'textDirection', 'textAlignVertical', 'textDecoration' ]) { diff --git a/tests/engine/scene-graph/basic/update-node.test.ts b/tests/engine/scene-graph/basic/update-node.test.ts index 6fe537e91..624088cc4 100644 --- a/tests/engine/scene-graph/basic/update-node.test.ts +++ b/tests/engine/scene-graph/basic/update-node.test.ts @@ -200,7 +200,7 @@ describe('updateNode', () => { const textNode = expectDefined(graph.getNode(textId), 'text node') textNode.figmaDerivedTextGlyphs = glyphs - graph.updateNode(textId, { fontFamily: 'Noto Sans SC' }) + graph.updateNode(textId, { textDirection: 'RTL' }) expect(expectDefined(graph.getNode(textId), 'updated node').figmaDerivedTextGlyphs).toBeNull() }) @@ -211,7 +211,6 @@ describe('updateNode', () => { { height: 24 }, { fills: [] }, { textAlignHorizontal: 'CENTER' as const }, - { textDirection: 'RTL' as const }, { textAlignVertical: 'CENTER' as const }, { textDecoration: 'UNDERLINE' as const } ]