From 9446e2cdd438c592f186ea545dd6c6c0f100cefa Mon Sep 17 00:00:00 2001 From: github-actions Date: Sun, 6 Dec 2020 13:41:26 -0800 Subject: [PATCH] feat #166 - Prevent Enter in input from automatically submitting form --- src/components/Form/Form.test.tsx | 28 ++----------------- .../Form/FormInput/FormInput.test.tsx | 24 ++++++++++++++++ src/components/Form/FormInput/index.tsx | 8 +++++- src/components/Form/index.tsx | 11 +------- src/components/Input/index.tsx | 5 +++- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/components/Form/Form.test.tsx b/src/components/Form/Form.test.tsx index 2a7db7b0..781e682b 100644 --- a/src/components/Form/Form.test.tsx +++ b/src/components/Form/Form.test.tsx @@ -4,25 +4,20 @@ import FormSubmitButton from './FormSubmitButton' import { UseFormMethods } from 'react-hook-form' import { Form, FormProps } from './index' import { mount, shallow, ShallowWrapper } from 'enzyme' -import React, { BaseSyntheticEvent, createRef } from 'react' - -const mockPreventDefault = jest.fn() -const mockHandleSubmit = ( - fn: (data: Record, event: BaseSyntheticEvent) => void -) => fn({}, { preventDefault: mockPreventDefault } as any) +import React, { createRef } from 'react' jest.mock('react-hook-form', () => ({ ...(jest.requireActual('react-hook-form') as {}), useForm: () => ({ getValues: mockGetValues, - handleSubmit: mockHandleSubmit, + handleSubmit: jest.fn(), reset: mockReset }), useFormContext: () => ({ formState: { isDirty: true }, - handleSubmit: mockHandleSubmit + handleSubmit: jest.fn() }) })) @@ -45,10 +40,6 @@ beforeEach(() => { ) }) -afterEach(() => { - jest.resetAllMocks() -}) - describe('Form', () => { it('renders', () => { expect(wrapper).toHaveLength(1) @@ -67,19 +58,6 @@ describe('Form', () => { ) }) - it('prevents event default on form submit', () => { - const mountedForm = mount( -
- Submit -
- ) - - mountedForm.find('form').simulate('submit') - - expect(mockPreventDefault).toHaveBeenCalled() - expect(mockOnSubmit).toHaveBeenCalled() - }) - it('exposes form methods when a ref is passed', () => { const formRef = createRef() diff --git a/src/components/Form/FormInput/FormInput.test.tsx b/src/components/Form/FormInput/FormInput.test.tsx index 99a06518..d4ac8092 100644 --- a/src/components/Form/FormInput/FormInput.test.tsx +++ b/src/components/Form/FormInput/FormInput.test.tsx @@ -96,6 +96,30 @@ describe('FormInput', () => { expect(mockFocus).toHaveBeenCalled() }) + it('prevents default behavior when enter is pressed within the input', () => { + const input = wrapper.find(Controller).invoke('render')!(mockRenderArgs) + const mockPreventDefault = jest.fn() + + input.props.onKeyDown({ + key: 'Enter', + preventDefault: mockPreventDefault + }) + + expect(mockPreventDefault).toHaveBeenCalled() + }) + + it('does not prevent default behavior when other keys are pressed within the input', () => { + const input = wrapper.find(Controller).invoke('render')!(mockRenderArgs) + const mockPreventDefault = jest.fn() + + input.props.onKeyDown({ + key: 'Escape', + preventDefault: mockPreventDefault + }) + + expect(mockPreventDefault).not.toHaveBeenCalled() + }) + it('clears errors on focus if there are any', () => { wrapper = getMountedFormInput() diff --git a/src/components/Form/FormInput/index.tsx b/src/components/Form/FormInput/index.tsx index 6b60c6f0..6f9b98a7 100644 --- a/src/components/Form/FormInput/index.tsx +++ b/src/components/Form/FormInput/index.tsx @@ -6,7 +6,7 @@ import { getFormFieldDataTag } from '../utils' import { Controller, useFormContext } from 'react-hook-form' import FieldContext, { FieldContextProps } from '../FieldContext' import { Input, InputProps } from 'components/Input' -import React, { FC, useContext, useEffect, useRef } from 'react' +import React, { FC, KeyboardEvent, useContext, useEffect, useRef } from 'react' export interface FormInputProps extends BaseFieldProps, @@ -34,6 +34,11 @@ const FormInput: FC = ({ if (errors[name]) clearErrors(name) } + const onKeyDown = (e: KeyboardEvent) => { + // This prevents the form from being automatically submitted when the Enter button is pressed + if (e.key === 'Enter') e.preventDefault() + } + useEffect(() => { if (focused && inputRef.current) { inputRef.current.focus() @@ -67,6 +72,7 @@ const FormInput: FC = ({ loading={loading} onChange={onChange} onFocus={onInputFocus} + onKeyDown={onKeyDown} value={value} {...rest} /> diff --git a/src/components/Form/index.tsx b/src/components/Form/index.tsx index 01b9af93..cdb205af 100644 --- a/src/components/Form/index.tsx +++ b/src/components/Form/index.tsx @@ -40,18 +40,9 @@ export function Form({ useImperativeHandle(formRef, () => methods) - const formOnSubmit = ( - data: Record, - e?: React.BaseSyntheticEvent - ) => { - e && e.preventDefault() - - onSubmit(data) - } - return ( -
+
{children}
diff --git a/src/components/Input/index.tsx b/src/components/Input/index.tsx index 0f074c95..4874bec6 100644 --- a/src/components/Input/index.tsx +++ b/src/components/Input/index.tsx @@ -12,7 +12,7 @@ import { fieldErrorStyles } from '../assets/styles/styleguide' import { generateInputSkeletonStyles, generateInputStyles } from './utils' -import React, { FC, RefObject } from 'react' +import React, { FC, KeyboardEvent, RefObject } from 'react' const { dark, light } = ThemeType @@ -48,6 +48,7 @@ const InputSkeleton: FC = (props: InputProps) => { export interface InputProps extends BaseFormElementProps { inputRef?: RefObject onFocus?: () => void + onKeyDown?: (e: KeyboardEvent) => void /** * Type of input (ex: text, password) * @default text @@ -63,6 +64,7 @@ export const Input: FC = (props: InputProps) => { inputRef, onChange, onFocus = noop, + onKeyDown = noop, error = false, loading = false, placeholder = '', @@ -99,6 +101,7 @@ export const Input: FC = (props: InputProps) => { className={cn(componentClasses.container, inputClasses)} disabled={disabled} onFocus={onFocus} + onKeyDown={onKeyDown} placeholder={placeholder} ref={inputRef} type={type}