Ubie Design Tokensを公開しました
こんにちは、Ubie株式会社でデザインエンジニアをやっているtakanoripです。
Ubieではデザインのクオリティと生産性向上のためデザイン生産基盤の整備に力を入れています。
今回その一環として開発したデザイントークンをnpmパッケージとして公開しました。(現在はColorのみ。)
開発経緯
Ubie Design Tokens開発以前からデザイントークンのようなものは存在しており、CSS Variablesとして実装されていました。しかしユースケースを想定せず作った変数があったり定義が細かすぎたりしたことで「どの変数をどういう場面で使用すれは良いかわからない」という問題が発生していました。
そこで変数の定義を見直し、より実際のデザインに即したデザイントークンを策定するとともに、プロダクトごとの実装差異をなくすためのライブラリの開発に着手しました。
Colorの定義
Ubie Design TokensではPrimitive Colors
とSemantic Colors
の2種類を定義しています。
Primitive Colors
は色に機械的に名前を付けたもので、ベースになる色セットです。
Semantic Colors
では色のユースケースごとに名前を付け、Primitive Colors
で定義された色を参照しています。名前だけで利用用途がわかるよう命名しています。
Primitive Colors
とSemantic Colors
を分離することで、色の利用用途を明確にできるだけでなく、変更も容易になりメンテナンス性が向上すると考えています。
例えばテキストの黒色のみを変更したい場合、Primitive Colorsのみ定義していた場合はテキストの色として使われている黒を検索して置き換えなければなりませんが、Semantic Colorsも定義されていれば参照先の色を変更するだけで完了します。
実際のCSSの定義は次のようになります。
:root {
--ubie-blue-700: #263f94;
--ubie-blue-500: #3959cc;
--color-primary: var(--ubie-blue-500);
--color-primary-darken: var(--ubie-blue-700);
}
技術構成
Ubie Design Tokensの技術構成は次のとおりです。
- Style Dictionary
- Figma API
- GitHub Actions
FigmaのStyleに定義したColorの情報をAPI経由でJSON化しStyle DictionaryでCSSなどの各種スタイルを生成する構成になっています。
Style Dictionary
Ubie Design TokensではStyle Dictionaryを採用しました。
Style DictionaryはAmazonが開発しているライブラリで、JSON形式で定義したスタイルを様々なプラットフォームや言語で利用できる形で出力してくれます。
もともとJSON形式のマスターから各環境向けのスタイルを生成できる仕組みを自作しようかと考えていたのですが、開発コストがかかりすぎることやネイティブアプリ向けのスタイルの出力を自力でやれるほどネイティブアプリ開発の知識がないことなどからStyle Dictionaryを採用しました。
現在はCSS
、SCSS
、JS
の3タイプのファイルを生成&配布しています。CSS
、SCSS
ともにCSS Variables
形式で出力しています。(CSS Modulesを採用しているプロジェクトが多いため。)
Tailwind向け設定ファイルの生成は今後対応予定です。
{
"source": ["tokens/**/*.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "dist/",
"files": [
{
"destination": "tokens.css",
"format": "css/variables",
"options": {
"outputReferences": true
}
},
{
"destination": "tokens.scss",
"format": "css/variables",
"options": {
"outputReferences": true
}
}
]
},
"js": {
"transformGroup": "js",
"buildPath": "dist/",
"files": [{
"destination": "tokens.js",
"format": "javascript/module"
}]
}
}
}
Figma API経由でStyleを取得する
Ubie Design TokensではFigmaのStyleをもとにStyle Dictionary用JSONを生成しています。
大まかな流れは次のような感じです。
-
GET /v1/files/:file_key/styles
からStyle一覧を取得 - スタイル一覧から
node_id
を抜き出して結合&文字列化 -
GET /v1/files/:key/nodes?ids=${node_idを結合した文字列}
でStyleが適用されてるNodeの一覧を取得 - 取得したNodeから色の情報を抜き出し、Styleの情報と統合してObjectに格納
- JSONとして書き出し
FigmaにはStyle一覧を取得するAPIはあるものの、そのAPIからStyleの詳細情報(色やフォントサイズなど)を取得することはできません。
その代わりそのStyleが使われているNodeのidが返ってくるので、そのidをもとにNodeを取得し、そこからStyleの詳細を抜き出す必要があります。
const responseStyles = await fetchFigma("/styles");
const styles = responseStyles.meta.styles;
const nodeIds = styles.map((style) => style.node_id);
const nodeIdsQuery = nodeIds.join(",");
const { nodes } = await fetchFigma(`/nodes?ids=${nodeIdsQuery}`);
詳しくはGitHubのコードを見てください。
Figmaでの定義
Semantic Colors
がPrimitive Colors
を参照する構造をFigma上で再現することは現状難しいため、それぞれ別々で定義してSemantic Colors
のdescriptionに参照しているPrimitive Colors
の名前を書くという方法を採用しています。
このdescriptionの情報をもとにSemantic Colors
のJSONを生成しています。
今後の展開
今後はSpaceやTypographyなどを追加し、より実用的なデザイントークンにしていきたいと考えています。
特にSpaceはFigmaのStyleに登録できないためFigmaとどう連携するか模索中です。
プロダクト開発への浸透もこれから取り組んでいきます!
Discussion