Sort auto-layout children by geometric position on import

Figma's parentIndex.position strings represent z-order, not visual
layout order. In auto-layout frames, children must be sorted by their
x (horizontal) or y (vertical) coordinate to match the visual order.
Fixes scrambled calendar dates and other auto-layout child ordering.
This commit is contained in:
Danila Poyarkov 2026-03-03 23:31:23 +03:00
parent 157c776c0c
commit 9044b1b183
2 changed files with 33 additions and 11 deletions

View file

@ -209,11 +209,22 @@ export function importClipboardNodes(
children.push(childId)
}
}
children.sort((a, b) => {
const aPos = guidMap.get(a)?.parentIndex?.position ?? ''
const bPos = guidMap.get(b)?.parentIndex?.position ?? ''
return aPos.localeCompare(bPos)
})
const parentNc = guidMap.get(figmaId)
const stackMode = (parentNc as unknown as Record<string, unknown>)?.stackMode as string | undefined
if (stackMode === 'HORIZONTAL' || stackMode === 'VERTICAL') {
const axis = stackMode === 'HORIZONTAL' ? 'm02' : 'm12'
children.sort((a, b) => {
const aT = guidMap.get(a)?.transform?.[axis] ?? 0
const bT = guidMap.get(b)?.transform?.[axis] ?? 0
return aT - bT
})
} else {
children.sort((a, b) => {
const aPos = guidMap.get(a)?.parentIndex?.position ?? ''
const bPos = guidMap.get(b)?.parentIndex?.position ?? ''
return aPos.localeCompare(bPos)
})
}
for (const childId of children) {
createNode(childId, node.id)
}

View file

@ -44,12 +44,23 @@ export function importNodeChanges(
}
}
for (const [, children] of childrenMap) {
children.sort((a, b) => {
const aPos = changeMap.get(a)?.parentIndex?.position ?? ''
const bPos = changeMap.get(b)?.parentIndex?.position ?? ''
return aPos.localeCompare(bPos)
})
for (const [parentId, children] of childrenMap) {
const parentNc = changeMap.get(parentId)
const stackMode = (parentNc as unknown as Record<string, unknown>)?.stackMode as string | undefined
if (stackMode === 'HORIZONTAL' || stackMode === 'VERTICAL') {
const axis = stackMode === 'HORIZONTAL' ? 'm02' : 'm12'
children.sort((a, b) => {
const aT = changeMap.get(a)?.transform?.[axis] ?? 0
const bT = changeMap.get(b)?.transform?.[axis] ?? 0
return aT - bT
})
} else {
children.sort((a, b) => {
const aPos = changeMap.get(a)?.parentIndex?.position ?? ''
const bPos = changeMap.get(b)?.parentIndex?.position ?? ''
return aPos.localeCompare(bPos)
})
}
}
function getChildren(ncId: string): string[] {