Skip to content

Commit

Permalink
v0.7.5 -> v0.7.6 (#168)
Browse files Browse the repository at this point in the history
* feat #166 - Prevent Enter in input from automatically submitting form
  • Loading branch information
nancy-dassana authored Dec 7, 2020
1 parent 8a3af77 commit 939b19f
Show file tree
Hide file tree
Showing 17 changed files with 55 additions and 159 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@dassana-io/web-components",
"version": "0.7.5",
"version": "0.7.6",
"publishConfig": {
"registry": "https://npm.pkg.github.com/dassana-io"
},
Expand Down
1 change: 0 additions & 1 deletion src/components/Form/FieldContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { FieldValues } from 'react-hook-form/dist/types/form'
import { SubmitHandler } from 'react-hook-form'

export interface FieldContextProps {
initialValues: FieldValues
loading: boolean
onSubmit: SubmitHandler<FieldValues>
}
Expand Down
25 changes: 0 additions & 25 deletions src/components/Form/Form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,37 +52,12 @@ describe('Form', () => {
it('passes the correct props to FieldContext provider', () => {
expect(wrapper.find(FieldContext.Provider).props().value).toMatchObject(
{
initialValues: mockInitialValues,
loading: false,
onSubmit: mockOnSubmit
}
)
})

it('correctly defaults initial values to empty object if none is passed in', () => {
wrapper = shallow(
<Form onSubmit={mockOnSubmit}>
<FormSubmitButton>Submit</FormSubmitButton>
</Form>
)

expect(
wrapper.find(FieldContext.Provider).props().value
).toMatchObject({ initialValues: {} })
})

it('correctly updates initial values', () => {
const form = mount(
<Form onSubmit={mockOnSubmit}>
<FormSubmitButton>Submit</FormSubmitButton>
</Form>
)

form.setProps({ initialValues: mockInitialValues })

expect(mockReset).toHaveBeenCalledWith(mockInitialValues)
})

it('exposes form methods when a ref is passed', () => {
const formRef = createRef<UseFormMethods>()

Expand Down
30 changes: 24 additions & 6 deletions src/components/Form/FormInput/FormInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const getMountedFormInput = (formInputProps: Partial<FormInputProps> = {}) =>
mount(
<FieldContext.Provider
value={{
initialValues: { foo: 'bar' },
loading: true,
onSubmit: mockOnSubmit
}}
Expand All @@ -62,10 +61,6 @@ describe('FormInput', () => {
expect(wrapper).toHaveLength(1)
})

it('correctly passes a default value from initial values if it exists', () => {
expect(wrapper.find(Controller).props().defaultValue).toEqual('bar')
})

it('should render an Input component', () => {
const input = wrapper.find(Controller).invoke('render')!(mockRenderArgs)

Expand All @@ -76,7 +71,6 @@ describe('FormInput', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
Expand All @@ -102,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()

Expand Down
15 changes: 8 additions & 7 deletions src/components/Form/FormInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -26,16 +26,19 @@ const FormInput: FC<FormInputProps> = ({
}: FormInputProps) => {
const inputRef = useRef<AntDInput>(null)
const { clearErrors, control, errors } = useFormContext()
const { initialValues, loading } = useContext<FieldContextProps>(
FieldContext
)
const { loading } = useContext<FieldContextProps>(FieldContext)

const errorMsg = errors[name] ? errors[name].message : ''

const onInputFocus = () => {
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()
Expand All @@ -46,8 +49,6 @@ const FormInput: FC<FormInputProps> = ({
rules.required = true
}

const defaultValue = (initialValues[name] as string) || ''

return (
<div>
{label && (
Expand All @@ -61,7 +62,6 @@ const FormInput: FC<FormInputProps> = ({
)}
<Controller
control={control}
defaultValue={defaultValue}
name={name}
render={({ onChange, value }) => (
<Input
Expand All @@ -72,6 +72,7 @@ const FormInput: FC<FormInputProps> = ({
loading={loading}
onChange={onChange}
onFocus={onInputFocus}
onKeyDown={onKeyDown}
value={value}
{...rest}
/>
Expand Down
6 changes: 0 additions & 6 deletions src/components/Form/FormRadioGroup/FormRadioGroup.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ beforeEach(() => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: { foo: 'bar' },
loading: true,
onSubmit: mockOnSubmit
}}
Expand All @@ -50,10 +49,6 @@ describe('FormRadioGroup', () => {
expect(wrapper).toHaveLength(1)
})

it('correctly passes a default value from initial values if it exists', () => {
expect(wrapper.find(Controller).props().defaultValue).toEqual('bar')
})

it('should render a Radio Group component', () => {
const radioGroup = getRenderedCmp(wrapper)

Expand All @@ -72,7 +67,6 @@ describe('FormRadioGroup', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
Expand Down
9 changes: 1 addition & 8 deletions src/components/Form/FormRadioGroup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ export interface FormRadioGroupProps
Omit<RadioGroupProps, 'onChange' | 'value'> {}

const FormRadioGroup: FC<FormRadioGroupProps> = ({
defaultValue,
label,
labelSkeletonWidth,
name,
Expand All @@ -20,14 +19,10 @@ const FormRadioGroup: FC<FormRadioGroupProps> = ({
...rest
}: FormRadioGroupProps) => {
const { control } = useFormContext()
const { initialValues, loading } = useContext<FieldContextProps>(
FieldContext
)
const { loading } = useContext<FieldContextProps>(FieldContext)

rules.required = true

const initialValue = (initialValues[name] as string) || defaultValue || ''

return (
<div>
{label && (
Expand All @@ -40,12 +35,10 @@ const FormRadioGroup: FC<FormRadioGroupProps> = ({
)}
<Controller
control={control}
defaultValue={initialValue}
name={name}
render={({ onChange, value }) => (
<RadioGroup
dataTag={getFormFieldDataTag(name)}
defaultValue={defaultValue}
loading={loading}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
Expand Down
6 changes: 0 additions & 6 deletions src/components/Form/FormSelect/FormSelect.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ beforeEach(() => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: { foo: 'bar' },
loading: true,
onSubmit: mockOnSubmit
}}
Expand All @@ -43,10 +42,6 @@ describe('FormSelect', () => {
expect(wrapper).toHaveLength(1)
})

it('correctly passes a default value from initial values if it exists', () => {
expect(wrapper.find(Controller).props().defaultValue).toEqual('bar')
})

it('should render a Select component', () => {
const test = {
onChange: jest.fn(),
Expand All @@ -62,7 +57,6 @@ describe('FormSelect', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
Expand Down
8 changes: 1 addition & 7 deletions src/components/Form/FormSelect/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,10 @@ const FormSelect: FC<FormSelectProps> = ({
...rest
}: FormSelectProps) => {
const { control } = useFormContext()
const { initialValues, loading } = useContext<FieldContextProps>(
FieldContext
)
const { loading } = useContext<FieldContextProps>(FieldContext)

rules.required = true

const defaultValue = (initialValues[name] as string) || ''

return (
<div>
{label && (
Expand All @@ -39,12 +35,10 @@ const FormSelect: FC<FormSelectProps> = ({
)}
<Controller
control={control}
defaultValue={defaultValue}
name={name}
render={({ onChange, value }) => (
<Select
dataTag={getFormFieldDataTag(name)}
defaultValue={defaultValue}
loading={loading}
onChange={onChange}
value={value}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ const getMockFormContext = (isDirty = true) =>
isDirty
},
getValues: jest.fn() as any,
handleSubmit: (onSubmit: any) => onSubmit()
handleSubmit: (onSubmit: any) => onSubmit(),
watch: jest.fn() as any
} as reactHookForm.UseFormMethods)

const getWrapper = (additionalButtonProps = {}) => (
<FieldContext.Provider
value={{
initialValues: {},
loading: false,
onSubmit: (_: any) => mockOnSubmit as any
}}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Form/FormSubmitButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ const FormSubmitButton: FC<FormButtonProps> = ({
isDisabled,
...rest
}: FormButtonProps) => {
const { handleSubmit, formState, getValues } = useFormContext()
const { handleSubmit, formState, watch } = useFormContext()
const { loading, onSubmit } = useContext(FieldContext)
const { isDirty } = formState

const isButtonDisabled = () =>
isDisabled ? isDisabled(formState, getValues()) : !isDirty
isDisabled ? isDisabled(formState, watch()) : !isDirty

useShortcut({
additionalConditionalFn: () => !isButtonDisabled(),
Expand Down
23 changes: 0 additions & 23 deletions src/components/Form/FormToggle/FormToggle.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ beforeEach(() => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: { foo: true },
loading: true,
onSubmit: mockOnSubmit
}}
Expand All @@ -42,26 +41,6 @@ describe('FormToggle', () => {
expect(wrapper).toHaveLength(1)
})

it('correctly passes a default value from initial values if it exists', () => {
expect(wrapper.find(Controller).props().defaultValue).toEqual(true)
})

it('correctly passes a default value from initial values if defaultChecked is true', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
>
<FormToggle defaultChecked label='foo' name='foo' />
</FieldContext.Provider>
)

expect(wrapper.find(Controller).props().defaultValue).toEqual(true)
})

it('should render a Toggle component', () => {
const mockOnChange = jest.fn()
const test = {
Expand All @@ -86,7 +65,6 @@ describe('FormToggle', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
Expand Down Expand Up @@ -117,7 +95,6 @@ describe('FormToggle', () => {
wrapper = mount(
<FieldContext.Provider
value={{
initialValues: {},
loading: true,
onSubmit: mockOnSubmit
}}
Expand Down
7 changes: 1 addition & 6 deletions src/components/Form/FormToggle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,10 @@ const FormToggle: FC<FormToggleProps> = ({
...rest
}: FormToggleProps) => {
const { control } = useFormContext()
const { initialValues, loading } = useContext<FieldContextProps>(
FieldContext
)
const { loading } = useContext<FieldContextProps>(FieldContext)

const classes = useStyles({ fullWidth })

const defaultValue = (initialValues[name] as boolean) || defaultChecked

// TODO: add info tips
return (
<div className={classes.container}>
Expand All @@ -64,7 +60,6 @@ const FormToggle: FC<FormToggleProps> = ({
/>
<Controller
control={control}
defaultValue={defaultValue}
name={name}
render={({ onChange, value }) => (
<Toggle
Expand Down
Loading

0 comments on commit 939b19f

Please sign in to comment.