Blueprint から React Fluent UI へ移行してみるよ

[リリックドラゴンRPGエディタ](https://www.lyridra.com/) （以下：リリドラ） というプロジェクトでゲームエンジンを作っています。

このプロジェクトではこれまで UI を作るコンポーネントライブラリに [Blueprint](https://blueprintjs.com/) を使っていましたが、 [Fluent UI](https://react.fluentui.dev/) への移行を起案しましたのでその背景について残しておきます。

## 見た目の雰囲気

参考までに、画像を切り貼りしただけですが簡単な比較を載せておきます。

### Blueprint

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/12852ef9-148b-4281-9f65-1398476a8257.png)

### Fluent UI

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/cb6d4aca-63f9-479f-98bb-ccde899b015e.png)


## 移行の動機

- エンドユーザー向けにネイティブアプリ感のある UI を作りたいのだけど、Blueprint のスタイル調整に苦労していた。
- GitHub Star の増加率的に Fluent UI の方が盛り上がりそう。

1つ目をもうちょっと細かく、 Blueprint の問題点として見ると次のような感じです。

- デザインシステムが無い
- カラー・テーマシステムが弱い。カスタマイズがあまり考慮されていない
- ネイティブコンポーネントのUI/UX・機能量との差異が大きい

### デザインシステムが無い

まずここで言うデザインシステムとは [このような](https://fluent2.microsoft.design/)、 コンポーネント開発の土台となるガイドラインのことです。（あんまりデザインシステムという言葉になじみが無いので、変なこと言ってたら教えてください）

デザインシステムはチーム開発で一貫性のある（個々の開発者の気分で色を変えたりしない） UI を作るための決まり事と考えています。これが無いとエディタの使いやすさや理解しやすさ、ツールへの安心感を損ねる可能性が高くなってしまうかと思います。

実際今のリリドラ開発でも、画面によって余白や色の使い方、枠線の有無などを統一しきれていません。Card を単なる見栄えの良い GroupBox として使ってしまうなど混沌が広がりつつあります。

ただこれは実際のところ当然という感じです。リリドラの開発開始当初はざっくりとしたガイドラインだけ設けて置き、機能がある程度仕上がってきた段階でデザインシステムを導入し、見た目を整えていこうとしていました。

しかし独自のデザインシステムを導入しようと考えたところ、想定よりもかなり大変な作業になるため、今のリリドラ開発でそこまでリソースをかけるのは難しいと考えました。

### カラー・テーマシステムが弱い

Blueprint のカラー・テーマシステムは固定的な感じがしました。
カスタマイズには css を直接書き換えたり、 sass で [import を工夫して](https://github.com/palantir/blueprint/issues/123) 変数を変更していく必要があるようです。

最近のデザインシステムだと、ブランドカラーやプライマリカラー、セカンダリカラーという仕組みでボタンの色を表したり、OSのユーザー設定を自動的に反映したりできます。
動的な色変更の要求にこたえるには css なり sass なりをかなりの割合で手を入れる必要がありそうだったので、途中で断念していました。

なおデフォルトのテーマは画面全体は微妙に青みがかった配色となっているため、アプリ固有のブランドカラーによってはより相性が悪くなります。これを潰すためのカラートークンを探す作業も負担でした。

ただこれについては、 Blueprint は「（ユーザーではなく）開発者が扱いやすく」「陳腐すぎない程度のUIを」「素早く開発できるようにする」というコンセプトで作られていると認識していまして、まぁそういうことなのかな、というかんじです。

### ネイティブコンポーネントとの差異が大きい

ここでいうネイティブコンポーネントとは、 Windows や macOS 等のデスクトップアプリの標準的な button や input のことです。

ここは個人的な主観が強いですが、長くデスクトップアプリ開発をしている身としては、割と独自路線を走ってる Blueprint には色々と気になりポイントがありました。

- 数値入力フィールドのスピンボタンが欄内にない
- コンテキストメニューの項目が整列されない
- スライダーのラベルを非表示にできない
- ツールチップがテーマと逆で、大きいテキストを表示するとコントラスト差がつらい
- Tree や List のサポートが無い（ので自分で作る必要がある）
- やや過剰なアニメーション（特にポップアップやダイアログ）

## 他ライブラリとのちょこっと比較

ぱっとデザインシステムが見つかるものを探して調べてみました。

- MaterialUI
  - 今のところ最も人気のあるライブラリだと思います。 私は業務での使用経験がありますが、Web・モバイルアプリを想定しているようなので、デスクトップアプリを作るには向かないかも。（ボタンや余白がめっちゃ大きいなど）
- SpectrumUI
  - Adobe 製品用のライブラリ。 Adobe らしくカラーピッカーをはじめにデザインツールで見かけるコンポーネントが豊富。でも Tree などデスクトップアプリでよく使うコンポーネントはまだ beta。
- FluentUI
  - 今回採用したいもの。リリドラ開発開始当初は機能が揃ってない感じがありましたけど、今は結構充実してます。結構充実した Tree もあります。

コンポーネントライブラリという枠だと他にも有名どころはあると思いますが、今回の目的のひとつはガイドラインをもとに混沌を抑え込むことなので、それが簡単に見つかりそうになかったものは対象外としています。

## 一部移行してみた結果

まだ移行中なので一部だけです。とりあえずポップアップの様子を紹介します。

### Fluent UI

![2025-02-26_20h39_22.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/bdbfaf04-7c12-40c6-9cb2-8505608504cb.gif)

↑なれの問題かもしれませんが、SingleSelection モードだとラジオボタンツリーになるので、調整は入れるかもしれません。

### Blueprint (移行前)

![2025-02-26_20h42_01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/474f81e8-84e9-4cc9-a27c-6da06ed71e6a.gif)

↑少しわかりづらいですが、 easeOutBack 的なけっこう大げさなアニメーションが付いています。


## Fluent UI の注意点

### Blueprint と比べて情報は少なめ

といってもこれは Blueprint と同じか、むしろ UnrealEngine とかの Blueprint と衝突して調べ辛さもあるので、あんまり気にしなくても良いかもです。

公式ドキュメントが一番わかりやすいのは Blueprint と同じ感じがします。（Blueprint で公式サイト以外の情報調べたことない…）

### スタイルのカスタマイズが Blueprint と比べて難しい

動的なスタイル変更は MaterialUI の styled と似た雰囲気の [makeStyles を使っていく](https://react.fluentui.dev/?path=/docs/concepts-developer-styling-components--docs) ので、少々新しいことを学ぶ必要ありです。

静的なスタイルは、こんな↓感じで class に `fui-xxxx` が付いているので、これに向かって CSS を組んでいく必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/6a57161f-ff77-48b7-89f3-023ce3750e85.png)

もっと細かくカスタマイズするときは [token](https://react.fluentui.dev/?path=/docs/concepts-developer-theming--docs#theming) と呼ばれている、CSS変数 を変更する必要があるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129567/18c9de1d-94d8-47fb-a112-5a457ad0067d.png)

token のリストは公式サイトにリストアップされているものの、何がどこで使われているかは示されていないので、互換性問題を覚悟でガチりたければ [リポジトリの中](https://github.com/microsoft/fluentui/blob/master/packages/react-components/react-button/library/src/components/Button/useButtonStyles.styles.ts) を見ることになりそうです。

## さいごに

リリドラ開発開始当初も Fluent 自体は調べたのですが、その時はあんまり盛り上がって見えなかったのと、コンポーネントもそれほど充実していなかったようでしたので見送っていました。しかしデザインシステムの不足による問題が顔を出し始めたのと、今では Fluent UI の使用感もそれほど悪くないと考えましたので、移行してみることにしてみました。

同じく React アプリで Fluent UI を使おうと考えている方の参考になれば幸いです。

開発メンバーには少しの間負担をかけることになると思いますが、サポートには最善を尽くしますのでよろしくお願いします🙇