Skip to content

Commit 90f10d1

Browse files
jin19980928WB01676250
and
WB01676250
authored
Fix:The dropdown list is not following the highlighted item when navigating through the result using up or down arrow after entering keyword (#575)
* fix:cascaderScroll * fix:cascader * fix: cascader * fix: cascader * fix: cascader * fix: cascader * fix: cascader * fix: cascader --------- Co-authored-by: WB01676250 <[email protected]>
1 parent e8a8761 commit 90f10d1

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
lines changed

src/OptionList/Column.tsx

+16-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export default function Column<OptionType extends DefaultOptionType = DefaultOpt
4343
}: ColumnProps<OptionType>) {
4444
const menuPrefixCls = `${prefixCls}-menu`;
4545
const menuItemPrefixCls = `${prefixCls}-menu-item`;
46+
const menuRef = React.useRef<HTMLUListElement>(null);
4647

4748
const {
4849
fieldNames,
@@ -100,9 +101,23 @@ export default function Column<OptionType extends DefaultOptionType = DefaultOpt
100101
[options, checkedSet, fieldNames, halfCheckedSet, loadingKeys, prevValuePath],
101102
);
102103

104+
React.useEffect(() => {
105+
if (menuRef.current) {
106+
const selector = `.${menuItemPrefixCls}-active`;
107+
const activeElement = menuRef.current.querySelector<HTMLElement>(selector);
108+
109+
if (activeElement) {
110+
activeElement.scrollIntoView({
111+
block: 'nearest',
112+
inline: 'nearest',
113+
});
114+
}
115+
}
116+
}, [activeValue, menuItemPrefixCls]);
117+
103118
// ============================ Render ============================
104119
return (
105-
<ul className={menuPrefixCls} role="menu">
120+
<ul className={menuPrefixCls} ref={menuRef} role="menu">
106121
{optionInfoList.map(
107122
({
108123
disabled,

tests/index.spec.tsx

+30
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { addressOptions, addressOptionsForUneven, optionsForActiveMenuItems } fr
66
import { mount } from './enzyme';
77
import { toRawValues } from '../src/utils/commonUtil';
88
import { fireEvent, render } from '@testing-library/react';
9+
import KeyCode from '@rc-component/util/lib/KeyCode';
910

1011
describe('Cascader.Basic', () => {
1112
let selectedValue: any;
@@ -995,6 +996,7 @@ describe('Cascader.Basic', () => {
995996
wrapper.find(`li[data-path-key]`).at(0).simulate('click');
996997
wrapper.find(`li[data-path-key]`).at(1).simulate('click');
997998
});
999+
9981000
it('hover + search', () => {
9991001
let getOffesetTopTimes = 0;
10001002
const spyElement = spyElementPrototypes(HTMLElement, {
@@ -1074,6 +1076,34 @@ describe('Cascader.Basic', () => {
10741076

10751077
spyElement.mockRestore();
10761078
});
1079+
1080+
it('should scroll into view when navigating with keyboard', () => {
1081+
const { container } = render(
1082+
<Cascader
1083+
options={Array.from({ length: 20 }).map((_, index) => ({
1084+
value: `item-${index}`,
1085+
label: `item-${index}`,
1086+
}))}
1087+
open
1088+
/>,
1089+
);
1090+
1091+
const input = container.querySelector('input')!;
1092+
fireEvent.focus(input);
1093+
1094+
fireEvent.keyDown(input, { key: 'ArrowDown', keyCode: KeyCode.DOWN });
1095+
1096+
const targetElement = container.querySelector('.rc-cascader-menu-item-active')!;
1097+
1098+
const scrollSpy = jest.spyOn(targetElement, 'scrollIntoView').mockImplementation(() => null);
1099+
1100+
expect(scrollSpy).toHaveBeenCalledWith({
1101+
block: 'nearest',
1102+
inline: 'nearest',
1103+
});
1104+
1105+
scrollSpy.mockReset();
1106+
});
10771107
});
10781108

10791109
it('not crash when value type is not array', () => {

tests/setup.js

+2
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ Object.assign(Enzyme.ReactWrapper.prototype, {
2525
return this;
2626
},
2727
});
28+
29+
window.HTMLElement.prototype.scrollIntoView = jest.fn();

0 commit comments

Comments
 (0)