Use Cases

Implémentation d'une palette de commandes avec Claude Code

Découvrez l'implémentation d'une palette de commandes avec Claude Code. Conseils pratiques et exemples de code inclus.

Améliorer radicalement l’expérience utilisateur avec une palette de commandes

La palette de commandes, que l’on retrouve dans VSCode ou Slack, est un élément d’interface destiné aux utilisateurs avancés permettant des opérations rapides au clavier. Avec Claude Code, vous pouvez implémenter efficacement une palette de commandes dotée de recherche, filtrage et navigation clavier.

Composant de palette de commandes de base

> Implémente une palette de commandes qui s'ouvre avec Cmd+K (Mac) / Ctrl+K (Windows).
> Avec recherche, navigation clavier et affichage par catégorie.
// components/CommandPalette.tsx
import { useState, useEffect, useRef, useCallback } from 'react';

interface Command {
  id: string;
  label: string;
  category: string;
  icon?: string;
  shortcut?: string;
  action: () => void;
}

interface CommandPaletteProps {
  commands: Command[];
}

export function CommandPalette({ commands }: CommandPaletteProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [query, setQuery] = useState('');
  const [selectedIndex, setSelectedIndex] = useState(0);
  const inputRef = useRef<HTMLInputElement>(null);

  const filtered = commands.filter(cmd =>
    cmd.label.toLowerCase().includes(query.toLowerCase()) ||
    cmd.category.toLowerCase().includes(query.toLowerCase())
  );

  // Raccourci global
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
        e.preventDefault();
        setIsOpen(prev => !prev);
      }
      if (e.key === 'Escape') setIsOpen(false);
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, []);

  // Gestion du focus
  useEffect(() => {
    if (isOpen) {
      inputRef.current?.focus();
      setQuery('');
      setSelectedIndex(0);
    }
  }, [isOpen]);

  const handleKeyNav = useCallback((e: React.KeyboardEvent) => {
    switch (e.key) {
      case 'ArrowDown':
        e.preventDefault();
        setSelectedIndex(i => Math.min(i + 1, filtered.length - 1));
        break;
      case 'ArrowUp':
        e.preventDefault();
        setSelectedIndex(i => Math.max(i - 1, 0));
        break;
      case 'Enter':
        e.preventDefault();
        if (filtered[selectedIndex]) {
          filtered[selectedIndex].action();
          setIsOpen(false);
        }
        break;
    }
  }, [filtered, selectedIndex]);

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-start justify-center pt-[20vh]">
      <div className="fixed inset-0 bg-black/50" onClick={() => setIsOpen(false)} />
      <div className="relative w-full max-w-lg rounded-xl bg-white shadow-2xl dark:bg-gray-800">
        <input
          ref={inputRef}
          type="text"
          value={query}
          onChange={e => { setQuery(e.target.value); setSelectedIndex(0); }}
          onKeyDown={handleKeyNav}
          placeholder="Rechercher une commande..."
          className="w-full border-b px-4 py-3 text-lg outline-none dark:bg-gray-800"
        />
        <ul className="max-h-80 overflow-y-auto p-2" role="listbox">
          {filtered.map((cmd, index) => (
            <li
              key={cmd.id}
              role="option"
              aria-selected={index === selectedIndex}
              onClick={() => { cmd.action(); setIsOpen(false); }}
              className={`flex cursor-pointer items-center justify-between rounded-lg px-3 py-2
                ${index === selectedIndex ? 'bg-blue-50 dark:bg-blue-900/30' : 'hover:bg-gray-50'}`}
            >
              <div className="flex items-center gap-3">
                {cmd.icon && <span className="text-lg">{cmd.icon}</span>}
                <div>
                  <div className="font-medium">{cmd.label}</div>
                  <div className="text-xs text-gray-500">{cmd.category}</div>
                </div>
              </div>
              {cmd.shortcut && (
                <kbd className="rounded bg-gray-100 px-2 py-1 text-xs dark:bg-gray-700">
                  {cmd.shortcut}
                </kbd>
              )}
            </li>
          ))}
          {filtered.length === 0 && (
            <li className="px-3 py-8 text-center text-gray-500">
              Aucune commande correspondante
            </li>
          )}
        </ul>
      </div>
    </div>
  );
}

Définition et enregistrement des commandes

// hooks/useCommands.ts
import { useRouter } from 'next/navigation';

export function useCommands(): Command[] {
  const router = useRouter();

  return [
    {
      id: 'home', label: 'Aller à l\'accueil', category: 'Navigation',
      icon: '🏠', shortcut: 'G H',
      action: () => router.push('/'),
    },
    {
      id: 'blog', label: 'Liste des articles', category: 'Navigation',
      icon: '📝', shortcut: 'G B',
      action: () => router.push('/blog'),
    },
    {
      id: 'theme', label: 'Changer de thème', category: 'Paramètres',
      icon: '🌙', shortcut: 'T T',
      action: () => document.documentElement.classList.toggle('dark'),
    },
    {
      id: 'search', label: 'Rechercher un article', category: 'Recherche',
      icon: '🔍', shortcut: '/',
      action: () => router.push('/search'),
    },
  ];
}

Support de l’accessibilité

// Application WAI-ARIA
<div
  role="dialog"
  aria-modal="true"
  aria-label="Palette de commandes"
>
  <input
    role="combobox"
    aria-expanded="true"
    aria-controls="command-list"
    aria-activedescendant={`command-${filtered[selectedIndex]?.id}`}
  />
  <ul id="command-list" role="listbox">
    {/* ... */}
  </ul>
</div>

Résumé

La palette de commandes, combinée aux raccourcis clavier, améliore considérablement la productivité des utilisateurs avancés. Avec Claude Code, vous pouvez implémenter en peu de temps une palette de commandes complète avec recherche, filtrage et navigation clavier. Pensez aussi à l’accessibilité pour viser une interface utilisable par tous. Comme référence d’implémentation, envisagez aussi la bibliothèque cmdk.

#Claude Code #palette de commandes #UI #navigation clavier #React

Passez votre flux Claude Code au niveau supérieur

50 modèles de prompts éprouvés, prêts à être copiés-collés dans Claude Code.

Gratuit

PDF gratuit : aide-mémoire Claude Code en 5 minutes

Commandes clés, raccourcis et exemples de prompts sur une seule page imprimable.

Télécharger le PDF
M

À propos de l'auteur

Masa

Ingénieur passionné par Claude Code. Il gère claudecode-lab.com, un média tech en 10 langues avec plus de 2 000 pages.