-
Notifications
You must be signed in to change notification settings - Fork 287
feat: 添加组件无障碍功能支持 #3383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat_v3.x
Are you sure you want to change the base?
feat: 添加组件无障碍功能支持 #3383
Conversation
- button - Checkbox - Countdown - Empty - Image - InputNumber - Price - Progress - NavBar - NoticeBar - Radio - Switch - Tabbar - Tabs - Toast
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough此PR为NutUI React组件库的多个组件系统添加ARIA可访问性属性支持,包括角色、标签、选中状态等属性,同时新增相关演示和类型定义,以改进屏幕阅读器兼容性。 Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 需要特别关注的区域:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 32
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/packages/tabs/tabs.tsx (1)
161-213: 建议完善 ARIA Tabs 模式的实现当前实现添加了基本的 ARIA 属性(
role="tablist"、role="tab"、aria-selected),这是一个良好的开端。但完整的 ARIA Tabs 模式还需要以下增强:
- 键盘导航支持:应实现方向键(左/右或上/下)、Home、End 键的导航
- tabIndex 管理:活动标签应设置
tabIndex={0},非活动标签设置tabIndex={-1}- aria-controls:每个标签应通过
aria-controls属性关联到对应的面板 ID这些是 ARIA 规范中 Tabs 模式的必需特性,能显著提升键盘用户和屏幕阅读器用户的体验。
参考 ARIA Tabs 模式获取完整实现指南。
src/packages/inputnumber/inputnumber.tsx (2)
183-198: 建议完善按钮的无障碍实现当前添加了
role="button"和tabIndex={0},使元素可聚焦,但还需要以下改进才能成为完整的可访问按钮:
- aria-label:添加描述性标签(如
aria-label="减少数值")- aria-disabled:反映禁用状态
aria-disabled={Number(shadowValue) <= Number(min) || disabled}- 键盘激活:添加
onKeyDown处理程序以支持 Enter 和 Space 键激活建议修改:
<div className={`${classPrefix}-minus`} onClick={handleReduce} role="button" tabIndex={0} + aria-label="减少数值" + aria-disabled={Number(shadowValue) <= Number(min) || disabled} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + handleReduce(e as any) + } + }} >
212-227: 增加按钮也需要完善的无障碍实现与减少按钮类似,增加按钮也需要添加
aria-label、aria-disabled和键盘激活支持。建议修改:
<div className={`${classPrefix}-add`} role="button" tabIndex={0} onClick={handlePlus} + aria-label="增加数值" + aria-disabled={Number(shadowValue) >= Number(max) || disabled} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + e.preventDefault() + handlePlus(e as any) + } + }} >src/packages/image/demo.tsx (1)
25-36: 修正拼写错误翻译键名称中存在拼写错误。应该是 "ARIA"(Accessible Rich Internet Applications),而不是 "ATRIA"。
应用此修复:
- ATRIAUsage: 'ATRIA用法', + ARIAUsage: 'ARIA用法', }, 'en-US': { basic: 'Basic Usage', @@ -32,7 +32,7 @@ error: 'Error', lazyload: 'Lazyload', imageText: 'image + text ', - ATRIAUsage: 'ATRIA Usage', + ARIAUsage: 'ARIA Usage', },
🧹 Nitpick comments (18)
src/packages/toast/Notification.tsx (1)
137-137: 考虑为不同类型的 Toast 使用不同的 ARIA 角色当前为所有 Toast 类型统一使用
role="alert"。虽然这对于 success、fail、warn 等提示类消息是合适的,但对于loading类型的 Toast,role="status"可能更为恰当,因为:
role="alert"隐式设置了aria-live="assertive",会立即打断屏幕阅读器loading状态更适合使用role="status"(隐式aria-live="polite"),以非打断方式通知用户建议根据 Toast 类型动态设置 role:
<div className={classNames( `${classPrefix}-inner`, `${classPrefix}-${position}`, contentClassName, `${classPrefix}-inner-${size}`, `${classPrefix}-inner-${wordBreak}`, { [`${classPrefix}-inner-descrption`]: content, } )} style={{ ...contentStyle, }} - role="alert" + role={icon === 'loading' ? 'status' : 'alert'} >src/packages/toast/toast.taro.tsx (1)
181-181: 建议为不同类型的 Toast 使用不同的 ARIA 角色与
Notification.tsx中的建议一致,Taro 版本也应该根据 Toast 类型动态设置ariaRole:
- 对于
loading类型,使用ariaRole="status"更为合适(非打断式通知)- 对于
success、fail、warn等类型,使用ariaRole="alert"是恰当的(立即通知)建议应用以下修改:
<View className={classNames( `${classPrefix}-inner`, `${classPrefix}-${position}`, contentClassName, `${classPrefix}-inner-${size}`, `${classPrefix}-inner-${wordBreak}`, { [`${classPrefix}-inner-descrption`]: content, } )} style={{ ...styles, ...contentStyle }} - ariaRole="alert" + ariaRole={icon === 'loading' ? 'status' : 'alert'} >src/packages/switch/switch.tsx (1)
85-93: 应根据禁用状态条件性地设置 tabIndex。无障碍属性的添加总体良好,但
tabIndex={0}应仅在组件未禁用时应用。当前实现即使在禁用状态下也会使元素可聚焦,这不符合无障碍最佳实践。应用以下修改:
<div className={classes()} onClick={onClick} style={style} {...rest} role="switch" - tabIndex={0} + tabIndex={disabled ? -1 : 0} aria-checked={value} >另外,建议添加键盘事件处理器以支持空格键和回车键切换开关状态:
+const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === ' ' || e.key === 'Enter') { + e.preventDefault() + onClick() + } +} + <div className={classes()} onClick={onClick} + onKeyDown={handleKeyDown} style={style} {...rest} role="switch" tabIndex={disabled ? -1 : 0} aria-checked={value} >src/packages/checkbox/checkbox.taro.tsx (1)
206-207: 考虑为不确定状态添加aria-checked="mixed"支持当前实现中,
ariaChecked在不确定状态(indeterminate)时值为false,但根据 ARIA 规范,复选框的不确定状态应该使用aria-checked="mixed"来正确传达给辅助技术。建议修改为:
ariaRole="checkbox" - ariaChecked={innerChecked && !innerIndeterminate} + ariaChecked={ + innerIndeterminate ? 'mixed' : innerChecked + }src/packages/navbar/navbar.taro.tsx (2)
70-70: 建议支持 ARIA 标签的国际化
ariaLabel="back"使用了硬编码的英文文本,这会影响非英语用户的无障碍体验。建议通过组件 props 或国际化系统来支持多语言的 ARIA 标签。
87-87: 标题的 ARIA 标签也需要国际化支持与返回按钮类似,
ariaLabel="nav title"的硬编码英文文本应该支持国际化,以便为不同语言的用户提供适当的无障碍标签。src/packages/inputnumber/inputnumber.taro.tsx (2)
185-200: 建议为按钮添加更完善的无障碍属性当前只添加了
ariaRole="button",但缺少其他重要的无障碍属性:
- ariaLabel: 应该添加描述性标签(如 "减少数值"),让屏幕阅读器用户了解按钮用途
- ariaDisabled: 当按钮禁用时(值达到最小值或 disabled 为 true),应该设置
ariaDisabled={true}来明确传达状态建议修改:
<View className={`${classPrefix}-minus`} onClick={handleReduce} ariaRole="button" + ariaLabel="减少数值" + ariaDisabled={Number(shadowValue) <= Number(min) || disabled} >
216-231: 增加按钮也需要完善的无障碍属性与减少按钮类似,增加按钮也应该添加
ariaLabel和ariaDisabled属性以提供完整的无障碍支持。建议修改:
<View className={`${classPrefix}-add`} onClick={handlePlus} ariaRole="button" + ariaLabel="增加数值" + ariaDisabled={Number(shadowValue) >= Number(max) || disabled} >src/types/spec/countdown/base.ts (1)
30-30: 建议将ariaRoledescription设为可选属性
ariaRoledescription通常不是所有倒计时场景都需要的属性。建议在类型定义中将其标记为可选:- ariaRoledescription: string + ariaRoledescription?: string或者确保在组件的
defaultProps中提供合理的默认值(如空字符串)。src/packages/navbar/navbar.tsx (1)
69-69: 建议支持 ARIA 标签的国际化与 Taro 版本类似,这里的
aria-label="back"和aria-label="nav title"使用了硬编码的英文文本。建议通过组件 props 或国际化系统来支持多语言的无障碍标签,以便为全球用户提供适当的无障碍体验。Also applies to: 86-86
src/packages/tabs/tabs.taro.tsx (2)
236-236: 检查冗余的角色属性在同一个元素上同时使用了
role="tablist"和ariaRole="tablist"。在 Taro 中,通常只需要使用ariaRole属性,role属性可能是冗余的。建议验证 Taro 文档以确认正确的用法。如果只需要
ariaRole,可以移除role属性:- <View className="nut-tabs-list" role="tablist" ariaRole="tablist"> + <View className="nut-tabs-list" ariaRole="tablist">
262-263: 验证 ariaHidden 属性语法
ariaHidden属性没有显式设置值。在 Taro 中,建议明确设置布尔值。建议明确设置为
true:- ariaHidden + ariaHidden={true}src/packages/navbar/demos/taro/demo4.tsx (1)
1-113: ARIA 演示实现良好此演示文件很好地展示了如何在 NavBar 组件中使用 ARIA 属性。各个交互元素都添加了适当的
ariaLabel,有助于屏幕阅读器用户理解界面。可选建议:第 59 和 63 行的
ariaLabel是添加在文本容器上的,这些元素不是交互元素,可以考虑是否需要这些标签。通常aria-label用于交互元素或需要替代文本的元素。src/packages/countdown/countdown.tsx (1)
296-300: 避免在 dangerouslySetInnerHTML 中使用字符串插值虽然当前代码中
role和alertContent是组件内部控制的,没有直接的 XSS 风险,但使用dangerouslySetInnerHTML配合字符串插值不是最佳实践。建议使用 React 的 ARIA live region 方法来实现提醒功能。建议重构为使用单独的元素和 React 状态:
- aria-label="倒计时" - aria-roledescription={ariaRoledescription} - {...rest} - dangerouslySetInnerHTML={{ - __html: `${renderTime}<span style="display:none" role=${role}>${alertContent}</span>`, - }} + aria-label="倒计时" + aria-roledescription={ariaRoledescription} + {...rest} + > + <div dangerouslySetInnerHTML={{ __html: renderTime }} /> + {role && ( + <span style={{ display: 'none' }} role={role}> + {alertContent} + </span> + )} + </div> - />这样可以避免在 HTML 字符串中插值,更安全且更符合 React 最佳实践。
src/sites/components/header.tsx (1)
32-32: 返回按钮无障碍属性正确为返回按钮添加
role='button'和aria-label='back'提高了可访问性,有助于屏幕阅读器用户理解此元素的功能。可选建议:为保持代码风格一致性,可以考虑使用双引号:
- <div className="back" onClick={navigateTo} role='button' aria-label='back'> + <div className="back" onClick={navigateTo} role="button" aria-label="back">src/packages/popup/popup.taro.tsx (1)
316-316: 建议添加 aria-modal 属性当 Popup 作为对话框(dialog)呈现并且具有遮罩层时,应该添加
ariaModal属性以向辅助技术指示这是一个模态对话框。这是 ARIA 对话框模式的最佳实践。应用以下修改:
onTouchEnd={handleTouchEnd} ariaRole="dialog" + ariaModal={overlay && innerVisible} >src/packages/image/demos/taro/demo9.tsx (1)
9-9: 建议澄清alt和ariaLabel的使用场景Image 组件同时使用了
alt="图片内容"和ariaLabel="图片"。对于图片元素,aria-label会覆盖alt文本。通常情况下:
- 仅使用
alt即可满足大多数无障碍需求aria-label适用于需要为屏幕阅读器提供与alt不同的额外上下文时建议在演示中明确两者的使用场景,或根据实际需求选择其一,避免混淆。
src/packages/noticebar/noticebar.tsx (1)
460-462: 建议显式设置 aria-hidden 值虽然在 HTML/React 中,
aria-hidden不带值会被浏览器解析为字符串 "true",但显式设置布尔值aria-hidden={true}会更清晰且与 TypeScript 的类型检查更一致。可选改进:
{leftIcon ? ( - <div className="nut-noticebar-box-left-icon" aria-hidden> + <div className="nut-noticebar-box-left-icon" aria-hidden="true"> {leftIcon} </div>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (70)
src/packages/button/button.taro.tsx(1 hunks)src/packages/checkbox/checkbox.taro.tsx(1 hunks)src/packages/checkbox/checkbox.tsx(1 hunks)src/packages/countdown/countdown.taro.tsx(4 hunks)src/packages/countdown/countdown.tsx(4 hunks)src/packages/countdown/demo.taro.tsx(5 hunks)src/packages/countdown/demo.tsx(5 hunks)src/packages/countdown/demos/h5/demo10.tsx(1 hunks)src/packages/countdown/demos/taro/demo10.tsx(1 hunks)src/packages/dialog/content.taro.tsx(2 hunks)src/packages/dialog/content.tsx(2 hunks)src/packages/dialog/dialog.taro.tsx(5 hunks)src/packages/dialog/dialog.tsx(2 hunks)src/packages/image/demo.taro.tsx(4 hunks)src/packages/image/demo.tsx(4 hunks)src/packages/image/demos/h5/demo9.tsx(1 hunks)src/packages/image/demos/taro/demo9.tsx(1 hunks)src/packages/image/image.taro.tsx(2 hunks)src/packages/image/image.tsx(2 hunks)src/packages/inputnumber/inputnumber.taro.tsx(2 hunks)src/packages/inputnumber/inputnumber.tsx(2 hunks)src/packages/navbar/demo.taro.tsx(2 hunks)src/packages/navbar/demo.tsx(2 hunks)src/packages/navbar/demos/h5/demo4.tsx(1 hunks)src/packages/navbar/demos/taro/demo4.tsx(1 hunks)src/packages/navbar/navbar.taro.tsx(3 hunks)src/packages/navbar/navbar.tsx(3 hunks)src/packages/noticebar/demo.taro.tsx(4 hunks)src/packages/noticebar/demo.tsx(4 hunks)src/packages/noticebar/demos/h5/demo12.tsx(1 hunks)src/packages/noticebar/demos/taro/demo12.tsx(1 hunks)src/packages/noticebar/noticebar.taro.tsx(4 hunks)src/packages/noticebar/noticebar.tsx(4 hunks)src/packages/popup/popup.taro.tsx(1 hunks)src/packages/popup/popup.tsx(1 hunks)src/packages/price/price.taro.tsx(1 hunks)src/packages/price/price.tsx(1 hunks)src/packages/progress/progress.taro.tsx(1 hunks)src/packages/progress/progress.tsx(1 hunks)src/packages/radio/radio.taro.tsx(1 hunks)src/packages/radio/radio.tsx(1 hunks)src/packages/swiper/demo.taro.tsx(4 hunks)src/packages/swiper/demos/taro/demo10.tsx(1 hunks)src/packages/swiper/effects/default.tsx(3 hunks)src/packages/swiper/effects/focus.tsx(1 hunks)src/packages/swiper/swiper.taro.tsx(2 hunks)src/packages/swiper/swiper.tsx(2 hunks)src/packages/switch/switch.taro.tsx(1 hunks)src/packages/switch/switch.tsx(1 hunks)src/packages/tabbar/demo.taro.tsx(5 hunks)src/packages/tabbar/demo.tsx(5 hunks)src/packages/tabbar/demos/h5/demo10.tsx(1 hunks)src/packages/tabbar/demos/taro/demo10.tsx(1 hunks)src/packages/tabbaritem/tabbaritem.taro.tsx(1 hunks)src/packages/tabbaritem/tabbaritem.tsx(2 hunks)src/packages/tabs/tabs.taro.tsx(3 hunks)src/packages/tabs/tabs.tsx(3 hunks)src/packages/toast/Notification.tsx(1 hunks)src/packages/toast/toast.taro.tsx(1 hunks)src/sites/components/header.tsx(1 hunks)src/types/spec/countdown/base.ts(1 hunks)src/types/spec/dialog/base.ts(1 hunks)src/types/spec/dialog/taro.ts(1 hunks)src/types/spec/image/base.ts(1 hunks)src/types/spec/noticebar/base.ts(1 hunks)src/types/spec/popup/base.ts(1 hunks)src/types/spec/progress/base.ts(1 hunks)src/types/spec/radio/base.ts(2 hunks)src/types/spec/swiper/taro.ts(1 hunks)src/types/spec/tabbar/base.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: oasis-cloud
Repo: jdf2e/nutui-react PR: 2700
File: src/packages/animatingnumbers/animatingnumbers.harmony.css:25-32
Timestamp: 2024-11-06T05:56:06.800Z
Learning: 在优化 NutUI React 动画性能时,添加 `will-change` 属性可能会对布局产生影响,需要谨慎使用。
📚 Learning: 2024-11-06T05:56:06.800Z
Learnt from: oasis-cloud
Repo: jdf2e/nutui-react PR: 2700
File: src/packages/animatingnumbers/animatingnumbers.harmony.css:25-32
Timestamp: 2024-11-06T05:56:06.800Z
Learning: 在优化 NutUI React 动画性能时,添加 `will-change` 属性可能会对布局产生影响,需要谨慎使用。
Applied to files:
src/packages/noticebar/demos/h5/demo12.tsxsrc/packages/noticebar/demos/taro/demo12.tsx
📚 Learning: 2024-07-05T02:58:57.992Z
Learnt from: Alex-huxiyang
Repo: jdf2e/nutui-react PR: 2416
File: src/packages/uploader/uploader.taro.tsx:230-230
Timestamp: 2024-07-05T02:58:57.992Z
Learning: When changes are made to the `fileList` state in the `src/packages/uploader/uploader.taro.tsx` file, ensure to generate unit tests to cover these changes.
Applied to files:
src/packages/checkbox/checkbox.taro.tsx
📚 Learning: 2025-05-02T01:45:09.576Z
Learnt from: irisSong
Repo: jdf2e/nutui-react PR: 3209
File: src/packages/searchbar/searchbar.taro.tsx:111-124
Timestamp: 2025-05-02T01:45:09.576Z
Learning: 在 React/Taro 组件中使用 setTimeout 或 setInterval 时,应当在组件卸载时通过 useEffect 的清理函数清除定时器,以防止内存泄漏。可以使用 useState 存储定时器 ID,并在 useEffect 的返回函数中清除。
Applied to files:
src/packages/countdown/demos/h5/demo10.tsxsrc/packages/countdown/demos/taro/demo10.tsxsrc/packages/navbar/demos/taro/demo4.tsxsrc/packages/countdown/countdown.taro.tsx
🧬 Code graph analysis (14)
src/packages/swiper/effects/focus.tsx (1)
src/hooks/use-ref-state.ts (1)
getRefValue(3-5)
src/packages/noticebar/demos/h5/demo12.tsx (3)
src/packages/noticebar/noticebar.taro.tsx (1)
NoticeBar(35-556)src/packages/noticebar/noticebar.tsx (1)
NoticeBar(35-551)src/packages/button/button.taro.tsx (1)
Button(63-182)
src/packages/radio/radio.taro.tsx (1)
src/packages/sidebar/utils.ts (1)
handleClick(22-22)
src/packages/tabbar/demos/taro/demo10.tsx (2)
src/packages/tabbar/demos/h5/demo9.tsx (1)
Tabbar(5-13)src/packages/tabbar/demos/h5/demo5.tsx (1)
Tabbar(5-13)
src/packages/countdown/demo.tsx (1)
scripts/create-properties.js (1)
h2(58-58)
src/packages/countdown/demos/h5/demo10.tsx (2)
src/packages/countdown/countdown.taro.tsx (1)
CountDown(355-357)src/packages/countdown/countdown.tsx (1)
CountDown(308-310)
src/packages/countdown/demos/taro/demo10.tsx (2)
src/packages/countdown/countdown.taro.tsx (1)
CountDown(355-357)src/packages/countdown/countdown.tsx (1)
CountDown(308-310)
src/types/spec/swiper/taro.ts (1)
src/types/spec/swiper/base.ts (1)
BaseSwiperItem(33-35)
src/packages/navbar/demos/h5/demo4.tsx (3)
src/packages/navbar/navbar.taro.tsx (1)
NavBar(19-138)src/packages/navbar/navbar.tsx (1)
NavBar(18-137)src/packages/toast/toast.taro.tsx (1)
Toast(39-194)
src/packages/navbar/demos/taro/demo4.tsx (3)
src/utils/taro/px-transform.ts (1)
pxTransform(5-9)src/packages/navbar/navbar.taro.tsx (1)
NavBar(19-138)src/utils/taro/platform.ts (1)
harmony(3-7)
src/packages/noticebar/demos/taro/demo12.tsx (2)
src/packages/noticebar/noticebar.taro.tsx (1)
NoticeBar(35-556)src/packages/button/button.taro.tsx (1)
Button(63-182)
src/packages/image/demos/h5/demo9.tsx (2)
src/packages/image/image.taro.tsx (1)
Image(25-141)src/packages/image/image.tsx (1)
Image(27-204)
src/packages/image/demos/taro/demo9.tsx (1)
src/packages/image/image.taro.tsx (1)
Image(25-141)
src/packages/swiper/demos/taro/demo10.tsx (3)
packages/nutui-inject-ui-styles/dist/index.js (1)
list(26-129)src/packages/swiper/swiper.taro.tsx (1)
Swiper(31-179)src/packages/image/image.taro.tsx (1)
Image(25-141)
🪛 ast-grep (0.39.7)
src/packages/countdown/countdown.tsx
[warning] 298-298: Usage of dangerouslySetInnerHTML detected. This bypasses React's built-in XSS protection. Always sanitize HTML content using libraries like DOMPurify before injecting it into the DOM to prevent XSS attacks.
Context: dangerouslySetInnerHTML
Note: [CWE-79] Improper Neutralization of Input During Web Page Generation [REFERENCES]
- https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml
- https://cwe.mitre.org/data/definitions/79.html
(react-unsafe-html-injection)
🔇 Additional comments (43)
src/types/spec/popup/base.ts (1)
20-20: 此更改似乎与 PR 目标不符。此 PR 的目标是添加无障碍功能支持,但
top?: ReactNode属性似乎是一个 UI 布局属性,而非无障碍相关的属性。请确认:
- 此更改是否应该包含在本 PR 中
- 或者应该在单独的 PR 中处理布局功能增强
src/packages/navbar/navbar.taro.tsx (1)
110-110: LGTM - 导航角色设置正确
ariaRole="navigation"正确使用了 ARIA 地标角色,有助于屏幕阅读器用户快速导航到页面的导航区域。src/types/spec/dialog/taro.ts (1)
6-7: LGTM - 类型定义正确为
TaroContentProps添加ariaModal和ariaRole属性的类型定义是正确的,这些属性将帮助对话框组件正确实现 ARIA 规范中的模态对话框语义。src/packages/tabs/tabs.tsx (1)
185-186: LGTM - 正确隐藏装饰性元素在视觉装饰元素(活动线指示器和笑脸图标)上使用
aria-hidden是正确的做法,这可以防止屏幕阅读器读取这些仅用于视觉呈现的元素。Also applies to: 189-192
src/packages/navbar/navbar.tsx (1)
109-109: LGTM - 导航角色设置正确
role="navigation"正确使用了 ARIA 地标角色,有助于屏幕阅读器用户识别和导航到导航区域。src/packages/tabs/tabs.taro.tsx (2)
266-269: 验证 ariaHidden 属性语法与上面的问题相同,建议为
ariaHidden明确设置布尔值。
[request_optional_refactor]- <View - className={`${classPrefix}-titles-item-smile`} - ariaHidden - > + <View + className={`${classPrefix}-titles-item-smile`} + ariaHidden={true} + >
281-284: ARIA 标签页属性实现正确
ariaRole="tab"和ariaSelected的实现符合 WAI-ARIA 规范,正确反映了标签页的选中状态。src/packages/progress/progress.taro.tsx (1)
225-226: 进度条无障碍属性实现正确正确添加了
ariaLabel和ariaRole="progressbar"属性,为屏幕阅读器提供了清晰的进度信息。默认的中文标签 "进度${percent}%" 对于中文用户友好。src/packages/progress/progress.tsx (1)
138-139: Web 版本无障碍属性实现正确使用标准的 React ARIA 属性
aria-label和role="progressbar",与 Taro 版本保持一致。src/packages/popup/popup.tsx (1)
292-292: 弹窗角色属性正确为弹窗容器添加
role="dialog"符合 WAI-ARIA 规范,有助于屏幕阅读器正确识别弹窗的语义。src/packages/countdown/countdown.tsx (2)
65-67: ARIA 提醒状态管理添加状态来管理 ARIA 提醒的角色和内容是合理的。
105-110: 倒计时结束提醒逻辑在倒计时结束时设置 ARIA 提醒,3秒后清除,这个交互逻辑合理。
src/packages/countdown/demo.tsx (1)
12-12: 代码更改看起来不错Demo10 的导入和 ARIA 基础用法示例集成正确,多语言翻译键(zh-CN、zh-TW、en-US)都已正确添加。
Also applies to: 26-26, 38-38, 50-50, 75-76
src/packages/swiper/demo.taro.tsx (1)
17-17: 代码更改看起来不错Demo10 的导入和 ARIA 示例集成正确,多语言翻译已正确添加。
Also applies to: 31-31, 43-43, 84-85
src/packages/navbar/demo.taro.tsx (1)
10-10: 代码更改看起来不错Demo4 的导入和 ARIA 基础用法示例集成正确,多语言翻译键已完整添加。
Also applies to: 18-18, 24-24, 30-30, 45-46
src/packages/navbar/demo.tsx (1)
7-7: 代码更改看起来不错Demo4 的导入和 ARIA 基础用法示例集成正确,多语言翻译已完整添加。
Also applies to: 15-15, 21-21, 27-27, 39-40
src/packages/noticebar/demo.tsx (1)
15-15: LGTM! ARIA 演示添加正确Demo12 的导入、翻译键和渲染逻辑都符合现有的演示模式,实现正确。
Also applies to: 31-31, 45-45, 78-79
src/packages/noticebar/demo.taro.tsx (1)
19-19: LGTM! Taro 版本的 ARIA 演示添加正确与 H5 版本保持一致,Demo12 的集成符合现有模式。
Also applies to: 35-35, 49-49, 88-89
src/packages/image/image.taro.tsx (1)
38-38: LGTM!ariaLabel属性传递正确正确地从 props 中解构
ariaLabel并传递给底层的TImage组件,实现了无障碍标签支持。Also applies to: 133-133
src/packages/tabbar/demo.tsx (1)
12-12: LGTM! Demo10 集成正确ARIA 演示的导入、翻译(除 zh-TW 的小问题外)和渲染逻辑都实现正确。
Also applies to: 26-26, 50-50, 73-74
src/types/spec/noticebar/base.ts (1)
26-26:rightIconAriaLabel属性定义不会造成破坏性变更虽然
rightIconAriaLabel: string在接口中被定义为必需属性,但实际并不会导致现有代码失败。组件的类型签名使用了Partial<WebNoticeBarProps>,这使得所有属性在组件层面都是可选的。此外,组件提供了默认值rightIconAriaLabel: ''。现有演示代码(如 demo1.tsx)已经在不提供此属性的情况下成功运行。将其改为可选属性仍是更好的做法,以保持接口定义与实现的一致性,但这不是必要的修复。
Likely an incorrect or invalid review comment.
src/packages/countdown/demo.taro.tsx (1)
15-15: LGTM!Demo10 组件导入和 ARIA 国际化配置实现正确,遵循了项目的标准 demo 集成模式。
Also applies to: 29-29, 41-41, 53-53, 83-84
src/packages/swiper/swiper.tsx (1)
41-41: LGTM!
alt属性的提取和转发实现正确,当未指定effect时,该属性会正确传递给defaultEffect用于设置 ARIA 标签。Also applies to: 256-263
src/packages/image/image.tsx (1)
45-45: LGTM!
ariaLabel属性的实现符合无障碍规范,正确应用于img元素的aria-label属性。Also applies to: 198-198
src/types/spec/dialog/base.ts (1)
45-45: LGTM!为
BaseDialog接口添加role属性的类型定义,与无障碍功能增强保持一致。src/packages/tabbar/demos/taro/demo10.tsx (1)
5-38: LGTM!Demo 正确演示了 ARIA 属性的使用方式,为每个
Tabbar.Item提供了ariaLabel和ariaRoledescription属性,有助于改善屏幕阅读器的用户体验。src/packages/dialog/dialog.tsx (1)
221-221: LGTM!为 Dialog 组件添加的 ARIA 属性实现正确:
role="dialog"正确标识了对话框角色aria-modal={visible}在对话框可见时正确设置模态状态这些改动提升了对话框组件的无障碍性。
Also applies to: 230-230
src/packages/countdown/demos/taro/demo10.tsx (2)
1-10: LGTM!导入和组件初始化代码正确,使用 useRef 存储 endTime 是合适的做法。
11-38: 演示代码清晰有效三个 CountDown 实例展示了不同的 type 属性,同时统一使用了 ariaRoledescription 属性,有效演示了无障碍功能的使用。
src/packages/image/demos/h5/demo9.tsx (2)
16-23: LGTM!正确使用了 alt 和 ariaLabel 属性,alt 描述图片内容,ariaLabel 提供可访问的名称,这是符合无障碍最佳实践的。
24-40: 错误处理演示清晰使用无效 URL 触发错误状态是演示错误处理功能的常见做法,同时展示了默认和自定义错误内容两种场景。
src/packages/tabbar/demo.taro.tsx (1)
15-15: Demo10 集成正确Demo10 的导入和渲染遵循了现有的演示模式,集成方式正确。
Also applies to: 78-79
src/packages/dialog/content.taro.tsx (1)
31-32: ARIA 属性集成正确ariaRole 和 ariaModal 属性的添加和使用符合 Taro 的无障碍实现模式,将 ariaModal 绑定到 visible 状态也是合理的。
Also applies to: 64-65
src/packages/countdown/demos/h5/demo10.tsx (1)
11-38: 演示结构实现正确三个 CountDown 实例正确展示了不同 type 属性下的 ariaRoledescription 使用,演示结构清晰。
src/packages/tabbar/demos/h5/demo10.tsx (1)
7-37: ARIA 属性使用规范每个 Tabbar.Item 都正确配置了 ariaLabel 和 ariaRoledescription 属性,ariaLabel 与 title 保持一致,ariaRoledescription 统一描述了操作类型,符合无障碍最佳实践。动态图标的使用也展示了更丰富的交互场景。
src/packages/noticebar/demos/taro/demo12.tsx (2)
20-26: rightIconAriaLabel 使用正确为右侧图标添加 rightIconAriaLabel="more" 提供了可访问的标签,这对于屏幕阅读器用户理解图标功能很重要。
28-39: 自定义右侧内容演示清晰使用 right 插槽放置自定义 Button 组件展示了 NoticeBar 的灵活性,虽然这个示例不直接涉及无障碍功能,但与其他演示一起提供了完整的使用场景。
src/packages/dialog/content.tsx (1)
57-64: ARIA 属性实现正确role 和 aria-modal 属性的实现符合无障碍规范。role 属性被正确传递,aria-modal 接收布尔值以反映对话框的模态状态。
src/packages/noticebar/noticebar.taro.tsx (1)
543-551: 验证 rightIconAriaLabel 为空的情况当
closeable为 false 且用户未提供rightIconAriaLabel时,aria-label 将是空字符串,这对屏幕阅读器用户没有帮助。虽然通常在有 rightIcon 时应该提供有意义的rightIconAriaLabel,但建议在文档中明确说明这一要求,或者在代码中添加条件判断,仅在有有效内容时才设置 aria-label。建议验证以下场景:
- 当使用
rightIcon但未提供rightIconAriaLabel时的行为- 文档是否明确要求提供
rightIconAriaLabel可以考虑改进实现:
ariaLabel={closeable ? 'close' : (rightIconAriaLabel || undefined)}这样当 rightIconAriaLabel 为空时,不会设置 aria-label 属性。
src/packages/noticebar/noticebar.tsx (1)
481-487: 验证 rightIconAriaLabel 为空的情况与 Taro 版本类似,当
closeable为 false 且rightIconAriaLabel为空时,aria-label将是空字符串。建议确保文档中明确要求在使用自定义rightIcon时必须提供有意义的rightIconAriaLabel。可选改进(与 Taro 版本保持一致):
<div className="nut-noticebar-box-right-icon" onClick={onClickIcon} - aria-label={`${closeable ? 'close' : rightIconAriaLabel}`} + aria-label={closeable ? 'close' : (rightIconAriaLabel || undefined)} >src/packages/dialog/dialog.taro.tsx (1)
234-259: ARIA 实现正确且完善Dialog 组件的无障碍实现非常完善:
- 正确传递 role 属性到 Content 组件
- ariaModal 属性正确反映对话框的模态状态
- 为 Overlay 添加了有意义的 ariaRoledescription="背景蒙层",帮助屏幕阅读器用户理解背景遮罩的用途
src/packages/navbar/demos/h5/demo4.tsx (1)
1-95: 优秀的无障碍示例这个 Demo 很好地展示了 NavBar 的无障碍用法:
- 所有交互元素都添加了有意义的
aria-label- 标签描述清晰准确
- 为开发者提供了良好的参考示例
src/packages/countdown/countdown.taro.tsx (1)
341-348: ARIA alert 实现正确倒计时结束时的 ARIA alert 实现遵循了无障碍最佳实践:
- 使用
role="alert"动态通知屏幕阅读器- 提供有意义的提示内容 "时间到"
- 通过隐藏的元素实现,不影响视觉布局
注意:已在上方评论中指出定时器清理的问题。
src/packages/button/button.taro.tsx
Outdated
| className={buttonClassNames} | ||
| style={{ ...getStyle, ...style }} | ||
| onClick={(e) => handleClick(e as any)} | ||
| ariaLabel="button" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
硬编码的 ariaLabel 值缺乏实用性。
将 ariaLabel 硬编码为 "button" 不会为屏幕阅读器用户提供有意义的信息。应该:
- 通过 props 使其可配置
- 描述按钮的具体用途而非仅说明它是按钮
- 设为可选属性,因为按钮内容通常已提供足够的上下文
建议应用以下修改:
在 ButtonProps 接口中添加可选的 ariaLabel 属性:
export interface ButtonProps
extends BasicComponent,
OmitMiniProgramButtonProps {
color: string
shape: ButtonShape
type: ButtonType
size: ButtonSize
fill: ButtonFill
block: boolean
loading: boolean
disabled: boolean
icon: React.ReactNode
rightIcon: React.ReactNode
nativeType: 'submit' | 'reset' // | 'button'
onClick: (e: MouseEvent<HTMLButtonElement>) => void
+ ariaLabel?: string
}然后在组件中使用:
const {
color,
shape,
fill,
loading,
disabled,
type,
size,
block,
icon,
rightIcon,
children,
className,
style,
formType,
nativeType,
onClick,
+ ariaLabel,
...rest
} = { ...defaultProps, ...props }在渲染时有条件地应用:
<TaroButton
{...rest}
ref={ref}
formType={formType || nativeType}
className={buttonClassNames}
style={{ ...getStyle, ...style }}
onClick={(e) => handleClick(e as any)}
- ariaLabel="button"
+ {...(ariaLabel && { ariaLabel })}
>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/packages/button/button.taro.tsx around line 162, the ariaLabel is
hardcoded to "button"; update ButtonProps to include an optional ariaLabel?:
string, accept it in the component props, and replace the hardcoded ariaLabel
with the passed-in prop so the rendered element conditionally sets the
aria-label attribute only when ariaLabel is provided (or uses a meaningful
fallback like the button text if you choose), ensuring the value describes the
button's purpose rather than the generic word "button".
src/packages/checkbox/checkbox.tsx
Outdated
| role="checkbox" | ||
| tabIndex={0} | ||
| aria-checked={innerChecked && !innerIndeterminate} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aria-checked 对不确定状态的处理不正确。
当前的 aria-checked={innerChecked && !innerIndeterminate} 实现存在严重问题:
- 不确定状态处理错误:当复选框处于不确定状态(indeterminate=true)时,
aria-checked应该是"mixed",而不是false - 类型不正确:
aria-checked应该接受"true" | "false" | "mixed",而非布尔运算结果 - tabIndex 未考虑禁用状态:禁用的复选框不应该可聚焦
应用以下修改:
<div
className={classNames(
classPrefix,
{
[`${classPrefix}-reverse`]: labelPosition === 'left',
'nut-checkbox-list-item': ctx?.list,
},
className
)}
{...rest}
onClick={handleClick}
role="checkbox"
- tabIndex={0}
- aria-checked={innerChecked && !innerIndeterminate}
+ tabIndex={innerDisabled ? -1 : 0}
+ aria-checked={innerIndeterminate ? 'mixed' : innerChecked}
>
{renderCheckboxItem()}
</div>此外,建议添加键盘事件处理器以支持空格键切换复选框:
+const handleKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key === ' ' || e.key === 'Enter') {
+ e.preventDefault()
+ handleClick()
+ }
+}
+
<div
className={classNames(
classPrefix,
{
[`${classPrefix}-reverse`]: labelPosition === 'left',
'nut-checkbox-list-item': ctx?.list,
},
className
)}
{...rest}
onClick={handleClick}
+ onKeyDown={handleKeyDown}
role="checkbox"
tabIndex={innerDisabled ? -1 : 0}
aria-checked={innerIndeterminate ? 'mixed' : innerChecked}
>Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/packages/checkbox/checkbox.tsx around lines 211-213, aria-checked and
tabIndex are incorrect: change aria-checked to return the string union "true" |
"false" | "mixed" (e.g. innerIndeterminate ? "mixed" : innerChecked ? "true" :
"false") instead of a boolean expression, make tabIndex non-focusable when
disabled (e.g. tabIndex={disabled ? -1 : 0}), and add a onKeyDown handler that
listens for the Space key, prevents default, and toggles the checkbox
(respecting disabled state) so keyboard users can toggle via space.
| setRole('alert') | ||
| setAlertContent('时间到') | ||
| setTimeout(() => { | ||
| setRole('') | ||
| setAlertContent('') | ||
| }, 3000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复潜在的内存泄漏
setTimeout 设置的定时器在组件卸载时未被清除,可能导致内存泄漏。当倒计时结束后,如果组件在 3 秒内被卸载,定时器仍会尝试调用 setRole 和 setAlertContent,可能导致 React 警告或内存泄漏。
基于学习经验(Based on learnings)
建议将定时器 ID 存储在 ref 中并在组件卸载时清除:
+ const alertTimerRef = useRef<number>()
+
// ... 在 tick 函数中
if (!remainTime) {
stateRef.current.counting = false
pause()
onEnd && onEnd()
setRole('alert')
setAlertContent('时间到')
- setTimeout(() => {
+ alertTimerRef.current = window.setTimeout(() => {
setRole('')
setAlertContent('')
}, 3000)
}并在 componentWillUnmount 中清除:
const componentWillUnmount = () => {
destroy && cancelAnimationFrame(stateRef.current.timer)
+ if (alertTimerRef.current) {
+ clearTimeout(alertTimerRef.current)
+ }
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/packages/countdown/countdown.taro.tsx around lines 110 to 115, the
setTimeout used to clear role/alertContent is not tracked or cleared on unmount
which can cause state updates after unmount; store the timeout ID in a ref (e.g.
timeoutRef), assign the ID when calling setTimeout, clear any existing timeout
before creating a new one, and clear the timeout in useEffect
cleanup/componentWillUnmount to prevent the callback running after the component
is unmounted.
src/packages/image/demo.taro.tsx
Outdated
| error: '加载失败', | ||
| lazyload: '图片懒加载', | ||
| imageText: 'Image + text 模式', | ||
| ATRIAUsage: '无障碍使用示例', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修正拼写错误:ATRIA → ARIA
翻译键名和英文翻译值中的 "ATRIA" 是拼写错误,应该是 "ARIA"(Accessible Rich Internet Applications,无障碍富互联网应用)。
应用此差异修复拼写错误:
- ATRIAUsage: '无障碍使用示例',
+ ARIAUsage: '无障碍使用示例',- ATRIAUsage: 'ATRIA Usage',
+ ARIAUsage: 'ARIA Usage',同时需要更新 Line 70 的引用:
- <View className="h2">{translated.ATRIAUsage}</View>
+ <View className="h2">{translated.ARIAUsage}</View>Also applies to: 39-39
🤖 Prompt for AI Agents
In src/packages/image/demo.taro.tsx around lines 28 and 39 (and update the usage
at line 70), fix the misspelling "ATRIA" to "ARIA": rename the translation
key(s) (e.g., ATRIAUsage → ARIAUsage), update any English/Chinese translation
values that contain "ATRIA" to "ARIA", and change the reference at line 70 to
use the new ARIAUsage key; ensure consistency across the file so all occurrences
of "ATRIA" are replaced with "ARIA".
src/types/spec/radio/base.ts
Outdated
| activeIcon: ReactNode | ||
| value: SimpleValue | ||
| onChange: (checked: boolean) => void | ||
| type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
属性名称 "type" 过于泛化且可能引起混淆。
在 BaseRadio 接口中添加 type: string 存在以下问题:
- 属性名称过于通用,不清楚其用途
- 可能与 HTML 原生的
type属性产生命名冲突 - 如果用于无障碍功能,应使用更具描述性的名称(如
ariaType或role) - 应设为可选属性而非必需
请说明此属性的具体用途,并考虑使用更具描述性的名称。
🤖 Prompt for AI Agents
In src/types/spec/radio/base.ts around line 24, the BaseRadio interface defines
a generic required property "type: string" which is ambiguous and could clash
with HTML attributes; clarify its purpose and either rename it to a descriptive
name (e.g., "variant", "role", or "ariaType") or make it optional if it conveys
non-essential metadata. Update the interface to use the new name or optional
modifier, adjust all imports/usages and tests to the new property, and add a
short JSDoc comment explaining the property's semantics and expected values to
avoid future confusion.
src/types/spec/radio/base.ts
Outdated
| disabled?: boolean | ||
| options: RadioGroupOption[] | ||
| onChange: (value: SimpleValue) => void | ||
| type: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
属性名称 "type" 过于泛化且可能引起混淆。
在 BaseRadioGroup 接口中添加 type: string 存在与 BaseRadio 相同的问题。建议:
- 使用更具描述性的属性名称
- 将其设为可选属性
- 在文档中明确说明其用途
🤖 Prompt for AI Agents
In src/types/spec/radio/base.ts around line 36, the property named "type:
string" is too generic and may conflict with BaseRadio; rename it to a more
descriptive identifier (for example radioType or variant), make the property
optional (radioType?: string) and update any usages/imports accordingly, and add
a short JSDoc comment above the property explaining its purpose and expected
values; ensure type references, interfaces and any serializers/deserializers are
updated to use the new optional name to avoid breaking changes.
src/types/spec/swiper/taro.ts
Outdated
| autoplay: boolean | ||
| loop: boolean | ||
| defaultValue: number | ||
| ariaLabel: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
ariaLabel 应设为可选属性。
将 ariaLabel 定义为必需属性会强制所有 Swiper 实例都必须提供 aria 标签。建议设为可选,因为:
- 组件可以提供合理的默认标签
- 并非所有使用场景都需要自定义标签
- 减少开发者的使用负担
应用以下修改:
export type TaroSwiperProps = Omit<BaseSwiper, OmittedKeys> &
OmittedSwiperProps &
BaseProps & {
width?: SimpleValue
height?: SimpleValue
direction: Direction
indicator: ReactNode
/**
* @deprecated Please use `autoplay` prop instead.
*/
autoPlay: boolean
autoplay: boolean
loop: boolean
defaultValue: number
- ariaLabel: string
+ ariaLabel?: string
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ariaLabel: string | |
| export type TaroSwiperProps = Omit<BaseSwiper, OmittedKeys> & | |
| OmittedSwiperProps & | |
| BaseProps & { | |
| width?: SimpleValue | |
| height?: SimpleValue | |
| direction: Direction | |
| indicator: ReactNode | |
| /** | |
| * @deprecated Please use `autoplay` prop instead. | |
| */ | |
| autoPlay: boolean | |
| autoplay: boolean | |
| loop: boolean | |
| defaultValue: number | |
| ariaLabel?: string | |
| } |
🤖 Prompt for AI Agents
In src/types/spec/swiper/taro.ts around line 22, the ariaLabel property is
currently defined as a required string which forces all Swiper instances to
supply an ARIA label; change the type to make ariaLabel optional (e.g., use
optional property syntax) so the component can rely on a default or omit it when
not needed, and update any related type usages or overrides that assume it is
always present to handle undefined.
src/types/spec/swiper/taro.ts
Outdated
| export interface TaroSwiperItemProps extends Omit<BaseSwiperItem, 'onClick'> { | ||
| itemId?: string | ||
| skipHiddenItemLayout?: boolean | ||
| ariaLabel: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
ariaLabel 应设为可选属性。
与 TaroSwiperProps 相同,TaroSwiperItemProps 的 ariaLabel 也应设为可选属性。
应用以下修改:
export interface TaroSwiperItemProps extends Omit<BaseSwiperItem, 'onClick'> {
itemId?: string
skipHiddenItemLayout?: boolean
- ariaLabel: string
+ ariaLabel?: string
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ariaLabel: string | |
| export interface TaroSwiperItemProps extends Omit<BaseSwiperItem, 'onClick'> { | |
| itemId?: string | |
| skipHiddenItemLayout?: boolean | |
| ariaLabel?: string | |
| } |
🤖 Prompt for AI Agents
In src/types/spec/swiper/taro.ts around line 28, the property ariaLabel is
currently required; make it optional to match TaroSwiperProps by changing its
declaration to an optional property (ariaLabel?: string) so TaroSwiperItemProps
aligns with the other prop definitions.
src/types/spec/tabbar/base.ts
Outdated
| ariaLabel: string | ||
| ariaSelected: boolean | ||
| ariaRoledescription: string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
建议将 ARIA 属性设为可选
这些 ARIA 属性被定义为必需属性,这会导致所有现有的 TabbarItem 使用处都需要提供这些值,可能造成破坏性变更。建议将它们设为可选属性以保持向后兼容。
应用此差异将属性改为可选:
- ariaLabel: string
- ariaSelected: boolean
- ariaRoledescription: string
+ ariaLabel?: string
+ ariaSelected?: boolean
+ ariaRoledescription?: string📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ariaLabel: string | |
| ariaSelected: boolean | |
| ariaRoledescription: string | |
| ariaLabel?: string | |
| ariaSelected?: boolean | |
| ariaRoledescription?: string |
🤖 Prompt for AI Agents
In src/types/spec/tabbar/base.ts around lines 25 to 27, the ARIA properties
ariaLabel, ariaSelected and ariaRoledescription are currently required; change
their type declarations to optional (e.g., add ? after each property name) so
existing TabbarItem usages aren’t broken, update any related exported
interfaces/types if necessary, and run type checks to ensure no downstream type
errors remain.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
🤔 这个变动的性质是?
🔗 相关 Issue
💡 需求背景和解决方案
为让更多人(包括残障人士)能够平等、便捷地使用和访问应用,对组件提升对无障碍的支持。
☑️ 请求合并前的自查清单
Summary by CodeRabbit
新功能