diff --git a/src/extractors/built-in.ts b/src/extractors/built-in.ts index 5173c5d6..2987f220 100644 --- a/src/extractors/built-in.ts +++ b/src/extractors/built-in.ts @@ -239,7 +239,8 @@ export function collapseSvgContainers( if ( (node.type === "FRAME" || node.type === "GROUP" || node.type === "INSTANCE") && - allChildrenAreSvgEligible + allChildrenAreSvgEligible && + !hasImageFillInChildren(node) ) { // Collapse to IMAGE-SVG and omit children result.type = "IMAGE-SVG"; @@ -249,3 +250,22 @@ export function collapseSvgContainers( // Include all children normally return children; } + +/** + * Check whether a node or its direct children have image fills. + * + * Only direct children need checking because afterChildren runs bottom-up: + * if a deeper descendant has image fills, its parent won't collapse (stays FRAME), + * and FRAME isn't SVG-eligible, so the chain breaks naturally at each level. + */ +function hasImageFillInChildren(node: FigmaDocumentNode): boolean { + if (hasValue("fills", node) && node.fills.some((fill) => fill.type === "IMAGE")) { + return true; + } + if (hasValue("children", node)) { + return node.children.some( + (child) => hasValue("fills", child) && child.fills.some((fill) => fill.type === "IMAGE"), + ); + } + return false; +} diff --git a/src/utils/image-processing.ts b/src/utils/image-processing.ts index 05784543..8581136c 100644 --- a/src/utils/image-processing.ts +++ b/src/utils/image-processing.ts @@ -105,6 +105,18 @@ export async function downloadAndProcessImage( const originalPath = await downloadFigmaImage(fileName, localPath, imageUrl); Logger.log(`Downloaded original image: ${originalPath}`); + // SVGs are vector — jimp can't read them and cropping/dimensions don't apply + const isSvg = fileName.toLowerCase().endsWith(".svg"); + if (isSvg) { + return { + filePath: originalPath, + originalDimensions: { width: 0, height: 0 }, + finalDimensions: { width: 0, height: 0 }, + wasCropped: false, + processingLog, + }; + } + // Get original dimensions before any processing const originalDimensions = await getImageDimensions(originalPath); Logger.log(`Original dimensions: ${originalDimensions.width}x${originalDimensions.height}`);