Import missing layout/text properties from Figma clipboard

- layoutAlignSelf (stackChildAlignSelf → STRETCH/AUTO)
- clipsContent (from frameMaskDisabled, inverted)
- textAutoResize (NONE/HEIGHT/WIDTH_AND_HEIGHT/TRUNCATE)
- fontWeight (from fontName.style via styleToWeight when not explicit)
- italic (from fontName.style)
- lineHeight (PIXELS only, PERCENT deferred)
- letterSpacing
This commit is contained in:
Danila Poyarkov 2026-03-02 17:41:42 +03:00
parent f54871fae2
commit e1b5f1901e

View file

@ -6,6 +6,7 @@ import {
parseFigKiwiChunks,
decompressFigKiwiDataAsync
} from './kiwi-serialize'
import { styleToWeight } from './fonts'
import { initCodec, getCompiledSchema, getSchemaBytes } from './kiwi/codec'
import { decodeBinarySchema, compileSchema, ByteBuffer } from './kiwi/kiwi-schema'
import { decodeVectorNetworkBlob } from './vector'
@ -259,6 +260,16 @@ export function importClipboardNodes(
layoutPositioning:
(nc.stackPositioning as string) === 'ABSOLUTE' ? ('ABSOLUTE' as const) : ('AUTO' as const),
layoutGrow: (nc.stackChildPrimaryGrow as number) ?? 0,
layoutAlignSelf:
(nc.stackChildAlignSelf as string) === 'STRETCH'
? ('STRETCH' as const)
: ('AUTO' as const),
clipsContent: nc.frameMaskDisabled === false,
textAutoResize: mapTextAutoResize(nc.textAutoResize as string),
fontWeight: nc.fontWeight ?? styleToWeight(nc.fontName?.style ?? ''),
italic: nc.fontName?.style?.toLowerCase().includes('italic') ?? false,
lineHeight: mapLineHeight(nc.lineHeight as { value: number; units: string } | undefined),
letterSpacing: nc.letterSpacing ?? 0,
vectorNetwork: decodeVectorData(nc, blobs)
})
@ -315,6 +326,20 @@ function mapCounterAlign(align?: string): LayoutCounterAlign {
return 'MIN'
}
function mapTextAutoResize(resize?: string): 'NONE' | 'HEIGHT' | 'WIDTH_AND_HEIGHT' | 'TRUNCATE' {
if (resize === 'HEIGHT') return 'HEIGHT'
if (resize === 'WIDTH_AND_HEIGHT') return 'WIDTH_AND_HEIGHT'
if (resize === 'TRUNCATE') return 'TRUNCATE'
return 'NONE'
}
function mapLineHeight(lh?: { value: number; units: string }): number | undefined {
if (!lh) return undefined
if (lh.units === 'PIXELS') return lh.value
if (lh.units === 'PERCENT') return undefined
return undefined
}
function mapNodeType(type?: string): SceneNode['type'] {
switch (type) {
case 'FRAME':