← Blog

Scorciatoie da tastiera con useKeymap

Dichiara un’associazione una sola volta con useKeymap e Text.js instrada il tasto, lo elenca in una schermata di aiuto ?, lo mostra nel piè di pagina e lo aggiunge a una palette di comandi Ctrl+K.

Adam

Finora, un’app Text.js gestiva i tasti in useInput e li elencava una seconda volta, a mano, in un piè di pagina <KeyHint>. useKeymap sostituisce entrambi con un’unica dichiarazione.

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 />    </>  );}

Premere j esegue next. Su macOS, <KeyHints> mostra j/↓ Next e ⌃S Save nel piè di pagina, perché quelle associazioni impostano hint. ? apre una schermata di aiuto con tutte e quattro, raggruppate sotto Navigation, e Ctrl+K apre una palette in cui puoi cercarle.

Sintassi dei tasti

SintassiSignificato
ctrl+kModificatori: ctrl, alt, shift, meta e mod
mod+k⌘ o Ctrl, a seconda di quale tieni premuto
j, downAlternative
g gUna sequenza, con un massimo di 1 secondo tra i tasti
GLa maiuscola implica Shift
?I tasti stampabili corrispondono al carattere

Un’associazione è un handler oppure un oggetto con label, group, hint, command, disabled e noRepeat. command: false esclude dalla palette un’associazione con etichetta. Le associazioni senza etichetta funzionano, ma restano fuori dalla schermata di aiuto e dalla palette.

Instradamento

Ogni mappa dei tasti registra un handler useInput, quindi si applicano le regole di input esistenti. Un <Input> con il focus gestisce i tasti per primo, perché gli editor ascoltano con priorità 10 e le mappe dei tasti con priorità 0. Un tasto che trova corrispondenza interrompe la propagazione. Un <Modal> aperto disabilita le associazioni al di fuori di esso, a meno che la mappa dei tasti non passi global: true.

Le sequenze vengono riconosciute all’interno di quell’handler. Un tasto che avvia una sequenza resta in attesa e interrompe la propagazione, e la sequenza si azzera quando il tasto successivo arriva dopo più di sequenceTimeout (1000 ms per impostazione predefinita):

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

Un registro per ogni radice

Le associazioni con etichetta sono pubblicate in un registro che appartiene alla radice della console. <KeyHelp>, <KeyHints> e <CommandPalette> lo leggono, e anche i tuoi componenti possono farlo tramite useKeymapBindings(). Quando una finestra modale è aperta, il registro restituisce solo le associazioni al suo interno, così la schermata di aiuto elenca i tasti che funzionano in quel momento.

Le mappe dei tasti sono solitamente scritte inline, creando un nuovo oggetto a ogni rendering. Per limitarne il costo, una mappa dei tasti ripubblica le proprie etichette solo quando cambia la loro forma visibile:

// 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");

Gli handler vengono letti da un ref quando arriva un tasto, quindi una nuova closure a ogni rendering non è mai obsoleta.

La schermata di aiuto e la palette

<KeyHelp> si apre con ? ed elenca per gruppo ogni associazione attiva con etichetta. keys e title cambiano il tasto di attivazione e il titolo.

<CommandPalette> si apre con Ctrl+K o Ctrl+P. Esegue una ricerca per corrispondenza approssimata tra i tuoi commands e tutte le associazioni con etichetta, ed evidenzia le lettere corrispondenti. Si chiude prima di eseguire un comando, così un comando può aprire una propria finestra modale.

formatKeys formatta un’associazione per la visualizzazione. formatKeys("ctrl+shift+p") restituisce ⌃⇧P su macOS e ctrl+shift+P altrove, e <Kbd> visualizza un singolo tasto con la stessa formattazione.

useKeymap, <KeyHelp>, <KeyHints>, <StatusBar> e <CommandPalette> sono inclusi in Text.js 1.0. La documentazione di riferimento si trova in Tastiera.