開発日記: 2026年01月13日 - キーボードショートカットで「遊び場」を実現

開発日記: 2026年01月13日 - キーボードショートカットで「遊び場」を実現

今日の作業

今日はテスラジオの「パワーユーザー体験」を大幅に強化しました。Vim風のキーボードナビゲーション、用語ツールチップ、ランダム選択機能など、テクノロジー好きな視聴者が楽しめる機能を多数追加しています。

エピソードページに「ランダムに選ぶ」機能を追加

「今日はどのエピソードを見よう?」と迷ったときのために、サイコロで決められる機能を実装しました。

  • クリックするとサイコロが720度回転するアニメーション
  • ランダムに選ばれたエピソードへ自動スクロール
  • パルスハイライトで選ばれたカードを強調表示
  • 連続クリックでも前回と同じものは選ばれない仕組み

scrollIntoView({ behavior: 'smooth', block: 'center' })でスムーズに中央表示され、box-shadowのアニメーションで選択されたカードが光る演出を入れました。

用語タグにホバーツールチップを追加

エピソードカードの用語タグにホバーすると、その用語の説明がツールチップで表示されるようになりました。

  • カテゴリアイコン、説明文(100文字まで)、「クリックで詳細へ」のヒントを表示
  • モバイルではタップでトグル表示
  • ダークモード対応済み
  • GlossaryTooltip.astroコンポーネントとして再利用可能に

これにより、用語集ページに遷移せずに専門用語の意味を確認できます。

3つの主要ページにキーボードショートカットを展開

エピソード、用語集、ブログ一覧の3ページに、統一されたキーボードショートカットを実装しました。

共通ショートカット

  • J / K - 次/前のアイテムに移動(Vim風)
  • R - ランダムに選択
  • T - ページトップに戻る
  • ? - ショートカットヘルプを表示
  • Escape - 選択解除 / フィルターをクリア

ページ固有ショートカット

  • / - 検索/フィルターにフォーカス(用語集・ブログ)
  • Enter - 選択中のアイテムを開く

右下に常時表示のヒントボタン「?」を配置し、クリックでもヘルプモーダルを開けます。

トップページにも用語タグを展開

FeaturedEpisodes(注目のエピソード)とLatestEpisodeBanner(最新エピソード)にも用語タグ+ツールチップを追加。サイト全体で一貫したUI/UXを実現しました。

学んだこと

キーボードショートカットの実装パターン

// 入力中はショートカットを無効化
if (document.activeElement.matches('input, textarea')) return;

// 選択状態の追跡
let currentSelectedIndex = -1;

// 表示中のアイテムのみを対象に
function getVisibleCards() {
  return Array.from(cards).filter(card =>
    card.style.display !== 'none'
  );
}

フィルター状態と連動させるためにgetVisibleCards()で表示中のアイテムのみを対象にするのがポイントでした。

CSSでキーボードキーを表現

kbd {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  background: linear-gradient(180deg, #fafafa 0%, #e4e4e4 100%);
  border: 1px solid #ccc;
  border-radius: 4px;
  box-shadow:
    0 1px 1px rgba(0,0,0,.15),
    inset 0 1px 0 rgba(255,255,255,.8);
  font-family: monospace;
  font-size: 0.85rem;
}

box-shadowを重ねることで物理キーボードのような立体感を表現できます。

次にやりたいこと

  • キーボードショートカットのアクセシビリティ改善(aria-live、スクリーンリーダー対応)
  • ショートカット設定のカスタマイズ機能(将来的に)
  • G + 数字キーでページ間ジャンプ(例: G1=Episodes, G2=Glossary, G3=Blog)
  • ツールチップの表示位置調整(画面端でのはみ出し対策)

この記事はClaude Codeによって自動生成されました。