Skip to content

Commit 0713269

Browse files
author
liyuan-meng
committed
✨[Select]下拉组件支持输入框内直接搜索
1 parent 0bd0bab commit 0713269

10 files changed

Lines changed: 639 additions & 41 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
order: 5
3+
title: 模糊搜索
4+
desc: 可对选项进行搜索
5+
---
6+
7+
```jsx
8+
/**
9+
* title: 模糊搜索
10+
* desc: 可对选项进行搜索
11+
*/
12+
import React from 'react';
13+
import { Select } from 'cloud-react';
14+
15+
const Option = Select.Option;
16+
17+
const dataList = [
18+
{
19+
label: 'React',
20+
value: 'React',
21+
},
22+
{
23+
label: 'Vue',
24+
value: 'Vue',
25+
},
26+
{
27+
label: 'Angular',
28+
value: 'Angular',
29+
},
30+
{
31+
label: '数云',
32+
value: 'sy',
33+
},
34+
{
35+
label: '选中项1',
36+
value: '1',
37+
},
38+
{
39+
label: '选中项2',
40+
value: '2',
41+
},
42+
{
43+
label: '选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3',
44+
value: '3',
45+
},
46+
{
47+
label: '选中项4',
48+
value: '4',
49+
},
50+
{
51+
label: '选中项5',
52+
value: '5',
53+
},
54+
{
55+
label: '选中项6',
56+
value: '6',
57+
},
58+
];
59+
60+
export default function SelectDemo() {
61+
const handleChange = (value) => {
62+
console.log('select --- ' + value);
63+
};
64+
65+
const handleSearch = (value) => {
66+
console.log(value);
67+
};
68+
69+
return (
70+
<div style={{ display: 'flex', gap: 20, flexDirection: 'column' }}>
71+
<div>
72+
<h5></h5>
73+
<Select
74+
searchable
75+
allowClear
76+
supportLightText
77+
placeholder="带搜索的下拉单选"
78+
onSearch={handleSearch}
79+
onChange={handleChange}
80+
style={{width: 200}}
81+
dataSource={dataList}
82+
position="auto"
83+
// size="large"
84+
/>
85+
</div>
86+
</div>
87+
);
88+
}
89+
```

src/components/select/demos/searchable.md

Lines changed: 109 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,34 @@ const dataList = [
2727
label: 'Angular',
2828
value: 'Angular',
2929
},
30+
{
31+
label: '数云',
32+
value: 'sy',
33+
},
34+
{
35+
label: '选中项1',
36+
value: '1',
37+
},
38+
{
39+
label: '选中项2',
40+
value: '2',
41+
},
42+
{
43+
label: '选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3选中项3',
44+
value: '3',
45+
},
46+
{
47+
label: '选中项4',
48+
value: '4',
49+
},
50+
{
51+
label: '选中项5',
52+
value: '5',
53+
},
54+
{
55+
label: '选中项6',
56+
value: '6',
57+
},
3058
];
3159

3260
export default function SelectDemo() {
@@ -39,17 +67,87 @@ export default function SelectDemo() {
3967
};
4068

4169
return (
42-
<>
43-
<Select
44-
searchable
45-
supportLightText
46-
placeholder="带搜索的下拉单选"
47-
onSearch={handleSearch}
48-
onChange={handleChange}
49-
style={{width: 200}}
50-
dataSource={dataList}
51-
/>
52-
</>
70+
<div style={{ display: 'flex', gap: 20, flexDirection: 'column' }}>
71+
<div>
72+
<h5>搜索框在下拉框内(单选)</h5>
73+
<Select
74+
searchable
75+
allowClear
76+
supportLightText
77+
placeholder="带搜索的下拉单选"
78+
onSearch={handleSearch}
79+
onChange={handleChange}
80+
style={{width: 200}}
81+
dataSource={dataList}
82+
position="auto"
83+
// size="large"
84+
/>
85+
</div>
86+
<div>
87+
<h5>搜索框在下拉框内(多选)</h5>
88+
<Select
89+
hasSelectAll
90+
multiple
91+
searchable
92+
allowClear
93+
supportLightText
94+
placeholder="带搜索的下拉单选"
95+
onSearch={handleSearch}
96+
onChange={handleChange}
97+
style={{width: 200}}
98+
dataSource={dataList}
99+
// size="large"
100+
/>
101+
</div>
102+
<div>
103+
<h5>搜索框在下拉框外(单选)</h5>
104+
<Select
105+
searchable
106+
searchInBox
107+
allowClear
108+
supportLightText
109+
placeholder="带搜索的下拉单选"
110+
onSearch={handleSearch}
111+
onChange={handleChange}
112+
style={{width: 200}}
113+
dataSource={dataList}
114+
// size="large"
115+
/>
116+
</div>
117+
<div>
118+
<h5>搜索框在下拉框外(多选)</h5>
119+
<Select
120+
hasSelectAll
121+
searchable
122+
searchInBox
123+
allowClear
124+
multiple
125+
supportLightText
126+
placeholder="带搜索的下拉多选"
127+
onSearch={handleSearch}
128+
onChange={handleChange}
129+
style={{width: 200}}
130+
dataSource={dataList}
131+
/>
132+
</div>
133+
<div>
134+
<h5>搜索框在下拉框外(多选限制标签数量)</h5>
135+
<Select
136+
hasSelectAll
137+
searchable
138+
searchInBox
139+
allowClear
140+
multiple
141+
supportLightText
142+
placeholder="带搜索的下拉多选"
143+
onSearch={handleSearch}
144+
onChange={handleChange}
145+
style={{width: 200}}
146+
dataSource={dataList}
147+
maxTagCount={1}
148+
/>
149+
</div>
150+
</div>
53151
);
54152
}
55153
```

src/components/select/index.js

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,12 @@ class Select extends Component {
327327
const { onSelectClose, open: propOpen, hasConfirmButton } = this.props;
328328
onSelectClose();
329329
if (hasConfirmButton) this.onMultiOptionChange(prevValue);
330-
if (propOpen === null) this.setState({ open: false });
330+
if (propOpen === null) {
331+
this.optionsNode.current.classList.remove('show');
332+
setTimeout(() => {
333+
this.setState({ open: false });
334+
}, 100);
335+
}
331336
}
332337
};
333338

@@ -341,10 +346,25 @@ class Select extends Component {
341346
onSelectOpen();
342347
}
343348

344-
if (propOpen === null) this.setState({ open: !open });
349+
if (propOpen === null) {
350+
if (!open) {
351+
this.setState({ open: !open });
352+
setTimeout(() => {
353+
this.optionsNode.current.classList.add('show');
354+
});
355+
} else {
356+
this.optionsNode.current.classList.remove('show');
357+
setTimeout(() => {
358+
this.setState({ open: !open });
359+
}, 100);
360+
}
361+
}
345362
};
346363

347364
onClickSelected = () => {
365+
if (this.props.searchable && this.props.searchInBox && this.selectedNode.current.getSearchValue()) {
366+
return;
367+
}
348368
this.onSearchValueChange('');
349369
const { disabled } = this.props;
350370
if (disabled) return;
@@ -481,6 +501,7 @@ class Select extends Component {
481501
onChange={this.onMultiSelectValueChange}
482502
onSearchValueChange={this.onSearchValueChange}
483503
handleSelect={this.handleSelect}
504+
searchValue={this.state.searchValue}
484505
/>
485506
);
486507
}
@@ -502,6 +523,7 @@ class Select extends Component {
502523
value={value}
503524
dataSource={this.children}
504525
onChange={this.onSimpleOptionChange}
526+
searchValue={this.state.searchValue}
505527
onSearchValueChange={this.onSearchValueChange}
506528
/>
507529
);
@@ -528,15 +550,15 @@ class Select extends Component {
528550
className,
529551
);
530552

531-
const optionContainer = (
553+
const optionContainer = open ? (
532554
<div
533555
className={`${selector}-option-container`}
534556
ref={this.optionsNode}
535557
style={{ ...popupStyle, width: `${width}px` }}
536558
>
537559
{this.renderOptions()}
538560
</div>
539-
);
561+
) : null;
540562

541563
return (
542564
<div className={`${classNames}`} style={style} ref={this.node}>
@@ -555,11 +577,14 @@ class Select extends Component {
555577
size={size}
556578
isSupportTitle={isSupportTitle}
557579
supportUnlimited={supportUnlimited}
580+
onSearchValueChange={this.onSearchValueChange}
581+
onMultiChange={this.onMultiSelectValueChange}
582+
positionPop={this.positionPop}
558583
/>
559584

560585
{isAppendToBody
561-
? open && ReactDOM.createPortal(optionContainer, this.portal)
562-
: open && optionContainer}
586+
? ReactDOM.createPortal(optionContainer, this.portal)
587+
: optionContainer}
563588
</div>
564589
);
565590
}
@@ -578,6 +603,7 @@ Select.propTypes = {
578603
valueKey: PropTypes.string,
579604
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
580605
searchable: PropTypes.bool,
606+
searchInBox: PropTypes.bool,
581607
emptyRender: PropTypes.oneOfType([ PropTypes.string, PropTypes.node ]),
582608
defaultValue: PropTypes.oneOfType([
583609
PropTypes.string,
@@ -608,6 +634,7 @@ Select.propTypes = {
608634
lightTextColor: PropTypes.string,
609635
supportUnlimited: PropTypes.bool,
610636
unlimitedLabel: PropTypes.string,
637+
maxTagCount: PropTypes.number,
611638
};
612639

613640
Select.defaultProps = {
@@ -624,6 +651,7 @@ Select.defaultProps = {
624651
valueKey: 'value',
625652
width: 'auto',
626653
searchable: false,
654+
searchInBox: false,
627655
emptyRender: '',
628656
defaultValue: null,
629657
value: null,
@@ -645,6 +673,7 @@ Select.defaultProps = {
645673
lightTextColor: undefined,
646674
supportUnlimited: false,
647675
unlimitedLabel: '不限',
676+
maxTagCount: undefined,
648677
};
649678

650679
export default Select;

0 commit comments

Comments
 (0)