From 5dff0d42857fbe0f1de60de07b3188d7db300037 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Wed, 20 May 2026 22:57:13 +0300 Subject: [PATCH] fix(fig): keep variable maps inside instance payloads - Continue stripping top-level variable maps that crash Figma import - Preserve nested variable maps in symbol overrides, component assignments, and derived symbol data for better instance reconstruction --- .../src/kiwi/fig/node-change/export-node.ts | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/packages/core/src/kiwi/fig/node-change/export-node.ts b/packages/core/src/kiwi/fig/node-change/export-node.ts index 9679c49a6..a8c06a207 100644 --- a/packages/core/src/kiwi/fig/node-change/export-node.ts +++ b/packages/core/src/kiwi/fig/node-change/export-node.ts @@ -99,16 +99,16 @@ function parseGuidOrNull(value: string) { return /^\d+:\d+$/.test(value) ? stringToGuid(value) : null } -const FIGMA_PAYLOAD_FIELDS_UNSAFE_FOR_EXPORT = new Set([ - 'variableConsumptionMap', - 'parameterConsumptionMap', - 'colorVar', - 'opacityVar' -]) +const FIGMA_PAYLOAD_VARIABLE_MAP_FIELDS = new Set(['variableConsumptionMap', 'parameterConsumptionMap']) +const FIGMA_PAYLOAD_PAINT_VARIABLE_FIELDS = new Set(['colorVar', 'opacityVar']) -function materializeFigmaPayload(value: unknown, blobs: Uint8Array[]): unknown { +function materializeFigmaPayload( + value: unknown, + blobs: Uint8Array[], + options: { includeVariableMaps?: boolean } = {} +): unknown { if (value instanceof Uint8Array) return value - if (Array.isArray(value)) return value.map((item) => materializeFigmaPayload(item, blobs)) + if (Array.isArray(value)) return value.map((item) => materializeFigmaPayload(item, blobs, options)) if (!value || typeof value !== 'object') return value if ('__openPencilFigmaBlob' in value) { const blob = (value as { __openPencilFigmaBlob?: Uint8Array | Record }) @@ -121,8 +121,9 @@ function materializeFigmaPayload(value: unknown, blobs: Uint8Array[]): unknown { const materialized: Record = {} for (const [key, child] of Object.entries(value)) { - if (FIGMA_PAYLOAD_FIELDS_UNSAFE_FOR_EXPORT.has(key)) continue - materialized[key] = materializeFigmaPayload(child, blobs) + if (FIGMA_PAYLOAD_PAINT_VARIABLE_FIELDS.has(key)) continue + if (!options.includeVariableMaps && FIGMA_PAYLOAD_VARIABLE_MAP_FIELDS.has(key)) continue + materialized[key] = materializeFigmaPayload(child, blobs, options) } return materialized } @@ -177,7 +178,9 @@ function applyInstancePayload( if (symbolID) { const symbolData: Record = { symbolID } if (node.figmaSymbolOverrides.length > 0) { - symbolData.symbolOverrides = materializeFigmaPayload(node.figmaSymbolOverrides, context.blobs) + symbolData.symbolOverrides = materializeFigmaPayload(node.figmaSymbolOverrides, context.blobs, { + includeVariableMaps: true + }) } if (node.figmaUniformScaleFactor != null) { symbolData.uniformScaleFactor = node.figmaUniformScaleFactor @@ -187,11 +190,14 @@ function applyInstancePayload( if (node.figmaComponentPropAssignments.length > 0) { nc.componentPropAssignments = materializeFigmaPayload( node.figmaComponentPropAssignments, - context.blobs + context.blobs, + { includeVariableMaps: true } ) } if (node.figmaDerivedSymbolData.length > 0) { - nc.derivedSymbolData = materializeFigmaPayload(node.figmaDerivedSymbolData, context.blobs) + nc.derivedSymbolData = materializeFigmaPayload(node.figmaDerivedSymbolData, context.blobs, { + includeVariableMaps: true + }) } if (node.figmaDerivedSymbolDataLayoutVersion != null) { nc.derivedSymbolDataLayoutVersion = node.figmaDerivedSymbolDataLayoutVersion