🍮 Jelly UI — フォーム部品がぷにぷに変形するWeb Componentsライブラリ、遊びに見えてa11yの筋が通っている

ボタンや入力欄がソフトボディ物理でぷにっと変形するJelly UIがHNで333ポイント。Canvas 2D+バネ膜+体積保存の実装、ElementInternalsでフォーム参加する設計、reduced-motion対応まで、触って楽しい系ライブラリの中では珍しく足腰がしっかりしている。

読む深さ

ボタンを押すと、ぷにっと潰れて戻る。スライダーをつまむと、ゼリーみたいに引っ張られてついてくる。Jelly UIのデモページは、用もないのに触り続けてしまう類のやつだ。HNで333ポイント。この手の「触って楽しい」系は年に何度か現れては消えるが、これは実装を覗いたら意外に足腰がしっかりしていたので紹介したい。

ぷにぷにの中身はバネと圧力

実装はCSSトリックでもSVGフィルタでもなく、本物のソフトボディ物理だ。各コンポーネントは角丸矩形の周囲にバネで結合された膜ポイントのリングを持ち、圧力ベースの体積保存で「潰れたら横に膨らむ」を再現する。描画はCanvas 2D。全部品が1本の共有requestAnimationFrameループで固定サブステップのシミュレーションを回し、触っていないときはループごと停止する

HNでは案の定「アイドル時も再描画してないか」という性能ツッコミが入ったが、プロファイルを取った人たちの検証で「重いのはデモページのヘッダーのLottieアニメで、ライブラリのコア部ではない」と収束した。この流れ自体が、ちゃんと計測してから殴り合うHNの良い日だった。

「遊び」で終わらせない設計が2つ

感心したのはビジュアルより設計判断のほうだ。

ひとつはフォームとの統合方式。見た目だけのdivにイベントを生やすのではなく、ElementInternalsを使ったform-associated custom elementsとして実装されている。つまり <jelly-input> は普通のフォームの中でFormDataに参加し、キーボードでも操作できる。40要素にダークモード・RTL・WCAG AAのカラートークンまで揃えてMIT。なお「native HTML form controls」という売り文句には「JS必須なのだからnativeではない」という正確な批判がHNで入っていて、これはその通り。ネイティブ部品の拡張ではなく、行儀の良い再実装です。

もうひとつは prefers-reduced-motion の扱い。動きを減らす設定のユーザーには変形そのものを無効化する。ぷにぷにが本体のライブラリが、ぷにぷにを切る道を最初から用意している。先週:openの記事でも書いたが、装飾は「切れること」までが設計だと思う。

面白かったのは、運動制御が難しいユーザーから「変形でヒットターゲットが実質広がるなら、むしろa11yに使えるのでは」という前向きな視点が出ていたことだ。「フォームが変形すべきか」「酔う」という真っ当な懐疑と同居していて、遊びのUIをどこまで実務に許すかの線引き論として読み応えがあった。

HN 333ポイント、GitHub 55 stars

数字の落差も記録しておく。HNで333ポイント集めながら、リポジトリのstarは55。「触って楽しい」と「自分のプロジェクトに入れる」の間には、深い谷がある。B2BのフォームでJelly UIを提案する勇気は自分にもない。

それでも、こういうライブラリの存在価値は採用数ではないと思っている。バネ膜+体積保存をWeb Componentsに閉じ込める設計、ElementInternalsの正しい使い方、共有rAFループのアイドル停止——読むだけで持ち帰れる部品が多い。日本語圏ではまだ誰も取り上げていないが、colissあたりが数日内に拾う気がするので、実装の中身まで読みたい人はリポジトリを先にどうぞ。

40個の部品のどれが一番ぷにぷにして気持ちいいか——デモを触って、あなたの推しを教えてください。

元ネタ: https://jelly-ui.com/