diff --git a/packages/core/src/kiwi/node-change/export-node.ts b/packages/core/src/kiwi/node-change/export-node.ts index a00e7b992..3868da63b 100644 --- a/packages/core/src/kiwi/node-change/export-node.ts +++ b/packages/core/src/kiwi/node-change/export-node.ts @@ -23,7 +23,7 @@ interface SceneNodeToKiwiContext { mapToFigmaType: (type: SceneNode['type']) => string fillToKiwiPaint: (fill: SceneNode['fills'][number]) => Paint safeColor: (color: Color) => Color - computeExportTransform: (node: SceneNode, graph: SceneGraph) => Matrix + computeExportTransform: (node: SceneNode) => Matrix serializeCornerRadii: (node: SceneNode, nc: KiwiNodeChange) => void serializeTextProps: ( node: SceneNode, @@ -250,7 +250,7 @@ export function sceneNodeToKiwiWithContext( opacity: node.opacity, phase: 'CREATED', size: { x: node.width, y: node.height }, - transform: context.computeExportTransform(node, context.graph), + transform: context.computeExportTransform(node), strokeWeight: node.strokes[0]?.weight ?? DEFAULT_STROKE_WEIGHT, strokeAlign: node.strokes[0]?.align ?? 'INSIDE' } diff --git a/packages/core/src/kiwi/node-change/serialize.ts b/packages/core/src/kiwi/node-change/serialize.ts index 9d130593b..41da0e276 100644 --- a/packages/core/src/kiwi/node-change/serialize.ts +++ b/packages/core/src/kiwi/node-change/serialize.ts @@ -410,20 +410,11 @@ function serializeVariableBindings( if (entries.length > 0) nc.variableConsumptionMap = { entries } } -function computeExportTransform(node: SceneNode, graph: SceneGraph): Matrix { +function computeExportTransform(node: SceneNode): Matrix { const sx = node.flipX ? -1 : 1 const cos = Math.cos((node.rotation * Math.PI) / 180) const sin = Math.sin((node.rotation * Math.PI) / 180) - // Auto-layout children should have (0,0) transform — Figma computes - // their positions from the layout engine at render time. - const parent = node.parentId ? graph.getNode(node.parentId) : undefined - const isAutoLayoutChild = - parent && - parent.layoutMode !== 'NONE' && - parent.layoutMode !== 'GRID' && - node.layoutPositioning !== 'ABSOLUTE' - const m00 = cos * sx const m01 = -sin const m10 = sin * sx @@ -443,10 +434,10 @@ function computeExportTransform(node: SceneNode, graph: SceneGraph): Matrix { return { m00, m01, - m02: isAutoLayoutChild ? 0 : node.x - offsetX, + m02: node.x - offsetX, m10, m11, - m12: isAutoLayoutChild ? 0 : node.y - offsetY + m12: node.y - offsetY } } diff --git a/tests/engine/kiwi/serialize-fixes/auto-layout/transforms.test.ts b/tests/engine/kiwi/serialize-fixes/auto-layout/transforms.test.ts index e38b36c6e..2552405f5 100644 --- a/tests/engine/kiwi/serialize-fixes/auto-layout/transforms.test.ts +++ b/tests/engine/kiwi/serialize-fixes/auto-layout/transforms.test.ts @@ -7,7 +7,7 @@ import { expectDefined, getNodeOrThrow } from '#tests/helpers/assert' import { ROOT_GUID, pageId } from '../helpers' describe('Fix 1: auto-layout child transforms', () => { - test('auto-layout child gets zero transform regardless of its x/y', () => { + test('auto-layout child preserves its stored transform offsets', () => { const graph = new SceneGraph() const parent = graph.createNode('FRAME', pageId(graph), { name: 'AutoLayout', @@ -48,8 +48,8 @@ describe('Fix 1: auto-layout child transforms', () => { 'child node change' ) expect(childNc).toBeDefined() - expect(childNc.transform.m02).toBe(0) - expect(childNc.transform.m12).toBe(0) + expect(childNc.transform.m02).toBe(50) + expect(childNc.transform.m12).toBe(100) }) test('absolute-positioned child inside auto-layout keeps its real x/y', () => { @@ -130,7 +130,7 @@ describe('Fix 1: auto-layout child transforms', () => { expect(childNc.transform.m12).toBe(45) }) - test('horizontal auto-layout child also gets zero transform', () => { + test('horizontal auto-layout child also preserves its stored transform offsets', () => { const graph = new SceneGraph() const parent = graph.createNode('FRAME', pageId(graph), { name: 'HorizontalLayout', @@ -164,8 +164,8 @@ describe('Fix 1: auto-layout child transforms', () => { changes.find((nc) => nc.name === 'Item'), 'item node change' ) - expect(itemNc.transform.m02).toBe(0) - expect(itemNc.transform.m12).toBe(0) + expect(itemNc.transform.m02).toBe(200) + expect(itemNc.transform.m12).toBe(50) }) })