输入与按键映射

用键盘浏览部署,并添加 ? 帮助浮层。

本章应用正在你的控制台中运行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 打开控制台(先开启开发者功能),然后试用。
观看本章3:25

本章内容

  • `useInput`
  • 按键映射
  • 帮助浮层
  • 焦点

按键通过页面上的隐藏输入框传递给应用,因此页面需要获得焦点。这就是每个 Text.js 应用都要求你先点击页面的原因。页面获得焦点后,你按下的每个键都会传递给 React。

useInput

useInput 是你目前一直在用的底层 Hook。它接收一个 KeyEvent,其中包含规范化的 key("up"、"return"、"escape")、input 中的输入字符,以及 ctrl、alt、shift 和 meta。

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

调用 e.stopPropagation(),阻止按键继续传递给树中更下层的处理程序。

按键映射

当一个界面需要处理的按键超过两三个时,用 useKeymap 来描述它们。绑定使用字符串表示:"up, k" 表示任一按键,"g g" 表示按键序列,"ctrl+k" 表示组合键。带标签的绑定还会显示在 <KeyHelp>、<KeyHints> 和命令面板中。

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

目前,DEPLOYMENTS 是 lib/deployments.ts 中的一个普通数组。第 6 章会改为通过路由处理程序访问它。

帮助浮层

<KeyHelp /> 监听 ?,并打开一个模态窗口,分组列出当前所有生效且带标签的绑定。在控制台中按 ? 打开,再按 ? 或 q 关闭。模态窗口内的绑定会将焦点限制在窗口内,因此下方的列表会停止响应,直到窗口关闭。

焦点

<Input>、<Select> 和 <Table> 等组件只有在获得焦点时才接收按键。Tab 在这些组件之间切换焦点;useFocus() 和 useFocusManager() 则供你自行控制焦点。

试用

这是本章结束时的 Acme Deploys,正在 DevTools 中运行。点击输入区,然后使用下列按键。

▼ 04 · 输入与按键映射

打开控制台

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

应用在 DevTools 中渲染。先在 Safari 设置 → 高级中开启“显示网页开发者功能”。 然后点击这里并按 ↓。

在桌面端打开

此应用在 DevTools 控制台中渲染,需要桌面浏览器。

测验

2 个问题

回答所有问题以完成本章。

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

 

为什么输入前要点击页面?