Skip to content

Commit

Permalink
add inputValue prop (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasJang authored Jul 17, 2024
1 parent 68e9041 commit 3a58b58
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 137 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ export default BasicExample;
<td>boolean | undefined</td>
<td>false</td>
<td></td>
</tr>
<tr>
<td>inputValue</td>
<td>string | undefined</td>
<td>undefined</td>
<td></td>
</tr>
</table>

Expand Down
13 changes: 11 additions & 2 deletions examples/BasicExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import * as React from 'react';
import styled from '@emotion/styled';
import { ReactMultiEmail } from '../react-multi-email';
import { Button } from 'antd';
import { useRef, useState } from 'react';

interface Props {}

function BasicExample(_props: Props) {
const [emails, setEmails] = React.useState<string[]>([]);
const [focused, setFocused] = React.useState(false);
const [input, setInput] = useState<string>('');

const ref = useRef<HTMLDivElement>(null);

return (
<Container>
<Container ref={ref}>
<form>
<h3>Email</h3>
<ReactMultiEmail
Expand All @@ -21,7 +25,10 @@ function BasicExample(_props: Props) {
}}
autoFocus={true}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
onBlur={() => {
setFocused(false);
setInput('');
}}
onKeyDown={evt => {
console.log(evt);
}}
Expand All @@ -38,8 +45,10 @@ function BasicExample(_props: Props) {
</div>
);
}}
inputValue={input}
onChangeInput={value => {
console.log(value);
setInput(value);
}}
/>
<br />
Expand Down
16 changes: 11 additions & 5 deletions react-multi-email/ReactMultiEmail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface IReactMultiEmailProps {
allowDisplayName?: boolean;
stripDisplayName?: boolean;
allowDuplicate?: boolean;
inputValue?: string;
}

export function ReactMultiEmail(props: IReactMultiEmailProps) {
Expand Down Expand Up @@ -62,12 +63,13 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
onKeyUp,
spinner,
disableOnBlurValidation = false,
inputValue,
} = props;
const emailInputRef = React.useRef<HTMLInputElement>(null);

const [focused, setFocused] = React.useState(false);
const [emails, setEmails] = React.useState<string[]>([]);
const [inputValue, setInputValue] = React.useState('');
const [inpValue, setInpValue] = React.useState('');
const [spinning, setSpinning] = React.useState(false);

const findEmailAddress = React.useCallback(
Expand Down Expand Up @@ -172,7 +174,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
}

setEmails([...emails, ...validEmails]);
setInputValue(inputValue);
setInpValue(inputValue);

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

React.useEffect(() => {
setInputValue(initialInputValue);
setInpValue(initialInputValue);
}, [initialInputValue]);

React.useEffect(() => {
setInpValue(inputValue ?? '');
}, [inputValue]);

React.useEffect(() => {
if (validateEmail) {
(async () => {
Expand All @@ -301,7 +307,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
return (
<div
className={`${className} ${noClass ? '' : 'react-multi-email'} ${focused ? 'focused' : ''} ${
inputValue === '' && emails.length === 0 ? 'empty' : 'fill'
inpValue === '' && emails.length === 0 ? 'empty' : 'fill'
}`}
style={style}
onClick={() => emailInputRef.current?.focus()}
Expand All @@ -319,7 +325,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) {
style={{ opacity: spinning ? 0.45 : 1.0 }}
ref={emailInputRef}
type='text'
value={inputValue}
value={inpValue}
onFocus={handleOnFocus}
onBlur={handleOnBlur}
onChange={handleOnChange}
Expand Down
102 changes: 54 additions & 48 deletions test/emails.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,47 @@ import { sleep } from './utils/sleep';
afterEach(cleanup);

describe('ReactMultEmail emails TEST', () => {
it('Emails validation children node count', () => {
render(
<ReactMultiEmail
emails={['test', 'tt', '[email protected]']}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
it('Emails validation children node count', async () => {
await act(async () => {
return render(
<ReactMultiEmail
emails={['test', 'tt', '[email protected]']}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
});

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

it('Emails empty', () => {
render(
<ReactMultiEmail
emails={[]}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
it('Emails empty', async () => {
await act(async () => {
return render(
<ReactMultiEmail
emails={[]}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
});

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

it('Emails with invalid text', () => {
render(
<ReactMultiEmail
emails={['test', 'email']}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
it('Emails with invalid text', async () => {
await act(async () => {
return render(
<ReactMultiEmail
emails={['test', 'email']}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
});

const emptyElement = document.querySelector('.empty');
const emailsWrapper = document.querySelector('.data-labels');
Expand Down
78 changes: 41 additions & 37 deletions test/enable.test.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,68 @@
import { cleanup, fireEvent, render } from '@testing-library/react';
import { ReactMultiEmail } from '../react-multi-email';
import React from 'react';
import { act } from 'react-dom/test-utils';

afterEach(cleanup);

it('check enable and disabled executed ', () => {
it('check enable and disabled executed ', async () => {
const enableMockFunc = jest.fn().mockImplementation(({ emailCnt }: { emailCnt: number }) => emailCnt < 3);
const disabledMockFunc = jest.fn();
const emailList = ['[email protected]', '[email protected]', '[email protected]'];

const { getByRole } = render(
<ReactMultiEmail
enable={enableMockFunc}
onDisabled={disabledMockFunc}
emails={emailList}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
const { getByRole } = await act(async () => {
return render(
<ReactMultiEmail
enable={enableMockFunc}
onDisabled={disabledMockFunc}
emails={emailList}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
});

const inputElement = getByRole('textbox');
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
for (let i = 0; i < 3; i++) {
fireEvent.change(inputElement, { target: { value: `test${i}@test.com` } });
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
}

expect(disabledMockFunc).toHaveBeenCalled();
});

it('check enable function is executed and disabled function is not executed', () => {
it('check enable function is executed and disabled function is not executed', async () => {
const enableMockFunc = jest.fn().mockImplementation(({ emailCnt }: { emailCnt: number }) => emailCnt < 3);
const disabledMockFunc = jest.fn();
const emailList = ['[email protected]', '[email protected]'];

const { getByRole } = render(
<ReactMultiEmail
enable={enableMockFunc}
onDisabled={disabledMockFunc}
emails={emailList}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
const { getByRole } = await act(async () => {
return render(
<ReactMultiEmail
enable={enableMockFunc}
onDisabled={disabledMockFunc}
emails={emailList}
getLabel={(email, index, removeEmail) => {
return (
<div data-tag key={index}>
<div data-tag-item>{email}</div>
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
</div>
);
}}
/>,
);
});

const inputElement = getByRole('textbox');
fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' });
Expand Down
Loading

0 comments on commit 3a58b58

Please sign in to comment.