All Projects → figma-tools → Figma Transformer

figma-tools / Figma Transformer

Licence: mit
A tiny utility library that makes the Figma API more human friendly.

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Figma Transformer

Lumen Api Starter
Lumen 8 基础上扩展出的API 启动项目,精心设计的目录结构,规范统一的响应数据格式,Repository 模式架构的最佳实践。
Stars: ✭ 197 (+629.63%)
Mutual labels:  api, transformer
Cjstoesm
A tool that can transform CommonJS to ESM
Stars: ✭ 109 (+303.7%)
Mutual labels:  api, transformer
Laravel5 Jsonapi
Laravel 5 JSON API Transformer Package
Stars: ✭ 313 (+1059.26%)
Mutual labels:  api, transformer
Symfony Jsonapi
JSON API Transformer Bundle for Symfony 2 and Symfony 3
Stars: ✭ 114 (+322.22%)
Mutual labels:  api, transformer
Laravel Responder
A Laravel Fractal package for building API responses, giving you the power of Fractal with Laravel's elegancy.
Stars: ✭ 673 (+2392.59%)
Mutual labels:  api, transformer
Random Cat
Modul to get random cat images
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Platform Documentation
Core Platform API Documentation & Tutorials
Stars: ✭ 25 (-7.41%)
Mutual labels:  api
Swaddle
Automagically create API clients/wrappers in JavaScript
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Forge Server Utils
Tools for accessing Autodesk Forge APIs from modern Node.js apps.
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Ghreleases
Interact with the GitHub releases API.
Stars: ✭ 26 (-3.7%)
Mutual labels:  api
Cell Detr
Official and maintained implementation of the paper Attention-Based Transformers for Instance Segmentation of Cells in Microstructures [BIBM 2020].
Stars: ✭ 26 (-3.7%)
Mutual labels:  transformer
Lor
a fast, minimalist web framework for lua based on OpenResty
Stars: ✭ 930 (+3344.44%)
Mutual labels:  api
Yet Another Rest Client
YARC (Yet Another REST Client) is an easy-to-use REST Client for Google Chrome.
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Django apistar
Django App to integrate API Star's routes and views into Django's ecossystem.
Stars: ✭ 25 (-7.41%)
Mutual labels:  api
Resolutejs
Finally get to retry during a Promise operation (works in modern browsers as well as nodejs), zero dependencies.
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Indian Courier Api
API to track parcel from various Indian Logistics Providers
Stars: ✭ 26 (-3.7%)
Mutual labels:  api
Geocoder
🌎 GoLang package that provides an easy way to use the Google Geocoding API
Stars: ✭ 23 (-14.81%)
Mutual labels:  api
Go Base
Go RESTful API Boilerplate with JWT Authentication backed by PostgreSQL
Stars: ✭ 928 (+3337.04%)
Mutual labels:  api
Offit
Simple but powerful API mocking library. Make mocks great again.
Stars: ✭ 25 (-7.41%)
Mutual labels:  api
Neanderthal
Fast Clojure Matrix Library
Stars: ✭ 927 (+3333.33%)
Mutual labels:  api


figma-transformer

A tiny utility library that makes the Figma API more human friendly.

npm version npm downloads gzip size modules MIT License PRs Welcome

How to use figma-transformer?

import { processFile } from "figma-transformer";

// Fetch the file you want using your favourite method
const originalFile = fetchFigmaFile();

const file = processFile(originalFile);

// ✨ You can now use `file` for whatever you need! ✨

// Let's get the styles for a component named "Test"
const testStyles = file.shortcuts.components.find(
    component => component.name === "Test"
).shortcuts.styles;

Why use figma-transformer?

The Figma API is great but sometimes it feels like it's built for machines, not humans. The more you use it, the more you'll end up wasting a lot of time to get to the information that you want.

These are the most common problems:

  • Code needs to change if file structure changes
  • Incomplete information about styles and components
  • No type safety

With figma-transformer you get the file structure that you wished the Figma API had.

How does figma-transformer solve these problems?

Break free from the file structure

The Figma API response is very strict in terms of the file structure. To get to a specific node you have to navigate through the entire tree of nodes and it's really easy for your code to break if there's a change in the design file that changes the initial hierarchy.

We break from that rigid structure by creating shortcuts that are grouped by node type, making it a lot easier to access the nodes that we want irrespective of their placement in the file.

{
    "children": [{...}, {...}],
    "shortcuts": {
        "CANVAS": [...],
        "INSTANCE": [...],
        "RECTANGLE": [...],
        "STYLE": [...],
        "TEXT": [...],
        "FRAME": [...],
        "COMPONENT": [...],
        "GROUP": [...]
    }
}

We can see that even though this node just has two direct children, it actually contains a lot more elements down the tree, which are surfaced in the shortcuts.

Each node of the document tree contains the shortcuts to all their respective child nodes, which reduces the amount of work needed to get to the information we need.

Missing information from nodes

From the API we can get the information about the styles and components that are present in the file, which is great, but it doesn't contain all the information so we need to parse the entire file to get the additional information that we usuallly need.

Let's look at how the Figma API describes the styles in a document:

styles: {
    "1:12": {
        key: "ea017aed6616af00f3c4d59e3d945c8c3e47adca",
        name: "Green",
        styleType: "FILL",
        description: "",
    },
    "1:11": {
        key: "e234400b962ffafce654af9b3220ce88857523ec",
        name: "Red",
        styleType: "FILL",
        description: "",
    },
    "97:6": {
        key: "cc806814e1b9b7d20ce0b6bed8adf52099899c01",
        name: "Body",
        styleType: "TEXT",
        description: "",
    },
},

and this is how it's represented after being processed (note the populated styles from the associated nodes)

[
    {
        id: "1:12",
        key: "ea017aed6616af00f3c4d59e3d945c8c3e47adca",
        name: "Green",
        styleType: "FILL",
        description: "",
        styles: [
            {
                blendMode: "NORMAL",
                type: "SOLID",
                color: {
                    r: 0.047774821519851685,
                    g: 0.9563318490982056,
                    b: 0.02923285961151123,
                    a: 1,
                },
            },
        ],
        type: "STYLE",
    },
    {
        id: "1:11",
        key: "e234400b962ffafce654af9b3220ce88857523ec",
        name: "Red",
        styleType: "FILL",
        description: "",
        styles: [
            {
                blendMode: "NORMAL",
                type: "SOLID",
                color: {
                    r: 0.8515284061431885,
                    g: 0.11155396699905396,
                    b: 0.11155396699905396,
                    a: 1,
                },
            },
        ],
        textStyles: {
            fontFamily: "Roboto",
            fontPostScriptName: null,
            fontWeight: 400,
            fontSize: 12,
            textAlignHorizontal: "LEFT",
            textAlignVertical: "TOP",
            letterSpacing: 0,
            lineHeightPx: 14.0625,
            lineHeightPercent: 100,
            lineHeightUnit: "INTRINSIC_%",
        },
        type: "STYLE",
    },
    {
        id: "97:6",
        key: "cc806814e1b9b7d20ce0b6bed8adf52099899c01",
        name: "Body",
        styleType: "TEXT",
        description: "",
        textStyles: {
            fontFamily: "Roboto",
            fontPostScriptName: null,
            fontWeight: 400,
            fontSize: 12,
            textAlignHorizontal: "LEFT",
            textAlignVertical: "TOP",
            letterSpacing: 0,
            lineHeightPx: 14.0625,
            lineHeightPercent: 100,
            lineHeightUnit: "INTRINSIC_%",
        },
        type: "STYLE",
    },
];

The same happens with the components, this is what we get from the API:

components: {
    "1:5": { key: "", name: "Rectangle", description: "" },
},

and this is the processed data:

{
    "id": "1:5",
    "parentId": "7:0",
    "fileId": "cLp23bR627jcuNSoBGkhL04E",
    "name": "Rectangle",
    "type": "COMPONENT",
    "blendMode": "PASS_THROUGH",
    "absoluteBoundingBox": {
        "x": -232,
        "y": -208,
        "width": 201,
        "height": 109
    },
    "constraints": {
        "vertical": "TOP",
        "horizontal": "LEFT"
    },
    "clipsContent": false,
    "background": [
        {
            "blendMode": "NORMAL",
            "visible": false,
            "type": "SOLID",
            "color": {
                "r": 1,
                "g": 1,
                "b": 1,
                "a": 1
            }
        }
    ],
    "backgroundColor": {
        "r": 0,
        "g": 0,
        "b": 0,
        "a": 0
    },
    "effects": [],
    "children": [...],
    "shortcuts": {...}
}

Not only we have the complete node definition but we also have its child nodes and shortcuts so we can easily navigate through the component tree if needed.

Improved type safety

The Figma API doesn't have official type definitions, but fortunately we can provide a better developer experience by extending the TypeScript type definitions provided by the awesome figma-js library.

This means that you can continue to use your preferred way of fetching the data from the Figma API and figma-transformer will provide the types for you.

Examples

Let's see more specific examples where the benefits of the library really stand out.

Getting all text used in a document

const text = file.shortcuts.texts.map(node => node.characters);

Finding the styles applied to a specific component

const styles = file.shortcuts.components
    .filter(component => component.name === "Test")
    .map(component => component.shortcuts.styles);

Getting the fill colours for all the rectangles in the first page

const fills = file.shortcuts.pages
    .filter(page => page.name === "Page 1")
    .map(page => page.shortcuts.rectangles.fills);

Projects using figma-transformer


Local Development

Below is a list of commands you will probably find useful.

npm start or yarn start

Runs the project in development/watch mode. Your project will be rebuilt upon changes. TSDX has a special logger for you convenience. Error messages are pretty printed and formatted for compatibility VS Code's Problems tab.

Your library will be rebuilt if you make edits.

npm run build or yarn build

Bundles the package to the dist folder. The package is optimized and bundled with Rollup into multiple formats (CommonJS, UMD, and ES Module).

npm test or yarn test

Runs the test watcher (Jest) in an interactive mode. By default, runs tests related to files changed since the last commit.

This project was bootstrapped with TSDX.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].