Tips & Tricks

Como implementar atajos de teclado con Claude Code

Aprenda a implementar atajos de teclado usando Claude Code. Incluye ejemplos practicos de codigo y guia paso a paso.

キーボードショートカットで操作効率を向上

キーボードショートカットは、パワーユーザーの操作効率を劇的に向上させる機能です。Claude Codeを使えば、ショートカットの登録・管理・ヘルプ表示を体系的に実装できます。

ショートカット管理システムの構築

> Webアプリ用のキーボードショートカットシステムを実装して。
> 修飾キー対応、スコープ管理、コンフリクト検出をサポートして。
// lib/shortcuts.ts
type ShortcutHandler = (e: KeyboardEvent) => void;

interface Shortcut {
  key: string;
  modifiers: ('ctrl' | 'shift' | 'alt' | 'meta')[];
  handler: ShortcutHandler;
  description: string;
  scope?: string;
}

class ShortcutManager {
  private shortcuts: Map<string, Shortcut> = new Map();
  private activeScope: string = 'global';

  constructor() {
    window.addEventListener('keydown', this.handleKeyDown.bind(this));
  }

  private buildId(key: string, modifiers: string[]): string {
    return [...modifiers.sort(), key.toLowerCase()].join('+');
  }

  register(shortcut: Shortcut): () => void {
    const id = this.buildId(shortcut.key, shortcut.modifiers);
    
    if (this.shortcuts.has(id)) {
      console.warn(`ショートカットの競合: ${id}`);
    }

    this.shortcuts.set(id, shortcut);
    return () => this.shortcuts.delete(id);
  }

  setScope(scope: string): void {
    this.activeScope = scope;
  }

  private handleKeyDown(e: KeyboardEvent): void {
    // 入力フィールドでは無効化
    const target = e.target as HTMLElement;
    if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) return;
    if (target.isContentEditable) return;

    const modifiers: string[] = [];
    if (e.ctrlKey) modifiers.push('ctrl');
    if (e.shiftKey) modifiers.push('shift');
    if (e.altKey) modifiers.push('alt');
    if (e.metaKey) modifiers.push('meta');

    const id = this.buildId(e.key, modifiers);
    const shortcut = this.shortcuts.get(id);

    if (shortcut && (!shortcut.scope || shortcut.scope === this.activeScope)) {
      e.preventDefault();
      shortcut.handler(e);
    }
  }

  getAll(): Shortcut[] {
    return Array.from(this.shortcuts.values());
  }

  destroy(): void {
    window.removeEventListener('keydown', this.handleKeyDown);
    this.shortcuts.clear();
  }
}

export const shortcuts = new ShortcutManager();

Reactフックでの利用

// hooks/useShortcut.ts
import { useEffect } from 'react';
import { shortcuts } from '../lib/shortcuts';

export function useShortcut(
  key: string,
  modifiers: ('ctrl' | 'shift' | 'alt' | 'meta')[],
  handler: () => void,
  description: string
) {
  useEffect(() => {
    const unregister = shortcuts.register({
      key,
      modifiers,
      handler,
      description,
    });
    return unregister;
  }, [key, modifiers, handler, description]);
}

// Usage example
function BlogEditor() {
  useShortcut('s', ['ctrl'], () => saveDraft(), '下書き保存');
  useShortcut('Enter', ['ctrl'], () => publish(), '公開');
  useShortcut('p', ['ctrl', 'shift'], () => togglePreview(), 'プレビュー切替');

  return <div>{/* エディタUI */}</div>;
}

ショートカットヘルプダイアログ

// components/ShortcutHelp.tsx
import { useState, useEffect } from 'react';
import { shortcuts } from '../lib/shortcuts';

export function ShortcutHelp() {
  const [isOpen, setIsOpen] = useState(false);

  useEffect(() => {
    const unregister = shortcuts.register({
      key: '?',
      modifiers: ['shift'],
      handler: () => setIsOpen(prev => !prev),
      description: 'ショートカット一覧を表示',
    });
    return unregister;
  }, []);

  if (!isOpen) return null;

  const allShortcuts = shortcuts.getAll();
  const grouped = Object.groupBy(allShortcuts, s => s.scope ?? 'global');

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50">
      <div className="w-full max-w-md rounded-xl bg-white p-6 dark:bg-gray-800">
        <h2 className="mb-4 text-xl font-bold">キーボードショートカット</h2>
        {Object.entries(grouped).map(([scope, items]) => (
          <div key={scope} className="mb-4">
            <h3 className="mb-2 text-sm font-semibold uppercase text-gray-500">
              {scope}
            </h3>
            {items?.map(s => (
              <div key={s.description} className="flex items-center justify-between py-1">
                <span>{s.description}</span>
                <kbd className="rounded bg-gray-100 px-2 py-0.5 text-sm dark:bg-gray-700">
                  {[...s.modifiers, s.key].join(' + ')}
                </kbd>
              </div>
            ))}
          </div>
        ))}
        <button onClick={() => setIsOpen(false)} className="mt-4 w-full rounded bg-gray-100 py-2">
          閉じる (Esc)
        </button>
      </div>
    </div>
  );
}

OS別のキー表示対応

function formatShortcut(modifiers: string[], key: string): string {
  const isMac = navigator.platform.includes('Mac');
  const symbolMap: Record<string, string> = isMac
    ? { ctrl: '⌃', shift: '⇧', alt: '⌥', meta: '⌘' }
    : { ctrl: 'Ctrl', shift: 'Shift', alt: 'Alt', meta: 'Win' };

  return [...modifiers.map(m => symbolMap[m]), key.toUpperCase()].join(isMac ? '' : '+');
}

Summary

キーボードショートカットはコマンドパレットと連携させると最も効果的です。Claude Codeを使えば、入力フィールドでの無効化やスコープ管理など、エッジケースを考慮した堅牢な実装が可能です。アクセシビリティの観点からも、キーボード操作のサポートは重要です。ショートカット設計のベストプラクティスはNielsen Norman Groupを参考にしてください。

#Claude Code #keyboard shortcuts #accessibility #UX #JavaScript