Skip to content

Commit da9bad3

Browse files
author
黎书行
committed
暂存
1 parent dcf5b99 commit da9bad3

File tree

3 files changed

+78
-154
lines changed

3 files changed

+78
-154
lines changed

docs/examples/combobox.tsx

Lines changed: 19 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,155 +1,22 @@
1-
/* eslint-disable no-console */
2-
import React from 'react';
3-
import Select, { Option } from 'rc-select';
4-
import '../../assets/index.less';
1+
import Select from '@/Select';
2+
import { useRef } from 'react';
53

6-
class Combobox extends React.Component {
7-
state = {
8-
disabled: false,
9-
value: '',
10-
options: [],
4+
const Demo: React.FC = () => {
5+
const ref = useRef<HTMLInputElement>(null);
6+
const onSelect = () => {
7+
ref.current!.blur();
118
};
12-
13-
textareaRef = React.createRef<HTMLTextAreaElement>();
14-
15-
timeoutId: number;
16-
17-
componentDidMount() {
18-
console.log('Ref:', this.textareaRef);
19-
}
20-
21-
onChange = (value, option) => {
22-
console.log('onChange', value, option);
23-
this.setState({
24-
value,
25-
});
26-
};
27-
28-
onKeyDown = (e) => {
29-
const { value } = this.state;
30-
if (e.keyCode === 13) {
31-
console.log('onEnter', value);
32-
}
33-
};
34-
35-
onSelect = (v, option) => {
36-
console.log('onSelect', v, option);
37-
};
38-
39-
onSearch = (text: string) => {
40-
console.log('onSearch:', text);
9+
const getInputElement = () => {
10+
return <input ref={ref} />;
4111
};
42-
43-
onAsyncChange = (value) => {
44-
window.clearTimeout(this.timeoutId);
45-
46-
this.setState({
47-
options: [],
48-
});
49-
50-
this.timeoutId = window.setTimeout(() => {
51-
this.setState({
52-
options: [{ value }, { value: `${value}-${value}` }],
53-
});
54-
}, 1000);
55-
};
56-
57-
toggleDisabled = () => {
58-
const { disabled } = this.state;
59-
this.setState({
60-
disabled: !disabled,
61-
});
62-
};
63-
64-
render() {
65-
const { value, disabled } = this.state;
66-
return (
67-
<div>
68-
<h2>combobox</h2>
69-
<p>
70-
<button type="button" onClick={this.toggleDisabled}>
71-
toggle disabled
72-
</button>
73-
<button
74-
type="button"
75-
onClick={() => {
76-
this.setState({ value: '' });
77-
}}
78-
>
79-
reset
80-
</button>
81-
</p>
82-
<Select
83-
value={value}
84-
mode="combobox"
85-
onChange={this.onChange}
86-
filterOption={(inputValue, option) => {
87-
if (!inputValue) {
88-
return true;
89-
}
90-
return (option.value as string).includes(inputValue);
91-
}}
92-
>
93-
{['1', '2', '3'].map((i) => (
94-
<Option value={i} key={i}>
95-
{i}
96-
</Option>
97-
))}
98-
</Select>
99-
<div>
100-
<Select
101-
disabled={disabled}
102-
style={{ width: 500 }}
103-
onChange={this.onChange}
104-
onSelect={this.onSelect}
105-
onSearch={this.onSearch}
106-
onInputKeyDown={this.onKeyDown}
107-
notFoundContent=""
108-
allowClear
109-
placeholder="please input, max len: 10"
110-
value={value}
111-
maxLength={10}
112-
mode="combobox"
113-
backfill
114-
onFocus={() => console.log('focus')}
115-
onBlur={() => console.log('blur')}
116-
>
117-
<Option value="jack">
118-
<b style={{ color: 'red' }}>jack</b>
119-
</Option>
120-
<Option value="lucy">lucy</Option>
121-
<Option value="disabled" disabled>
122-
disabled
123-
</Option>
124-
<Option value="yiminghe">yiminghe</Option>
125-
<Option value="竹林星光">竹林星光</Option>
126-
</Select>
127-
128-
<h3>Customize Input Element</h3>
129-
<Select
130-
mode="combobox"
131-
style={{ width: 200 }}
132-
getInputElement={() => (
133-
<textarea style={{ background: 'red' }} rows={3} ref={this.textareaRef} />
134-
)}
135-
options={[{ value: 'light' }, { value: 'bamboo' }]}
136-
allowClear
137-
placeholder="2333"
138-
/>
139-
140-
<h3>Async Input Element</h3>
141-
<Select
142-
mode="combobox"
143-
notFoundContent={null}
144-
style={{ width: 200 }}
145-
options={this.state.options}
146-
onChange={this.onAsyncChange}
147-
/>
148-
</div>
149-
</div>
150-
);
151-
}
152-
}
153-
154-
export default Combobox;
155-
/* eslint-enable */
12+
return (
13+
<Select
14+
options={[{ value: 'aa' }, { value: 'bb' }]}
15+
onSelect={onSelect}
16+
mode="combobox"
17+
getInputElement={getInputElement}
18+
/>
19+
);
20+
};
21+
22+
export default Demo;

tests/Select.test.tsx

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { LabelInValueType } from '@/Select';
1+
import { type LabelInValueType } from '@/Select';
22
import {
33
createEvent,
44
fireEvent,
@@ -10,7 +10,7 @@ import KeyCode from 'rc-util/lib/KeyCode';
1010
import { spyElementPrototypes } from 'rc-util/lib/test/domHook';
1111
import { resetWarned } from 'rc-util/lib/warning';
1212
import type { ScrollConfig } from 'rc-virtual-list/lib/List';
13-
import React from 'react';
13+
import React, { useRef } from 'react';
1414
import type { SelectProps } from '../src';
1515
import Select, { OptGroup, Option, useBaseProps } from '../src';
1616
import type { BaseSelectRef } from '../src/BaseSelect';
@@ -20,7 +20,9 @@ import focusTest from './shared/focusTest';
2020
import inputFilterTest from './shared/inputFilterTest';
2121
import keyDownTest from './shared/keyDownTest';
2222
import openControlledTest from './shared/openControlledTest';
23+
2324
import {
25+
delay,
2426
expectOpen,
2527
findSelection,
2628
injectRunAllTimers,
@@ -2367,4 +2369,51 @@ describe('Select.Basic', () => {
23672369
expect(element[0]).not.toHaveClass('rc-select-item-option-disabled');
23682370
expect(element[1]).toHaveClass('rc-select-item-option-disabled');
23692371
});
2372+
2373+
it('release Enter key lock after customize input calls blur()', async () => {
2374+
let inputElem: HTMLInputElement | null = null;
2375+
const Demo: React.FC = () => {
2376+
const ref = useRef<HTMLInputElement>(null);
2377+
const onSelect = () => {
2378+
ref.current!.blur();
2379+
};
2380+
const getInputElement = () => {
2381+
return <input ref={ref} />;
2382+
};
2383+
return (
2384+
<Select
2385+
options={[{ value: 'aa' }, { value: 'bb' }]}
2386+
onSelect={onSelect}
2387+
mode="combobox"
2388+
getInputElement={getInputElement}
2389+
/>
2390+
);
2391+
};
2392+
const { container } = render(<Demo />);
2393+
inputElem = container.querySelector('input');
2394+
toggleOpen(container);
2395+
await delay(100);
2396+
expectOpen(container, true);
2397+
keyDown(inputElem!, 40);
2398+
keyUp(inputElem!, 40);
2399+
keyDown(inputElem!, 13);
2400+
2401+
await delay(100);
2402+
expectOpen(container, false);
2403+
expect(inputElem.value).toEqual('aa');
2404+
2405+
toggleOpen(container);
2406+
await delay(100);
2407+
expectOpen(container, true);
2408+
keyDown(inputElem!, 40);
2409+
keyUp(inputElem!, 40);
2410+
2411+
const itemNode = document.querySelectorAll('.rc-select-item')[1];
2412+
2413+
expect(itemNode.classList.contains('rc-select-item-option-active')).toBeTruthy();
2414+
keyDown(inputElem!, 13);
2415+
2416+
await delay(100);
2417+
expect(inputElem.value).toEqual('bb');
2418+
});
23702419
});

tests/utils/common.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,11 @@ export function keyUp(element: HTMLElement, keyCode: number) {
117117
fireEvent(element, event);
118118
});
119119
}
120+
121+
export async function delay(timeout = 0) {
122+
await act(async () => {
123+
await new Promise((resolve) => {
124+
setTimeout(resolve, timeout);
125+
});
126+
});
127+
}

0 commit comments

Comments
 (0)