Use Cases

Implementacion de paleta de comandos con Claude Code

Aprende sobre la implementacion de una paleta de comandos usando Claude Code. Incluye consejos practicos y ejemplos de codigo.

Mejorando drasticamente la experiencia de usuario con una paleta de comandos

La paleta de comandos, como las que se ven en VSCode y Slack, es un elemento de UI para usuarios avanzados que permite operar rapidamente solo con el teclado. Con Claude Code, puedes implementar eficientemente una paleta de comandos con busqueda, filtrado y navegacion por teclado.

Componente basico de paleta de comandos

> Implementa una paleta de comandos que se abra con Cmd+K (Mac) / Ctrl+K (Windows).
> Con soporte para busqueda, operacion por teclado y visualizacion por categorias.
// 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())
  );

  // Atajo 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);
  }, []);

  // Control de foco
  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="Buscar comandos..."
          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">
              No se encontraron comandos coincidentes
            </li>
          )}
        </ul>
      </div>
    </div>
  );
}

Definicion y registro de comandos

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

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

  return [
    {
      id: 'home', label: 'Ir al inicio', category: 'Navegacion',
      icon: '🏠', shortcut: 'G H',
      action: () => router.push('/'),
    },
    {
      id: 'blog', label: 'Lista del blog', category: 'Navegacion',
      icon: '📝', shortcut: 'G B',
      action: () => router.push('/blog'),
    },
    {
      id: 'theme', label: 'Cambiar tema', category: 'Configuracion',
      icon: '🌙', shortcut: 'T T',
      action: () => document.documentElement.classList.toggle('dark'),
    },
    {
      id: 'search', label: 'Buscar articulos', category: 'Busqueda',
      icon: '🔍', shortcut: '/',
      action: () => router.push('/search'),
    },
  ];
}

Soporte de accesibilidad

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

Resumen

La paleta de comandos, combinada con los atajos de teclado, mejora significativamente la productividad de los usuarios avanzados. Con Claude Code, puedes implementar en poco tiempo una paleta de comandos completa con busqueda, filtrado y navegacion por teclado. No olvides considerar tambien la accesibilidad para crear una UI accesible para todos los usuarios. Como referencia de implementacion, considera tambien la biblioteca cmdk.

#Claude Code #paleta de comandos #UI #operacion por teclado #React