| 日本語 | English |
|---|---|
![]() |
![]() |
元々はUIコンポーネントの「統一資料」を作ろうとしていた
UI設計をするとき、最適なコンポーネントを選ぶために、いろいろなコンポーネントライブラリを見比べてコンポーネントを探すことがあります。ライブラリごとに載っているものが違ったり、同じUIを違う名前で呼んでいることもよくあります。
「いろんなUIの知識を1つに統一した資料として整理したい」というのがWIM UIを作り始めた動機でした。コンポーネントライブラリとしては過剰な、定番だけでなく、あまり見かけない・珍しいコンポーネントも片っ端から集めていったのは、あらゆるコンポーネントを網羅したいためです。
作っていくうちに気づいたのが、ただライブラリを眺めているだけでは気づかないことが、自分で追加しようとすると山ほど出てくるということでした。状態設計、アクセシビリティ、命名、他コンポーネントとの一貫性など。その学びをStorybookのMDXに残すようにしています。
締め切りがないので、作り直し放題になった
追加しながら学ぶたびに「ここは設計を変えないと」となり、その結果として全体に影響する破壊的変更を何度もやりました。普通、業務でこれはできません。締め切りがない個人制作だからこそ、後戻りを恐れず作り直していたのがこのプロジェクトの実態です。完成させるつもりがなかったのでプロジェクトと呼んでいいのかはわかりません。
長期に渡ったので、正直、個々の判断はもう覚えていないです。AIと対話しながら「今ここはどうする?」を一つずつ決めていった、という感覚です。
| Dashboard | features | pricing |
|---|---|---|
![]() |
![]() |
![]() |
AIはデザイントークンをカジュアルに無視してくるので「守らせる仕組み」を作ることになった
デザイントークンは、実は最初からある程度は用意していましたが、コンポーネントを足していくと全体がどんどんバラバラになっていきました。原因ははっきりしていて、AIが、用意したトークンを結構カジュアルに無視してくることです。デザイントークンには無い色を直書きする、余白を自由な数値でハードコードする、命名も揃わないなど。「トークンを使うように」伝えても、次の生成ではまた素の値が混ざります。
どうすればデザイントークンやルールを守ってもらえるかを考えながらAIとの対話を続け、その過程でルールとトークン自体が整備されていきました。
具体的には
- ハードコード値をCIで弾く:生のpxやHEX色を検出して落とすチェックを入れることで、デザイントークンを使わざるを得なくなる
- トークンの公開面をスナップショットで固定することで、勝手に増減したらCIが気づく
- 命名・import経路を"公開API"として凍結し、Selectbox→Selectのように業界標準へ寄せて統一し、逸脱を検出
- 最終的には「AIが生成しがちな"それっぽい画面"を避ける」コンポジション指針まで言語化してルール化
AIに守らせるためのガードレールを整備する作業そのものが、デザインシステムを体系化していきました。「AIがサボる」→「サボれない仕組みを作る」→「結果、ルールとトークンが洗練される」。壊しては直すの繰り返しの中で、バラバラだった部品に共通の秩序ができていきました。
| Light Mode | Dark Mode |
|---|---|
![]() |
![]() |
WIM UIを支えている設計判断3つ
- i18nをi18next非依存に:言語切替の仕組み自体は、実は最初期の手書き時代からありました(当時は穴だらけでしたが)。今は翻訳を内蔵しsetWimLocale("ja")で切り替える形に落ち着いていて、ライブラリのために特定のi18nライブラリを利用者に強制しません。対応はen/ja/pt-BRの3言語(内蔵なので利用者側でも切替可能)。
- optional peerをサブパスで隔離:ルートwimuiはpeer-free。重い依存はwimui/chartsのように使う分だけ。peerが要る部品はwimui/data-display/qr-codeのように名前で必要peerが分かる専用サブパスへ。「Buttonだけ欲しい人がrechartsを巻き込まない」。
- デザイントークン駆動:色・間隔・サイズを全部トークン化し、ダーク/密度も完結。
(正直、AIはこの3つ以外にもいろいろ提案してきて、中にはよく分からないものもありましたが、ここまで一緒にやってきたパートナーが言うなら改善につながるんだろう、と信頼して任せたことも結構あります。)
余談:なぜ3言語目がポルトガル語なのか
enとjaだけだと少し物足りなくて、せっかく多言語対応をうたうなら、もう1言語増やしたいと思いました。以前ブラジルに1ヶ月ほど滞在する機会があり、必要に迫られて勉強していたのがポルトガル語だったので、そのままpt-BR(ブラジルポルトガル語)を選びました。深い戦略というより、ただの個人的な縁です。翻訳はライブラリに内蔵しているので、利用者側でもsetWimLocale("pt")でpt表示に切り替わります(ドキュメントのStorybookも3言語)。
| English | português |
|---|---|
![]() |
![]() |
AIとの共同作業が、"npm公開"まで連れて行ってくれた
実は、npm公開はもともと視野に入っていませんでした。
初期はコードを全部手で書いていました。それが、別件で忙しくなってしばらく放置していたのですが、その間にAIのコーディングエージェントを導入していて、WIM UIにも使うことにしました。
その時点でも、私は「ドキュメントとしてStorybookを公開する」ところまでしか考えていませんでした。ところがAIは、当然のようにnpm公開を目指してあれこれ助言してくる。「exportsはこう」「provenanceを付けよう」「公開前にこれを検証しよう」。最初は「いや、そこまでは」と思っていたのに、対話を重ねるうちに公開が現実味を帯びてきました。
そして気づけば、AIと一緒にここまで頑張った(実際にコードを書いて頑張ったのはAIなのですが)ぶん、ちゃんとゴールまで持っていかないと、という気持ちになっていました。普通のデザインシステムの公開はゴールというよりスタートかもしれませんが、それでもnpmとして公開することにしました。
| ai-artifacts |
|---|
![]() |
AIとの協業が、私の"行動"を変えている
実は、この記事を書いているのもAIがきっかけです。npm公開のあと「次は何をしよう」とAIに相談したら、やることリストの中に「記事を書く」が入っていました。AIはZennを挙げてきたのですが、私はQiitaのアカウントを持っていたので、こうしてQiitaに書いています。AIに言われなければ、この記事は存在しませんでした。
思えば、npm公開もそうでした。もともとStorybookを出すだけのつもりが、AIと話すうちに公開まで来た。「作る」だけでなく「公開する」「書く」という行動そのものが、AIとの協業で引き出されたんです。振り返ると、これはただのツール利用ではなく、自分の行動を変えた"協業"だったと思います。
長く一緒に、壊しては直しを繰り返すうちに、だんだん相棒に近い感覚になっていきました。性質はまるで違う相手なのに、気づけばチームになっていました。
そんな協業の産物がWIM UIです。珍しいコンポーネントも入っているので、引き出しを増やす感覚で覗いてもらえたら嬉しいです。









