これは何
- 2021年10月27日に実施されるイベント、UXPin Workshopの中で話す内容をまとめた記事です
- なお、UXPin Mergeの公式サイトはこちらです
-
イベント内で話す内容を説明するためのリポジトリも公開していて、こちらで公開しています
- UXPinを使っている方、よろしければこのリポジトリをforkして遊んでみてください
コードで描画されたものをGUIツール上で使える
以下はプレビュー画面でdevツールを開いてみた様子です。
そして次が実際に書いているコード(の一部)です。
export const Card = ({
image = false,
imageUrl = 'https://placehold.jp/600x315.png',
title = 'Card title',
titleAs = 'span',
date = '2021.2.3'
}: Props): JSX.Element => {
return (
<div css={styles.wrapper}>
{image && <img src={imageUrl} alt="" css={styles.image} />}
<div css={styles.information}>
<Typography as={titleAs} css={styles.title}>
{title}
</Typography>
<Typography as="time" css={styles.date}>
{date}
</Typography>
<Button css={styles.button}>Read more</Button>
</div>
</div>
)
}
CSS in JSを使っているから最終的にクラス名の変換がなされているとか、そういう違いこそあれど書いたコードと出力されているグラフィックがしっかり一致しています。
GUI上でどれだけ正確にパーツを作っても、コードに変換する時間はどうしてもかかります。
また、user agent stylesheetによって定義されているスタイルを上手く調整するのはなんとも面倒なときも……。
後述するselect要素の矢印の話も当てはまるのですが、そういった悩みから解放されるのが非常に魅力的です。
コードで出来ることはなんでもできる
今お見せしているのはUXPin Boilerplate
という公式配布のライブラリのうちCameraPreview
コンポーネントです。
この動画だけでは分かりづらいですから説明しますと、以下のようなことが起こっています。
-
CameraPreview
コンポーネントを配置する - プレビュー画面へ進む
- カメラアクセス許可を求められる
- 許可するとカメラに写しているものがブラウザ上に表示される
色々試している中で、これはかなり驚きました。
コードを書けば実現できる機能とは言え、デザインツールでこのレベルまで実現できるのか……と。
またここまででなくても、他のツールだとハック気味に実装しないといけないものも割と楽に再現できます。
モーダルウィンドウとかディスクロージャーとか、それらを作るためだけにレイヤーを汚くしてしまう場面もあると思うんですが、UXPinならその心配は無さそうです。
「GUIだから楽にできてしまう」をなくせる
もしかしたら人によってはデメリットに映るかもしれませんが、自分にとっては完全にメリットな話なので紹介します。
先ほどちらっとだけ触れたselectタグの話なのですが、GUIツールで作るなら四角い枠の右端に下向きの▼を置くだけでそれっぽい見た目になりますがコードで書こうとすると……
- 下向きの▼がパスで書かれているだけなので、CSSの疑似要素で頑張って作った
- モックアップと微妙にpaddingが揃わない、数値的には合ってるはずなのになんだか微妙に違う
こんなことありませんか?僕はあります笑
自分の場合はモックアップ作成からコードを書くのまで大概自分でやってしまうので、後から「昨日の自分の馬鹿野郎、面倒くさいデータ作りやがって〜」とぼやく程度ですが、デザイナーとエンジニアが協業している場面では色々相談が発生してしまうのではないでしょうか。
ちなみにここで見せているSelectコンポーネントはこちらです。
あと昔見かけて不毛だなあと思ったのが、autofocus
されるinput要素に色がついていて、モックアップ通りじゃないから色を消してくれないかってコミュニケーション。
得てしてこういう「イメージベースで作ると上手くいく」をコードで無理矢理再現しようとするととんでもないハックが必要になります。
はじめからコードとして作られて、レンダリング結果のコンポーネントを使ってレイアウトを組めばこういう悲劇も起こらないんじゃないかな?と思っています。
レイアウトコンポーネントを用意できる
FigmaやSketchなどのUIツールでも、Storybookのようなコンポーネントカタログでも、叶えづらいことの1つに「レイアウトコンポーネントの確認」があるのではないでしょうか。
FigmaでいうAuto layoutの仕組みはレイアウトコンポーネント的ではありますが、あれで作った設定をいざコード化しようとして迷ってしまう人も見たことがありますし、現段階ではflex-wrap
のような挙動も再現できません。
Storybookにおいては、あのアプリケーション上で何かを操作するようなものではないので、予め決まったコンポーネントを内包したStoryを作ることはできても、別なコンポーネントに適用した際の見た目をその場で確認するのは……多分難しいはずです。
(私が言うほどStorybookに詳しいわけではないので、アドオンなどでできるよ、という場合はすみません)
UXPinであれば、以下のようなフローにすることができて、割と楽に感じています。
- コードを書く
- experimental modeで起動してUXPin上で確認
- 変な箇所があれば修正
そして試しに簡単なStackコンポーネント作ってみました。
モックアップデータが壊れる余地が無い
FigmaでもSketchでも、コンポーネントを解除してしまえばどんなオーバーライドでもできます。
そして解除できないコンポーネントなんてものはありません。
UXPinの場合、コードからimportすると解除
という行為が無いんですね。
あらかじめ型指定されたプロパティを触るか、さもなくば削除するのみ。
定義されていないものについては一切触れないので、自分が最初に試しで作ってみたコンポーネントは「サイズも色もテキストも何も変えられないボタン」になってしまいました笑
個人の性格なり、忙しさが優先するなりでどうしてもコンポーネントに定義されていない野良UIが出現しがちではありますが、かなり防いでくれる仕組みだと思います。
Reactの型指定に忠実
自分はTypeScriptを使っていますが、多分PropTypesでも同じ話です。
例えば以下のような具合。
- childrenをReactNodeにしたらコンポーネントのネストができる
- stringとかnumberとかにしたらネストができない
forwardRefをするのが面倒でrefを名前だけ変えて渡していたら、propsの中でrefの指定をする都合上refObjectとしてJSONで記載してね
みたいなフィールドがプロパティ一覧の箇所に出たんですよ。
実務だと、UI触ってるときにrefObjectの構造を考えて何かを書く……とか絶対やらないじゃないですか。
だからこれはちゃんとforwardRefを使おう、と思えました笑
そういうのもあって、コードを書いてUXPinで確認している時点で軽いテストができている……ような気がしています。
childrenが自由
少し分かりづらいかもしれませんが、オレンジのアイコンがついているものはコンポーネントです。
コンポーネントの中に、好きなコンポーネントを入れられる、そういう設定にもできます。
ボタンとかチェックボックスとか、プリミティブなコンポーネントがあって、それらをwrapしてより大きなコンポーネントが作られるのが普段のUI作成ですよね。
childrenを足したり抜いたりが自由にできるUIツールって多分まだ無いと思っていて、型指定の部分で厳格さを持たせている代わりにこういうあたりに自由をもたらすっていうのがバランスとして好きだな、と思っています。
あとはさっとネストして試してみて、頻出するからコード上でコンポーネントとして定義しよう!となったときでも楽です。
何故かというと既にchildrenを受け取れる作りでコードを書いているし、既にあるコンポーネントを組み合わせるだけなので、新規に書くコードがほとんど必要ないからです。
プロトタイピングの精度をささっと変えられる
ささっと作りたいときは、単に画面上に要素を配置するだけでOKなのは言わずもがなです。
しかし気合いを入れれば先ほどお見せしたCameraPreview
のようなものを組み込んだプロトタイプや、入力内容にあわせてバリデーションなどがちゃんと走るプロトタイプなど、ほとんど現実のプロダクトに近いものまで作れます。
そしてコードをベースにしているのでハックっぽい実装も要りません。
常にhi-fiプロトタイプを作るのは骨が折れますし、low-fiプロトタイプしか作れないのは困る場面もありますが、どちらでも自由にやれるのは非常に嬉しいです。
ただ、ページをまたいでステート管理をするようなことは試せていません。
もしかしたらできるのでしょうか?若干あやふやなままで申し訳ありませんが、試してみたいなと思っている箇所です。
ここもうちょっと……!と思う箇所
ここまでベタ褒めしてきていますが、今後ここに期待……!というのもいくつか紹介します。
基本的にかなり好きなプロダクトなのですが、このあたりが良くなったら更に強いなあと感じています。
- 各種スピード
- 少し遅い
- 自動リロードなどが組み込まれると嬉しい
- 現在experimental modeでは手動でのリロードが必要
- 手軽さ
- デザイナーひとりとかじゃ相当難しそう
- 実質Storybookやバンドラーと一緒に組み込むコードを書くはず
- 僕も今回初めてRollup(ライブラリのパブリッシュ用)とStorybookとUXPinを複合させるコードを書いて涙を流しそうになっていました
- ライブラリから手軽に呼び出して使えたら……
- npm installするだけで使えたら嬉しい
- 今はforkしないといけない
- トークンもリポジトリから呼び出して使えたら……
- UXPin上で定義したトークンは使えるけど、コードからimportはできない
- presetsサブディレクトリの必要性
- UIライブラリとしてのデータ、と考えるとちょっと異質
- 自分はgit管理する中に.vscodeのディレクトリを作るのが苦手意識あるので、そういう人はちょっと違和感持つかも