Figma Code Connect 社内勉強会資料

## この記事の概要

2024年8月15日に社内で開催したFigmaのCode Connectについての勉強会の資料です。
社内だけに閉じる必要もなかったので、Qiitaにて記事として公開しました。

:::note
Code ConnectはReact, React Native, SwiftUI, Jetpack Composeに対応しています。
今回紹介するのはReactでの内容です。
:::

## コンポーネントの準備

Code Connectを実施する前に、Figmaデータとしてのコンポーネントと、コードとしてのコンポーネント、両方が必要です。

今回は簡単にボタンコンポーネントでの例を見せます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/66126864-944e-48de-e369-e9231ff21638.png)

Figmaでのpropertiesは以下のようになっています。

| Property名 | 内容 |
| --- | --- |
| proprity | primary, secondary, tertiary |
| state | default, hover |
| label | ラベルのテキスト |

上から順にprimary, secondary, tertiary。
左がdefault、右がhoverです。

---

コードではこのようになっています。

```tsx:src/components/Button/Button.tsx
import type { ButtonHTMLAttributes } from "react";
import classes from "./Button.module.css";

type Props = {
	priority?: "primary" | "secondary" | "tertiary";
} & ButtonHTMLAttributes<HTMLButtonElement>;

export function Button({
	children,
	priority = "primary",
	type = "button",
	...props
}: Props) {
	return (
		<button className={classes[priority]} type={type} {...props}>
			{children}
		</button>
	);
}
```

---

現時点ではFigmaでDev modeに入ると`Get started with Code Connect`と表示されていて、まだ繋がっていないことが分かります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/51419812-1396-26d8-a970-39feca967625.png)

ここから繋いでいきます。

## トークンの発行と設定

Figmaの`Settings > Account > Personal access tokens`から`Generate new token`して、トークンを作成します。

Token nameは自由につけてください。
Expirationもお任せします。
Scopesは、File contentをRead-onlyに、Code ConnectをWriteに設定し、それ以外はNo accessで大丈夫です。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/2fd440a0-c449-dc20-125d-98c6a7d604f9.png)

作成したら、コピーして手元に保存しておいてください。

次に、リポジトリ内に`.env`を作成し、トークンを設定します。

```:.env
FIGMA_ACCESS_TOKEN=先ほど作成したトークン
```

## 依存関係のインストールとセットアップ

次に、Code ConnectのCLIをインストールします。

```sh
npm i @figma/code-connect
```

インストールが完了したら、ルートディレクトリに`figma.config.json`を作成し、中身を以下のようにします。

```json:figma.config.json
{
	"codeConnect": {
		"include": ["src/components/**/*.{tsx,jsx}"],
		"parser": "react"
	}
}
```

## ひとまずの接続

Code ConnectしたいコンポーネントのURLを取得してからコマンドを叩きます。
`右クリック > Copy/Paste as > Copy link to selection`で要素ごとのURLがクリップボードにコピーされます。

```sh
npx figma connect create 今コピーしたURL
```

ルートディレクトリに`Button.figma.tsx`が作成されるので、`src/components/Button/`に移動させましょう。

```tsx:Button.figma.tsx
import { Button } from "./Button";
import figma from "@figma/code-connect";

figma.connect(
	Button,
	"ファイルのURL",
	{
		props: {
			label300: figma.string("label"),
			priority: figma.enum("priority", {
				primary: "primary",
				secondary: "secondary",
				tertiary: "tertiary",
			}),
			state: figma.enum("state", {
				default: "default",
				hover: "hover",
			}),
		},
		example: (props) => <Button  />,
	},
)
```

できたら一度publishします。

```sh
npx figma connect publish
```

完了したらFimgaに戻り、Dev modeに入ってcomponentを選択すると、Code Connectされていると思います。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/a7be1020-fd79-0887-1754-37414698533e.png)

## 使えるコードにする

Figmaデータとコードの接続こそされましたが、現時点では正直使えるものではありません。

まずは以下のように変更します。

```diff_tsx:Button.figma.tsx
figma.connect(
	Button,
	"ファイルのURL",
	{
		props: {
			label300: figma.string("label"),
			priority: figma.enum("priority", {
				primary: "primary",
				secondary: "secondary",
				tertiary: "tertiary",
			}),
			state: figma.enum("state", {
				default: "default",
				hover: "hover",
			}),
		},
-		example: (props) => <Button  />,
+		example: (props) => <Button {...props} />
	},
)
```

再度publishします。

```sh
npx figma connect publish
```

これで`label`や`priority`などにあわせたコードが表示されるようになりました。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/c544d603-b309-506c-2d8b-489e581229d7.png)

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/85bee2ab-bc6b-d678-26f9-38476c7074d0.png)

ただ、今の時点だといくつか不整合もあります。

- `label`が`label300`という名前になっている
- テキストをchildrenで受け取っていない
- hoverのスタイルをpropsとして渡すはずないのに、渡っている
- import文が実態にそぐわない

`label300`という名前は、なぜかこうなってしまっているだけで勝手に変えていいそうです（Figma Japanに確認しました）。
childrenは適切になるようにコードを修正します。
hoverのスタイルまわりは不要なので削ります。

```diff_tsx
figma.connect(
	Button,
	"ファイルのURL",
	{
		props: {
-			label300: figma.string("label"),
+			label: figma.string("label"),
			priority: figma.enum("priority", {
				primary: "primary",
				secondary: "secondary",
				tertiary: "tertiary",
			}),
-			state: figma.enum("state", {
-				default: "default",
-				hover: "hover",
-			}),
		},
-		example: (props) => <Button {...props} />
+		example: ({ label, priority }) => (
+			<Button priority={priority}>{label}</Button>
+		),
	},
)
```

この状態で再publishしましょう。

```sh
npx figma connect publish
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/0e6c9d81-59ba-495e-4b42-debcd5a5e67f.png)

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/67d666cc-5548-d27a-1d25-ab42f0de6199.png)

解消されています。

最後にimportですが、tsconfigのpathsを設定しているプロジェクトも多いと思います。
それに合わせた変更をします。

```diff_json
{
	"codeConnect": {
+ 		"importPaths": {
+			"src/components/*": "@components/*"
+		},
		"include": ["src/components/**/*.{tsx,jsx}"],
		"parser": "react"
	}
}
```

`@components`の部分は実際のコードにあわせてください。
これで再度publishします。

```sh
npx figma connect publish
```

これで、Code Connectで示されたコードをコピー&ペーストするだけで、実際のコードの中でも使えるようになるはずです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214677/e0bb5e30-30bc-3c62-a14a-f26dd32978e6.png)