← Blog

Atajos de teclado con useKeymap

Declara una asignación una vez con useKeymap y Text.js dirige la tecla, la enumera en una pantalla de ayuda con ?, la muestra en el pie y la añade a una paleta de comandos con Ctrl+K.

Adam

Hasta ahora, una app de Text.js gestionaba las teclas en useInput y las enumeraba una segunda vez, a mano, en un pie de página con <KeyHint>. useKeymap sustituye ambas cosas con una sola declaración.

import { CommandPalette, KeyHelp, KeyHints, StatusBar, Text, useKeymap } from "@textjs/react";export default function Sessions() {  useKeymap(    {      "j, down": { label: "Next", run: next, hint: true },      "k, up": { label: "Previous", run: previous },      "g g": { label: "Go to top", run: top },      "ctrl+s": { label: "Save", run: save, hint: true },    },    { group: "Navigation" },  );  return (    <>      <StatusBar right={<Text color="subtle">main</Text>}>        <KeyHints />      </StatusBar>      <CommandPalette commands={commands} />      <KeyHelp />    </>  );}

Al pulsar j se ejecuta next. En macOS, <KeyHints> muestra j/↓ Next y ⌃S Save en el pie de página, porque esas asignaciones definen hint. ? abre una pantalla de ayuda con las cuatro, agrupadas bajo Navegación, y Ctrl+K abre una paleta que permite buscarlas.

Sintaxis de teclas

SintaxisSignificado
ctrl+kModificadores: ctrl, alt, shift, meta y mod
mod+k⌘ o Ctrl, según cuál se mantenga pulsada
j, downAlternativas
g gUna secuencia, con hasta 1 segundo entre teclas
GLa mayúscula implica Shift
?Las teclas imprimibles coinciden con el carácter

Una asignación es un manejador o un objeto con label, group, hint, command, disabled y noRepeat. command: false excluye de la paleta una asignación con etiqueta. Las asignaciones sin etiqueta funcionan, pero no aparecen en la pantalla de ayuda ni en la paleta.

Enrutamiento

Cada mapa de teclas registra un manejador de useInput, por lo que se aplican las reglas de entrada existentes. Un <Input> con el foco gestiona las teclas primero, porque los editores escuchan con prioridad 10 y los mapas de teclas con prioridad 0. Una tecla que coincide detiene la propagación. Un <Modal> abierto desactiva las asignaciones externas, salvo que el mapa de teclas pase global: true.

Las secuencias se reconocen dentro de ese manejador. Una tecla que inicia una secuencia queda pendiente y detiene la propagación, y la secuencia se reinicia cuando la siguiente tecla llega después de más de sequenceTimeout (1000 ms de forma predeterminada):

if (p.events.length > 0 && now - p.at > sequenceTimeout) p.events = [];

Un registro por raíz

Las asignaciones con etiqueta se publican en un registro que pertenece a la raíz de la consola. <KeyHelp>, <KeyHints> y <CommandPalette> leen de él, y tus propios componentes también pueden hacerlo mediante useKeymapBindings(). Mientras un modal está abierto, el registro devuelve solo las asignaciones de su interior, de modo que la pantalla de ayuda enumera las teclas que funcionan en ese momento.

Los mapas de teclas suelen escribirse en línea, lo que crea un objeto nuevo en cada renderizado. Para mantener un coste bajo, un mapa de teclas vuelve a publicar sus etiquetas solo cuando cambia su forma visible:

// Publish labels only when the visible shape changes (inline keymap objects are fine).const signature = compiled  .map((c) => `${c.keys}\u0000${c.binding.label ?? ""}\u0000${c.binding.group ?? ""}\u0000${c.binding.hint ? 1 : 0}${c.binding.command === false ? 0 : 1}\u0000${c.binding.disabled ? 1 : 0}`)  .join("\u0001");

Los manejadores se leen de una referencia cuando llega una tecla, por lo que un cierre nuevo en cada renderizado nunca queda desactualizado.

La pantalla de ayuda y la paleta

<KeyHelp> se abre con ? y enumera por grupo todas las asignaciones activas con etiqueta. keys y title cambian la tecla de activación y el encabezado.

<CommandPalette> se abre con Ctrl+K o Ctrl+P. Busca coincidencias aproximadas entre tus commands y todas las asignaciones con etiqueta, y resalta las letras coincidentes. Se cierra antes de ejecutar un comando, de modo que un comando puede abrir su propio modal.

formatKeys renderiza una asignación para mostrarla. formatKeys("ctrl+shift+p") devuelve ⌃⇧P en macOS y ctrl+shift+P en los demás sistemas, y <Kbd> renderiza una sola tecla con el mismo formato.

useKeymap, <KeyHelp>, <KeyHints>, <StatusBar> y <CommandPalette> se incluyen en Text.js 1.0. La referencia está en Teclado.