GODRICH
#cssアニメーション#ボタン#ローディング#トランジション#スクロール#ダッシュボード#実用ui#デザイントレンド

ダッシュボード ウィジェット単体UI9選 —そのまま貼れる部品だけ

管理画面をまるごと使うのではなく、この部品だけを自分のプロジェクトにそのまま貼りたい人のために、単体で動くダッシュボード ウィジェットを9個集めました。ドーナツチャートは実際に数字が数え上がります。

自動再生 · タイルを押すとその項目へ · すべて1つのzip

9個は人気順ではなく、ダッシュボード デザイン 参考として画面に入ってくる順番で並べました。まず骨格になるサイドバー、次に一目で把握できる要約(統計カード・表・チャート)、続いて実際に触る部分(フィルター・空の状態・設定)、最後にヘッダーの隅に付く小さなポップアップ2つ(通知・ユーザーメニュー)です。どのデモも完成した管理画面ではなく、その部品ひとつだけを画面中央に置いています。同じダッシュボード部品を統計カード中心に組み直したのがダッシュボード コンポーネント9選で、部品をブログに埋め込む用途に振ったのがシェアボタンなどの埋め込みウィジェットです。

01単体サイドバーナビ

何が動くか

折りたたみボタンを押すと、サイドバーの幅が実際に208pxから76pxへ縮み、文字ラベルが消えてアイコンだけが残ります。

単体サイドバーナビ
新しいタブで開く

01 · 単体サイドバーナビ — 計測 累積面積 12.547% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

widtharia-pressedclick

コードで見る所

今選ばれているメニューは、左の細い縦バーと薄い背景色で示されます。

.sd { width: 208px; transition: width $duration $easing; }
.sd.is-collapsed { width: 76px; }
.sd__label { transition: opacity $duration $easing; }
.sd.is-collapsed .sd__label { opacity: 0; }

02スパークライン表示の統計カード

何が動くか

期間の切り替えを押すと、訪問者数・コンバージョン率・売上の3つの数字が実際に入れ替わります。

スパークライン表示の統計カード
新しいタブで開く

02 · スパークライン表示の統計カード — 計測 累積面積 0.374% · 動いたフレーム 15/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

stroke-dashoffsetopacitymouseenter

コードで見る所

下のミニグラフ線は SVG の pathLength を100に固定しているので、形が違っても同じ描画方法で動きます。

.sc__spark-path { stroke-dasharray: 100; stroke-dashoffset: 100; }
.sc__card.is-demo .sc__spark-path { animation: sc-draw 2s $easing infinite; }
@keyframes sc-draw {
  0%  { stroke-dashoffset: 100; }
  60% { stroke-dashoffset: 0; }
}

03並び替え可能なミニテーブル

何が動くか

列見出しを押すと、矢印の向きが変わって行の順番が実際に入れ替わります。

並び替え可能なミニテーブル
新しいタブで開く

03 · 並び替え可能なミニテーブル — 計測 累積面積 54.986% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

clickaria-sortorder

コードで見る所

金額列は数値として、名前列は文字列として、それぞれ別の比較方法で並べ替えています。

rows.sort(function (a, b) {
  var av = a.dataset[key], bv = b.dataset[key];
  if (key === 'amount') { av = Number(av); bv = Number(bv); return (av - bv) * dir; }
  return av.localeCompare(bv) * dir;
});
rows.forEach(function (r) { tbody.appendChild(r); });

04中央カウンター付きドーナツチャート

何が動くか

凡例を押すと、その区間が実際にリングから外れて、中央の数字が新しい合計まで数え上がります。

中央カウンター付きドーナツチャート
新しいタブで開く

04 · 中央カウンター付きドーナツチャート — 計測 累積面積 2.739% · 動いたフレーム 16/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

@propertyconic-gradientclick

コードで見る所

リングは SVG ではなく conic-gradient と登録済みのカスタムプロパティ(@property)だけで描いています。

@property --pct-a { syntax: "<percentage>"; inherits: true; initial-value: 0%; }
.cc__ring {
  background: conic-gradient($color 0 var(--pct-a), $stage-yellow var(--pct-a) var(--pct-b), rgba(23,20,26,.08) var(--pct-b) 100%);
  mask: radial-gradient(farthest-side, transparent 60%, #000 61%);
  transition: --pct-a $duration $easing, --pct-b $duration $easing;
}

05チップ型フィルターバー

何が動くか

チップを押すたびに実際に選択状態(色が付いた錠剤の形)に変わり、下の選択数も一緒に増えます。

チップ型フィルターバー
新しいタブで開く

05 · チップ型フィルターバー — 計測 累積面積 5.824% · 動いたフレーム 23/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

aria-pressedtransformclick

コードで見る所

ひとつでも選ぶと「全解除」の文字ボタンが現れます。

c.addEventListener('click', function () {
  c.classList.remove('is-demo');
  var on = c.getAttribute('aria-pressed') === 'true';
  c.setAttribute('aria-pressed', String(!on));
  refresh();
});

06追加モーフ付き空状態イラスト

何が動くか

図形だけで描いた空の箱イラストがゆっくり浮かび続け、「最初の項目を追加」ボタンを押すとその場所が実際にリストカード1枚へ変わります。もう一度押すと元の空の状態に戻ります。

追加モーフ付き空状態イラスト
新しいタブで開く

06 · 追加モーフ付き空状態イラスト — 計測 累積面積 24.73% · 動いたフレーム 13/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transformopacityclick

コードで見る所

.es__empty, .es__item { position: absolute; inset: 0; transition: opacity $duration $easing, transform $duration $easing; }
.es__item { opacity: 0; transform: scale(.9); }
.es.is-added .es__item { opacity: 1; transform: scale(1); }
.es.is-added .es__empty { opacity: 0; transform: scale(.9); }

07保存状態付き設定フォームセクション

何が動くか

トグルを切り替えて保存ボタンを押すと、ボタンが実際に3段階に変わります。くるくる回るリング状のスピナーになり、700ミリ秒後に緑色の「保存済み」になり、1.6秒後に元の文字に戻ります。

保存状態付き設定フォームセクション
新しいタブで開く

07 · 保存状態付き設定フォームセクション — 計測 累積面積 0.167% · 動いたフレーム 10/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transitionaria-checkedclick

コードで見る所

設定ページ丸ごとではなく、このセクションだけを移植できるよう<form>ひとつで閉じています。

save.classList.add('is-busy'); label.textContent = '保存中';
setTimeout(function () {
  save.classList.remove('is-busy'); save.classList.add('is-done'); label.textContent = '保存済み';
  setTimeout(function () { save.classList.remove('is-done'); label.textContent = '保存'; }, 1600);
}, 700);

08通知ドロップダウンパネル

何が動くか

ベルアイコンを押すと、パネルが実際にその場から広がって開きます。

通知ドロップダウンパネル
新しいタブで開く

08 · 通知ドロップダウンパネル — 計測 累積面積 5.662% · 動いたフレーム 9/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transform-originaria-expandedclick

コードで見る所

通知を1件押すとその項目だけ既読になり、上のバッジの数字が残りの未読数だけ実際に減ります。

function syncBadge() {
  var n = document.querySelectorAll('.np__item.is-unread').length;
  badge.textContent = String(n);
  badge.style.display = n > 0 ? '' : 'none';
}
it.addEventListener('click', function () { it.classList.remove('is-unread'); syncBadge(); });

09ユーザーアバタードロップダウン

何が動くか

アバターを押すと、メニューが右上を基点に実際に広がって開きます。

ユーザーアバタードロップダウン
新しいタブで開く

09 · ユーザーアバタードロップダウン — 計測 累積面積 28.833% · 動いたフレーム 10/23GODRICH オリジナル · SCSS と React は zip に同梱 · パスワードを見る

transformEscapeclick

コードで見る所

外側をクリックするか Esc キーを押すと実際に閉じ、メニュー自体をクリックしたときは閉じないよう closest('.um') で範囲を区別しています。

document.addEventListener('click', function (e) {
  if (!e.target.closest('.um')) close();
});
document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });

どこで壊れるか — 落とし穴

ダッシュボード デザイン、どこで壊れるか?

9個を作る間に実際にはまった落とし穴は、通知とユーザーメニュー2つのポップアップの縦位置でした。舞台のCSSがウィジェットを画面中央に揃えるため、ベルやアバターがキャンバス中央に来て、その下に開くパネルが300pxの舞台の底より下にはみ出し、スクロールバーが出てしまいました。中央揃えではなく上揃えに変えて、ようやくパネル全体が1画面に収まりました。幅320px・縦が短い画面ではさらに厳しく、パネルの見出しと説明文まで全部入れると縦200pxに収まらず、狭い画面では見出しと通知の説明文だけを隠し、太字の項目名だけ残す調整を別に行いました。ドーナツチャートは最初数字が上がる部品だけを集めたのが天気 ウィジェット 9選です。SVGの弧2本で描こうとしましたが、開始角度をそろえる計算がずれ続けたため、conic-gradientと@propertyに切り替えてから、値ひとつの変更だけで滑らかに切り替わるようになりました。並び替え表は最初、行ごとに背景色が順番に流れる作りにしましたが、実測すると隣り合うフレーム間の変化がほとんどなく「動いていない」と判定されました。表の上から下へ実際に移動するハイライト帯1本に変えたところ、この9個の圧縮ファイルのパスワードrzae7dqhで開いた最新のzipでは、表も他の8個と同じくはっきり動きます。

アクセシビリティ

押さえた点

9個すべて prefers-reduced-motion: reduce では装飾用の繰り返しアニメーション(サイドバーの自動開閉、スパークラインの自動描画、フィルターチップの自動押下、ベルとアバターの淡いパルス)を止めますが、実際の状態値はそのまま残します。通知パネル(08)とユーザーメニュー(09)は role="menu"・role="menuitem" を備え、外側クリックやEscで閉じます。設定フォーム(07)のトグルは role="switch" と aria-checked を持ち、Enterとスペースキーだけで操作できます。並び替え表(03)のボタンは aria-sort で今の並び順を伝え、空状態(06)で追加されたカードは aria-hidden を実際に切り替えて、見えないカードをスクリーンリーダーが読まないようにしています。この実装はMDNのARIAウィジェットロール文書を参考にしました。

次に見る所

ほかのテンプレート素材はテンプレートカテゴリーに、このサイト全体の内容は紹介ページにあります。

FAQ

完成した管理画面テンプレートではなく、この ウィジェット デザイン 1個だけ使ってもいいですか?

はい、それがこの9個を作った理由です。どのデモもページ全体ではなくウィジェット1個だけを画面に置いていて、zipの中にもその1個分のHTML・SCSS・JSだけが入っているので、自分のプロジェクトのサイドバーやヘッダーにそのまま移せます。初めて開いた人を画面に沿って案内する側はチュートリアル UI デザインで別に扱っています。

React版はCSS版と動きが違いますか?

動きは同じです。開閉や選択のような状態は useState で持ち、変数3つ(duration・easing・color)はpropsで受け取ってCSSカスタムプロパティに渡します。ドーナツのカウントアップは useEffect の中で requestAnimationFrame を使って同じ計算を繰り返します。

通知バッジの数字やサイドバーの折りたたみは実際に動いていますか、それとも装飾ですか?

実際に動いています。通知を押すとその項目の未読状態が実際に変わり、バッジは残りの件数を数え直して表示します。サイドバーのボタンも幅の値を実際に変えます。自動再生のGIFで見える繰り返しの動きは、人が触る前だけ回る装飾ループで、クリックやタップした瞬間に止まります。

解凍パスワードを入力してください

パスワードはこの記事の本文の中にあります。読み進めると出てきます。