Angular ARIA Listbox 组件 API 完全指南:从 ngListbox/ngOption 到键盘导航与焦点管理

Angular ARIA Listbox 组件 API 完全指南:从 ngListbox/ngOption 到键盘导航与焦点管理 Angular ARIA Listbox 组件 API 完全指南从 ngListbox/ngOption 到键盘导航与焦点管理【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components本文以官方 API 报告 goldens/aria/listbox/index.api.md 为核心骨架结合本仓库Angular Components即 Material Design components for Angular中ngListbox与ngOption指令的完整源码实现系统讲解该无障碍 Listbox 组件的公共 API、输入参数、事件模型、键盘交互、焦点策略与测试手段。读完本文你将能独立实现一个符合 WAI-ARIA Listbox 模式、支持单/多选、roving tabindex 或 activedescendant 焦点管理、typeahead 搜索的 Angular 列表选择组件并能在单元测试中通过官方 Harness 进行交互断言。一、关联文档概览一份自动生成的公共 API 快照goldens/aria/listbox/index.api.md 是由 API Extractor 针对angular/aria_listbox包自动生成的 API 报告它精确刻画了该包的对外公共面。其核心结论有三包对外只导出三个符号指令类ListboxV、指令类Option源码中为Option_2导出别名Option、以及注入令牌LISTBOXListboxV是一个泛型指令V即选项 value 的泛型类型它通过大量InputSignal/ModelSignal暴露声明式输入例如id、orientation、multi、focusMode、selectionMode、value等报告中的ɵdir字段揭示了真实的指令元数据选择器分别为[ngListbox]exportAsngListbox与[ngOption]exportAsngOption且value与valueChange组成双向绑定的一对。API 报告中的“undocumented”标记仅表示该成员缺少 JSDoc 注释不代表其不可用。例如scrollActiveItemIntoView、gotoFirst、gotoIndex等命令式方法以及LISTBOX令牌都属于稳定公共 API。二、核心指令与模板用法ngListbox ngOption从源码 src/aria/listbox/listbox.ts 的Directive装饰器可以看到Listbox指令选择器为[ngListbox]宿主元素被赋予rolelistbox并动态绑定id、tabindex、aria-readonly、aria-disabled、aria-orientation、aria-multiselectable、aria-activedescendant等 ARIA 属性Option指令选择器为[ngOption]宿主元素被赋予roleoption并绑定aria-selected、aria-disabled、data-active等属性见 src/aria/listbox/option.ts。官方 JSDoc 给出的最小完整模板如下ul ngListbox [(value)]selectedItems [multi]true orientationvertical for (item of items; track item.id) { li ngOption [value]item.id [label]item.name [disabled]item.disabled {{item.name}} /li } /ul要点说明[(value)]是双向绑定value的类型为V[]见readonly value: ModelSignalV[]任何时刻都能取到当前选中项的值数组ngOption的value是必填输入input.requiredV()它决定该项选中后写入value数组的元素label输入作为可访问名称与 typeahead 搜索文本见searchTerm: () this.label() ?? disabled输入使单个选项不可交互。指令内部还通过providers: [{provide: LISTBOX, useExisting: Listbox}]将自身注册到LISTBOX注入令牌src/aria/listbox/tokens.tsOption构造时通过inject(LISTBOX)反向拿到父级 Listbox并在ngOnInit/ngOnDestroy中向父级的SortedCollection注册/注销自己从而维护有序的选项集合。三、Listbox 输入参数全解附默认值与取值范围结合 API 报告与 src/aria/listbox/listbox.ts 的input()声明各输入如下输入类型默认值说明idstring由_IdGenerator生成形如ng-listbox-0宿主元素 id也是aria-activedescendant引用的根orientationvertical \| horizontalvertical列表方向决定上下/左右方向键映射multibooleanbooleanAttribute 变换false是否允许多选开启后渲染aria-multiselectablewrapbooleanbooleanAttribute 变换true焦点导航是否循环范围选择时会临时关闭softDisabledbooleanbooleanAttribute 变换true为true时禁用项仍可获得焦点但不可交互为false时导航直接跳过禁用项focusModeroving \| activedescendantroving焦点管理策略详见第四节selectionModefollow \| explicitfollowfollow表示焦点跟随即自动选中explicit表示用户必须显式确认空格/回车/点击typeaheadDelaynumber毫秒500typeahead 输入缓冲重置时间源码注释标注“Picked arbitrarily”可按需调整disabledbooleanbooleanAttribute 变换false整体禁用禁用时键盘/点击事件被忽略见onKeydown/onClick的if (!this.disabled())守卫readonlybooleanbooleanAttribute 变换false只读模式仍可导航与搜索但不改变选中状态tabindex别名tabindexnumber \| undefinedundefined自定义容器 tabindex未设置时由_pattern.tabIndex()即-1或0决定valueV[]ModelSignal[]当前选中值数组支持[(value)]双向绑定并通过valueChange输出注意tabindex输入在源码中使用了别名alias: tabindex因此模板里应写成[tabindex]...这也是 API 报告中tabIndex: { alias: tabindex }的由来。所有布尔输入均通过booleanAttribute变换因此支持ul ngListbox multi wrap这种“裸属性”写法。四、焦点管理roving tabindex 与 activedescendant 两种策略focusMode决定键盘焦点落在哪里见 src/aria/listbox/listbox.ts 的 JSDoc 与宿主绑定roving默认焦点随导航移动到当前激活的ngOption上各选项的tabindex由ListPattern统一调度_pattern.tabIndex()列表容器本身不可聚焦activedescendant焦点始终停留在 listbox 容器上当前项通过宿主属性aria-activedescendant绑定_pattern.activeDescendant()指示选项自身保持tabindex-1。对应地Listbox对外暴露了两个命令式 APIgotoFirst()把激活项移到列表第一项内部调用listBehavior.first()gotoIndex(index)按索引导航索引越界时被钳制到[0, length-1]见Math.min(Math.max(index, 0), patterns.length - 1)scrollActiveItemIntoView(options?)调用激活项元素的scrollIntoView默认{block: nearest}适合长列表滚动场景。从源码结构看src/aria/private/behaviors/list/list.ts底层List行为聚合了四个子行为ListFocus焦点与 tabindex 分配、ListNavigation方向键/Home/End 导航与 wrap、ListSelection单/多选、范围选择与 anchor 锚点、ListTypeahead按键搜索。这解释了为何一个看似简单的列表组件拥有如此完整的键盘语义。五、键盘与鼠标交互矩阵键盘与点击的完整映射实现在 src/aria/private/listbox/listbox.ts 的keydown与clickManager两个 computed 中可归纳如下键盘导航所有模式ArrowUp/ArrowDown垂直方向水平方向为ArrowLeft/ArrowRightRTL 下自动镜像见prevKey/nextKey对textDirection的判断Home/End跳到首/末项单字符按键触发 typeahead正则typeaheadRegexp /^.$/匹配任意单字符。选择语义selectionModefollow模式方向键移动即同时{selectOne: true}选中该项explicit模式Space/Enter切换选中状态多选时Ctrl/Meta A全选、Ctrl/Meta 点击单独切换某一项。多选范围选择multi true 时额外生效按下Shift记录 anchor 锚点Shift 方向键、Shift Home/End、Shift Space、Shift Enter执行范围选择{selectRange: true}范围选择期间自动关闭 wrap避免循环定位错乱。只读模式readonly true只保留导航、Home/End 与 typeahead所有选择类快捷键被移除点击仅移动焦点goto。点击行为单选 follow点击即{selectOne: true}单选 explicit点击{toggle: true}多选 follow普通点击选中、Ctrl/Command 点击切换多选 explicit点击即切换。所有点击都通过target.closest([roleoption])定位选项。此外softDisabledtrue时禁用项仍可聚焦、不可选中整个组件disabled时onKeydown与onClick直接短路仅onFocusIn仍记录交互状态。六、内置一致性校验开发模式ListboxPattern.validate()见 src/aria/private/listbox/listbox.ts在开发模式下ngDevMode通过afterRenderEffect自动检测三类错误并在控制台reportViolations单选框multifalse却选中了多个值选项value重复Duplicate option value ... detected inside ngListbox.选项id重复。这能帮助开发者在开发期尽早发现数据配置问题生产构建无ngDevMode自动跳过该开销。七、测试支持Listbox Harness仓库为测试提供了完整的 Component Harness见 src/aria/listbox/testing/listbox-harness.tsListboxHarness宿主选择器[ngListbox]支持getOrientation()、isMulti()、isDisabled()、getActiveDescendantId()、focus()/blur()、getOptions(filters?)ListboxOptionHarness宿主选择器[ngOption]支持isSelected()、isDisabled()、getText()、click()其static with()谓词可按text、selected、disabled过滤选项过滤参数定义于 src/aria/listbox/testing/listbox-harness-filters.ts完整的交互测试示例见 src/aria/listbox/testing/listbox-harness.spec.ts 与 src/aria/listbox/listbox.spec.ts。典型测试片段const listbox await loader.getHarness(ListboxHarness); const options await listbox.getOptions({selected: true}); expect(await options[0].getText()).toBe(Option 1);八、与其他 ARIA 组件的关系Listbox是仓库angular/aria系列无障碍组件族的基石之一。源码 JSDoc 明确指向同族的 Autocompleteguide/aria/autocomplete、Selectguide/aria/select与 Multiselectguide/aria/multiselect同时ListboxPattern/OptionPattern及其底层List、ListNavigation、ListSelection、ListTypeahead等行为类被提取到 src/aria/private 目录作为可复用的 UI 行为层供整个 ARIA 组件族共享。理解ngListbox的输入/事件契约是深入阅读这些上层组件源码的最佳切入点。九、实践清单与注意事项双向绑定始终使用[(value)]绑定选中值数组组件会主动将value与现存选项同步源码中afterRenderEffect会过滤掉已不存在的值必填 value每个ngOption必须提供唯一的value否则开发模式会收到重复值告警按需调整默认值typeaheadDelay默认 500ms与softDisabled默认 true、wrap默认 true、focusMode默认 roving均应按产品交互修改例如触屏/视障场景更推荐activedescendant长列表可调用scrollActiveItemIntoView()在程序化导航gotoFirst/gotoIndex后把激活项滚入视野测试优先使用ListboxHarness/ListboxOptionHarness断言aria-selected、aria-activedescendant与点击、键盘交互避免直接操作 DOM。通过本文对 API 报告逐符号的解读、与 listbox.ts、option.ts、私有行为层 的源码对照你已经掌握了angular/aria_listbox从声明式输入、双向模型、键盘/鼠标语义到焦点策略、开发期校验与测试 Harness 的完整知识闭环可以放心在无障碍要求严格的生产项目中使用或在其基础上二次开发。【免费下载链接】componentsComponent infrastructure and Material Design components for Angular项目地址: https://gitcode.com/GitHub_Trending/co/components创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考