Skip to content

Instantly share code, notes, and snippets.

@smashercosmo
Created July 10, 2020 14:52
Show Gist options
  • Save smashercosmo/023478075b5e0988fb96d4dc10a34990 to your computer and use it in GitHub Desktop.
Save smashercosmo/023478075b5e0988fb96d4dc10a34990 to your computer and use it in GitHub Desktop.
import React from 'react'
import { useForm } from 'react-hook-form'
import { FormButtons } from '../../components/FormButtons/FormButtons'
import { TextFieldComponent } from '../../components/TextFieldComponent/TextFieldComponent'
import { Box } from '../../components/Box/Box'
import { getErrorsToShow } from '../../lib/formErrorsUtils'
type CreateOrganizationFormValues = {
name: string
}
type CreateOrganizationFormProps = {
onSubmit: (values: CreateOrganizationFormValues) => Promise<void>
}
function CreateOrganizationForm(props: CreateOrganizationFormProps) {
const { onSubmit } = props
const { register, reset, handleSubmit, errors, formState } = useForm<
CreateOrganizationFormValues
>({ mode: 'onChange' })
const { touched, dirtyFields, isSubmitted, isSubmitting, isValid } = formState
const errorsToShow = getErrorsToShow({
touched,
dirtyFields,
errors,
isSubmitted,
fields: ['name'],
})
return (
<form onSubmit={handleSubmit(onSubmit)} noValidate>
<TextFieldComponent
id="createOrganizationFormName"
name="name"
label="Name"
type="text"
error={errorsToShow.name}
required
inputRef={register({ required: true })}
/>
<Box pt={25}>
<FormButtons
submitButtonText="Create"
submitting={isSubmitting}
invalid={!isValid}
reset={reset}
/>
</Box>
</form>
)
}
export type { CreateOrganizationFormValues }
export { CreateOrganizationForm }
function getErrorToShow({
touched,
dirty,
error,
isSubmitted,
initial,
field,
}: {
touched?: boolean
dirty?: boolean
error?: { type: string; message?: string }
isSubmitted: boolean
initial: boolean
field: string
}): string | undefined {
if ((error && initial) || (error && touched && (dirty || isSubmitted))) {
return getFormErrorMessage(field, error)
}
return undefined
}
function getErrorsToShow<T extends Record<string, unknown>>({
touched,
dirtyFields,
errors,
isSubmitted,
defaultValues,
fields,
}: {
touched: { [K in keyof T]?: true }
dirtyFields: { [K in keyof T]?: true }
errors: { [K in keyof T]?: { type: string; message?: string } | undefined }
isSubmitted: boolean
defaultValues?: Record<keyof T, unknown>
fields: ReadonlyArray<keyof T>
}) {
const errorsToShow = {} as Record<keyof T, string | undefined>
for (let i = 0, l = fields.length; i < l; i += 1) {
const field = fields[i] as string
errorsToShow[fields[i]] = getErrorToShow({
touched: touched[field],
dirty: dirtyFields[field],
initial: Boolean(defaultValues && defaultValues[field]),
error: errors[field],
isSubmitted,
field,
})
}
return errorsToShow
}
export { getErrorsToShow }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment