组件 · 输入
KbdButton
包住可修改快捷键的按钮,以及它录制中和无效时的样子;不能修改的快捷键仍然用 KbdShortcut。
也叫 Shortcut binding, Shortcut recorder, Keybinding, Hotkey input
import { KbdButton } from "@botiverse/raft-ui/wip";KbdButton 是快捷键列表里包住可修改快捷键的控件。它包着一个 md 的 KbdShortcut;点击后,它变成一个输入框,录下接下来按的快捷键。Kbd 本身从不是控件,所以悬停、焦点环和点击都由按钮承担,键帽仍是只读列表里显示的那些键帽。
何时使用
只在绑定可以修改的地方用它。什么也改不了的按钮,是一个启用着却没有作用的控件;只读的绑定仍然用 Kbd,这样列表一眼就能看出哪些快捷键可以修改。
结构
KbdButton:原生按钮。必需。在里面放一个md的KbdShortcut:静止时是当前的按键,录制时是目前已经按住的按键。KbdButtonPlaceholder:录制中的 KbdButton 在按下任何键之前显示的提示,由使用方提供("Press a shortcut");或者没有快捷键的命令所显示的文字("No shortcut")。可选。KbdButtonCaret:按住的按键后面的插入符,表示输入框还在等更多按键。可选:按键已经落定、被拒绝,或被暂留等待选择时,就去掉它。
表示快捷键被改过的标记(行标签前的黄色圆点,以及行的第二行上它的默认快捷键)和 Reset 按钮属于行,不属于 KbdButton:它们是产品的状态。
状态
用点击开始录制时,输入框不显示焦点环,就像用鼠标点击的文本输入框也不显示一样:它的边框、插入符和行的高亮已经标出了它,而且这个人刚刚就指着那里(焦点)。用 Enter 或 Space 开始时,保留焦点环。
插入符不闪烁:它标出下一个按键落在哪里;在供人阅读的列表里,闪烁是不带任何新信息的动效(动效)。
尺寸
- 静止时,按钮的方框在键帽四周各超出 4px,包着 24px 的键帽,高 32px;再用负外边距把这 4px 收回来,所以键帽正好在只读
KbdShortcut所在的位置:在行尾,在行内垂直居中,行高也不变。它的点击区域达到 44px(无障碍)。 - 录制时,输入框是控件高度,和旁边的输入框、按钮一样高;它的外边距收回比键帽多出的部分:用鼠标时是 (34 − 24) / 2 = 5px,触屏上是 10px。键帽和行的边缘之间至少要留这么多:ListRow 的 12px 就够(ListRow)。输入框向起始端扩展,所以它的末端保持在行尾。
行为
KbdButton 负责画出各个状态;录下按键由产品来做。
- 点击、按 Enter 或按 Space 开始录制。录制时,每次按键都是快捷键:阻止它的默认行为,实时显示按住的修饰键,在第一个不是修饰键的按键上落定快捷键。
- 按 Esc、点击别处或离开面板都会取消;在有效的快捷键落定之前,什么都不保存。
- 让不带修饰键的 Tab 离开输入框并取消,这样录制永远不会困住键盘。
- 不能用的按键(浏览器或系统保留的按键、单个按键)以
invalid状态留在输入框里,原因写在行的第二行,直到下一次按键;录制保持开启。 - 属于另一个命令的按键先暂留,不保存:保留输入框,去掉插入符,在行下面附一条提示,带 Cancel 和各个选项(Banner)。
无障碍
- KbdButton 是 Base UI 的 Button,即原生
button。它自己没有文字:用aria-label按它对应的命令给它命名("Change the shortcut for Search")。键帽的视觉隐藏文字会被这个名称取代。 - 用
aria-keyshortcuts传入当前的快捷键(Meta+K),让读屏软件能读出来;没有快捷键的命令就不要加。 data-recording和data-invalid是样式钩子,不会播报。把aria-describedby指向行的第二行,产品在那里写操作说明("Press the new shortcut, Esc to cancel")或拒绝这些按键的原因。- 附在行上的提示关闭时,把焦点移回 KbdButton,以免焦点落在文档本身上。
- 不要加
aria-pressed:录制不是按下后一直保持开启的切换,标成按下的按钮传达的意思是错的。
规则
API
KbdButton
A shortcut that can be changed: a native button around a KbdShortcut at `md`. Name it with `aria-label` ("Change the shortcut for Search") and pass the current keys in `aria-keyshortcuts`. A shortcut that can't be changed stays a KbdShortcut, with no button.
| Prop | 类型 | 默认值 |
|---|---|---|
| The keys in it can't be used: the caps take the danger tint, the field a danger border, and it sets `data-invalid`. Say why in text the button names with `aria-describedby`. | boolean | false |
| The button is listening for a new shortcut: it draws as a field with the focus ring when it was reached from the keyboard, and sets `data-recording`. Put the held keys in it, then `KbdButtonCaret` while more can come. | boolean | false |
| Whether the button should be focusable when disabled. | boolean | false |
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | boolean | true |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
KbdButtonCaret, KbdButtonPlaceholder
The caret after the held keys, while a recording KbdButton waits for more.
接受其元素的全部属性。