-
-
Notifications
You must be signed in to change notification settings - Fork 182
feat(spinner): support spinner type #721
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
Conversation
|
@guoyunhe is attempting to deploy a commit to the React Component Team on Vercel. A member of the Team first needs to authorize it. |
Summary of ChangesHello @guoyunhe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 此拉取请求为 InputNumber 组件引入了一个新的 'spinner' 类型。这个新类型通过将增减按钮分别放置在输入框的两侧,提供了一种直观的用户体验,特别适用于需要快速调整数值的场景,例如电商网站中的商品数量选择。此更改涉及组件属性的扩展、渲染逻辑的调整以及相应样式的添加,以确保新功能能够无缝集成并正确显示。 Highlights
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Walkthrough添加 InputNumber 的可选属性 Changes
Sequence Diagram(s)sequenceDiagram
participant User as 用户
participant Public as InputNumber(public)
participant Internal as InternalInputNumber
participant Step as StepHandler
rect rgb(232,248,255)
User->>Public: 传入 props(含 type='spinner')
Public->>Internal: 传递 props 与 type(class 包含 -type-spinner)
end
rect rgb(247,247,247)
Internal->>Step: 渲染 action='down' 的 StepHandler(输入前)
Internal->>Step: 渲染 action='up' 的 StepHandler(输入后)
Note right of Step: StepHandler 根据 action 决定 增/减 行为
end
User->>Step: 点击或按住 增/减
Step->>Internal: 触发 onStep(action)
Internal->>Public: 更新值并触发 onChange
Public->>User: 返回新的值 / 触发回调
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 分钟 重点检查:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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.
Code Review
你好,感谢你的贡献。本次 PR 新增了 spinner 类型的 InputNumber 组件,将增减按钮分别置于输入框两侧,功能实现良好。代码整体结构清晰,但在一些细节上还有可以改进的地方。我主要提出了三点建议:
- 在
InputNumber.tsx中,spinner类型没有遵循controls属性的控制,导致即使controls={false}按钮依然会显示。 - 在
spinner.tsx示例文件中,onChange事件处理器的类型定义不完整,当开启stringMode时可能导致类型错误。 - 在
index.less样式文件中,颜色值#d9d9d9多次硬编码,建议提取为变量以方便维护。
请查看具体的代码审查评论。
862c9bb to
d5a3e4b
Compare
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: 0
🧹 Nitpick comments (1)
src/InputNumber.tsx (1)
624-632: spinner 模式实现正确,但可考虑优化代码复用。spinner 模式的双 StepHandler 布局(左侧减号、右侧加号)实现了预期的数量选择器 UX。注意到之前的审查意见关于
controls属性检查的建议已经得到落实(两处都有controls &&判断)。不过,两个 StepHandler 块的代码存在一定的重复。
可选优化建议:可以考虑提取一个辅助函数来减少重复代码,例如:
+ const renderSpinnerHandler = (position: 'left' | 'right') => { + const isLeft = position === 'left'; + return ( + <StepHandler + prefixCls={prefixCls} + {...(isLeft ? { downNode: downHandler } : { upNode: upHandler })} + {...(isLeft ? { downDisabled } : { upDisabled })} + {...(isLeft ? { upHidden: true } : { downHidden: true })} + onStep={onInternalStep} + /> + ); + }; + - {type === 'spinner' && controls && ( - <StepHandler - prefixCls={prefixCls} - downNode={downHandler} - downDisabled={downDisabled} - upHidden - onStep={onInternalStep} - /> - )} + {type === 'spinner' && controls && renderSpinnerHandler('left')} <div className={`${inputClassName}-wrap`}> {/* ... input ... */} </div> - {type === 'spinner' && controls && ( - <StepHandler - prefixCls={prefixCls} - upNode={upHandler} - upDisabled={upDisabled} - downHidden - onStep={onInternalStep} - /> - )} + {type === 'spinner' && controls && renderSpinnerHandler('right')}Also applies to: 652-660
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
assets/index.less(1 hunks)docs/demo/spinner.tsx(1 hunks)docs/example.md(1 hunks)src/InputNumber.tsx(7 hunks)src/StepHandler.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- assets/index.less
- docs/demo/spinner.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-09-29T06:18:11.993Z
Learnt from: bombillazo
PR: react-component/input-number#644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
Applied to files:
src/InputNumber.tsx
🧬 Code graph analysis (1)
src/InputNumber.tsx (1)
src/StepHandler.tsx (1)
StepHandler(28-134)
🔇 Additional comments (6)
src/StepHandler.tsx (2)
22-24: 新增的隐藏控制属性实现合理。
upHidden和downHidden属性为条件渲染提供了清晰的控制方式,支持 spinner 模式的独立按钮布局需求。
105-131: 条件渲染逻辑正确。使用
!upHidden和!downHidden进行条件渲染的实现清晰且符合预期,disabled 状态的处理也保持了一致性。docs/example.md (1)
55-58: LGTM!新增的 spinner 演示文档入口与现有格式保持一致。
src/InputNumber.tsx (3)
66-67: 新增的 type 属性设计合理。
type?: 'input' | 'spinner'提供了清晰的模式选择,类型定义准确。
613-622: 现有输入模式的条件渲染处理正确。为原有的 input 模式添加条件判断保持了向后兼容性,逻辑清晰。
668-668: type 属性的默认值和传递处理正确。
type = 'input'的默认值确保了向后兼容性,className 和 props 的传递也都正确实现。Also applies to: 703-703, 724-724
d5a3e4b to
fda11c6
Compare
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: 0
🧹 Nitpick comments (1)
src/InputNumber.tsx (1)
66-67: 可选:为 type 属性添加 JSDoc 注释。建议为新增的
type属性添加 JSDoc 注释,说明'input'和'spinner'两种模式的区别和使用场景,以提升开发者体验。例如:
+ /** + * 输入框类型 + * - 'input': 默认模式,步进按钮在右侧垂直排列 + * - 'spinner': 数量选择器模式,减少按钮在左侧,增加按钮在右侧 + */ type?: 'input' | 'spinner';
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
assets/index.less(1 hunks)docs/demo/spinner.tsx(1 hunks)docs/example.md(1 hunks)src/InputNumber.tsx(9 hunks)src/StepHandler.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/StepHandler.tsx
- docs/demo/spinner.tsx
- docs/example.md
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-09-29T06:18:11.993Z
Learnt from: bombillazo
PR: react-component/input-number#644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
Applied to files:
src/InputNumber.tsx
🧬 Code graph analysis (1)
src/InputNumber.tsx (1)
src/StepHandler.tsx (1)
StepHandler(28-134)
🔇 Additional comments (5)
src/InputNumber.tsx (4)
89-90: LGTM!新增的
spinnerUpHandler和spinnerDownHandler属性设计合理,与现有的upHandler/downHandler保持了一致的命名模式,为 spinner 模式提供了独立的自定义能力。
617-664: LGTM!条件渲染逻辑实现正确:
type === 'input'模式:在输入框右侧渲染包含上下按钮的步进控件type === 'spinner'模式:在输入框左右两侧分别渲染减少和增加按钮所有三处
StepHandler的渲染都正确地检查了controls属性,确保在controls={false}时能正确隐藏按钮。降级逻辑(spinnerDownHandler || downHandler和spinnerUpHandler || upHandler)也为向后兼容提供了良好支持。
707-707: LGTM!通过
${prefixCls}-type-${type}为不同类型添加专属类名,与assets/index.less中的样式规则正确对应,实现了类型样式的隔离。
672-672: LGTM!为
type设置默认值'input'确保了向后兼容性,现有代码无需修改即可继续使用默认的输入框模式。assets/index.less (1)
137-160: LGTM!spinner 类型的样式实现正确:
- 使用
display: inline-flex和align-items: center实现了左右按钮布局- 通过调整
border-left/border-right和高度样式,使增减按钮分别显示在输入框两侧- 样式规则与
src/InputNumber.tsx中的条件渲染逻辑配合良好,实现了预期的数量选择器 UX
fda11c6 to
d6cec40
Compare
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: 0
🧹 Nitpick comments (1)
assets/index.less (1)
137-160: Spinner 样式布局合理样式规则正确实现了 spinner 类型的横向布局,包括 flex 容器设置、固定宽度的按钮区域以及适当的边框调整。
需要注意的是,第 153 行和第 158 行继续使用了硬编码的颜色值
#d9d9d9。如之前评审中所提到的,建议将该颜色提取为 Less 变量以提高可维护性,不过这可以作为后续重构任务处理。
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
assets/index.less(1 hunks)docs/demo/spinner.tsx(1 hunks)docs/example.md(1 hunks)src/InputNumber.tsx(7 hunks)src/StepHandler.tsx(3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- docs/demo/spinner.tsx
- src/StepHandler.tsx
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-09-29T06:18:11.993Z
Learnt from: bombillazo
PR: react-component/input-number#644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
Applied to files:
src/InputNumber.tsx
🧬 Code graph analysis (1)
src/InputNumber.tsx (1)
src/StepHandler.tsx (1)
StepHandler(28-134)
🔇 Additional comments (8)
src/InputNumber.tsx (7)
66-67: 类型定义清晰,向后兼容新增的
type属性使用了明确的联合类型,保持了 API 的类型安全性,且作为可选属性不会破坏现有代码。
613-622: 输入模式渲染逻辑正确正确检查了
type和controls属性,保持了原有输入模式的行为。
624-632: Spinner 模式左侧按钮渲染正确正确使用
upHidden属性隐藏上方按钮,仅显示减量按钮。同时也正确检查了controls属性,符合预期行为。
652-660: Spinner 模式右侧按钮渲染正确正确使用
downHidden属性隐藏下方按钮,仅显示增量按钮。与左侧按钮配合,实现了完整的 spinner 布局。
668-668: 默认值确保向后兼容将
type默认设置为'input'保证了现有代码无需修改即可继续工作。
703-703: 类名动态包含类型信息在 className 中包含
type-${type}后缀,为不同类型提供了独立的样式命名空间,便于 CSS 针对性定制。
724-724: 属性正确传递至内部组件
type属性正确传递给InternalInputNumber,确保了内部渲染逻辑能够访问到该配置。docs/example.md (1)
55-58: 文档更新清晰简洁新增的 spinner 示例章节格式与现有示例保持一致,便于用户查找和使用。
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #721 +/- ##
==========================================
+ Coverage 95.98% 96.01% +0.02%
==========================================
Files 7 7
Lines 299 301 +2
Branches 78 81 +3
==========================================
+ Hits 287 289 +2
Misses 12 12 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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: 0
🧹 Nitpick comments (1)
tests/props.test.tsx (1)
410-415: 基础测试覆盖合理,可选择性增强。测试正确验证了
type="spinner"属性会添加对应的 CSS 类名。测试语法和结构正确。可选建议:考虑添加更全面的测试用例,例如:
- 验证 spinner 模式下左右按钮是否正确渲染
- 测试默认 type(应为 'input')是否正常工作
- 验证点击 spinner 按钮的交互行为
可以在此测试套件中添加以下测试用例:
it('render input type by default', () => { const { container } = render(<InputNumber value={1} />); expect(container.querySelector('.rc-input-number')).toHaveClass('rc-input-number-type-input'); }); it('spinner type should have left and right handlers', () => { const { container } = render(<InputNumber value={1} type="spinner" />); expect(container.querySelector('.rc-input-number-handler-down')).toBeTruthy(); expect(container.querySelector('.rc-input-number-handler-up')).toBeTruthy(); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
tests/__snapshots__/baseInput.test.tsx.snapis excluded by!**/*.snap
📒 Files selected for processing (3)
assets/index.less(1 hunks)src/StepHandler.tsx(3 hunks)tests/props.test.tsx(9 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/StepHandler.tsx
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-09-29T06:18:11.993Z
Learnt from: bombillazo
PR: react-component/input-number#644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
Applied to files:
tests/props.test.tsx
📚 Learning: 2024-10-08T21:56:37.546Z
Learnt from: bombillazo
PR: react-component/input-number#644
File: tests/validator.test.tsx:34-83
Timestamp: 2024-10-08T21:56:37.546Z
Learning: In `tests/validator.test.tsx`, the test cases focus on the `validator` function. When the validator condition is not met, the input value should not change. The `formatter` is tested separately in another file.
Applied to files:
tests/props.test.tsx
🔇 Additional comments (2)
assets/index.less (1)
137-155: Spinner 样式逻辑正确。新增的 spinner 样式规则正确实现了水平布局:
- 使用
inline-flex和align-items: center实现按钮与输入框水平排列- 通过
flex: 0 0 20px固定按钮宽度- 移除上下按钮之间的边框(
border-bottom: 0和border-top: 0),添加左右分隔边框- 样式符合 PR 描述中的"左右分布递增递减按钮"的设计
注意:之前的评审已指出第 150 行(以及第 154 行)的硬编码颜色值
#d9d9d9应提取为 Less 变量以提高可维护性。这个建议仍然有效。tests/props.test.tsx (1)
5-5: 格式化改进恰当。这些格式化更改提高了代码一致性:
- 统一使用双引号
- 为按钮添加
type="button"属性避免意外的表单提交- 改善了多行代码的可读性
Also applies to: 97-98, 115-116, 187-187, 216-216, 277-279, 285-285, 292-292, 299-299, 307-309, 389-389, 419-419, 428-428, 436-436
src/InputNumber.tsx
Outdated
| prefixCls={prefixCls} | ||
| upNode={upHandler} | ||
| upDisabled={upDisabled} | ||
| downHidden |
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.
耦合度有点太高了,StepHandler 单独拆一个子组件出来消费吧
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: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/InputNumber.tsx(7 hunks)src/StepHandler.tsx(4 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-09-29T06:18:11.993Z
Learnt from: bombillazo
Repo: react-component/input-number PR: 644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
Applied to files:
src/InputNumber.tsx
📚 Learning: 2024-10-08T21:56:37.546Z
Learnt from: bombillazo
Repo: react-component/input-number PR: 644
File: src/InputNumber.tsx:393-395
Timestamp: 2024-10-08T21:56:37.546Z
Learning: The `InputNumber` component does not use error states or messages; it is designed to prevent the value from updating if validation fails without displaying additional feedback to the user.
Applied to files:
src/InputNumber.tsx
🧬 Code graph analysis (1)
src/InputNumber.tsx (1)
src/StepHandler.tsx (1)
StepHandler(25-113)
🪛 Biome (2.1.2)
src/StepHandler.tsx
[error] 110-110: Wrap comments inside children within braces.
Unsafe fix: Wrap the comments with braces
(lint/suspicious/noCommentText)
🔇 Additional comments (11)
src/InputNumber.tsx (8)
66-67: LGTM!新增的
type属性声明正确,可选类型和联合类型定义清晰合理。
592-607: LGTM!正确使用了重构后的
StepHandler组件的 action-based API,props 传递正确。
630-638: LGTM!
input模式的渲染逻辑正确保留了原有行为,并正确处理了controls属性。
640-640: LGTM!正确添加了
controls属性判断,解决了之前评审中提到的问题。
660-660: LGTM!正确添加了
controls属性判断,与 line 640 的逻辑保持一致。
668-668: LGTM!默认值
'input'确保了向后兼容性,未指定 type 时保持原有行为。
703-703: LGTM!添加基于 type 的 className 后缀,便于针对不同类型进行样式定制。
724-724: LGTM!正确将
typeprop 传递给内部组件。src/StepHandler.tsx (3)
17-23: LGTM!重构为基于 action 的统一接口,相比之前的分离 up/down props,API 设计更简洁清晰。
46-61: LGTM!
onStepMouseDown逻辑正确,通过action === 'up'将 action 转换为方向布尔值,保持了 onStep 回调的接口契约。
94-106: LGTM!渲染逻辑正确,ARIA 属性设置恰当,事件处理完善。假定上述 className 问题被修复后,此段代码将正常工作。
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: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/InputNumber.tsx(13 hunks)src/StepHandler.tsx(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/InputNumber.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: bombillazo
Repo: react-component/input-number PR: 644
File: src/InputNumber.tsx:173-174
Timestamp: 2024-09-29T06:18:11.993Z
Learning: In `src/InputNumber.tsx`, within the `InternalInputNumber` component, the state variables `prevValueRef` and `inputValueRef` are typed as `string | number` to maintain consistency with existing code.
| return ( | ||
| <div className={clsx(`${handlerClassName}-wrap`, classNames?.actions)} style={styles?.actions}> | ||
| <span | ||
| {...sharedHandlerProps} | ||
| onMouseDown={(e) => { | ||
| onStepMouseDown(e, true); | ||
| }} | ||
| aria-label="Increase Value" | ||
| aria-disabled={upDisabled} | ||
| className={upClassName} | ||
| > | ||
| {upNode || <span unselectable="on" className={`${prefixCls}-handler-up-inner`} />} | ||
| </span> | ||
| <span | ||
| {...sharedHandlerProps} | ||
| onMouseDown={(e) => { | ||
| onStepMouseDown(e, false); | ||
| }} | ||
| aria-label="Decrease Value" | ||
| aria-disabled={downDisabled} | ||
| className={downClassName} | ||
| > | ||
| {downNode || <span unselectable="on" className={`${prefixCls}-handler-down-inner`} />} | ||
| </span> | ||
| </div> | ||
| <span | ||
| {...sharedHandlerProps} | ||
| onMouseDown={(e) => { | ||
| onStepMouseDown(e); | ||
| }} | ||
| aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'} | ||
| aria-disabled={disabled} | ||
| className={mergedClassName} | ||
| style={style} | ||
| > | ||
| {children || <span unselectable="on" className={`${prefixCls}-handler-${action}-inner`} />} | ||
| </span> |
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.
添加 tabIndex 属性以支持键盘焦点。
role="button" 的元素需要 tabIndex 才能接收键盘焦点。当前键盘用户无法通过 Tab 键聚焦到此控件。
应用此 diff 添加 tabIndex:
return (
<span
{...sharedHandlerProps}
onMouseDown={(e) => {
onStepMouseDown(e);
}}
aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'}
aria-disabled={disabled}
+ tabIndex={disabled ? -1 : 0}
className={mergedClassName}
style={style}
>📝 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.
| return ( | |
| <div className={clsx(`${handlerClassName}-wrap`, classNames?.actions)} style={styles?.actions}> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e, true); | |
| }} | |
| aria-label="Increase Value" | |
| aria-disabled={upDisabled} | |
| className={upClassName} | |
| > | |
| {upNode || <span unselectable="on" className={`${prefixCls}-handler-up-inner`} />} | |
| </span> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e, false); | |
| }} | |
| aria-label="Decrease Value" | |
| aria-disabled={downDisabled} | |
| className={downClassName} | |
| > | |
| {downNode || <span unselectable="on" className={`${prefixCls}-handler-down-inner`} />} | |
| </span> | |
| </div> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e); | |
| }} | |
| aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'} | |
| aria-disabled={disabled} | |
| className={mergedClassName} | |
| style={style} | |
| > | |
| {children || <span unselectable="on" className={`${prefixCls}-handler-${action}-inner`} />} | |
| </span> | |
| return ( | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e); | |
| }} | |
| aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'} | |
| aria-disabled={disabled} | |
| tabIndex={disabled ? -1 : 0} | |
| className={mergedClassName} | |
| style={style} | |
| > | |
| {children || <span unselectable="on" className={`${prefixCls}-handler-${action}-inner`} />} | |
| </span> |
🤖 Prompt for AI Agents
In src/StepHandler.tsx around lines 100 to 112, the span with role="button"
lacks a tabIndex so it can't receive keyboard focus; add a tabIndex attribute
(e.g. tabIndex={disabled ? -1 : 0}) to the span so it is focusable when enabled
and removed from tab order when disabled, keeping other props and handlers
intact.
添加键盘事件处理以满足可访问性要求。
组件使用了 role="button" 但缺少键盘事件处理,导致键盘用户无法与控件交互。按照 WCAG 2.1.1 (Keyboard) 标准,按钮必须响应 Enter 和 Space 键。
应用此 diff 添加键盘支持:
+ const onKeyDown = (e: React.KeyboardEvent) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ if (!disabled) {
+ onStepMouseDown(e as any);
+ }
+ }
+ };
+
return (
<span
{...sharedHandlerProps}
onMouseDown={(e) => {
onStepMouseDown(e);
}}
+ onKeyDown={onKeyDown}
aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'}
aria-disabled={disabled}
className={mergedClassName}
style={style}
>📝 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.
| return ( | |
| <div className={clsx(`${handlerClassName}-wrap`, classNames?.actions)} style={styles?.actions}> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e, true); | |
| }} | |
| aria-label="Increase Value" | |
| aria-disabled={upDisabled} | |
| className={upClassName} | |
| > | |
| {upNode || <span unselectable="on" className={`${prefixCls}-handler-up-inner`} />} | |
| </span> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e, false); | |
| }} | |
| aria-label="Decrease Value" | |
| aria-disabled={downDisabled} | |
| className={downClassName} | |
| > | |
| {downNode || <span unselectable="on" className={`${prefixCls}-handler-down-inner`} />} | |
| </span> | |
| </div> | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e); | |
| }} | |
| aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'} | |
| aria-disabled={disabled} | |
| className={mergedClassName} | |
| style={style} | |
| > | |
| {children || <span unselectable="on" className={`${prefixCls}-handler-${action}-inner`} />} | |
| </span> | |
| const onKeyDown = (e: React.KeyboardEvent) => { | |
| if (e.key === 'Enter' || e.key === ' ') { | |
| e.preventDefault(); | |
| if (!disabled) { | |
| onStepMouseDown(e as any); | |
| } | |
| } | |
| }; | |
| return ( | |
| <span | |
| {...sharedHandlerProps} | |
| onMouseDown={(e) => { | |
| onStepMouseDown(e); | |
| }} | |
| onKeyDown={onKeyDown} | |
| aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'} | |
| aria-disabled={disabled} | |
| className={mergedClassName} | |
| style={style} | |
| > | |
| {children || <span unselectable="on" className={`${prefixCls}-handler-${action}-inner`} />} | |
| </span> | |
| ); |
🤖 Prompt for AI Agents
In src/StepHandler.tsx around lines 100 to 112, the span uses role="button" but
lacks keyboard handlers; add role="button" (if not already present) and
implement an onKeyDown handler that listens for Enter and Space keys to invoke
the same action as onMouseDown (call onStepMouseDown) — for Space also call
e.preventDefault() to avoid page scroll; optionally handle onKeyUp for Space if
your mouse handler relies on keyup/release semantics; ensure aria-disabled is
respected so the handlers early-return when disabled.
| onMouseDown={(e) => { | ||
| onStepMouseDown(e); | ||
| }} |
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.
在交互处理器中检查 disabled 状态。
当 disabled=true 时,onMouseDown 处理器仍然会触发 onStepMouseDown,导致用户可以与禁用状态的按钮交互。这违反了 aria-disabled 的语义。
应用此 diff 添加 disabled 检查:
<span
{...sharedHandlerProps}
onMouseDown={(e) => {
- onStepMouseDown(e);
+ if (!disabled) {
+ onStepMouseDown(e);
+ }
}}
aria-label={isUpAction ? 'Increase Value' : 'Decrease Value'}📝 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.
| onMouseDown={(e) => { | |
| onStepMouseDown(e); | |
| }} | |
| onMouseDown={(e) => { | |
| if (!disabled) { | |
| onStepMouseDown(e); | |
| } | |
| }} |
🤖 Prompt for AI Agents
In src/StepHandler.tsx around lines 103 to 105, the onMouseDown handler always
calls onStepMouseDown even when the step is disabled; update the handler to
first check the component's disabled state (e.g., props.disabled or
aria-disabled) and bail out early when disabled is true so the click does
nothing and respects aria-disabled semantics; ensure the check uses the same
prop used elsewhere for disabled state and returns without calling
onStepMouseDown when disabled.
新增 spinner 类型,增减按钮分别放到左右两侧,以实现类似于淘宝加购数量的效果:
Summary by CodeRabbit