TextFieldを小さくしたいだけなのに

# 困ったこと
「TextFieldの高さを小さくしたい・・・」

TextFieldの高さを小さくしたい場合、デフォルトの設定では難しいことがあります。
本記事では、その解決方法について説明します。

# TextFieldの高さ
まず、以下のようにTextFieldを作成してみます。

```kotlin
var text by remember { mutableStateOf("") }
 
TextField(
    value = text,
    onValueChange = { text = it },
    placeholder = { Text(text = "入力してください", color = Color.Gray) },
    modifier = Modifier.fillMaxWidth()
)
```

![qiita.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/5c77214f-8b14-0753-8fb9-3dea3e677542.jpeg)

特に`padding`などを指定していないにもかかわらず、内部には適度な隙間が生じます。これは、TextFieldにデフォルトで16.dpの`padding`が設定されているためです。

では、デフォルトのTextFieldよりも高さが小さいTextFieldを実現するにはどうすれば良いのでしょうか？(^_^;)

## 🙅‍♀️TextFieldにheightを指定する
以下のように`height`を直接指定してみます。
```kotlin
TextField(
    value = text,
    onValueChange = { text = it },
    placeholder = { Text(text = "入力してください", color = Color.Gray) },
    modifier = Modifier.fillMaxWidth()
                       .height(45.dp)  // heightを追加
)
```

![qiita.002.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/9c587122-c222-8c07-7c11-e9a769d147e2.jpeg)


フォーム内部の要素が潰れてしまいました。そんな・・・
ちなみに親要素に`height`を指定しても同じことが起きます。

## Paddingの指定を外側から書き換えにいく
問題の原因となる`padding`を特定し、これを調整する方法を考えます。

### TextFieldの内部
TextFieldの内部では、`BasicTextField`が呼び出され、さらにその`decorationBox`に `TextFieldDefaults.TextFieldDecorationBox`が利用されています。

```kotlin
@Composable
fun TextField(
    value: String,
    onValueChange: (String) -> Unit,
    // 
    //（省略）
    //
    )

    @OptIn(ExperimentalMaterialApi::class)
    BasicTextField(
        value = value,
        //
        //（省略）
        //
        decorationBox = @Composable { innerTextField ->
            // places leading icon, text field with label and placeholder, trailing icon
            TextFieldDefaults.TextFieldDecorationBox(
                value = value,
                //
                //（省略）
                //                    
            )
        }
    )
}
```

### TextFieldDefaults.TextFieldDecorationBoxの内部
`TextFieldDefaults.TextFieldDecorationBox`では、以下のように`contentPadding`が設定されています。
```kotlin
@Composable
    @ExperimentalMaterialApi
    fun TextFieldDecorationBox(
        //
        //（省略）
        //

        // ↓↓↓ 注目‼️ ↓↓↓
        contentPadding: PaddingValues =
            if (label == null) {
                textFieldWithoutLabelPadding()
            } else {
                textFieldWithLabelPadding()
            }
        ) {
        CommonDecorationBox(
            //
            //（省略）
            //
            contentPadding = contentPadding
        )
    }
```
ここで16.dpが指定されていました。この`contentPadding`を外部から変更可能な形でカスタマイズします。

### CustomTextField（自前実装）
以下にカスタマイズ可能な`CustomTextField`を実装します。
```kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun CustomTextField(
    value: String,
    onValueChange: (String) -> Unit,
    placeholder: @Composable (() -> Unit)? = null,
    modifier: Modifier,
) {
    BasicTextField(
        modifier = modifier,
        value = value,
        onValueChange = onValueChange,
        decorationBox = @Composable { innerTextField ->
            androidx.compose.material3.TextFieldDefaults.DecorationBox(
                value = value,
                visualTransformation = VisualTransformation.None,
                innerTextField = innerTextField,
                placeholder = placeholder,
                enabled = true,
                singleLine = true,
                interactionSource = remember { MutableInteractionSource() },
                // ↓↓↓ ここで上書きする‼️ ↓↓↓
                contentPadding = PaddingValues(0.dp),
            )
        }
    )
}
```

使用例：
```kotlin
CustomTextField(
    value = text,
    onValueChange = { text = it },
    placeholder = { Text(text = "入力してください", color = Color.Gray) },
    modifier = Modifier.fillMaxWidth()
)
```

![qiita.003.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1578726/9397142a-5953-c6f6-5545-191dfcd6b298.jpeg)


これで、TextFieldの高さを小さくすることができました！



# おわりに
以上のように、`contentPadding`部分を上書きすることで、TextFieldの高さを小さくすることが可能です。ただしデフォルトの設定を上書きする方法にはリスクもあります。
将来、アップデートで挙動が変わる可能性もあるため注意が必要です。

より良い実装方法をご存じの方がいれば、ぜひ教えてください。

# 参考

https://stackoverflow.com/questions/67681416/jetpack-compose-decrease-height-of-textfield

https://tech.gunosy.io/entry/android_compose_text_field

https://qiita.com/mikiFlag/items/4aba63267684dd9d748e

https://qiita.com/kilalabu/items/b193a41b69b5747d1a0f