浮层
SearchableMenu
一个能打字筛选的动作菜单。
什么时候用它
DropdownMenu 超过十几行就不再能扫读,而用二级菜单去救只会更糟。这就是同一份列表加上一个过滤框。它不是 Command 面板:那个是页面级的、模态的;这个锚在某个控件上。
示例
default
说明
一个能打字筛选的动作菜单。
这个正方形本来只有三个角,它是第四个;值得把区别讲清楚,因为拿错太容易了:
| | 选项少 | 选项多 | |---|---|---| | 设置一个值 | Select | Combobox | | 执行一个动作 | DropdownMenu | SearchableMenu |
DropdownMenu 超过十几行就不再能扫读,而通常的应对——套二级菜单——只会更糟。这个就是同一份列表,上面加一个筛选框。
和 Command 不是一回事:那个是页面级的面板,通常是模态的,通常绑在 ⌘K 上。这个锚在某个控件上,就像它替代的那个菜单一样。
这些行是 listbox 里的 option 而不是 menuitem,因为筛选这个模式要求如此——高亮通过 aria-activedescendant 移动而焦点留在输入框里,菜单做不到这件事。这个取舍是刻意的:一个没法筛的菜单,对读者来说比一个会执行动作的 listbox 更糟。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| actions必填 | MenuAction[] | — | |
| children必填 | ReactNode | 触发器上的文字。 | |
| label必填 | string | 给这个菜单起名字,供辅助技术使用。 | |
| align | 'start' | 'center' | 'end' | 'start' | — |
| className | string | — | |
| emptyMessage | string | 'Nothing matches.' | — |
| searchPlaceholder | string | 'Filter…' | — |
键盘操作
| 按键 | 作用 |
|---|---|
| EnterSpace | 打开菜单。 |
| ↑↓ | 移动高亮,焦点始终留在筛选框里。 |
| Enter | 执行高亮那一项动作。 |
| Escape | 什么都不执行,直接关闭。 |
无障碍
- 在有边界的框里——设备预览、内嵌控制台——用 `<OverlayContainer container={el}>` 包住这棵子树。面板会渲染进那个元素,按它的边界翻转,而不是按视口;框上设的 `dir` 和 `data-density` 也就跟着生效了。
- 行是 listbox 里的 option 而不是 menuitem,因为过滤这件事要求如此——高亮通过 aria-activedescendant 移动,焦点留在输入框里,而菜单做不到。
- 这个取舍是刻意的:一个没法筛的菜单,对读者来说比一个会执行动作的 listbox 更糟。