Atalhos de teclado com useKeymap
Declare uma associação uma vez com useKeymap, e Text.js direciona a tecla, lista-a em uma tela de ajuda ?, exibe-a no rodapé e a adiciona a uma paleta de comandos Ctrl+K.
Até agora, um app Text.js tratava teclas em useInput e as listava uma segunda vez, manualmente, em um rodapé <KeyHint>. useKeymap substitui ambos por uma única declaração.
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 /> </> );}Pressionar j executa next. No macOS, <KeyHints> mostra j/↓ Next e ⌃S Save no rodapé, porque essas associações definem hint. ? abre uma tela de ajuda com as quatro associações, agrupadas em Navigation, e Ctrl+K abre uma paleta que permite buscá-las.
Sintaxe das teclas
| Sintaxe | Significado |
|---|---|
ctrl+k | Modificadores: ctrl, alt, shift, meta e mod |
mod+k | ⌘ ou Ctrl, conforme a tecla mantida pressionada |
j, down | Alternativas |
g g | Uma sequência, com até 1 segundo entre as teclas |
G | Maiúscula implica Shift |
? | Teclas imprimíveis correspondem ao caractere |
Uma associação é um handler ou um objeto com label, group, hint, command, disabled e noRepeat. command: false mantém uma associação com rótulo fora da paleta. Associações sem rótulo funcionam, mas ficam fora da tela de ajuda e da paleta.
Roteamento
Cada mapa de teclas registra um handler useInput, então as regras de entrada existentes se aplicam. Um <Input> com foco trata as teclas primeiro, porque os editores escutam na prioridade 10 e os mapas de teclas na 0. Uma tecla correspondente interrompe a propagação. Um <Modal> aberto desativa as associações fora dele, a menos que o mapa de teclas passe global: true.
As sequências são identificadas dentro desse handler. Uma tecla que inicia uma sequência fica pendente e interrompe a propagação, e a sequência é reiniciada quando a próxima tecla chega após mais de sequenceTimeout (1.000 ms por padrão):
if (p.events.length > 0 && now - p.at > sequenceTimeout) p.events = [];Um registro por raiz
As associações com rótulo são publicadas em um registro que pertence à raiz do console. <KeyHelp>, <KeyHints> e <CommandPalette> leem esse registro, e seus próprios componentes também podem lê-lo por meio de useKeymapBindings(). Enquanto um modal está aberto, o registro retorna apenas as associações dentro dele, então a tela de ajuda lista as teclas que funcionam naquele momento.
Os mapas de teclas costumam ser escritos inline, o que cria um novo objeto a cada renderização. Para manter esse custo baixo, um mapa de teclas republica seus rótulos apenas quando sua forma visível muda:
// 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");Os handlers são lidos de uma ref quando uma tecla chega, então uma nova closure a cada renderização nunca fica desatualizada.
A tela de ajuda e a paleta
<KeyHelp> abre com ? e lista por grupo todas as associações ativas com rótulo. keys e title alteram o acionador e o título.
<CommandPalette> abre com Ctrl+K ou Ctrl+P. Ela faz uma busca aproximada em seus commands e em todas as associações com rótulo, e destaca as letras correspondentes. Ela fecha antes de executar um comando, então um comando pode abrir seu próprio modal.
formatKeys renderiza uma associação para exibição. formatKeys("ctrl+shift+p") retorna ⌃⇧P no macOS e ctrl+shift+P nos demais sistemas, e <Kbd> renderiza uma única tecla com a mesma formatação.
useKeymap, <KeyHelp>, <KeyHints>, <StatusBar> e <CommandPalette> estão incluídos no Text.js 1.0. A referência está em Teclado.