Skip to content

Commit

Permalink
fix: make children body input components controlled from the start
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin9foong committed Nov 8, 2024
1 parent 49e88ce commit 4eea259
Showing 1 changed file with 54 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useMemo, useRef } from 'react'
import {
Controller,
FieldArrayWithId,
FieldError,
useFieldArray,
Expand Down Expand Up @@ -214,7 +215,7 @@ const ChildrenBody = ({
formContext,
error,
}: ChildrenBodyProps): JSX.Element => {
const { register, getValues, setValue, watch } = formContext
const { register, getValues, setValue, watch, control } = formContext

const childNamePath = useMemo(
() => `${schema._id}.child.${currChildBodyIdx}.0`,
Expand All @@ -226,13 +227,6 @@ const ChildrenBody = ({
[schema, disableRequiredValidation],
)

const {
ref: childNameRegisterRef,
onChange: selectOnChange,
onBlur: selectOnBlur,
...selectRest
} = register(childNamePath, validationRules)

const childNameRef = useRef<HTMLInputElement | null>(null)

const childNameError = error
Expand Down Expand Up @@ -329,27 +323,30 @@ const ChildrenBody = ({
<Flex align="stretch" alignItems="stretch" justify="space-between">
<Box flexGrow={10}>
<FormControl key={field.id} isRequired isInvalid={!!childNameError}>
<SingleSelect
isRequired
{...selectRest}
placeholder={"Select your child's name"}
colorScheme={`theme-${colorTheme}`}
items={childNameValues}
value={childName}
isDisabled={isSubmitting}
onChange={(name) => {
// This is bad practice but we have no choice because our
// custom Select doesn't forward the event.
// FIXME: Fix types
// @ts-expect-error type inference issue
setValue(childNamePath, name, { shouldValidate: true })
}}
ref={(e) => {
childNameRegisterRef(e)
if (e) {
childNameRef.current = e
}
}}
<Controller
control={control}
name={childNamePath}
rules={validationRules}
render={({
field: { value, onChange, onBlur, ref, ...rest },
}) => (
<SingleSelect
isRequired
{...rest}
placeholder={"Select your child's name"}
colorScheme={`theme-${colorTheme}`}
items={childNameValues}
value={value as unknown as string}
isDisabled={isSubmitting}
onChange={onChange}
ref={(e) => {
ref(e)
if (e) {
childNameRef.current = e
}
}}
/>
)}
/>
<FormErrorMessage>{childNameError?.message}</FormErrorMessage>
</FormControl>
Expand Down Expand Up @@ -422,7 +419,6 @@ const ChildrenBody = ({
case MyInfoChildAttributes.ChildGender:
case MyInfoChildAttributes.ChildRace:
case MyInfoChildAttributes.ChildSecondaryRace: {
const { onBlur, ...rest } = register(fieldPath, validationRules)
return (
<FormControl
key={key}
Expand All @@ -433,26 +429,22 @@ const ChildrenBody = ({
<FormLabel useMarkdownForDescription gridArea="formlabel">
{MYINFO_ATTRIBUTE_MAP[subField].description}
</FormLabel>
<SingleSelect
{...rest}
value={value}
items={
MYINFO_ATTRIBUTE_MAP[subField].fieldOptions as string[]
}
onChange={(option) => {
// prevent updates if there's no change to the values
// there's an infinite loop on the update
// upgrading to v8.xx, or v9.xx doesn't seem to have resolved the issue
// https://github.com/downshift-js/downshift/issues/1511#issuecomment-1598307130

setTimeout(() =>
// This is bad practice but we have no choice because our
// custom Select doesn't forward the event.
// FIXME: Fix types
// @ts-expect-error type inference issue
setValue(fieldPath, option, { shouldValidate: true }),
)
}}
<Controller
control={control}
name={fieldPath}
render={({
field: { value, onChange, onBlur, ...rest },
}) => (
<SingleSelect
{...rest}
value={value as unknown as string}
items={
MYINFO_ATTRIBUTE_MAP[subField]
.fieldOptions as string[]
}
onChange={onChange}
/>
)}
/>
<FormErrorMessage>
{childrenSubFieldError?.message}
Expand All @@ -461,7 +453,6 @@ const ChildrenBody = ({
)
}
case MyInfoChildAttributes.ChildDateOfBirth: {
const { onChange, ...rest } = register(fieldPath, validationRules)
return (
<FormControl
key={key}
Expand All @@ -472,16 +463,18 @@ const ChildrenBody = ({
<FormLabel useMarkdownForDescription gridArea="formlabel">
{MYINFO_ATTRIBUTE_MAP[subField].description}
</FormLabel>
<DatePicker
{...rest}
displayFormat={DATE_DISPLAY_FORMAT}
inputValue={value}
onInputValueChange={(date) => {
// FIXME: Fix types
// @ts-expect-error type inference issue
setValue(fieldPath, date, { shouldValidate: true })
}}
colorScheme={`theme-${colorTheme}`}
<Controller
control={control}
name={fieldPath}
render={({ field: { value, onChange, ...rest } }) => (
<DatePicker
{...rest}
displayFormat={DATE_DISPLAY_FORMAT}
inputValue={value as unknown as string}
onInputValueChange={onChange}
colorScheme={`theme-${colorTheme}`}
/>
)}
/>
<FormErrorMessage>
{childrenSubFieldError?.message}
Expand Down

0 comments on commit 4eea259

Please sign in to comment.