[questions][ui] extract useFormRegister hook

pull/346/head
Jeff Sieu 3 years ago committed by wlren
parent baf31d35cb
commit 1f2a07e8fd

@ -1,7 +1,4 @@
import type { ComponentProps, ForwardedRef } from 'react';
import { useState } from 'react'; import { useState } from 'react';
import { forwardRef } from 'react';
import type { UseFormRegisterReturn } from 'react-hook-form';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { import {
BuildingOffice2Icon, BuildingOffice2Icon,
@ -10,6 +7,8 @@ import {
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import { Button, TextInput } from '@tih/ui'; import { Button, TextInput } from '@tih/ui';
import { useFormRegister } from '~/utils/questions/useFormRegister';
import ContributeQuestionDialog from './ContributeQuestionDialog'; import ContributeQuestionDialog from './ContributeQuestionDialog';
export type ContributeQuestionData = { export type ContributeQuestionData = {
@ -19,27 +18,6 @@ export type ContributeQuestionData = {
questionType: string; questionType: string;
}; };
type TextInputProps = ComponentProps<typeof TextInput>;
type FormTextInputProps = Omit<TextInputProps, 'onChange'> &
Pick<UseFormRegisterReturn<never>, 'onChange'>;
function FormTextInputWithRef(
props: FormTextInputProps,
ref?: ForwardedRef<HTMLInputElement>,
) {
const { onChange, ...rest } = props;
return (
<TextInput
{...(rest as TextInputProps)}
ref={ref}
onChange={(_, event) => onChange(event)}
/>
);
}
const FormTextInput = forwardRef(FormTextInputWithRef);
export type ContributeQuestionCardProps = { export type ContributeQuestionCardProps = {
onSubmit: (data: ContributeQuestionData) => void; onSubmit: (data: ContributeQuestionData) => void;
}; };
@ -47,7 +25,9 @@ export type ContributeQuestionCardProps = {
export default function ContributeQuestionCard({ export default function ContributeQuestionCard({
onSubmit, onSubmit,
}: ContributeQuestionCardProps) { }: ContributeQuestionCardProps) {
const { register, handleSubmit } = useForm<ContributeQuestionData>(); const { register: formRegister, handleSubmit } =
useForm<ContributeQuestionData>();
const register = useFormRegister(formRegister);
const [showDraftDialog, setShowDraftDialog] = useState(false); const [showDraftDialog, setShowDraftDialog] = useState(false);
const handleDraftDialogCancel = () => { const handleDraftDialogCancel = () => {
@ -59,7 +39,7 @@ export default function ContributeQuestionCard({
<form <form
className="flex flex-col items-stretch justify-center gap-2 rounded-md border border-slate-300 p-4" className="flex flex-col items-stretch justify-center gap-2 rounded-md border border-slate-300 p-4"
onSubmit={handleSubmit(onSubmit)}> onSubmit={handleSubmit(onSubmit)}>
<FormTextInput <TextInput
isLabelHidden={true} isLabelHidden={true}
label="Question" label="Question"
placeholder="Contribute a question" placeholder="Contribute a question"
@ -67,7 +47,7 @@ export default function ContributeQuestionCard({
/> />
<div className="flex items-end justify-center gap-x-2"> <div className="flex items-end justify-center gap-x-2">
<div className="min-w-[150px] flex-1"> <div className="min-w-[150px] flex-1">
<FormTextInput <TextInput
label="Company" label="Company"
startAddOn={BuildingOffice2Icon} startAddOn={BuildingOffice2Icon}
startAddOnType="icon" startAddOnType="icon"
@ -75,7 +55,7 @@ export default function ContributeQuestionCard({
/> />
</div> </div>
<div className="min-w-[150px] flex-1"> <div className="min-w-[150px] flex-1">
<FormTextInput <TextInput
label="Question type" label="Question type"
startAddOn={QuestionMarkCircleIcon} startAddOn={QuestionMarkCircleIcon}
startAddOnType="icon" startAddOnType="icon"
@ -83,7 +63,7 @@ export default function ContributeQuestionCard({
/> />
</div> </div>
<div className="min-w-[150px] flex-1"> <div className="min-w-[150px] flex-1">
<FormTextInput <TextInput
label="Date" label="Date"
startAddOn={CalendarDaysIcon} startAddOn={CalendarDaysIcon}
startAddOnType="icon" startAddOnType="icon"

@ -1,5 +1,4 @@
import type { ChangeEvent } from 'react'; import { useState } from 'react';
import { useCallback, useState } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { import {
BuildingOffice2Icon, BuildingOffice2Icon,
@ -15,6 +14,8 @@ import {
TextInput, TextInput,
} from '@tih/ui'; } from '@tih/ui';
import { useFormRegister } from '~/utils/questions/useFormRegister';
import SimilarQuestionCard from './card/SimilarQuestionCard'; import SimilarQuestionCard from './card/SimilarQuestionCard';
import Checkbox from './ui-patch/Checkbox'; import Checkbox from './ui-patch/Checkbox';
@ -38,23 +39,12 @@ export default function ContributeQuestionForm({
}: ContributeQuestionFormProps) { }: ContributeQuestionFormProps) {
const { register: formRegister, handleSubmit } = const { register: formRegister, handleSubmit } =
useForm<ContributeQuestionData>(); useForm<ContributeQuestionData>();
const register = useFormRegister(formRegister);
const [canSubmit, setCanSubmit] = useState<boolean>(false); const [canSubmit, setCanSubmit] = useState<boolean>(false);
const handleCheckSimilarQuestions = (checked: boolean) => { const handleCheckSimilarQuestions = (checked: boolean) => {
setCanSubmit(checked); setCanSubmit(checked);
}; };
const register = useCallback(
(...args: Parameters<typeof formRegister>) => {
const { onChange, ...rest } = formRegister(...args);
return {
...rest,
onChange: (value: string, event: ChangeEvent<unknown>) => {
onChange(event);
},
};
},
[formRegister],
);
return ( return (
<form <form
className="flex flex-col items-stretch justify-center gap-2 pb-[100px]" className="flex flex-col items-stretch justify-center gap-2 pb-[100px]"

@ -0,0 +1,21 @@
import type { ChangeEvent } from 'react';
import { useCallback } from 'react';
import type { FieldValues, UseFormRegister } from 'react-hook-form';
export const useFormRegister = <TFieldValues extends FieldValues>(
register: UseFormRegister<TFieldValues>,
) => {
const formRegister = useCallback(
(...args: Parameters<typeof register>) => {
const { onChange, ...rest } = register(...args);
return {
...rest,
onChange: (value: string, event: ChangeEvent<unknown>) => {
onChange(event);
},
};
},
[register],
);
return formRegister;
};
Loading…
Cancel
Save