Entrada e mapas de teclas

Navegue pelos deploys com o teclado e adicione uma sobreposição de ajuda com ?.

O app deste capítulo está rodando no seu console. Abra o console com ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (ative os recursos de desenvolvedor primeiro), depois experimente.
Assistir ao capítulo3:25

Neste capítulo

  • `useInput`
  • Mapas de teclas
  • A sobreposição de ajuda
  • Foco

As teclas pressionadas chegam ao seu app por um campo de entrada oculto na página, por isso a página precisa estar com foco. É por isso que todo app Text.js pede que você clique na página primeiro. Quando ela está com foco, cada tecla que você pressiona é entregue ao React.

useInput

useInput é o hook de baixo nível que você usou até aqui. Ele recebe um KeyEvent com uma key normalizada ("up", "return", "escape"), o caractere digitado em input e ctrl, alt, shift e meta.

useInput((e) => {  if (e.ctrl && e.key === "k") openPalette();});

Chame e.stopPropagation() para impedir que uma tecla chegue aos manipuladores mais abaixo na árvore.

Mapas de teclas

Quando uma tela tiver mais do que algumas teclas, descreva-as com useKeymap. As associações são strings: "up, k" representa qualquer uma das duas teclas, "g g" é uma sequência, "ctrl+k" é uma combinação. As associações com rótulos também aparecem em <KeyHelp>, <KeyHints> e na paleta de comandos.

app/deployments/page.tsx+31tsx
Adicionado: import { useState } from "react";Adicionado: import { Box, KeyHelp, Text, useKeymap } from "@textjs/app";Adicionado: import { DEPLOYMENTS } from "../../lib/deployments";Adicionado: Adicionado: export default function DeploymentsPage() {Adicionado:   const [index, setIndex] = useState(0);Adicionado:   const [open, setOpen] = useState(false);Adicionado:   const move = (by: number) => setIndex((i) => Math.max(0, Math.min(DEPLOYMENTS.length - 1, i + by)));Adicionado: Adicionado:   useKeymap({Adicionado:     "up, k": { label: "Previous deployment", run: () => move(-1) },Adicionado:     "down, j": { label: "Next deployment", run: () => move(1) },Adicionado:     enter: { label: "Toggle details", run: () => setOpen((o) => !o) },Adicionado:     "g g": { label: "First deployment", run: () => setIndex(0) },Adicionado:   });Adicionado: Adicionado:   return (Adicionado:     <Box className="flex-row grow p-1 gap-2">Adicionado:       <Box className="flex-col grow">Adicionado:         {DEPLOYMENTS.map((d, i) => (Adicionado:           <Box key={d.id} className="flex-row h-1 gap-2 px-1" backgroundColor={i === index ? "selection" : undefined}>Adicionado:             <Text>{i === index ? "›" : " "}</Text>Adicionado:             <Text bold={i === index} wrap="truncate-end">{d.commit}</Text>Adicionado:           </Box>Adicionado:         ))}Adicionado:       </Box>Adicionado:       {open && <Details deployment={DEPLOYMENTS[index]} />}Adicionado:       <KeyHelp />Adicionado:     </Box>Adicionado:   );Adicionado: }

Por enquanto, DEPLOYMENTS é um array comum em lib/deployments.ts. O capítulo 6 passa a acessá-lo por meio de um manipulador de rota.

A sobreposição de ajuda

<KeyHelp /> escuta a tecla ? e abre um modal que lista, em grupos, todas as associações com rótulos ativas no momento. Pressione ? no console e depois ? ou q para fechá-lo. As associações dentro de um modal retêm o foco, então a lista por baixo para de reagir até que ele seja fechado.

Foco

Componentes como <Input>, <Select> e <Table> só recebem teclas enquanto estão com foco. Tab move o foco entre eles; useFocus() e useFocusManager() permitem que você faça isso por conta própria.

Experimentar

Este é Acme Deploys ao final do capítulo, rodando no DevTools. Clique na área de entrada e use as teclas abaixo.

▼ 04 · Entrada e mapas de teclas

Abrir o console

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

O app renderiza no DevTools.Primeiro ative “Mostrar recursos para desenvolvedores web” em Ajustes do Safari → Avançado. Depois clique aqui e pressione ↓.

Abrir em um computador

Este app renderiza no console do DevTools, que precisa de um navegador de computador.

Questionário

2 perguntas

Responda a todas as perguntas para concluir o capítulo.

In useKeymap, what does the binding "g g" mean?

 

Por que você clica na página antes de digitar?