From 18bc53cbc1267f43dba697e9f979eb7f842530aa Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 17 Jul 2024 15:41:27 +0900 Subject: [PATCH] add inputValue prop --- README.md | 6 ++ examples/BasicExample.tsx | 13 +++- react-multi-email/ReactMultiEmail.tsx | 16 ++-- test/emails.test.tsx | 102 ++++++++++++++------------ test/enable.test.tsx | 78 ++++++++++---------- test/validateEmail.test.tsx | 97 ++++++++++++------------ 6 files changed, 175 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 8115fea..e9d153b 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,12 @@ export default BasicExample; boolean | undefined false + + + inputValue + string | undefined + undefined + diff --git a/examples/BasicExample.tsx b/examples/BasicExample.tsx index 78586cc..2de6fb3 100644 --- a/examples/BasicExample.tsx +++ b/examples/BasicExample.tsx @@ -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([]); const [focused, setFocused] = React.useState(false); + const [input, setInput] = useState(''); + + const ref = useRef(null); return ( - +

Email

setFocused(true)} - onBlur={() => setFocused(false)} + onBlur={() => { + setFocused(false); + setInput(''); + }} onKeyDown={evt => { console.log(evt); }} @@ -38,8 +45,10 @@ function BasicExample(_props: Props) { ); }} + inputValue={input} onChangeInput={value => { console.log(value); + setInput(value); }} />
diff --git a/react-multi-email/ReactMultiEmail.tsx b/react-multi-email/ReactMultiEmail.tsx index 6b4d5e6..de901cd 100644 --- a/react-multi-email/ReactMultiEmail.tsx +++ b/react-multi-email/ReactMultiEmail.tsx @@ -33,6 +33,7 @@ export interface IReactMultiEmailProps { allowDisplayName?: boolean; stripDisplayName?: boolean; allowDuplicate?: boolean; + inputValue?: string; } export function ReactMultiEmail(props: IReactMultiEmailProps) { @@ -62,12 +63,13 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) { onKeyUp, spinner, disableOnBlurValidation = false, + inputValue, } = props; const emailInputRef = React.useRef(null); const [focused, setFocused] = React.useState(false); const [emails, setEmails] = React.useState([]); - const [inputValue, setInputValue] = React.useState(''); + const [inpValue, setInpValue] = React.useState(''); const [spinning, setSpinning] = React.useState(false); const findEmailAddress = React.useCallback( @@ -172,7 +174,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) { } setEmails([...emails, ...validEmails]); - setInputValue(inputValue); + setInpValue(inputValue); if (validEmails.length) { onChange?.([...emails, ...validEmails]); @@ -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 () => { @@ -301,7 +307,7 @@ export function ReactMultiEmail(props: IReactMultiEmailProps) { return (
emailInputRef.current?.focus()} @@ -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} diff --git a/test/emails.test.tsx b/test/emails.test.tsx index 8a5549f..3ecd070 100644 --- a/test/emails.test.tsx +++ b/test/emails.test.tsx @@ -7,43 +7,47 @@ import { sleep } from './utils/sleep'; afterEach(cleanup); describe('ReactMultEmail emails TEST', () => { - it('Emails validation children node count', () => { - render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + it('Emails validation children node count', async () => { + await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const emailsWrapper = document.querySelector('.data-labels'); expect(emailsWrapper?.childElementCount).toEqual(1); }); - it('Emails empty', () => { - render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + it('Emails empty', async () => { + await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const emptyElement = document.querySelector('.empty'); const emailsWrapper = document.querySelector('.data-labels'); @@ -52,22 +56,24 @@ describe('ReactMultEmail emails TEST', () => { expect(emptyElement).toBeTruthy(); }); - it('Emails with invalid text', () => { - render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + it('Emails with invalid text', async () => { + await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const emptyElement = document.querySelector('.empty'); const emailsWrapper = document.querySelector('.data-labels'); diff --git a/test/enable.test.tsx b/test/enable.test.tsx index a7a827c..5726845 100644 --- a/test/enable.test.tsx +++ b/test/enable.test.tsx @@ -1,31 +1,34 @@ 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 = ['test0@test.com', 'test1@test.com', 'test2@test.com']; - const { getByRole } = render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + const { getByRole } = await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const inputElement = getByRole('textbox'); fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' }); @@ -33,32 +36,33 @@ it('check enable and disabled executed ', () => { 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 = ['test0@test.com', 'test1@test.com']; - const { getByRole } = render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + const { getByRole } = await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const inputElement = getByRole('textbox'); fireEvent.keyDown(inputElement, { key: 'Enter', code: 'Enter' }); diff --git a/test/validateEmail.test.tsx b/test/validateEmail.test.tsx index 78dbe42..010a18f 100644 --- a/test/validateEmail.test.tsx +++ b/test/validateEmail.test.tsx @@ -1,27 +1,30 @@ import { cleanup, fireEvent, render, waitFor } from '@testing-library/react'; import { ReactMultiEmail } from '../react-multi-email'; import React from 'react'; +import { act } from 'react-dom/test-utils'; afterEach(cleanup); it('ReactMultiEmail validateEmail function works test', async () => { const mockValidateEmailFunc = jest.fn(); - const { getByRole } = render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + const { getByRole } = await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const input = getByRole('textbox') as HTMLElement; @@ -37,21 +40,23 @@ it('validateEmail = true , test code ending in .com', async () => { const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.(com)$/; const mockValidateEmailFunc = jest.fn().mockImplementation(email => regex.test(email)); - const { getByRole } = render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + const { getByRole } = await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const input = getByRole('textbox') as HTMLInputElement; @@ -66,21 +71,23 @@ it('validateEmail = false', async () => { const regex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.(com)$/; const mockValidateEmailFunc = jest.fn().mockImplementation(email => regex.test(email)); - const { getByRole } = render( - { - return ( -
-
{email}
- removeEmail(index)}> - × - -
- ); - }} - />, - ); + const { getByRole } = await act(async () => { + return render( + { + return ( +
+
{email}
+ removeEmail(index)}> + × + +
+ ); + }} + />, + ); + }); const input = getByRole('textbox') as HTMLInputElement;