Figma Plugin API を用いた Local Variables Export/Import プラグインの開発

# はじめに

こんにちは。debiru です。

Figma をお使いの方は Local Variables を使っているでしょうか。

`Color` の `blue` トークンは `#0000FF` など、デザイントークンを変数として管理するための機能ですが、Figma には Local Variables を JSON として Export / Import する機能がありません。

そのような機能が欲しい場合、プラグインとして開発するなり、既存のプラグインを使う必要があります。既存のプラグインはいくつかありますが、挙動がよくわからず必要な設定項目を全て JSON として出力できるものが見当たらなかったのでプラグインを自作することにしました。

# 成果物

- プラグイン
    - https://www.figma.com/community/plugin/1395633889534142383/local-variables-manipulator
- ソースコード
    - https://github.com/debiru/LocalVariablesManipulator

# Figma プラグインの開発を始める

Figma アプリ内のメニューバー一番左にある Figma アイコンから、`Plugins`, `Development`, `New plugin` を選びます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/8764bfda-f82b-e685-87b1-282f2511b3a6.png)

Figma design を選んでプラグイン名を入力します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/06f0ae86-7451-7d1d-a61f-32ada5e2d551.png)

Custom UI を選んで Save as ボタンを押します。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/3e6c891e-0639-a0e3-b9ab-f508bf1eb507.png)

すると開発ファイル一式が手に入るので開発を始めます。`code.ts` を `code.js` にコンパイルするための手順は同梱されている README.md に書かれています。

# Local Variables の概念

Local Variables は Figma で管理できるデザイントークン全体のことです。

Local Variables は、次の要素から成り立ちます。

- Collection
- Modes
- Group
- Variable
    - variableName
    - description
    - valuesByMode
    - codeSyntax
    - scopes
    - hiddenFromPublishing

Local Variables を使っている方はそれぞれの項目や概念については理解できているかと思います。これらの概念を知りたければ、前述したソースコードの README.md を参照ください。

# Local Variables の Export / Import に必要な Figma Plugin API

## Collection

### Export: Collection

- https://www.figma.com/plugin-docs/api/figma-variables/#getlocalvariablecollectionsasync

```
const collections = await figma.variables.getLocalVariableCollectionsAsync();
```

Local Variables の全ての Collection が取得できます。

### Import: Collection

- https://www.figma.com/plugin-docs/api/figma-variables/#createvariablecollection

```
const newCollection = figma.variables.createVariableCollection(collectionName);
```

新しい Collection を作成できます。

## Modes

### Export: Modes

- https://www.figma.com/plugin-docs/api/VariableCollection/#modes

```
const modes = collection.modes;
// => [{ modeId: "522:0", name: "Light" }, { modeId: "522:1", name: "Dark" }]
```

Collection に設定されている Modes 一覧を取得できます。

### Import: Modes

- https://www.figma.com/plugin-docs/api/VariableCollection/#addmode
- https://www.figma.com/plugin-docs/api/VariableCollection/#renamemode
- https://www.figma.com/plugin-docs/api/VariableCollection/#removemode

```
// 新しい Mode を追加する
const newModeId = collection.addMode(modeName);

// Mode の名前を変更する
collection.renameMode(modeId, modeName);

// Mode を削除する
collection.removeMode(modeId);
```

Collection に設定したい ModeName の配列を受け取って、それを基に Collection の Modes を設定するようなコードを書くことができます。

## Group

Group はスラッシュ区切りの variableName によって表現される概念です。そのためこれ専用の getter や setter はありません。

## Variable

### Export: Variable

- https://www.figma.com/plugin-docs/api/VariableCollection/#variableids
- https://www.figma.com/plugin-docs/api/figma-variables/#getvariablebyidasync

```
const promiseList = [] as Array<Promise<Variable>>;
for (const variableId of collection.variableIds) {
  promiseList.push(figma.variables.getVariableByIdAsync(variableId) as Promise<Variable>);
}
const variables = await Promise.all(promiseList);
```

ある Collection に含まれる全ての Variables を取得できます。

### Import: Variable

- https://www.figma.com/plugin-docs/api/figma-variables/#createvariable
- https://www.figma.com/plugin-docs/api/Variable/#setvalueformode

```
// 新しい Variable を追加する
const newVariable = figma.variables.createVariable(variableName, collection, variableType)

// Variable に値を設定する
// COLOR 値の場合：const internalValue = figma.util.rgba(value as string);
// ALIAS 値の場合：const internalValue = figma.variables.createVariableAlias(variable);
variable.setValueForMode(modeId, internalValue)
```

Variable の作成は、まず値が空の Variable を作成し、後から Mode 毎に値を設定するインターフェイスになっています。値の設定時には、COLOR 値は `figma.util.rgba()` を、ALIAS 値は `figma.variables.createVariableAlias()` を実行した結果を利用する必要があります。COLOR 値に関しては `figma.util.rgb()` もありますが、アルファ値を捨てる意図がなければ常に `figma.util.rgba()` の方を使っておけば良さそうです。

## variableName

### Export: variableName

- https://www.figma.com/plugin-docs/api/Variable/#name

```
const name = variable.name;
```

Variable から変数名を取得できます。

### Import: variableName

- https://www.figma.com/plugin-docs/api/Variable/#name

```
variable.name = newName;
```

Variable に変数名を設定できます。

## description

### Export: description

- https://www.figma.com/plugin-docs/api/Variable/#description

```
const description = variable.description;
```

Variable から description を取得できます。

### Import: description

- https://www.figma.com/plugin-docs/api/Variable/#description

```
variable.description = newDescription;
```

Variable に description を設定できます。

## valuesByMode

### Export: valuesByMode

- https://www.figma.com/plugin-docs/api/Variable/#valuesbymode

```
const values = variable.valuesByMode;
// => { "522:0": { r: 1, g: 1, b: 1, a: 1 }, "522:1": { r: 0, g: 0, b: 0, a: 1 } }
```

Variable に設定されている値を Mode 毎に取得できます。

### Import: valuesByMode

- https://www.figma.com/plugin-docs/api/Variable/#setvalueformode

```
// Variable に値を設定する
// COLOR 値の場合：const internalValue = figma.util.rgba(value as string);
// ALIAS 値の場合：const internalValue = figma.variables.createVariableAlias(variable);
variable.setValueForMode(modeId, internalValue)
```

"Import: Variable" セクションでも紹介しましたが、mode 毎に値を設定できます。

値の設定時には、COLOR 値は `figma.util.rgba()` を、ALIAS 値は `figma.variables.createVariableAlias()` を実行した結果を利用する必要があります。COLOR 値に関しては `figma.util.rgb()` もありますが、アルファ値を捨てる意図がなければ常に `figma.util.rgba()` の方を使っておけば良さそうです。

## codeSyntax

### Export: codeSyntax

- https://www.figma.com/plugin-docs/api/Variable/#codesyntax

```
const codeSyntax = variable.codeSyntax;
// => { "WEB": "color.globalToken.blue['100']" }
```

Variable の CodeSyntax に設定した内容を取得できます。

### Import: codeSyntax

- https://www.figma.com/plugin-docs/api/Variable/#setvariablecodesyntax

```
const platform = 'WEB';
variable.setVariableCodeSyntax(platform, newCodeSyntax);
```

Variable の CodeSyntax を platform 別に設定できます。platform には `WEB`, `ANDROID`, `iOS` があります。

## scopes

### Export: scopes

- https://www.figma.com/plugin-docs/api/Variable/#scopes

```
const scopes = variable.scopes;
// => ["ALL_SCOPES"]
```

Variable から scopes を取得できます。

### Import: scopes

- https://www.figma.com/plugin-docs/api/Variable/#scopes

```
variable.scopes = newScopes;
```

Variable に scopes を設定できます。

## hiddenFromPublishing

### Export: hiddenFromPublishing

- https://www.figma.com/plugin-docs/api/Variable/#hiddenfrompublishing

```
const hiddenFromPublishing = variable.hiddenFromPublishing;
```

Variable から hiddenFromPublishing を取得できます。

### Import: hiddenFromPublishing

- https://www.figma.com/plugin-docs/api/Variable/#hiddenfrompublishing

```
variable.hiddenFromPublishing = newHiddenFromPublishing;
```

Variable に hiddenFromPublishing を設定できます。

# 実装

- https://github.com/debiru/LocalVariablesManipulator
- ui.html
    - https://github.com/debiru/LocalVariablesManipulator/blob/main/ui.html
- code.ts
    - https://github.com/debiru/LocalVariablesManipulator/blob/main/code.ts

## Example JSON

```
{
  "ColorExample": {
    "Alias Token/primary": {
      "$variableValues": {
        "Light": "$Global Token/blue/100",
        "Dark": "$Global Token/blue/100"
      },
      "$description": "",
      "$codeSyntax": {
        "WEB": "color.aliasToken.primary"
      },
      "$scopes": [
        "ALL_SCOPES"
      ],
      "$hiddenFromPublishing": false
    },
    "Global Token/blue/100": {
      "$variableValues": {
        "Light": "#0000FF",
        "Dark": "#0000FF"
      },
      "$description": "",
      "$codeSyntax": {
        "WEB": "color.globalToken.blue['100']"
      },
      "$scopes": [
        "ALL_SCOPES"
      ],
      "$hiddenFromPublishing": false
    }
  }
}
```

JSON の構造は以下のような感じです。

```
{
  "CollectionName": {
    "VariableName": {
      "$variableValues": {},
      "$description": "",
      "$codeSyntax": {},
      "$scopes": [],
      "$hiddenFromPublishing": false
    },
    "VariableName2": {
      ...
    }
  },
  "CollectionName2": {
    ...
  }
}
```

## 画面イメージ

Local Variables Manipulator プラグインの起動画面です。

![上部に Export、下部に Import のボタンとテキストエリアが表示されている](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/7bf288ef-7722-65b8-2d7a-293e7adc9a93.png)

## プラグインを利用する

- https://www.figma.com/community/plugin/1395633889534142383/local-variables-manipulator

# おわりに

Figma Plugin API を用いた Local Variables の操作方法について解説してみました。

この情報が Figma プラグイン開発をしようとしている方の参考になれば幸いです。

また、このプラグインについてフィードバックがあればぜひお聞かせください！