Skip to content

Commit 2d99ce4

Browse files
wanpan11zombieJ
andauthored
feat: Supports onPopupScroll props (#507)
* feat: Supports onPopupScroll props * fix: eslint fix * feat: add test case * fix: update test * test: update case * test: fix test case * test: fix onPopupScroll evt is null * test: fix outdated cases * test: fix test case * docs: clean up --------- Co-authored-by: 二货机器人 <[email protected]>
1 parent edb31b3 commit 2d99ce4

13 files changed

+810
-709
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ online example: https://tree-select-react-component.vercel.app/
5757
|dropdownMatchSelectWidth | whether dropdown's with is same with select. Default set `min-width` same as input | bool | true |
5858
|dropdownClassName | additional className applied to dropdown | String | - |
5959
|dropdownStyle | additional style applied to dropdown | Object | {} |
60-
|dropdownPopupAlign | specify alignment for dropdown (alignConfig of [dom-align](https://github.com/yiminghe/dom-align)) | Object | - |
6160
|onDropdownVisibleChange | control dropdown visible | function | `() => { return true; }` |
6261
|notFoundContent | specify content to show when no result matches. | String | 'Not Found' |
6362
|showSearch | whether show search input in single mode | bool | true |
@@ -75,6 +74,7 @@ online example: https://tree-select-react-component.vercel.app/
7574
|onSelect | called when select treeNode | function(value, node, extra) | - |
7675
|onSearch | called when input changed | function | - |
7776
|onTreeExpand | called when tree node expand | function(expandedKeys) | - |
77+
|onPopupScroll | called when popup scroll | function(event) | - |
7878
|showCheckedStrategy | `TreeSelect.SHOW_ALL`: show all checked treeNodes (Include parent treeNode). `TreeSelect.SHOW_PARENT`: show checked treeNodes (Just show parent treeNode). Default just show child. | enum{TreeSelect.SHOW_ALL, TreeSelect.SHOW_PARENT, TreeSelect.SHOW_CHILD } | TreeSelect.SHOW_CHILD |
7979
|treeIcon | show tree icon | bool | false |
8080
|treeLine | show tree line | bool | false |

examples/basic.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ class Demo extends React.Component {
212212
});
213213
}}
214214
onSelect={this.onSelect}
215+
onPopupScroll={evt => {
216+
console.log('onPopupScroll:', evt.target);
217+
}}
215218
/>
216219

217220
<h2>single select (just select children)</h2>
@@ -256,7 +259,7 @@ class Demo extends React.Component {
256259
choiceTransitionName="rc-tree-select-selection__choice-zoom"
257260
style={{ width: 300 }}
258261
// dropdownStyle={{ height: 200, overflow: 'auto' }}
259-
dropdownPopupAlign={{
262+
dropdownAlign={{
260263
overflow: { adjustY: 0, adjustX: 0 },
261264
offset: [0, 2],
262265
}}

examples/filter.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ class Demo extends React.Component {
6464
transitionName="rc-tree-select-dropdown-slide-up"
6565
choiceTransitionName="rc-tree-select-selection__choice-zoom"
6666
// dropdownStyle={{ height: 200, overflow: 'auto' }}
67-
dropdownPopupAlign={{
68-
overflow: { adjustY: 0, adjustX: 0 },
69-
offset: [0, 2],
70-
}}
67+
// dropdownPopupAlign={{
68+
// overflow: { adjustY: 0, adjustX: 0 },
69+
// offset: [0, 2],
70+
// }}
7171
placeholder={<i>请下拉选择</i>}
7272
treeLine
7373
maxTagTextLength={10}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@
7272
"rc-dialog": "^7.5.7",
7373
"rc-field-form": "^2.0.0",
7474
"rc-test": "^7.0.4",
75-
"rc-virtual-list": "^1.1.0",
75+
"rc-virtual-list": "^3.0.0",
7676
"react": "^16.8.0",
7777
"react-dom": "^16.8.0",
7878
"typescript": "^5.0.0"

src/OptionList.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
4444
dropdownMatchSelectWidth,
4545
treeExpandAction,
4646
treeTitleRender,
47+
onPopupScroll,
4748
} = React.useContext(TreeSelectContext);
4849

4950
const {
@@ -70,6 +71,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
7071

7172
const memoTreeData = useMemo(
7273
() => treeData,
74+
// eslint-disable-next-line react-hooks/exhaustive-deps
7375
[open, treeData],
7476
(prev, next) => next[0] && prev[1] !== next[1],
7577
);
@@ -97,6 +99,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
9799
treeRef.current?.scrollTo({ key: checkedKeys[0] });
98100
setActiveKey(checkedKeys[0]);
99101
}
102+
// eslint-disable-next-line react-hooks/exhaustive-deps
100103
}, [open]);
101104

102105
// ========================== Search ==========================
@@ -123,6 +126,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
123126
if (searchValue) {
124127
setSearchExpandedKeys(getAllKeys(treeData, fieldNames));
125128
}
129+
// eslint-disable-next-line react-hooks/exhaustive-deps
126130
}, [searchValue]);
127131

128132
const onInternalExpand = (keys: Key[]) => {
@@ -252,6 +256,7 @@ const OptionList: React.ForwardRefRenderFunction<ReviseRefOptionListProps> = (_,
252256
onLoad={onTreeLoad}
253257
filterTreeNode={filterTreeNode}
254258
expandAction={treeExpandAction}
259+
onScroll={onPopupScroll}
255260
/>
256261
</div>
257262
);

src/TreeSelect.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
240240
treeMotion,
241241
treeTitleRender,
242242

243+
onPopupScroll,
243244
...restProps
244245
} = props;
245246

@@ -465,6 +466,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
465466
...item,
466467
label: item.label ?? item.value,
467468
}));
469+
// eslint-disable-next-line react-hooks/exhaustive-deps
468470
}, [
469471
mergedFieldNames,
470472
mergedMultiple,
@@ -681,6 +683,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
681683
onSelect: onOptionSelect,
682684
treeExpandAction,
683685
treeTitleRender,
686+
onPopupScroll,
684687
}),
685688
[
686689
virtual,
@@ -693,6 +696,7 @@ const TreeSelect = React.forwardRef<BaseSelectRef, TreeSelectProps>((props, ref)
693696
onOptionSelect,
694697
treeExpandAction,
695698
treeTitleRender,
699+
onPopupScroll,
696700
],
697701
);
698702

src/TreeSelectContext.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface TreeSelectContextProps {
1313
onSelect: OnInternalSelect;
1414
treeExpandAction?: ExpandAction;
1515
treeTitleRender?: (node: any) => React.ReactNode;
16+
onPopupScroll?: React.UIEventHandler<HTMLDivElement>;
1617
}
1718

1819
const TreeSelectContext = React.createContext<TreeSelectContextProps>(null as any);

tests/Select.multiple.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import TreeSelect, { TreeNode } from '../src';
77
import focusTest from './shared/focusTest';
88

99
describe('TreeSelect.multiple', () => {
10-
focusTest('multiple');
10+
focusTest(true);
1111

1212
const treeData = [
1313
{ key: '0', value: '0', title: 'label0' },

tests/Select.props.spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import { mount } from 'enzyme';
33
import Tree, { TreeNode } from 'rc-tree';
44
import React from 'react';
5+
import { render, fireEvent } from '@testing-library/react';
6+
57
import TreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode as SelectNode } from '../src';
68

79
// Promisify timeout to let jest catch works
@@ -241,6 +243,33 @@ describe('TreeSelect.props', () => {
241243
expect(handleSearch).toHaveBeenCalledWith('Search changed');
242244
});
243245

246+
it('onPopupScroll', async () => {
247+
const onPopupScroll = jest.fn(e => {
248+
// Prevents React from resetting its properties:
249+
e.persist();
250+
});
251+
render(
252+
<TreeSelect
253+
open
254+
treeDefaultExpandAll
255+
onPopupScroll={onPopupScroll}
256+
treeData={new Array(10).fill(0).map((_, index) => ({
257+
title: `Title ${index}`,
258+
value: index,
259+
}))}
260+
/>,
261+
);
262+
263+
fireEvent.scroll(document.querySelector('.rc-tree-select-tree-list-holder'), {
264+
scrollY: 100,
265+
});
266+
267+
expect(onPopupScroll).toHaveBeenCalled();
268+
expect(onPopupScroll.mock.calls[0][0].target).toBe(
269+
document.querySelector('.rc-tree-select-tree-list-holder'),
270+
);
271+
});
272+
244273
it('showArrow', () => {
245274
const wrapper = mount(createOpenSelect({ suffixIcon: null }));
246275
expect(wrapper.find('.rc-tree-select-arrow').length).toBeFalsy();

tests/Select.spec.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,17 @@ import TreeSelect, { TreeNode } from '../src';
66
import focusTest from './shared/focusTest';
77
import { selectNode } from './util';
88

9+
const mockScrollTo = jest.fn();
10+
11+
// Mock `useScrollTo` from `rc-virtual-list/lib/hooks/useScrollTo`
12+
jest.mock('rc-virtual-list/lib/hooks/useScrollTo', () => {
13+
return () => mockScrollTo;
14+
});
15+
916
describe('TreeSelect.basic', () => {
1017
beforeEach(() => {
1118
jest.useFakeTimers();
19+
mockScrollTo.mockReset();
1220
});
1321

1422
beforeAll(() => {
@@ -19,7 +27,7 @@ describe('TreeSelect.basic', () => {
1927
jest.useRealTimers();
2028
});
2129

22-
focusTest('single');
30+
focusTest();
2331

2432
describe('render', () => {
2533
const treeData = [
@@ -391,11 +399,8 @@ describe('TreeSelect.basic', () => {
391399
wrapper.openSelect();
392400
expect(wrapper.isOpen()).toBeFalsy();
393401

394-
const scrollTo = jest.fn();
395-
wrapper.find('List').instance().scrollTo = scrollTo;
396-
397402
wrapper.openSelect();
398-
expect(scrollTo).toHaveBeenCalled();
403+
expect(mockScrollTo).toHaveBeenCalled();
399404
});
400405
});
401406

@@ -525,7 +530,7 @@ describe('TreeSelect.basic', () => {
525530

526531
keyDown(KeyCode.DOWN);
527532
expect(wrapper.find('.rc-tree-select-tree-treenode-active').text()).toBe('0 label');
528-
533+
529534
keyDown(KeyCode.UP);
530535
expect(wrapper.find('.rc-tree-select-tree-treenode-active').text()).toBe('11 label');
531536
});

0 commit comments

Comments
 (0)