fix(fig): preserve imported instance layout sync
This commit is contained in:
parent
6d8920a496
commit
9e2cd356e5
|
|
@ -38,11 +38,7 @@ export function syncChildrenDeep(
|
|||
const tgtNode = graph.getNode(tgt.childIds[i])
|
||||
if (!srcNode || !tgtNode || srcNode.type !== tgtNode.type) continue
|
||||
|
||||
if (
|
||||
srcNode.type === 'INSTANCE' &&
|
||||
swappedInstances.has(src.childIds[i]) &&
|
||||
srcNode.componentId !== tgtNode.componentId
|
||||
) {
|
||||
if (srcNode.type === 'INSTANCE' && srcNode.componentId !== tgtNode.componentId) {
|
||||
recloneChildren(graph, src.childIds[i], tgtNode, swappedInstances, protections)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ function applyFrameSize(graph: SceneGraph, frame: SceneNode, yogaNode: YogaNode)
|
|||
}
|
||||
|
||||
function updateChildFromYoga(graph: SceneGraph, child: SceneNode, yogaChild: YogaNode): void {
|
||||
if (!child.visible || child.layoutPositioning === 'ABSOLUTE' || child.type === 'INSTANCE') return
|
||||
if (!child.visible || child.layoutPositioning === 'ABSOLUTE') return
|
||||
|
||||
const derived = child.figmaDerivedLayout
|
||||
graph.updateNode(child.id, {
|
||||
x: derived?.x ?? yogaChild.getComputedLeft(),
|
||||
y: derived?.y ?? yogaChild.getComputedTop(),
|
||||
x: child.type === 'INSTANCE' ? yogaChild.getComputedLeft() : (derived?.x ?? yogaChild.getComputedLeft()),
|
||||
y: child.type === 'INSTANCE' ? yogaChild.getComputedTop() : (derived?.y ?? yogaChild.getComputedTop()),
|
||||
width: derived?.width ?? yogaChild.getComputedWidth(),
|
||||
height: derived?.height ?? yogaChild.getComputedHeight()
|
||||
})
|
||||
|
|
|
|||
34
tests/engine/kiwi/instance-overrides/sync-clones.test.ts
Normal file
34
tests/engine/kiwi/instance-overrides/sync-clones.test.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { SceneGraph } from '@open-pencil/core'
|
||||
|
||||
import { syncChildrenDeep } from '#core/kiwi/instance-overrides/sync/clones'
|
||||
|
||||
describe('instance override clone sync', () => {
|
||||
test('reclones nested instance children when the source component changes', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = graph.getPages()[0]
|
||||
const sourceParent = graph.createNode('FRAME', page.id)
|
||||
const targetParent = graph.createNode('FRAME', page.id)
|
||||
const sourceComponent = graph.createNode('COMPONENT', page.id, { name: 'source component' })
|
||||
const targetComponent = graph.createNode('COMPONENT', page.id, { name: 'target component' })
|
||||
graph.createNode('TEXT', sourceComponent.id, { name: 'label', text: 'Source' })
|
||||
graph.createNode('TEXT', targetComponent.id, { name: 'label', text: 'Target' })
|
||||
const sourceChild = graph.createNode('INSTANCE', sourceParent.id, {
|
||||
name: 'nested',
|
||||
componentId: sourceComponent.id
|
||||
})
|
||||
graph.populateInstanceChildren(sourceChild.id, sourceComponent.id)
|
||||
const targetChild = graph.createNode('INSTANCE', targetParent.id, {
|
||||
name: 'nested',
|
||||
componentId: targetComponent.id
|
||||
})
|
||||
graph.populateInstanceChildren(targetChild.id, targetComponent.id)
|
||||
|
||||
syncChildrenDeep(graph, sourceParent.id, targetParent.id, new Set())
|
||||
|
||||
const syncedChild = graph.getNode(targetChild.id)
|
||||
expect(syncedChild?.componentId).toBe(sourceComponent.id)
|
||||
expect(graph.getChildren(targetChild.id).map((child) => child.text)).toEqual(['Source'])
|
||||
})
|
||||
})
|
||||
|
|
@ -103,4 +103,29 @@ describe('imported auto-layout bounds', () => {
|
|||
|
||||
expect(graph.getNode(field.id)).toMatchObject({ x: 0, y: 0, width: 276, height: 40 })
|
||||
})
|
||||
|
||||
test('uses Yoga positions for imported instances while preserving imported size', () => {
|
||||
const graph = new SceneGraph()
|
||||
const page = graph.getPages()[0]
|
||||
const row = graph.createNode('FRAME', page.id, {
|
||||
width: 200,
|
||||
height: 40,
|
||||
layoutMode: 'HORIZONTAL',
|
||||
primaryAxisSizing: 'FIXED',
|
||||
counterAxisSizing: 'FIXED',
|
||||
primaryAxisAlign: 'MAX',
|
||||
counterAxisAlign: 'CENTER'
|
||||
})
|
||||
const instance = graph.createNode('INSTANCE', row.id, {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 40,
|
||||
height: 20,
|
||||
figmaDerivedLayout: { x: 0, y: 0, width: 40, height: 20 }
|
||||
})
|
||||
|
||||
computeAllLayouts(graph)
|
||||
|
||||
expect(graph.getNode(instance.id)).toMatchObject({ x: 160, y: 10, width: 40, height: 20 })
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue