
Style Dictionaryでデザイントークンの作成にチャレンジ
現在、私は自社プロダクトのデザイン業務に携わっています。
プロダクトは自分が担当しているもの以外にも複数ある為、その他の兄弟プロダクトと一貫したユーザー体験ができるように意識する必要があります。
しかし開発が進むと色が少し違ったり、フォントサイズやマージンが異なるなど…iOSやAndorid、Webなどのプラットフォームごとに微妙に異なるUIが生まれてしまいます(仕方がないことですが)。
そこで、デザイントークンを作成し、共通化する仕組みを導入することを考えました(他社の記事を真似してみたいと思いました)。
デザイントークンとは
デザイントークンは、デザイン要素の基本的なルールブックです。
色、フォント、スペースなど、デザインの構成要素を定義し、一貫性を保ちます。
デザインシステム内で再利用可能で、効率的なデザイン作業をサポートします。
仕組みを考える
業務ではFigmaを利用しています。
他社事例をそのまま真似て、Figmaで定義した、Local Styles、Local Variableなどデザイントークン相当のものをコードとして書き出すことを試してみました。
最終的な出力はStyle Dictionaryを利用します。こちらも他社の事例をそのままです。

Style Dictionaryを使ってみる
Style Dictionaryは、デザインシステムを効率的に管理するためのツールです。
デザイントークン(色、フォント、スペースなど)を定義し、異なるプラットフォーム(Web、iOS、Androidなど)に合わせて自動的に変換して出力します。これにより、デザインの一貫性を保ちながら、開発者やデザイナーが簡単にデザインルールを利用できるようになります。
やってみる
公式サイトを見ながらやってみます。
私はなんとなくグローバルにnpm moduleをインストールしたくなかったので、ディレクトリを作成してその中にstyle-dictionaryをインストールしました。
// 特定のディレクトリを作成してnode moduleをインストール
$ mkdir sample
$ cd sample
$ npm init
... 色々質問があるが適当に答える
// style-dictionaryをインストール
$ npm i style-dictionary
// ローカルでnpm moduleを実行するのでnpxを使う
// style-dictionary init {basic, complete}
$ npx style-dictionary init basic
ディレクトリ内にファイルが作成されます。
.
├── README.md
├── build
├── config.json // 変換するプラットフォームの設定や、出力フォーマットの設定など
├── node_modules
├── package-lock.json
├── package.json
└── tokens // デザイントークンを定義する
├── color
│ ├── base.json
│ └── font.json
└── size
└── font.json
tokensディレクトリ配下がCSS, iOS, Androidなど様々なプラットフォームで利用できるフォーマットに変換する値のファイルです。
中身は以下のようなデータになります。
◎tokens/color/base.json
{
"color": {
"base": {
"gray": {
"light" : { "value": "#CCCCCC" },
"medium": { "value": "#999999" },
"dark" : { "value": "#111111" }
},
"red": { "value": "#FF0000" },
"green": { "value": "#00FF00" }
}
}
}
ビルドコマンド用にpackage.jsonに以下を追加しておきます。
"scripts": {
"build": "style-dictionary build"
}
ビルド上記で定義したscriptsを利用して「npm run build、yarn build」などで行います。
ビルドするとbuildディレクトリ配下にファイルが作成されます。
※style-dictionary init時点で既にbuildファイルは作成済み
build
├── android
│ ├── colors.xml
│ └── font_dimens.xml
├── compose
│ ├── StyleDictionaryColor.kt
│ └── StyleDictionarySize.kt
├── ios
│ ├── StyleDictionaryColor.h
│ ├── StyleDictionaryColor.m
│ ├── StyleDictionarySize.h
│ └── StyleDictionarySize.m
├── ios-swift
│ ├── StyleDictionary+Class.swift
│ ├── StyleDictionary+Enum.swift
│ ├── StyleDictionary+Struct.swift
│ ├── StyleDictionaryColor.swift
│ └── StyleDictionarySize.swift
└── scss
└── _variables.scss
ビルドファイルの中身はこんな感じです。
◎build/scss/_variables.scss
// Do not edit directly
// Generated on Sun, 21 Apr 2024 13:46:20 GMT
$color-base-gray-light: #cccccc;
$color-base-gray-medium: #999999;
$color-base-gray-dark: #111111;
$color-base-red: #ff0000;
$color-base-green: #00ff00;
$color-font-base: #ff0000;
$color-font-secondary: #00ff00;
$color-font-tertiary: #cccccc;
$size-font-small: 0.75rem; // the small size of the font
$size-font-medium: 1rem; // the medium size of the font
$size-font-large: 2rem; // the large size of the font
$size-font-base: 1rem; // the base size of the font
◎build/android/colors.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
Do not edit directly
Generated on Sun, 21 Apr 2024 13:46:20 GMT
-->
<resources>
<color name="color_base_gray_light">#ffcccccc</color>
<color name="color_base_gray_medium">#ff999999</color>
<color name="color_base_gray_dark">#ff111111</color>
<color name="color_base_red">#ffff0000</color>
<color name="color_base_green">#ff00ff00</color>
<color name="color_font_base">#ffff0000</color>
<color name="color_font_secondary">#ff00ff00</color>
<color name="color_font_tertiary">#ffcccccc</color>
</resources>
出力設定
出力の設定は、config.jsonで行います。
{
"source": ["tokens/**/*.json"],
"platforms": {
"scss": {
"transformGroup": "scss",
"buildPath": "build/scss/",
"files": [{
"destination": "_variables.scss",
"format": "scss/variables"
}]
},
"android": {
"transformGroup": "android",
"buildPath": "build/android/",
"files": [{
"destination": "font_dimens.xml",
"format": "android/fontDimens"
},{
"destination": "colors.xml",
"format": "android/colors"
}]
},
...省略
}
細かな設定変更は公式ドキュメントを見るのが良さそうです。
初期値はtransformGroupが設定されています。内容は以下で確認できます。
Figmaからtoken.jsonを書き出す
FigmaのLocal Styles、Local Variablesの設定をStyle Dictionaryで利用できる形のJSONファイルとして書き出したいです。
既によいプラグインがありますが、今回は勉強も兼ねて自分でプラグインを作成してみました。
単純にLocal Styles、Local VariablesをJSON形式で書き出すだけのプラグインです。
デザイントークン管理で有名な、Tokens Studio for Figmaの劣化版だとおもっていただければと思います。
Tokens Studio for Figmaでももちろん同じことができます。
JSONを書き出してみる
Local Stylesの設定はこんな感じです。

JSONで書き出すとこんな感じになります。
{
"color": {
"base": {
"gray": {
"light": {
"value": "#d9d9d9",
"comment": "AAAAAA"
},
"dark": {
"value": "#6b6b6b",
"comment": ""
}
},
"primary": {
"01": {
"value": "#ff0000",
"comment": ""
},
"02": {
"value": "#0085ff",
"comment": ""
}
}
}
},
"size": {
"fontSize": {
"md": {
"value": "12",
"comment": "this is test"
},
"sm": {
"value": "10",
"comment": "ちいさい"
},
"lg": {
"value": "14",
"comment": "でかい"
}
}
}
}
Local Variablesはこんな感じです。

書き出すとこんな感じです。
{
"color": {
"base": {
"MyColor01": {
"mode0": {
"value": "#ff0000",
"comment": ""
},
"mode1": {
"value": "#ff9e9e",
"comment": ""
}
},
"MyColor02": {
"mode0": {
"value": "#3c41b2",
"comment": ""
},
"mode1": {
"value": "#a3c2ff",
"comment": ""
}
}
}
},
"size": {
"MyNumber": {
"mode0": {
"value": 0,
"comment": "コメントだよ"
},
"mode1": {
"value": 10,
"comment": "コメントだよ"
}
}
}
}
書き出したJSONをStyle Dictionaryの所定のフォルダ(初期設定は"tokens/**/*.json")に配置してビルドすることで各プラットフォームごとのデザイントークンを書き出すことができます。
開発が進むに連れ、同じ色の定義が複数でてきたり、マージンが微妙に異なる画面がでてきたりすることをデザイントークンを利用することで解決できそうな予感がします。