Skip to content

Figma Reader Options

files

The IDs of files you want to read from.

parser

parser.considerMode()

Variables support different modes. Some are relevant for your design system, others you can completely ignore for synching tokens. As theemo cannot predict which ones you want to consider for exporting tokens, you can declare such.

INFO

It only applies to collections with more then one mode.

For considering your light and dark modes, here is how:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        parser: {
          considerMode: (mode: string) => {
            return ['light', 'dark'].includes(mode);
          },
        }
      })
    }
  }
});

parser.formats

  • Type: ColorConfig
  • Default: { color: ColorFormat.Hex, colorAlpha: ColorAlphaFormat.Rgb }

Color format options

parser.getConstraints()

As your modes can take arbitrary names, such as:

  • light, dark
  • light-more, light-less, dark-more, dark-less
  • sunrise, day, sunset, night

For theemo it is impossible to guess the appropriate constraints. As such, you need to provide and explain the behavior of your system. The example above for considerMode(), qualifies light and dark as appropriate modes, let's continue assigning their constraints:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        parser: {
          getConstraints(mode: string/*, variable: FigmaVariable*/) {
            if (mode === 'light' || mode === 'dark') {
              return { features: { 'color-scheme': mode } };
            }
          }
        }
      })
    }
  }
});

parser.getNameFromStyle()

To actually get the name of a style. By default, it will pass through the name of the token as in Figma, replacing / with ..

For customizations, such as prefixing text styles with typography/, see here:

theemo.config.js
ts
import { figmaReader, getNameFromStyle } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';
import type { Style } from 'figma-api';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        parser: {
          getNameFromStyle(style: Style) {
            if (style.styleType === 'TEXT') {
              return getNameFromStyle({
                ...style,
                name: `typography/${style.name}`
              });
            }

            return getNameFromStyle(style);
          },
        }
      })
    }
  }
});

parser.getNameFromText()

Next up is to actually get the name from the node we let pass earlier. Here we drop the [token] tag to get the clean token name:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';
import type { Node } from 'figma-api';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          getNameFromText(node: Node<'TEXT'>) {
            return node.name.replace('[token]', '').trim();
          }
        }
      })
    }
  }
});

parser.getNameFromVariable()

Even though Figma shows hierarchy for your styles and variables, internally those are separated with a / character, hence Figma disallows the usage of . as part of the variable name, to align with DTCG Format as the . is used as group separator. The default implementation takes care of this transformation. You may use this functions to apply name transformations, according to your token specification.

theemo.config.js
ts
import { figmaReader, getNameFromVariable } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          getNameFromVariable: (variable: FigmaVariable) => {
            // implement your custom logic here
            if (variable.name.includes('primary')) {
              return variable.name.replace('primary', 'ARE-YOU-SURE-WHAT-THAT-MEANS?');
            }

            // ... or else use default behavior
            return getNameFromVariable(variable);
          };
        }
      })
    }
  }
});

parser.getPropertiesForToken()

You might find yourself in the need to add additional properties to the token that is parsed from Figma. For example, you might want to include the Figma name of the related style to be able to show them both on the generated token documentation. Here is how:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          getPropertiesForToken: (token: FigmaToken/*, document?: FigmaDocument*/) => {
            if (token.figmaName) {
              return {
                figmaName: token.figmaName
              };
            }
          };
        }
      })
    }
  }
});

You'll also receive the Figma document as second parameter. With that you can perform your own lookups with the Figma document. Please refer to their REST API documention.

parser.getValueFromText()

So far theemo is handling a node which it knows it is a token and what the name is. Finally we need to get the actual value from the node. Theemo provides a default implementation by returning the characters property from the node (= the contents), which should already do it. However, you are free to overwrite this behavior at this point.

parser.isTokenByStyle()

Each style found in the Figma file is passed into that function and being asked, whether this is a token or not.

The default implementation is, if the name of the token starts with a ., it will respond false. That is the default behavior of Figma, where you can't publish styles that begin with a . (as it is like a hidden folder on a unix system).

You can use this function to apply your own behavior. Here in this case, styles are ignored, when they contain braces:

theemo.config.js
ts
import { figmaReader, isTokenByStyle } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';
import type { Style } from 'figma-api';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        parser: {
          isTokenByStyle: (style: Style) => {
            return !style.name.includes('(') && !style.name.includes(')') && isTokenByStyle(style);
          }
        }
      })
    }
  }
});

parser.isTokenByText()

By default no tokens are recognized, so we need to teach theemo to understand text nodes who include the [token] tag:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';
import type { Node } from 'figma-api';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          isTokenByText(node: Node<'TEXT'>) {
            return node.name.includes('[token]');
          }
        }
      })
    }
  }
});

parser.isTokenByVariable()

Tokens can be hidden from publishing within Figma. However, accessing through the REST API is exposing all variables. The default behavior mimics Figma's behavior. You have the chance to add some additional logic, custom to your system on checking which variables shall result in tokens or not.

theemo.config.js
ts
import { figmaReader, isTokenByVariable } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          isTokenByVariable: (variable: FigmaVariable) => {
            // implement your custom logic here
            if (yourCustomLogic(variable)) {
              return false;
            }

            // ...or else use default behavior
            return isTokenByVariable(variable);
          };
        }
      })
    }
  }
});

parser.getTypeFromToken()

While handling the tokens from reading and parsing the source, theemo tries to detect the type of a token, based on the related Figma construct (ie. Node or Style). You can provide your own customization to this:

theemo.config.js
ts
import { figmaReader } from '@theemo/figma';
import { defineConfig } from '@theemo/cli';

export default defineConfig({
  sync: {
    reader: {
      sources: figmaReader({
        // ...
        parser: {
          getTypeFromToken: (token: FigmaToken) => {
            if (token.style) {
              return getTypefromStyle(token.style);
            }

            return '';
          };
        }
      })
    }
  }
});

parser.skipTypeForReferences

  • Type: boolean
  • Default: false

Skip type for tokens that are references.

According to the spec, $type can be optional when certain criteria are met. One of them being references. If you wish, you can skip types here.

plugins

Configure the plugins you want to use.

secrect

Your API key to connect to Figma.