ChakraUIとConformでフォームを作る2

話としてはこれの続きです
https://qiita.com/stopod/items/42ac91a67037e849e97f

# 目標
- もっと簡単にFormを作成したい

# 実際のソースコード
https://github.com/stopod/rr-chakra-conform-sample/blob/main/app/routes/home.tsx

画面は以前の記事から変わっていません
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3468047/a48abfb1-1385-d990-7c55-babdab76e01a.png)

# やったこと
https://github.com/stopod/rr-chakra-conform-sample/pull/1/files#diff-3ec068130cef9045a02c77acbeaddae8a4b87abf91c5feb30f4f7b7223e95374

だいたいはこのPRに込められてます

課題点はここです
```home.tsx
<ConfromField
 label="性"
 required
 id={fields.lastName.id}
 errorId={fields.lastName.errorId}
 errorText={fields.lastName.errors}
 invalid={!!fields.lastName.errors?.length}
>
    <Input
     placeholder="性"
     variant="outline"
     {...getInputProps(fields.lastName, { type: "text" })}
    />
</ConfromField>
```

これをこうしました
```home.tsx
<FormFieldText
 label="姓"
 inputProps={{
     ...getInputTypeTextProps(fields.lastName),
 }}
/>
```

Conformに用意されているヘルパーからだとerrorId, errorText等が取得できず、個別で受け取る必要がありました
また、FieldComponentとInputComponentでそれぞれ必要なものがあるのでまとめて、ヘルパーからまとめて渡すことができませんでした

なので以下のようにしました
- FiledとInputをまとめたform-filed-textというcomponentを作成
- ヘルパー関数をラップしたものを作成

それがこれです
```form-field-text/index.tsx
import { Input, InputProps } from "@chakra-ui/react";
import { ConfromField, ConfromFieldProps } from "../ui/field";
import { FieldMetadata, getInputProps } from "@conform-to/react";
import { ReactNode } from "react";

type FormFiledTextProps = ConfromFieldProps & {
  inputProps?: InputProps & {
    errorId?: string;
    errorText?: ReactNode;
    invalid?: boolean;
  };
};

export const FormFieldText = (props: FormFiledTextProps) => {
  const { inputProps, ...rest } = props;
  const { id, errorId, errorText, invalid, required, ...inputPropsRest } =
    inputProps || {};

  return (
    <ConfromField
      id={id}
      errorId={errorId}
      errorText={errorText}
      invalid={invalid}
      required={required}
      {...rest}
    >
      <Input id={id} {...inputPropsRest} />
    </ConfromField>
  );
};

export const getInputTypeTextProps = (metadata: FieldMetadata) => {
  const errorId = metadata.errorId;
  const errorText = metadata.errors;
  const invalid = !metadata.valid;
  return {
    errorId,
    errorText,
    invalid,
    ...getInputProps(metadata, { type: "text" }),
  };
};

export const getInputTypeDateProps = (metadata: FieldMetadata) => {
  const errorId = metadata.errorId;
  const errorText = metadata.errors;
  const invalid = !metadata.valid;
  return {
    errorId,
    errorText,
    invalid,
    ...getInputProps(metadata, { type: "date" }),
  };
};

```

ヘルパー関数としてこれが適切なカスタマイズ方法かがわかりませんが、getInputTypeTextPropsを作成してerrorId, errorText, invalidを付与するようにしました
これをComponent側で分解してFiledとInputにそれぞれ適切に渡します
そうすることで呼び出し側では（基本的には）ヘルパー関数だけで入力フォームが完成します

似たような感じでselect componentも分離してヘルパー関数をラップした関数を作りました
https://github.com/stopod/rr-chakra-conform-sample/commit/e34dcee19c1f0239b85dd0b63bd56764f2d85305#diff-a573f4e9daaa115b6c047848fa5a19015971f432b7f88446c12c60e42300b5f2

# 終わりに
ついでにReactRouter v7がリリースされたのでv7.0.1にしました
ヘルパー関数の扱いがわからないのと（ググるとこんな適当にカスタマイズしてるのではなくて、ちゃんとなんかもにょもにょしている人がいた）、FieldとInputをまとめたcomponentにおけるpropsのいい感じの扱いがわからない