diff --git a/README.md b/README.md index d5c4462..7ceb42b 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ figmaReact.runFigmaReact(options).catch(err => { - decorator // default 'observer' - classAfterFix // default 'Generated' - fileAfterFix // default '.generated' +- useBase64Images // default false - typeFactory // default ({ props: componentProps }) => `string` - prettierOptions // default ``` diff --git a/content.plugins.js b/content.plugins.js index e6dd782..caa555c 100644 --- a/content.plugins.js +++ b/content.plugins.js @@ -23,22 +23,12 @@ function applyStyles(state) { // TODO: use import from './${getComponentName(node.name, options)}' async function setComponentFromCache(state, shared) { const { node, content, classNames } = state; - const { - component, - imgMap, - pngImages, - componentMap, - componentDescriptionMap, - localComponentMap, - options, - additionalStyles, - genClassName - } = shared; + const { component, componentMap, localComponentMap, options, additionalStyles, genClassName } = shared; if (node.id !== component.id && node.name.charAt(0) === '#') { const name = getComponentName(node.name, options); emptyChildren(state); content.push(`<${name} {...props} nodeId='${node.id}' />`); - if (!componentMap[name]) await createComponent(node, imgMap, pngImages, componentMap, componentDescriptionMap, options); + if (!componentMap[name]) await createComponent(node, shared); localComponentMap[name] = componentMap[name]; const currentClass = genClassName(); diff --git a/index.js b/index.js index 98a7cda..496864e 100755 --- a/index.js +++ b/index.js @@ -43,7 +43,9 @@ async function runFigmaReact(options = {}) { componentDescriptionMap, vectorMap, vectorList, - options + options, + fileKey, + headers }; // Load the document from Figma @@ -61,7 +63,7 @@ async function runFigmaReact(options = {}) { // Load all images used in the document from Figma const imageJSON = await loadURLImages(vectorList, fileKey, headers); - const images = await loadImages(imageJSON, fileKey, headers); + const imgMap = await loadImages(imageJSON, fileKey, headers); const pngImages = await loadURLPNGImages(fileKey, headers); // Debug @@ -69,7 +71,15 @@ async function runFigmaReact(options = {}) { fs.writeFileSync('./temp.json', JSON.stringify(canvas, null, 4)); // Create components - await createComponents(canvas, images, pngImages, componentMap, componentDescriptionMap, options); + await createComponents(canvas, { + fileKey, + headers, + imgMap, + pngImages, + componentMap, + componentDescriptionMap, + options + }); // Generate components for (const key in componentMap) { diff --git a/lib.js b/lib.js index ab99de4..3fd7563 100644 --- a/lib.js +++ b/lib.js @@ -582,7 +582,8 @@ function getDescriptionStyles({ componentDescriptionMap, options }, node) { return description.substring(description.indexOf(delimiter) + delimiter.length).replace(/\\n/g, `\n`); } -async function createComponent(component, imgMap, pngImages, componentMap, componentDescriptionMap, options = {}) { +async function createComponent(component, parentShared) { + const { componentMap, options } = parentShared; const name = getComponentName(component.name, options); const fileName = getFileName(name); const instance = getComponentInstance(component, options); @@ -625,6 +626,7 @@ async function createComponent(component, imgMap, pngImages, componentMap, compo const path = `src/design-system/${fileName}.tsx`; const shared = { + ...parentShared, name, fileName, path, @@ -636,14 +638,9 @@ async function createComponent(component, imgMap, pngImages, componentMap, compo genClassName, printStyle, additionalStyles, - imgMap, - pngImages, - componentMap, - componentDescriptionMap, localComponentMap, stylePlugins: options.stylePlugins, - contentPlugins: options.contentPlugins, - options + contentPlugins: options.contentPlugins }; print(`return (<>`); @@ -691,12 +688,12 @@ async function createComponent(component, imgMap, pngImages, componentMap, compo componentMap[name] = { instance, name, doc, fileName, localComponentMap }; } -async function createComponents(canvas, images, pngImages, componentMap, componentDescriptionMap, options = {}) { +async function createComponents(canvas, shared) { for (let i = 0; i < canvas.children.length; i++) { const child = canvas.children[i]; if (child.name.charAt(0) === '#' && child.visible !== false) { const child = canvas.children[i]; - await createComponent(child, images, pngImages, componentMap, componentDescriptionMap, options); + await createComponent(child, shared); } } } diff --git a/presets.js b/presets.js index 6b02c88..14b6a34 100644 --- a/presets.js +++ b/presets.js @@ -19,6 +19,7 @@ module.exports = { typeFactory: typeFactoryDefault, classAfterFix: 'Generated', fileAfterFix: '.generated', + useBase64Images: false, prettierOptions: { parser: 'typescript', semi: true, @@ -44,6 +45,7 @@ module.exports = { typeFactory: typeFactoryDefault, classAfterFix: 'Generated', fileAfterFix: '.generated', + useBase64Images: false, prettierOptions: { parser: 'typescript', semi: true, diff --git a/style.plugins.js b/style.plugins.js index bf87ff7..9a330b8 100644 --- a/style.plugins.js +++ b/style.plugins.js @@ -1,4 +1,5 @@ const requestImageSize = require('request-image-size'); +const fetch = require('node-fetch'); const { colorString, dropShadow, innerShadow, getPaint, paintToLinearGradient, paintToRadialGradient, applyFontStyle } = require('./lib'); const stylePlugins = [ @@ -198,8 +199,8 @@ function setHorizontalLayout({ node, middleStyle, innerStyle, parent, classNames } } -async function setFrameStyles(state, { pngImages }) { - const { node, middleStyle } = state; +async function setFrameStyles(state, { pngImages, headers, options }) { + const { node, middleStyle, props } = state; if (['FRAME', 'RECTANGLE', 'INSTANCE', 'COMPONENT'].indexOf(node.type) >= 0) { if (['FRAME', 'COMPONENT', 'INSTANCE'].indexOf(node.type) >= 0) { middleStyle.backgroundColor = colorString(node.backgroundColor); @@ -212,7 +213,14 @@ async function setFrameStyles(state, { pngImages }) { middleStyle.opacity = lastFill.opacity; } else if (lastFill.type === 'IMAGE') { const imageSize = await requestImageSize(pngImages[lastFill.imageRef]); - middleStyle.backgroundImage = `url(${pngImages[lastFill.imageRef]})`; + if (options.useBase64Images || Object.keys(props).includes('useBase64')) { + const imageRequest = await fetch(pngImages[lastFill.imageRef], { headers }); + const imageBuffer = await imageRequest.buffer(); + const imageDataURL = `data:${imageRequest.headers.get('content-type')};base64,${imageBuffer.toString('base64')}`; + middleStyle.backgroundImage = `url(${imageDataURL})`; + } else { + middleStyle.backgroundImage = `url(${pngImages[lastFill.imageRef]})`; + } middleStyle.backgroundPosition = 'center center'; middleStyle.backgroundRepeat = 'no-repeat'; if (lastFill.scaleMode === 'FILL') {