-
Notifications
You must be signed in to change notification settings - Fork 29
fix: prevent selecting disabled items with keyboard navigation #326
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -237,15 +237,20 @@ const Segmented = React.forwardRef<HTMLDivElement, SegmentedProps>( | ||||||||||
|
|
|||||||||||
| // ======================= Keyboard ======================== | |||||||||||
| const onOffset = (offset: number) => { | |||||||||||
| const currentIndex = segmentedOptions.findIndex( | |||||||||||
| // keep the current option and not disabled options | |||||||||||
| const validOptions = segmentedOptions.filter( | |||||||||||
| (option) => option.value === rawValue || !option.disabled, | |||||||||||
| ); | |||||||||||
|
|
|||||||||||
| const currentIndex = validOptions.findIndex( | |||||||||||
| (option) => option.value === rawValue, | |||||||||||
| ); | |||||||||||
|
|
|||||||||||
| const total = segmentedOptions.length; | |||||||||||
| const total = validOptions.length; | |||||||||||
| const nextIndex = (currentIndex + offset + total) % total; | |||||||||||
| const nextOption = validOptions[nextIndex]; | |||||||||||
|
|
|||||||||||
| const nextOption = segmentedOptions[nextIndex]; | |||||||||||
| if (nextOption) { | |||||||||||
| if (nextOption && nextOption.value !== rawValue) { | |||||||||||
| setRawValue(nextOption.value); | |||||||||||
| onChange?.(nextOption.value); | |||||||||||
|
Comment on lines
+245
to
255
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在当前值已失效时先短路,避免方向键偷偷改值。 当 💡 建议修复 const currentIndex = validOptions.findIndex(
(option) => option.value === rawValue,
);
+ if (currentIndex === -1) {
+ return;
+ }
const total = validOptions.length;
const nextIndex = (currentIndex + offset + total) % total;🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 同上,可以check一下这个边界是否需要处理;或者单独pr处理? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
分析
但在受控模式下,如果上层传入的
由于 建议:在本 PR 中一并修复修复量极小(3 行),且改动就在本次修改的同一函数内,建议直接加入: const currentIndex = validOptions.findIndex(
(option) => option.value === rawValue,
);
+ if (currentIndex === -1) {
+ return;
+ }
const total = validOptions.length;
const nextIndex = (currentIndex + offset + total) % total;这样既保持本 PR 的改动集中,又能一次性封住"受控值不在 options 中时方向键仍触发 onChange"的漏洞,无需单独开 PR。 |
|||||||||||
| } | |||||||||||
|
|
|||||||||||
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.
当
rawValue不在validOptions中时(例如初始值不在选项列表中),currentIndex会被设为-1。在这种情况下,如果offset为-1(按下左/上方向键),nextIndex的计算结果(currentIndex + offset + total) % total会指向错误的索引(例如total为 3 时,结果为 1 而不是 2)。建议对currentIndex === -1的情况进行特殊处理,以确保在初始值无效时也能正确导航到第一个或最后一个有效选项。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.
这里看起来和之前的逻辑是一致的;应该无需处理吧;