- Jelly UI v1.1は、実際のフォームコントロールと柔らかなソフトボディ物理効果を組み合わせた、依存関係のないWebコンポーネントライブラリで、40個のカスタム要素を提供
- 1つのモジュールスクリプトでインストールでき、ダークモード、OSテーマの自動追従、アクセントカラーの変更、右から左へ書くRTLレイアウトに対応
- ボタンはネイティブの
<button>、スライダーは隠しrange入力を使い、キーボード操作・スクリーンリーダー・フォーム参加のためのネイティブな意味構造を維持 - チェックボックスや入力欄からトースト、タブ、ダイアログまで、さまざまな要素に押し込み・伸び・波紋・弾みといった触覚的なアニメーションを適用
- WCAG AAのカラートークンとARIAパターンを内蔵し、柔らかな視覚効果を活かしながらもアクセシブルなプロダクトインターフェースを構築可能
インストールとテーマ
- Jelly UIは依存関係なしで、40個のカスタム要素と1つの
<script type="module">タグだけで利用できる<script type="module" src="https://jelly-ui.com/package.js"></script> <jelly-theme mode="auto"> <jelly-button variant="mint">Publish</jelly-button> </jelly-theme> <jelly-theme>は、配下のツリーにデザイントークンを限定適用するテーマプロバイダーmodeはauto、light、darkに対応し、OS設定に従うか特定のテーマを強制できるaccentでアクセントカラーを再指定できる
- 共通のカラーバリエーションは
azure、rose、amber、mint、graphite、platinum、whiteで、サイズは主にsmall、medium、largeで構成される
ボタンと操作要素
<jelly-button>は、内部に実際のネイティブ<button>を入れてキーボードとスクリーンリーダーをサポートするカプセル型ボタン- 色・サイズと
pill・square形状、無効化、ブロック配置を設定できる
- 色・サイズと
<jelly-icon-button>は、1つのアイコンに合わせた四角形または円形のボタンlabel属性でスクリーンリーダーが認識する名前を指定する
フォーム入力コントロール
<jelly-checkbox>はフォームに参加し、checkedと不確定状態(indeterminate)に対応し、状態が変わるとゼリー状の四角形が跳ね上がる<jelly-input>は、text、email、password用の1行入力フィールド- フォーカスを受けると表面が持ち上がって境界線が現れ、入力のたびにキャレット位置から波紋が広がる
disabledとreadonlyに対応
<jelly-label>はforでコントロールと関連付けられる- クリックすると対象にフォーカスし、ラベルテキストがアクセシブルな名前になり、必須かどうかとサイズを指定できる
<jelly-otp>は、数字ごとに1つのボックスを提供するワンタイムコード入力- 入力、Backspace、矢印キー、貼り付けを処理し、長さ・色・サイズ・無効化を設定できる
<jelly-radio>は、同じルートで同一のnameを共有する項目同士でグループを形成する- 移動式
tabindexと文書方向を考慮した矢印キー操作に対応
- 移動式
<jelly-radio-group>は、jelly-radio向けのラベル付きradiogroupコンテナ- 凡例、横・縦のフロー配置、子要素へのサイズ伝播を提供
<jelly-range>は、最小値と最大値の範囲を選ぶデュアルハンドルスライダー- 2つのつまみに
role="slider"、フォーカス、ARIAを適用し、ドラッグ時にゼリー状のつまみが押し込まれる
- 2つのつまみに
<jelly-segmented>は、相互排他的な選択肢を含むカプセル型トラック- 選択表示は区間の間を移動しながら傾き、伸びるゼリー状のピルとして動作する
<jelly-select>は、ARIAcombobox・listboxパターンを使うフォーム連携ドロップダウン- トリガーとオプションパネルはいずれもソフトボディ表面で構成される
- パネルはフィールドから展開され、下のスペースが足りない場合は上方向に切り替わる
<jelly-slider>は、単一の値を選択するスライダー- 隠しネイティブ
range入力が意味構造とフォーム参加を担い、画面には押し込まれるゼリー状のつまみが表示される
- 隠しネイティブ
<jelly-switch>はドラッグ可能なスイッチで、つまみが液滴のように伸び、オフ・オンの色がクロスフェードする<jelly-textarea>は、複数行入力に応じて最小・最大高さの間で自動的に大きくなる- 表面も高さに合わせて伸び、入力時にキャレット位置から波紋が発生し、
disabledとreadonlyに対応
- 表面も高さに合わせて伸び、入力時にキャレット位置から波紋が発生し、
状態とフィードバック
<jelly-alert>は、info、success、warning、dangerの4つのトーンと任意の閉じるボタンを提供するバナー<jelly-badge>は、バッジ・タグ・状態表示に使う小さな要素で、テキストが変わると跳ね上がる- 塗りつぶし・アウトライン、ピル・四角形の形状と
live、instantの動作を設定できる
- 塗りつぶし・アウトライン、ピル・四角形の形状と
<jelly-progress>は、進捗に応じて塗りつぶしの先端が揺れる進捗バー- 不確定モードでは、塊が両側の壁の間を跳ねる
<jelly-skeleton>は、きらめきの代わりに柔らかく呼吸するように揺れるローディングプレースホルダーline、rect、circle形状に対応
<jelly-spinner>は、3つの点の間を移動する粘液の塊状のdotsと、形を変えながら回転するblobインジケーターを提供<jelly-toaster>は、インライン終端方向から現れて消えるトースト通知を管理する- 一般的に
jellyToast('Saved!', { tone: 'success' })ヘルパーで呼び出す - 配置した要素に
position="bottom"を付けると、通知スタックが上方向に伸びる
- 一般的に
コンテンツ表面
<jelly-accordion>は、複数の<jelly-collapsible>項目をまとめるsingleモードでは、1つが開くと残りが弾むように閉じる
<jelly-card>は、コンテンツの下に置かれるゼリー状の表面コンテナsquishを追加すると、柔らかなクッションのように押し込まれながらボタンの役割を果たす
<jelly-chip>は、静的ラベル、切り替え可能なフィルター、削除可能なタグとして使用できる- 選択可否・選択状態・削除可否・無効化を設定する
<jelly-collapsible>は、ヘッダーボタンでパネルを弾むように開閉する展開・折りたたみ領域- テキストではなく表面が動くように構成される
<jelly-divider>は、横・縦またはラベル付きの細い区切り線<jelly-kbd>は、押してみることができるゼリー状のキーキャップkeyで実際のキーと関連付けると、ページ上のどこでそのキーを押している間でもキーキャップも沈み込む
ナビゲーションとレイアウト
<jelly-resizable>は、ゼリー状の区切り線をドラッグしたりキーボードでサイズ調整したりするパネルグリッドrow、vertical、both方向に対応
<jelly-tabs>は、実際のtablist意味構造を使うタブビュー- ゼリー状のピル型選択表示が移動し、タブパネルが弾みながら現れる
オーバーレイ
<jelly-dialog>は、ゼリーのように弾みながら現れるモーダルダイアログ- ページをロックし、閉じた後に以前の位置へフォーカスを戻す
- Escapeキー、閉じるボタン、または背景クリックで閉じられる
<jelly-drawer>は、端から少し行き過ぎて戻るスプリング効果で現れるフローティングシート- インライン開始・終了、または下方向から開ける
<jelly-popover>は、クリックで開く非モーダルパネル- トリガーに固定され、Escapeキーや外部クリックで閉じる
top、bottom、start、endの配置に対応
<jelly-tooltip>は、マウスオーバー時やキーボードフォーカス時に、トリガーの上にテーマ適用済みの吹き出しを表示する- 4方向配置と3つのサイズに対応
1件のコメント
Hacker Newsのコメント
ウィンドウがややカクついていたので原因を掘り下げてみたが、このライブラリはページ上のすべてのコンポーネントに対して 8msごとに requestAnimationFrame(RAF) アニメーションループ を実行し、ドキュメント全体を再描画している
上の「アクティブなコンポーネントを1フレーム内でまとめて処理し、アイドル時には停止する」という注釈もAI生成っぽい。
JellyEngineはポインターイベントが発生したときだけジェリーアニメーションを計算するのではなく、ページ上のすべてのアクティブなコンポーネントを毎フレーム再計算している。普通の人が見れば「こうしてはいけない、やりすぎだ」と言いたくなる実装だSet()で管理し、動きが止まると削除する構造に見える注釈がややAIの雑な生成っぽい点には同意するが、アプローチ自体に明白な問題は見つからなかったし、何も動作していないときのコアループは数マイクロ秒で終わる
気に入ったが、標準的なUX慣行 には合っていない気がする
押したままマウスを要素の外へ移動した場合、クリックとして扱われるべきではないと思う。現状ではボタンはクリック扱いになるが、チェックボックスはそうならず一貫性がない
心からかわいらしいし、
@media (prefers-reduced-motion: reduce)で自然に機能を抑える点もよいただ、デモサイトではシステム設定を変えなくてもユーザーがこれを上書きできるようにするか、少なくとも アニメーションが表示されないという案内 があるとよい
こういう素敵なデモが出るたびに設定を思い出すまで少し時間がかかり、その間は「何がそんなに特別なんだ?」とがっかりしながらクリックしてしまう
若い頃なら本当に気に入っていただろうが、最近はローカルスタイルシートでこういう効果を消したり、ダークモードとリーダーモード を使ったりすることにもっと時間をかけている。ずいぶん時代が変わった
マウスオーバー時にも弱い強度で効果が出るとよさそう。一部のコントロール、たとえばプログレスバーやトーストにはジェリー効果がないようだ
デモページの パフォーマンスもあまり良くなく、スクロールを奪われる感じ がするが、全体としてはかわいく、ゲームUIにはよく合いそうだ
Chip要素はその場に留まったまま遷移するべきなのに、クリックすると 境界の外へ飛び出して しまうのが気に入らないかわいいが、一部のコントロールの 反応速度 が悪すぎる。スライダーを前後にドラッグするとマウスカーソルに大きく遅れ、接着剤でくっついたようにカーソルに追従すべきだ
一方で
jelly-resizableのような他のコントロールはカーソルにしっかり追従して動く。"Placeholder"コントロールはクリックしてもプレースホルダーが消えないようだ2007〜2010年ごろ、Paul Neaveのウェブサイト・ブログ・ショーケースで、ページの縁に似たような ジェリー効果 があったのを覚えている人はいるだろうか。当時はFlashで実装されていた
あの頃のPaul Neaveは個人的なヒーローで、もしこれを読んでいたら元気でいてほしい
このUIデザインシステムでは、物理効果 と呼べるものをまったく見つけにくい
自分の 色覚異常のタイプ やモニター設定のせいかもしれないが、赤とアンバーがあまりに似ていて、ボタンを押したのかどうかすら判別できなかった