TextFormFieldはSizedBoxで大きさを変えるのをオススメしない

## 本題
`TextFormWidget`はValidationなどができるかなり便利なメソッドですが、
SizedBoxを使用して大きさを変えることはおすすめしない理由と回避策を説明します。

## TextFormFieldの一般的なサンプル
![スクリーンショット 2024-10-24 210820.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844247/64e0f258-29c8-cc0b-096f-45f808850fd7.png)
特に問題ありません。
```dart
class MyCustomForm extends StatefulWidget {
  const MyCustomForm({super.key});

  @override
  MyCustomFormState createState() {
    return MyCustomFormState();
  }
}
class MyCustomFormState extends State<MyCustomForm> {
  final _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          TextFormField(
            validator: (value) {
              if (value == null || value.isEmpty) {
                return '入力してください';
              }
              return null;
            },
          ),
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 16),
            child: ElevatedButton(
              onPressed: () {
                if (_formKey.currentState!.validate()) {}
              },
              child: const Text('送信'),
            ),
          ),
        ],
      ),
    );
  }
}
```
## TextFormFieldをSizeBoxでラップする場合
- SizeBoxを設定するとTextFormField自体を小さくできる
![スクリーンショット 2024-10-24 211358.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844247/37c7ca8e-5bc9-b942-2475-4afb87aec51f.png)

- しかし、送信ボタンを押すと...
![スクリーンショット 2024-10-24 211537.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844247/3f1c3188-b666-63b2-b29b-527287d5fac7.png)

上記のようになるのでその回避法を紹介します

```dart
    return Form(
      key: _formKey,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Row(
            crossAxisAlignment:
                CrossAxisAlignment.start, 
            children: [
              SizedBox(height: 30, child: Icon(Icons.mail)),
              SizedBox(width: 10), 
              Expanded(
                child: SizedBox(
                  height: 30,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email', 
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),
          SizedBox(height: 20), 
          ElevatedButton(
            onPressed: () {
              if (_formKey.currentState!.validate()) {
              }
            },
            child: Text('Submit'),
          ),
        ],
      ),
    );
```

## 回避法
-　変更前
```diff_dart
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
-             SizedBox(height: 30, child: Icon(Icons.mail)),
              SizedBox(width: 10),
              Expanded(
                child: SizedBox(
-                 height: 30,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email',
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
-                      
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),
```

- 変更後
![スクリーンショット 2024-10-24 213218.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/844247/f9098b48-d165-64f7-f9f8-bd322d0b4c0b.png)

- helperTextを追加し、そもそも描画時点でエラーテキストのエリアを確保しておく
- SizedBoxのheightを調節する
```diff_dart
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
+             SizedBox(height: 32, child: Icon(Icons.mail)),
              SizedBox(width: 10),
              Expanded(
                child: SizedBox(
+                 height: 52,
                  child: TextFormField(
                    decoration: InputDecoration(
                      labelText: 'Email',
                      hintText:
                          'メールアドレスを入力',
                      border: OutlineInputBorder(),
+                     helperText: '',
                    ),
                    validator: (value) {
                      if (value == null || value.isEmpty) {
                        return '入力してください';
                      }
                      return null;
                    },
                  ),
                ),
              ),
            ],
          ),
```
## ちょっと解説
SizeBoxで大きさを変えるとerrorTextを含んだ高さがSizeBoxへ収まるようになってしまい、レイアウトが崩れるようです。

## 参考
https://github.com/flutter/flutter/issues/15400#issuecomment-475773473