figma-api-stub icon indicating copy to clipboard operation
figma-api-stub copied to clipboard

Improvements to external styles

Open blairwilcox opened this issue 3 years ago • 3 comments

It would be helpful if we had a better way to simulate the workflow for "importing external styles"

const externalStyle = await figma.importByKeyAsync(key);
node.fillStyleId = externalStyle.id

I think to do this, we'd need to support:

  1. styles to have a "key" property
  2. an implementation for figma.importantByKeyAsync, which uses that key to import a style
  3. Maybe some way of initializing the mock API with "external" libraries

Not sure what the best way of representing "external" libraries. Maybe there could be some internal field like _orig in nodes? something like:

const externalStyle1 = figma.createPaintStyle();
// setup externalStyle1 with keys, paints, etc...

const externalStyle2 = figma.createTextStyle();
// setup externalStyle2 with keys, fontFamilies, etc...

figma._externalStyles = [
  externalStyle1,
  externalStyle2
];

// definition for importByKeyAsync

figma.importByKeyAsync = async function(key: string) {
  const style = this._externalStyles.find(style => style.key === key);
  return style;
}

Another option might be to have some sort of configuration?

createFigma({
  externalStyles: {
    key1: { /* externalStyle1 info */ },
    key2: { /* externalStyle2 info */ }
  }
});

this might be difficult though, since the creation functions wouldn't have been initialized yet

blairwilcox avatar Apr 04 '22 19:04 blairwilcox

I could try to make a PR for this when I get a chance, but I wanted to run it by you first to see if you had any thoughts on how something like this would be implemented 😅

blairwilcox avatar Apr 04 '22 20:04 blairwilcox

Coming back to this one after a while. I found a solution here that seems to work for me! It works by making a local mock for figma.importStyleByKeyAsync. Suppose you have some mock style data you'd like to be able to import, like this:

export const externalStyles = [
  {
    name: 'TestPaint',
    key: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
    type: 'PAINT',
  },
  {
    name: 'TestText',
    key: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
    type: 'TEXT',
  },
]

In a Jest Setup file, you could write something like this:

import {externalStyles} from "./__mocks__/external-styles"
import {createFigma} from 'figma-api-stub';

// create the API
const figma = createFigma({});

figma.importStyleByKeyAsync = async function(key: string) {
  const styleInfo = externalStyles.find(style => style.key === key)
  if (styleInfo) {
    switch(styleInfo.type) {
      case "PAINT": {
        const style = figma.createPaintStyle();
        style.name = styleInfo.name;
        style.key = styleInfo.key;
        return style;
      }
      case "TEXT": {
        const style = figma.createTextStyle();
        style.name = styleInfo.name;
        style.key = styleInfo.key;
        return style;
      }
      case "EFFECT": {
        const style = figma.createEffectStyle();
        style.name = styleInfo.name;
        style.key = styleInfo.key;
        return style;
      }
    }
  }
  throw Error('Style not found');
}

Then, in your tests, you can run:

const style = await figma.createStyleByKeyAsync("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")

Do you think something like this would be helpful to include in the README or any other documentation?

blairwilcox avatar Nov 18 '22 23:11 blairwilcox

Hey, @reccanti! If you are still willing to contribute it (it's been a long time!), You can do that here: cva-plugin#4

I intend to continue the work of this repo in that new one and get it to cover 100% of Figma's plugin API

svallory avatar Aug 19 '23 03:08 svallory