Skip to content

Commit 3a58b58

Browse files
authored
add inputValue prop (#177)
1 parent 68e9041 commit 3a58b58

File tree

6 files changed

+175
-137
lines changed

6 files changed

+175
-137
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ export default BasicExample;
242242
<td>boolean | undefined</td>
243243
<td>false</td>
244244
<td></td>
245+
</tr>
246+
<tr>
247+
<td>inputValue</td>
248+
<td>string | undefined</td>
249+
<td>undefined</td>
250+
<td></td>
245251
</tr>
246252
</table>
247253

examples/BasicExample.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ import * as React from 'react';
22
import styled from '@emotion/styled';
33
import { ReactMultiEmail } from '../react-multi-email';
44
import { Button } from 'antd';
5+
import { useRef, useState } from 'react';
56

67
interface Props {}
78

89
function BasicExample(_props: Props) {
910
const [emails, setEmails] = React.useState<string[]>([]);
1011
const [focused, setFocused] = React.useState(false);
12+
const [input, setInput] = useState<string>('');
13+
14+
const ref = useRef<HTMLDivElement>(null);
1115

1216
return (
13-
<Container>
17+
<Container ref={ref}>
1418
<form>
1519
<h3>Email</h3>
1620
<ReactMultiEmail
@@ -21,7 +25,10 @@ function BasicExample(_props: Props) {
2125
}}
2226
autoFocus={true}
2327
onFocus={() => setFocused(true)}
24-
onBlur={() => setFocused(false)}
28+
onBlur={() => {
29+
setFocused(false);
30+
setInput('');
31+
}}
2532
onKeyDown={evt => {
2633
console.log(evt);
2734
}}
@@ -38,8 +45,10 @@ function BasicExample(_props: Props) {
3845
</div>
3946
);
4047
}}
48+
inputValue={input}
4149
onChangeInput={value => {
4250
console.log(value);
51+
setInput(value);
4352
}}
4453
/>
4554
<br />

react-multi-email/ReactMultiEmail.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export interface IReactMultiEmailProps {
3333
allowDisplayName?: boolean;
3434
stripDisplayName?: boolean;
3535
allowDuplicate?: boolean;
36+
inputValue?: string;
3637
}
3738

3839
export function ReactMultiEmail(props: IReactMultiEmailProps) {
@@ -62,12 +63,13 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
6263
onKeyUp,
6364
spinner,
6465
disableOnBlurValidation = false,
66+
inputValue,
6567
} = props;
6668
const emailInputRef = React.useRef<HTMLInputElement>(null);
6769

6870
const [focused, setFocused] = React.useState(false);
6971
const [emails, setEmails] = React.useState<string[]>([]);
70-
const [inputValue, setInputValue] = React.useState('');
72+
const [inpValue, setInpValue] = React.useState('');
7173
const [spinning, setSpinning] = React.useState(false);
7274

7375
const findEmailAddress = React.useCallback(
@@ -172,7 +174,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
172174
}
173175

174176
setEmails([...emails, ...validEmails]);
175-
setInputValue(inputValue);
177+
setInpValue(inputValue);
176178

177179
if (validEmails.length) {
178180
onChange?.([...emails, ...validEmails]);
@@ -272,9 +274,13 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
272274
}, [onFocus]);
273275

274276
React.useEffect(() => {
275-
setInputValue(initialInputValue);
277+
setInpValue(initialInputValue);
276278
}, [initialInputValue]);
277279

280+
React.useEffect(() => {
281+
setInpValue(inputValue ?? '');
282+
}, [inputValue]);
283+
278284
React.useEffect(() => {
279285
if (validateEmail) {
280286
(async () => {
@@ -301,7 +307,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
301307
return (
302308
<div
303309
className={`${className} ${noClass ? '' : 'react-multi-email'} ${focused ? 'focused' : ''} ${
304-
inputValue === '' && emails.length === 0 ? 'empty' : 'fill'
310+
inpValue === '' && emails.length === 0 ? 'empty' : 'fill'
305311
}`}
306312
style={style}
307313
onClick={() => emailInputRef.current?.focus()}
@@ -319,7 +325,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
319325
style={{ opacity: spinning ? 0.45 : 1.0 }}
320326
ref={emailInputRef}
321327
type='text'
322-
value={inputValue}
328+
value={inpValue}
323329
onFocus={handleOnFocus}
324330
onBlur={handleOnBlur}
325331
onChange={handleOnChange}

test/emails.test.tsx

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,47 @@ import { sleep } from './utils/sleep';
77
afterEach(cleanup);
88

99
describe('ReactMultEmail emails TEST', () => {
10-
it('Emails validation children node count', () => {
11-
render(
12-
<ReactMultiEmail
13-
emails={['test', 'tt', 'test@gmail.com']}
14-
getLabel={(email, index, removeEmail) => {
15-
return (
16-
<div data-tag key={index}>
17-
<div data-tag-item>{email}</div>
18-
<span data-tag-handle onClick={() => removeEmail(index)}>
19-
×
20-
</span>
21-
</div>
22-
);
23-
}}
24-
/>,
25-
);
10+
it('Emails validation children node count', async () => {
11+
await act(async () => {
12+
return render(
13+
<ReactMultiEmail
14+
emails={['test', 'tt', 'test@gmail.com']}
15+
getLabel={(email, index, removeEmail) => {
16+
return (
17+
<div data-tag key={index}>
18+
<div data-tag-item>{email}</div>
19+
<span data-tag-handle onClick={() => removeEmail(index)}>
20+
×
21+
</span>
22+
</div>
23+
);
24+
}}
25+
/>,
26+
);
27+
});
2628

2729
const emailsWrapper = document.querySelector('.data-labels');
2830
expect(emailsWrapper?.childElementCount).toEqual(1);
2931
});
3032

31-
it('Emails empty', () => {
32-
render(
33-
<ReactMultiEmail
34-
emails={[]}
35-
getLabel={(email, index, removeEmail) => {
36-
return (
37-
<div data-tag key={index}>
38-
<div data-tag-item>{email}</div>
39-
<span data-tag-handle onClick={() => removeEmail(index)}>
40-
×
41-
</span>
42-
</div>
43-
);
44-
}}
45-
/>,
46-
);
33+
it('Emails empty', async () => {
34+
await act(async () => {
35+
return render(
36+
<ReactMultiEmail
37+
emails={[]}
38+
getLabel={(email, index, removeEmail) => {
39+
return (
40+
<div data-tag key={index}>
41+
<div data-tag-item>{email}</div>
42+
<span data-tag-handle onClick={() => removeEmail(index)}>
43+
×
44+
</span>
45+
</div>
46+
);
47+
}}
48+
/>,
49+
);
50+
});
4751

4852
const emptyElement = document.querySelector('.empty');
4953
const emailsWrapper = document.querySelector('.data-labels');
@@ -52,22 +56,24 @@ describe('ReactMultEmail emails TEST', () => {
5256
expect(emptyElement).toBeTruthy();
5357
});
5458

55-
it('Emails with invalid text', () => {
56-
render(
57-
<ReactMultiEmail
58-
emails={['test', 'email']}
59-
getLabel={(email, index, removeEmail) => {
60-
return (
61-
<div data-tag key={index}>
62-
<div data-tag-item>{email}</div>
63-
<span data-tag-handle onClick={() => removeEmail(index)}>
64-
×
65-
</span>
66-
</div>
67-
);
68-
}}
69-
/>,
70-
);
59+
it('Emails with invalid text', async () => {
60+
await act(async () => {
61+
return render(
62+
<ReactMultiEmail
63+
emails={['test', 'email']}
64+
getLabel={(email, index, removeEmail) => {
65+
return (
66+
<div data-tag key={index}>
67+
<div data-tag-item>{email}</div>
68+
<span data-tag-handle onClick={() => removeEmail(index)}>
69+
×
70+
</span>
71+
</div>
72+
);
73+
}}
74+
/>,
75+
);
76+
});
7177

7278
const emptyElement = document.querySelector('.empty');
7379
const emailsWrapper = document.querySelector('.data-labels');

test/enable.test.tsx

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,68 @@
11
import { cleanup, fireEvent, render } from '@testing-library/react';
22
import { ReactMultiEmail } from '../react-multi-email';
33
import React from 'react';
4+
import { act } from 'react-dom/test-utils';
45

56
afterEach(cleanup);
67

7-
it('check enable and disabled executed ', () => {
8+
it('check enable and disabled executed ', async () => {
89
const enableMockFunc = jest.fn().mockImplementation(({ emailCnt }: { emailCnt: number }) => emailCnt < 3);
910
const disabledMockFunc = jest.fn();
1011
const emailList = ['test0@test.com', 'test1@test.com', 'test2@test.com'];
1112

12-
const { getByRole } = render(
13-
<ReactMultiEmail
14-
enable={enableMockFunc}
15-
onDisabled={disabledMockFunc}
16-
emails={emailList}
17-
getLabel={(email, index, removeEmail) => {
18-
return (
19-
<div data-tag key={index}>
20-
<div data-tag-item>{email}</div>
21-
<span data-tag-handle onClick={() => removeEmail(index)}>
22-
×
23-
</span>
24-
</div>
25-
);
26-
}}
27-
/>,
28-
);
13+
const { getByRole } = await act(async () => {
14+
return render(
15+
<ReactMultiEmail
16+
enable={enableMockFunc}
17+
onDisabled={disabledMockFunc}
18+
emails={emailList}
19+
getLabel={(email, index, removeEmail) => {
20+
return (
21+
<div data-tag key={index}>
22+
<div data-tag-item>{email}</div>
23+
<span data-tag-handle onClick={() => removeEmail(index)}>
24+
×
25+
</span>
26+
</div>
27+
);
28+
}}
29+
/>,
30+
);
31+
});
2932

3033
const inputElement = getByRole('textbox');
3134
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
3235
for (let i = 0; i < 3; i++) {
3336
fireEvent.change(inputElement, { target: { value: `test${i}@test.com` } });
3437
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
3538
}
36-
3739
expect(disabledMockFunc).toHaveBeenCalled();
3840
});
3941

40-
it('check enable function is executed and disabled function is not executed', () => {
42+
it('check enable function is executed and disabled function is not executed', async () => {
4143
const enableMockFunc = jest.fn().mockImplementation(({ emailCnt }: { emailCnt: number }) => emailCnt < 3);
4244
const disabledMockFunc = jest.fn();
4345
const emailList = ['test0@test.com', 'test1@test.com'];
4446

45-
const { getByRole } = render(
46-
<ReactMultiEmail
47-
enable={enableMockFunc}
48-
onDisabled={disabledMockFunc}
49-
emails={emailList}
50-
getLabel={(email, index, removeEmail) => {
51-
return (
52-
<div data-tag key={index}>
53-
<div data-tag-item>{email}</div>
54-
<span data-tag-handle onClick={() => removeEmail(index)}>
55-
×
56-
</span>
57-
</div>
58-
);
59-
}}
60-
/>,
61-
);
47+
const { getByRole } = await act(async () => {
48+
return render(
49+
<ReactMultiEmail
50+
enable={enableMockFunc}
51+
onDisabled={disabledMockFunc}
52+
emails={emailList}
53+
getLabel={(email, index, removeEmail) => {
54+
return (
55+
<div data-tag key={index}>
56+
<div data-tag-item>{email}</div>
57+
<span data-tag-handle onClick={() => removeEmail(index)}>
58+
×
59+
</span>
60+
</div>
61+
);
62+
}}
63+
/>,
64+
);
65+
});
6266

6367
const inputElement = getByRole('textbox');
6468
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });

0 commit comments

Comments
 (0)