Skip to content

Commit

Permalink
feat #76 - Refactor Form.Button to be Form.SubmitButton
Browse files Browse the repository at this point in the history
Closes #76
  • Loading branch information
github-actions committed Sep 8, 2020
1 parent 2e5d713 commit 2f474d7
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 83 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.2.6",
"version": "0.2.7",
"publishConfig": {
"registry": "https://npm.pkg.github.com/dassana-io"
},
Expand Down
12 changes: 6 additions & 6 deletions src/__snapshots__/storybook.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,16 @@ exports[`Storyshots Form Default 1`] = `
onSubmit={[Function]}
>
<div
className="container-0-2-4"
className="container-0-2-1"
>
<div>
<div
className="container-0-2-5 required-0-2-6"
className="container-0-2-2 required-0-2-3"
>
First Name
</div>
<div
className="container-0-2-7 container-d0-0-2-10"
className="container-0-2-4 container-d0-0-2-7"
>
<input
className="ant-input"
Expand All @@ -174,12 +174,12 @@ exports[`Storyshots Form Default 1`] = `
</div>
<div>
<div
className="container-0-2-5"
className="container-0-2-2"
>
Last Name
</div>
<div
className="container-0-2-7 container-d1-0-2-11"
className="container-0-2-4 container-d1-0-2-8"
>
<input
className="ant-input"
Expand All @@ -196,7 +196,7 @@ exports[`Storyshots Form Default 1`] = `
</div>
<button
className="ant-btn ant-btn-default"
disabled={false}
disabled={true}
onClick={[Function]}
type="button"
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/Form/Form.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const Template: Story<FormProps<UserModel>> = (args: FormProps<UserModel>) => (
<Form {...args} initialValues={{ firstName: 'First Name' }}>
<Form.Input label='First Name' name='firstName' required />
<Form.Input label='Last Name' name='lastName' />
<Form.Button />
<Form.SubmitButton>Submit</Form.SubmitButton>
</Form>
)

Expand Down
16 changes: 11 additions & 5 deletions src/components/Form/Form.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import FieldContext from './FieldContext'
import FormButton from './FormButton'
import FormSubmitButton from './FormSubmitButton'
import React from 'react'
import Form, { FormProps } from './index'
import { mount, shallow, ShallowWrapper } from 'enzyme'
Expand All @@ -9,6 +9,12 @@ jest.mock('react-hook-form', () => ({
useForm: () => ({
handleSubmit: jest.fn(),
reset: mockReset
}),
useFormContext: () => ({
formState: {
isDirty: true
},
handleSubmit: jest.fn()
})
}))

Expand All @@ -25,7 +31,7 @@ const mockReset = jest.fn()
beforeEach(() => {
wrapper = shallow(
<Form initialValues={mockInitialValues} onSubmit={mockOnSubmit}>
<FormButton />
<FormSubmitButton>Submit</FormSubmitButton>
</Form>
)
})
Expand All @@ -36,7 +42,7 @@ describe('Form', () => {
})

it('renders children properly', () => {
expect(wrapper.find(FormButton)).toHaveLength(1)
expect(wrapper.find(FormSubmitButton)).toHaveLength(1)
})

it('passes the correct props to FieldContext provider', () => {
Expand All @@ -52,7 +58,7 @@ describe('Form', () => {
it('correctly defaults initial values to empty object if none is passed in', () => {
wrapper = shallow(
<Form onSubmit={mockOnSubmit}>
<FormButton />
<FormSubmitButton>Submit</FormSubmitButton>
</Form>
)

Expand All @@ -64,7 +70,7 @@ describe('Form', () => {
it('correctly updates initial values', () => {
const form = mount(
<Form onSubmit={mockOnSubmit}>
<FormButton />
<FormSubmitButton>Submit</FormSubmitButton>
</Form>
)

Expand Down
46 changes: 0 additions & 46 deletions src/components/Form/FormButton/FormButton.test.tsx

This file was deleted.

22 changes: 0 additions & 22 deletions src/components/Form/FormButton/index.tsx

This file was deleted.

70 changes: 70 additions & 0 deletions src/components/Form/FormSubmitButton/FormSubmitButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import * as reactHookForm from 'react-hook-form'
import Button from '../../Button'
import FieldContext from '../FieldContext'
import React from 'react'
import FormSubmitButton, { FormButtonProps } from './index'
import { mount, ReactWrapper } from 'enzyme'

let wrapper: ReactWrapper<FormButtonProps>

const mockOnSubmit = jest.fn()

const getMockFormContext = (isDirty = true) =>
({
formState: {
isDirty
},
handleSubmit: (onSubmit: any) => onSubmit()
} as reactHookForm.UseFormMethods)

const getWrapper = () => (
<FieldContext.Provider
value={{ initialValues: {}, loading: true, onSubmit: mockOnSubmit }}
>
<FormSubmitButton>Submit</FormSubmitButton>
</FieldContext.Provider>
)

beforeEach(() => {
jest.spyOn(reactHookForm, 'useFormContext').mockImplementation(() =>
getMockFormContext()
)

wrapper = mount(getWrapper())
})

afterEach(() => {
jest.resetAllMocks()
})

describe('FormButton', () => {
it('renders', () => {
expect(wrapper).toHaveLength(1)
})

it('calls onSubmit when clicked', () => {
wrapper.simulate('click')

expect(mockOnSubmit).toHaveBeenCalledTimes(1)
})

it('correctly passes loading from field context', () => {
expect(wrapper.find(Button).props().loading).toBe(true)
})

it('enables the submit button if form is dirty', () => {
expect(wrapper.find(Button).props().disabled).toBe(false)
})

it('disables the submit button if form is pristine', () => {
jest.clearAllMocks()

jest.spyOn(reactHookForm, 'useFormContext').mockImplementation(() =>
getMockFormContext(false)
)

wrapper = mount(getWrapper())

expect(wrapper.find(Button).props().disabled).toBe(true)
})
})
23 changes: 23 additions & 0 deletions src/components/Form/FormSubmitButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import FieldContext from '../FieldContext'
import { useFormContext } from 'react-hook-form'
import Button, { ButtonProps } from '../../Button'
import React, { FC, useContext } from 'react'

export type FormButtonProps = Omit<ButtonProps, 'loading' | 'onClick'>

const FormSubmitButton: FC<FormButtonProps> = (props: FormButtonProps) => {
const { handleSubmit, formState } = useFormContext()
const { loading, onSubmit } = useContext(FieldContext)
const { isDirty } = formState

return (
<Button
disabled={!isDirty}
loading={loading}
onClick={handleSubmit(onSubmit)}
{...props}
/>
)
}

export default FormSubmitButton
4 changes: 2 additions & 2 deletions src/components/Form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createUseStyles } from 'react-jss'
import FieldContext from './FieldContext'
import { FieldValues } from 'react-hook-form/dist/types/form'
import FormButton from './FormButton'
import FormInput from './FormInput'
import FormSubmitButton from './FormSubmitButton'
import { FormProvider, SubmitHandler, useForm } from 'react-hook-form'
import React, { ReactNode, useEffect } from 'react'

Expand Down Expand Up @@ -49,7 +49,7 @@ function Form<Model>({
)
}

Form.Button = FormButton
Form.SubmitButton = FormSubmitButton
Form.Input = FormInput

export default Form

0 comments on commit 2f474d7

Please sign in to comment.