Skip to content

Instantly share code, notes, and snippets.

@fillmember
Last active July 19, 2024 08:57
Show Gist options
  • Save fillmember/f0c60121ed423b6fd1e49060f0265f32 to your computer and use it in GitHub Desktop.
Save fillmember/f0c60121ed423b6fd1e49060f0265f32 to your computer and use it in GitHub Desktop.
Useful Figma scripts

Useful Figma Scripts

These are some scripts that can help automate operations within Figma.

image

To use them, focus Figma and open up the Developer Tools panel by using the shortcut key Command + Option + I. Switch to Console tab and click on the last line of the white text area to input text. You are now ready to copy-paste scripts into Figma.

Disclaimer: Not liable for data loss or misoperations. Use at your own risk.

Select all components on a page

This script contains a second condition to not select things with name icon-template

I use this to quickly select all my icons and export them.

Copy the following script into the console and press enter:

figma.currentPage.selection = figma.currentPage.findAll( n => n.type === "COMPONENT" && n.name !== "icon-template" )

Create variables from color styles

This script takes Color Styles (a.k.a. Paint Styles) with a certain name and transform them into Figma variables.

Copy the following script into the console and press enter:

(function () {
  /**
   * Get a reference of the destination collection where we want to store our new variables. 
   * Also get a reference to its first mode. 
   */
  const collection = figma.variables
    .getLocalVariableCollections()
    .filter((collection) => collection.name === "Primitives")[0];
  const mode = collection.modes[0];
  /**
   * 1. Get local paint styles (the internal name for Color Styles)
   * 2. Filter them to get only the ones with `Basic` in their name. 
   * 3. For each of them, build a name that is for our new variable,
   *    get a reference of the first color in the paint style. 
   *    (A paint style can contain multiple colors, but I am only using one. )
   * 4. create a COLOR-type variable with the above name, tell it which collection should contain it,
   *    transfer the description from the paint style to the variable. 
   * 5. Finally, set the value (color) of the variable,
   *    for this operation, we need the modeId from the mode of the collection,
   *    we got this on line 32.  
   */
  figma
    .getLocalPaintStyles()
    .filter((style) => style.name.indexOf("Basic") > -1)
    .forEach((style) => {
      const name = style.name.replace("Basic/", "").replace("*", "");
      const color = style.paints[0].color;
      const variable = figma.variables.createVariable(
        name,
        collection.id,
        "COLOR"
      );
      variable.description = style.description;
      variable.setValueForMode(mode.modeId, color);
    });
})();

Notes:

image

Figma consider the folder name part of the name of a variable or a paint style. So the names of the above styles are something like Basic/red/50, Basic/red/100, Basic/red/200.

Shuffle the folders of variables

This is useful when you originally organise your tokens in one format but later changes your mind. For example, you want to move away from this:

Input/Border/Active

to this:

Input/Active/Border

This script does exactly the above, copy the following script into the console and press enter:

(function () {

  // get a reference of the targeted collection
  const collection = figma.variables
    .getLocalVariableCollections()
    .filter((collection) => collection.name === "Color Tokens")[0];
  
  // get a reference of all the variables inside that collection. 
  const variables = collection.variableIds.map((id) =>
    figma.variables.getVariableById(id)
  );
  
  // for each variable, split (delimitor `/`) and re-join the components in a different order. 
  variables.forEach((v) => {
    const [yee, obj, state] = v.name.split("/");
    v.name = [yee, state, obj].join("/");
  });
})();

To customize this script, change the lines inside the variables.forEach function to meet your need.

Export Figma Variables as an object

Export Figma variables as an object that has the following structure.

{
  Collection: {
    Mode: {
      VariableName: VariableValue,
      MoreVariables: ...,
    }
  }
}

Collection: name of the collection, keyed by its name inside the object. Mode: name of the modes that the collection has, keyed by its name inside the collection object. VariableName: name of the variable (/ is part of the name), stores the value under that mode in that collection.

function exportVariables() {
  function sortByName(a, b) {
    return a.name.localeCompare(b.name);
  }
  function getVariableValueByMode(mode, variable) {
    for (var modeId in variable.valuesByMode) {
      if (mode.modeId === modeId) {
        return variable.valuesByMode[modeId];
      }
    }
  }
  //
  const variables = figma.variables.getLocalVariables();
  variables.sort(sortByName);
  const collections = figma.variables.getLocalVariableCollections();
  collections.sort(sortByName);
  //
  const result = {};
  collections.forEach((col) => {
    // each collection an object with name as its key
    result[col.name] = col.modes.reduce(
      (obj, mode) => ({
        ...obj,
        [mode.name]: variables.reduce((obj, variable) => {
          const value = getVariableValueByMode(mode, variable);
          if (value) {
            return { ...obj, [variable.name]: value };
          } else {
            return obj;
          }
        }, {}),
      }),
      {}
    );
  });
  return result;
}
JSON.stringify(exportVariables());

I use it to create the content of a JSON file which I will commit into my codebase separately.

Create Variables from Selected Frames

To use this script, select a frame like this: a frame named 'red|brand1' containing 11 squares filled with different shades of red

And then run the script in console to create variables for the color swatches within the frame.

This script apply the color in the specified mode (in the name of the frame)

(async () => {

    const firstSelected = figma.currentPage.selection[0];
    const [brandName, scaleName] = firstSelected.name.split("|");
    const swatches = figma.currentPage.selection[0].children;

    const localVariables = await figma.variables.getLocalVariablesAsync();
    const localCollections = await figma.variables.getLocalVariableCollectionsAsync();

    function ensureVariable(name, collection, type) {
        let existingVariable;
        existingVariable = localVariables.find((v) => v.name === name && v.resolvedType == type && v.variableCollectionId == collection.id)
        if (!existingVariable) {
            existingVariable = figma.variables.createVariable(name, collection, type)
        }
        return existingVariable
    }

    const collection = localCollections[1]

    if (!collection) {
        console.error("no collection found.")
        return
    }

    swatches.forEach(swatch => {
        const level = parseInt(swatch.name.replace(/\D/g, ""))
        const name = `${scaleName}/${level}`;
        const variable = ensureVariable(name, collection, "COLOR")
        if (variable) {
            console.log(swatch.fills[0].color)
            collection.modes.forEach(({ name, modeId }) => {
                if (name === brandName) {
                    variable.setValueForMode(modeId, swatch.fills[0].color)
                }
            })
        }
    })

})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment