fix(fig): propagate derived text glyphs

This commit is contained in:
Danila Poyarkov 2026-05-18 02:35:33 +03:00
parent 773b1539d2
commit 1de4f65767
2 changed files with 49 additions and 12 deletions

View file

@ -3,6 +3,32 @@ import type { OverrideContext } from '#core/kiwi/instance-overrides/types'
import type { SceneNode } from '#core/scene-graph'
import { copyGeometryPaths } from '#core/scene-graph/copy'
function buildCloneUpdates(
ctx: OverrideContext,
source: SceneNode,
clone: SceneNode,
cloneId: string,
sizeSet: Set<string>
): Partial<SceneNode> {
const updates: Partial<SceneNode> = {}
if (sizeSet.has(cloneId)) return updates
if (source.width !== clone.width) updates.width = source.width
if (source.height !== clone.height) updates.height = source.height
if (source.x !== clone.x) updates.x = source.x
if (source.y !== clone.y) updates.y = source.y
if (!ctx.geometryOverrideNodes.has(cloneId)) {
if (source.fillGeometry !== clone.fillGeometry) updates.fillGeometry = copyGeometryPaths(source.fillGeometry)
if (source.strokeGeometry !== clone.strokeGeometry) updates.strokeGeometry = copyGeometryPaths(source.strokeGeometry)
}
if (source.text === clone.text && source.figmaDerivedTextGlyphs) {
updates.figmaDerivedTextGlyphs = structuredClone(source.figmaDerivedTextGlyphs)
}
if (source.text === clone.text && source.figmaDerivedLayout) {
updates.figmaDerivedLayout = { ...source.figmaDerivedLayout }
}
return updates
}
export function propagateDsdChanges(
ctx: OverrideContext,
modified: Set<string>,
@ -27,18 +53,8 @@ export function propagateDsdChanges(
visited.add(cloneId)
const clone = ctx.graph.getNode(cloneId)
if (!clone) continue
if (!sizeSet.has(cloneId)) {
const cu: Partial<SceneNode> = {}
if (source.width !== clone.width) cu.width = source.width
if (source.height !== clone.height) cu.height = source.height
if (source.x !== clone.x) cu.x = source.x
if (source.y !== clone.y) cu.y = source.y
if (!ctx.geometryOverrideNodes.has(cloneId)) {
if (source.fillGeometry !== clone.fillGeometry) cu.fillGeometry = copyGeometryPaths(source.fillGeometry)
if (source.strokeGeometry !== clone.strokeGeometry) cu.strokeGeometry = copyGeometryPaths(source.strokeGeometry)
}
if (Object.keys(cu).length > 0) ctx.graph.updateNode(cloneId, cu)
}
const updates = buildCloneUpdates(ctx, source, clone, cloneId, sizeSet)
if (Object.keys(updates).length > 0) ctx.graph.updateNode(cloneId, updates)
queue.push(cloneId)
}
}

View file

@ -1,6 +1,7 @@
import { describe, expect, test } from 'bun:test'
import { buildDsdLayoutUpdates } from '#core/kiwi/instance-overrides/derived-symbol-data/layout'
import { propagateDsdChanges } from '#core/kiwi/instance-overrides/derived-symbol-data/propagate'
import type { OverrideContext } from '#core/kiwi/instance-overrides'
import { SceneGraph } from '#core/scene-graph'
@ -9,6 +10,26 @@ function pageId(graph: SceneGraph): string {
}
describe('fig import derived symbol data', () => {
test('propagates derived glyphs through clone chains', () => {
const graph = new SceneGraph()
const source = graph.createNode('TEXT', pageId(graph), {
text: 'Account',
figmaDerivedTextGlyphs: [{ commandsBlob: new Uint8Array([0]), x: 0, y: 10, fontSize: 14 }],
figmaDerivedLayout: { width: 56, height: 20 }
})
const clone = graph.createNode('TEXT', pageId(graph), { text: 'Account', componentId: source.id })
const ctx = {
graph,
activeNodeIds: new Set([source.id, clone.id]),
geometryOverrideNodes: new Set()
} as OverrideContext
propagateDsdChanges(ctx, new Set([source.id]), new Set())
expect(clone.figmaDerivedTextGlyphs).toEqual(source.figmaDerivedTextGlyphs)
expect(clone.figmaDerivedLayout).toEqual(source.figmaDerivedLayout)
})
test('routes derived text glyphs through layout patch updates', () => {
const graph = new SceneGraph()
const target = graph.createNode('TEXT', pageId(graph), { text: 'Menu Item' })