---
title: "BasicTextField"
description: "Basic text composable that provides an interactive box that accepts text input through software
or hardware keyboard, but provides no decorations like hint or placeholder.

All the editing state of this composable is hoisted through [state]. Whenever the contents of
this composable change via user input or semantics, [TextFieldState.text] gets updated.
Similarly, all the programmatic updates made to [state] also reflect on this composable.

If you want to add decorations to your text field, such as icon or similar, and increase the hit
target area, use the decorator.

In order to filter (e.g. only allow digits, limit the number of characters), or change (e.g.
convert every character to uppercase) the input received from the user, use an
[InputTransformation].

Limiting the height of the [BasicTextField] in terms of line count and choosing a scroll
direction can be achieved by using [TextFieldLineLimits].

Scroll state of the composable is also hoisted to enable observation and manipulation of the
scroll behavior by the developer, e.g. bringing a searched keyword into view by scrolling to its
position without focusing, or changing selection.

It's also possible to internally wrap around an existing TextFieldState and expose a more
lightweight state hoisting mechanism through a value that dictates the content of the TextField
and an onValueChange callback that communicates the changes to this value."
type: "composable"
---

<div class='type'>Composable Function</div>


<a id='references'></a>

<div class='sourceset sourceset-common'>Common</div>


```kotlin
@Composable
fun BasicTextField(
    state: TextFieldState,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    inputTransformation: InputTransformation? = null,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    onKeyboardAction: KeyboardActionHandler? = null,
    lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default,
    onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,
    interactionSource: MutableInteractionSource? = null,
    cursorBrush: Brush = BasicTextFieldDefaults.CursorBrush,
    outputTransformation: OutputTransformation? = null,
    decorator: TextFieldDecorator? = null,
    scrollState: ScrollState = rememberScrollState(),
)
```


Basic text composable that provides an interactive box that accepts text input through software
or hardware keyboard, but provides no decorations like hint or placeholder.

All the editing state of this composable is hoisted through `state`. Whenever the contents of
this composable change via user input or semantics, `TextFieldState.text` gets updated.
Similarly, all the programmatic updates made to `state` also reflect on this composable.

If you want to add decorations to your text field, such as icon or similar, and increase the hit
target area, use the decorator.

In order to filter (e.g. only allow digits, limit the number of characters), or change (e.g.
convert every character to uppercase) the input received from the user, use an
`InputTransformation`.

Limiting the height of the `BasicTextField` in terms of line count and choosing a scroll
direction can be achieved by using `TextFieldLineLimits`.

Scroll state of the composable is also hoisted to enable observation and manipulation of the
scroll behavior by the developer, e.g. bringing a searched keyword into view by scrolling to its
position without focusing, or changing selection.

It's also possible to internally wrap around an existing TextFieldState and expose a more
lightweight state hoisting mechanism through a value that dictates the content of the TextField
and an onValueChange callback that communicates the changes to this value.

#### Parameters

| | |
| --- | --- |
| state | `TextFieldState` object that holds the internal editing state of `BasicTextField`. |
| modifier | optional `Modifier` for this text field. |
| enabled | controls the enabled state of the `BasicTextField`. When `false`, the text field will be neither editable nor focusable, the input of the text field will not be selectable. |
| readOnly | controls the editable state of the `BasicTextField`. When `true`, the text field can not be modified, however, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that user can not edit. |
| inputTransformation | Optional `InputTransformation` that will be used to transform changes to the `TextFieldState` made by the user. The transformation will be applied to changes made by hardware and software keyboard events, pasting or dropping text, accessibility services, and tests. The transformation will _not_ be applied when changing the `state` programmatically, or when the transformation is changed. If the transformation is changed on an existing text field, it will be applied to the next user edit. the transformation will not immediately affect the current `state`. |
| textStyle | Typographic and graphic style configuration for text content that's displayed in the editor. |
| keyboardOptions | Software keyboard options that contain configurations such as `KeyboardType` and `ImeAction`. |
| onKeyboardAction | Called when the user presses the action button in the input method editor (IME), or by pressing the enter key on a hardware keyboard if the `lineLimits` is configured as `TextFieldLineLimits.SingleLine`. By default this parameter is null, and would execute the default behavior for a received IME Action e.g., `ImeAction.Done` would close the keyboard, `ImeAction.Next` would switch the focus to the next focusable item on the screen. |
| lineLimits | Whether the text field should be `SingleLine`, scroll horizontally, and ignore newlines; or `MultiLine` and grow and scroll vertically. If `SingleLine` is passed, all newline characters ('\n') within the text will be replaced with regular whitespace (' '), ensuring that the contents of the text field are presented in a single line. |
| onTextLayout | Callback that is executed when the text layout becomes queryable. The callback receives a function that returns a `TextLayoutResult` if the layout can be calculated, or null if it cannot. The function reads the layout result from a snapshot state object, and will invalidate its caller when the layout result changes. A `TextLayoutResult` object contains paragraph information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text. For example, to draw a cursor or selection around the text. `Density` scope is the one that was used while creating the given text layout. |
| interactionSource | the `MutableInteractionSource` representing the stream of `Interaction`s for this TextField. You can create and pass in your own remembered `MutableInteractionSource` if you want to observe `Interaction`s and customize the appearance / behavior of this TextField for different `Interaction`s. |
| cursorBrush | `Brush` to paint cursor with. If `SolidColor` with `Color.Unspecified` provided, then no cursor will be drawn. |
| outputTransformation | An `OutputTransformation` that transforms how the contents of the text field are presented. |
| decorator | Allows to add decorations around text field, such as icon, placeholder, helper messages or similar, and automatically increase the hit target area of the text field. |
| scrollState | Scroll state that manages either horizontal or vertical scroll of TextField. If `lineLimits` is `SingleLine`, this text field is treated as single line with horizontal scroll behavior. In other cases the text field becomes vertically scrollable. |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
@Composable
fun BasicTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource? = null,
    cursorBrush: Brush = SolidColor(Color.Black),
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
        @Composable { innerTextField -> innerTextField() },
)
```


Basic composable that enables users to edit text via hardware or software keyboard, but provides
no decorations like hint or placeholder.

Whenever the user edits the text, `onValueChange` is called with the most up to date state
represented by `String` with which developer is expected to update their state.

Unlike `TextFieldValue` overload, this composable does not let the developer control selection,
cursor and text composition information. Please check `TextFieldValue` and corresponding
`BasicTextField` overload for more information.

It is crucial that the value provided to the `onValueChange` is fed back into `BasicTextField` in
order to actually display and continue to edit that text in the field. The value you feed back
into the field may be different than the one provided to the `onValueChange` callback, however
the following caveats apply:
- The new value must be provided to `BasicTextField` immediately (i.e. by the next frame), or the text field may appear to glitch, e.g. the cursor may jump around. For more information about this requirement, see `this article`(https://developer.android.com/jetpack/compose/text/user-input#state-practices).
- The value fed back into the field may be different from the one passed to `onValueChange`, although this may result in the input connection being restarted, which can make the keyboard flicker for the user. This is acceptable when you're using the callback to, for example, filter out certain types of input, but should probably not be done on every update when entering freeform text.

This composable provides basic text editing functionality, however does not include any
decorations such as borders, hints/placeholder. A design system based implementation such as
Material Design Filled text field is typically what is needed to cover most of the needs. This
composable is designed to be used when a custom implementation for different design system is
needed.




For example, if you need to include a placeholder in your TextField, you can write a composable
using the decoration box like this:


If you want to add decorations to your text field, such as icon or similar, and increase the hit
target area, use the decoration box:


In order to create formatted text field, for example for entering a phone number or a social
security number, use a `visualTransformation` parameter. Below is the example of the text field
for entering a credit card number:


Note: This overload does not support `KeyboardOptions.showKeyboardOnFocus`.

#### Parameters

| | |
| --- | --- |
| value | the input `String` text to be shown in the text field |
| onValueChange | the callback that is triggered when the input service updates the text. An updated text comes as a parameter of the callback |
| modifier | optional `Modifier` for this text field. |
| enabled | controls the enabled state of the `BasicTextField`. When `false`, the text field will be neither editable nor focusable, the input of the text field will not be selectable |
| readOnly | controls the editable state of the `BasicTextField`. When `true`, the text field can not be modified, however, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that user can not edit |
| textStyle | Style configuration that applies at character level such as color, font etc. |
| keyboardOptions | software keyboard options that contains configuration such as `KeyboardType` and `ImeAction`. |
| keyboardActions | when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in `KeyboardOptions.imeAction`. |
| singleLine | when set to true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the `ImeAction`. `maxLines` and `minLines` are ignored as both are automatically set to 1. |
| maxLines | the maximum height in terms of maximum number of visible lines. It is required that 1 <= `minLines` <= `maxLines`. This parameter is ignored when `singleLine` is true. |
| minLines | the minimum height in terms of minimum number of visible lines. It is required that 1 <= `minLines` <= `maxLines`. This parameter is ignored when `singleLine` is true. |
| visualTransformation | The visual transformation filter for changing the visual representation of the input. By default no visual transformation is applied. |
| onTextLayout | Callback that is executed when a new text layout is calculated. A `TextLayoutResult` object that callback provides contains paragraph information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text. For example, to draw a cursor or selection around the text. |
| interactionSource | an optional hoisted `MutableInteractionSource` for observing and emitting `Interaction`s for this text field. You can use this to change the text field's appearance or preview the text field in different states. Note that if `null` is provided, interactions will still happen internally. |
| cursorBrush | `Brush` to paint cursor with. If `SolidColor` with `Color.Unspecified` provided, there will be no cursor drawn |
| decorationBox | Composable lambda that allows to add decorations around text field, such as icon, placeholder, helper messages or similar, and automatically increase the hit target area of the text field. To allow you to control the placement of the inner text field relative to your decorations, the text field implementation will pass in a framework-controlled composable parameter "innerTextField" to the decorationBox lambda you provide. You must call innerTextField exactly once. |




<div class='sourceset sourceset-common'>Common</div>


```kotlin
@Composable
fun BasicTextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
    minLines: Int = 1,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource? = null,
    cursorBrush: Brush = SolidColor(Color.Black),
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
        @Composable { innerTextField -> innerTextField() },
)
```


Basic composable that enables users to edit text via hardware or software keyboard, but provides
no decorations like hint or placeholder.

Whenever the user edits the text, `onValueChange` is called with the most up to date state
represented by `TextFieldValue`. `TextFieldValue` contains the text entered by user, as well as
selection, cursor and text composition information. Please check `TextFieldValue` for the
description of its contents.

It is crucial that the value provided to the `onValueChange` is fed back into `BasicTextField` in
order to actually display and continue to edit that text in the field. The value you feed back
into the field may be different than the one provided to the `onValueChange` callback, however
the following caveats apply:
- The new value must be provided to `BasicTextField` immediately (i.e. by the next frame), or the text field may appear to glitch, e.g. the cursor may jump around. For more information about this requirement, see `this article`(https://developer.android.com/jetpack/compose/text/user-input#state-practices).
- The value fed back into the field may be different from the one passed to `onValueChange`, although this may result in the input connection being restarted, which can make the keyboard flicker for the user. This is acceptable when you're using the callback to, for example, filter out certain types of input, but should probably not be done on every update when entering freeform text.

This composable provides basic text editing functionality, however does not include any
decorations such as borders, hints/placeholder. A design system based implementation such as
Material Design Filled text field is typically what is needed to cover most of the needs. This
composable is designed to be used when a custom implementation for different design system is
needed.




For example, if you need to include a placeholder in your TextField, you can write a composable
using the decoration box like this:


If you want to add decorations to your text field, such as icon or similar, and increase the hit
target area, use the decoration box:


Note: This overload does not support `KeyboardOptions.showKeyboardOnFocus`.

#### Parameters

| | |
| --- | --- |
| value | The `androidx.compose.ui.text.input.TextFieldValue` to be shown in the `BasicTextField`. |
| onValueChange | Called when the input service updates the values in `TextFieldValue`. |
| modifier | optional `Modifier` for this text field. |
| enabled | controls the enabled state of the `BasicTextField`. When `false`, the text field will be neither editable nor focusable, the input of the text field will not be selectable |
| readOnly | controls the editable state of the `BasicTextField`. When `true`, the text field can not be modified, however, a user can focus it and copy text from it. Read-only text fields are usually used to display pre-filled forms that user can not edit |
| textStyle | Style configuration that applies at character level such as color, font etc. |
| keyboardOptions | software keyboard options that contains configuration such as `KeyboardType` and `ImeAction`. |
| keyboardActions | when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in `KeyboardOptions.imeAction`. |
| singleLine | when set to true, this text field becomes a single horizontally scrolling text field instead of wrapping onto multiple lines. The keyboard will be informed to not show the return key as the `ImeAction`. `maxLines` and `minLines` are ignored as both are automatically set to 1. |
| maxLines | the maximum height in terms of maximum number of visible lines. It is required that 1 <= `minLines` <= `maxLines`. This parameter is ignored when `singleLine` is true. |
| minLines | the minimum height in terms of minimum number of visible lines. It is required that 1 <= `minLines` <= `maxLines`. This parameter is ignored when `singleLine` is true. |
| visualTransformation | The visual transformation filter for changing the visual representation of the input. By default no visual transformation is applied. |
| onTextLayout | Callback that is executed when a new text layout is calculated. A `TextLayoutResult` object that callback provides contains paragraph information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text. For example, to draw a cursor or selection around the text. |
| interactionSource | an optional hoisted `MutableInteractionSource` for observing and emitting `Interaction`s for this text field. You can use this to change the text field's appearance or preview the text field in different states. Note that if `null` is provided, interactions will still happen internally. |
| cursorBrush | `Brush` to paint cursor with. If `SolidColor` with `Color.Unspecified` provided, there will be no cursor drawn |
| decorationBox | Composable lambda that allows to add decorations around text field, such as icon, placeholder, helper messages or similar, and automatically increase the hit target area of the text field. To allow you to control the placement of the inner text field relative to your decorations, the text field implementation will pass in a framework-controlled composable parameter "innerTextField" to the decorationBox lambda you provide. You must call innerTextField exactly once. |




<div class='sourceset sourceset-common'>Common</div>


> **Deprecated** Maintained for binary compatibility

```kotlin
@Composable
fun BasicTextField(
    value: String,
    onValueChange: (String) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    cursorBrush: Brush = SolidColor(Color.Black),
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
        @Composable { innerTextField -> innerTextField() },
)
```


<div class='sourceset sourceset-common'>Common</div>


> **Deprecated** Maintained for binary compatibility

```kotlin
@Composable
fun BasicTextField(
    value: TextFieldValue,
    onValueChange: (TextFieldValue) -> Unit,
    modifier: Modifier = Modifier,
    enabled: Boolean = true,
    readOnly: Boolean = false,
    textStyle: TextStyle = TextStyle.Default,
    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
    keyboardActions: KeyboardActions = KeyboardActions.Default,
    singleLine: Boolean = false,
    maxLines: Int = Int.MAX_VALUE,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    onTextLayout: (TextLayoutResult) -> Unit = {},
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    cursorBrush: Brush = SolidColor(Color.Black),
    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
        @Composable { innerTextField -> innerTextField() },
)
```



## Code Examples
### BasicTextFieldCustomInputTransformationSample
```kotlin
@Composable
fun BasicTextFieldCustomInputTransformationSample() {
    // Demonstrates how to create a custom and relatively complex InputTransformation.
    val state = remember { TextFieldState() }
    BasicTextField(
        state,
        inputTransformation =
            InputTransformation {
                // A filter that always places newly-input text at the start of the string, after a
                // prompt character, like a shell.
                val promptChar = '>'
                fun CharSequence.countPrefix(char: Char): Int {
                    var i = 0
                    while (i < length && get(i) == char) i++
                    return i
                }
                // Step one: Figure out the insertion point.
                val newPromptChars = asCharSequence().countPrefix(promptChar)
                val insertionPoint = if (newPromptChars == 0) 0 else 1
                // Step two: Ensure text is placed at the insertion point.
                if (changes.changeCount == 1) {
                    val insertedRange = changes.getRange(0)
                    val replacedRange = changes.getOriginalRange(0)
                    if (!replacedRange.collapsed && insertedRange.collapsed) {
                        // Text was deleted, delete forwards from insertion point.
                        delete(insertionPoint, insertionPoint + replacedRange.length)
                    }
                }
                // Else text was replaced or there were multiple changes - don't handle.
                // Step three: Ensure the prompt character is there.
                if (newPromptChars == 0) {
                    insert(0, ">")
                }
                // Step four: Ensure the cursor is ready for the next input.
                placeCursorAfterCharAt(0)
            },
    )
}
```
### BasicTextFieldDecoratorSample
```kotlin
@Composable
fun BasicTextFieldDecoratorSample() {
    // Demonstrates how to use the decorator API on BasicTextField
    val state = rememberTextFieldState("Hello, World!")
    BasicTextField(
        state = state,
        decorator = { innerTextField ->
            // Because the decorator is used, the whole Row gets the same behaviour as the internal
            // input field would have otherwise. For example, there is no need to add a
            // `Modifier.clickable` to the Row anymore to bring the text field into focus when user
            // taps on a larger text field area which includes paddings and the icon areas.
            Row(
                Modifier.background(Color.LightGray, RoundedCornerShape(percent = 30))
                    .padding(16.dp)
            ) {
                Icon(Icons.Default.MailOutline, contentDescription = "Mail Icon")
                Spacer(Modifier.width(16.dp))
                innerTextField()
            }
        },
    )
}
```
### BasicTextFieldSample
```kotlin
@Composable
fun BasicTextFieldSample() {
    var value by
        rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue()) }
    BasicTextField(
        value = value,
        onValueChange = {
            // it is crucial that the update is fed back into BasicTextField in order to
            // see updates on the text
            value = it
        },
    )
}
```
### BasicTextFieldWithStringSample
```kotlin
@Composable
fun BasicTextFieldWithStringSample() {
    var value by rememberSaveable { mutableStateOf("initial value") }
    BasicTextField(
        value = value,
        onValueChange = {
            // it is crucial that the update is fed back into BasicTextField in order to
            // see updates on the text
            value = it
        },
    )
}
```
### BasicTextFieldWithValueOnValueChangeSample
```kotlin
@Composable
fun BasicTextFieldWithValueOnValueChangeSample() {
    var text by remember { mutableStateOf("") }
    // A reference implementation that demonstrates how to create a TextField with the legacy
    // state hoisting design around `BasicTextField(TextFieldState)`
    StringTextField(value = text, onValueChange = { text = it })
}
```
### CreditCardSample
```kotlin
@Composable
fun CreditCardSample() {
    /** The offset translator used for credit card input field */
    val creditCardOffsetTranslator =
        object : OffsetMapping {
            override fun originalToTransformed(offset: Int): Int {
                return when {
                    offset < 4 -> offset
                    offset < 8 -> offset + 1
                    offset < 12 -> offset + 2
                    offset <= 16 -> offset + 3
                    else -> 19
                }
            }
            override fun transformedToOriginal(offset: Int): Int {
                return when {
                    offset <= 4 -> offset
                    offset <= 9 -> offset - 1
                    offset <= 14 -> offset - 2
                    offset <= 19 -> offset - 3
                    else -> 16
                }
            }
        }
    /**
     * Converts up to 16 digits to hyphen connected 4 digits string. For example, "1234567890123456"
     * will be shown as "1234-5678-9012-3456"
     */
    val creditCardTransformation = VisualTransformation { text ->
        val trimmedText = if (text.text.length > 16) text.text.substring(0..15) else text.text
        var transformedText = ""
        trimmedText.forEachIndexed { index, char ->
            transformedText += char
            if ((index + 1) % 4 == 0 && index != 15) transformedText += "-"
        }
        TransformedText(AnnotatedString(transformedText), creditCardOffsetTranslator)
    }
    var text by rememberSaveable { mutableStateOf("") }
    BasicTextField(
        value = text,
        onValueChange = { input ->
            if (input.length <= 16 && input.none { !it.isDigit() }) {
                text = input
            }
        },
        modifier = Modifier.size(170.dp, 30.dp).background(Color.LightGray).wrapContentSize(),
        singleLine = true,
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
        visualTransformation = creditCardTransformation,
    )
}
```
### PlaceholderBasicTextFieldSample
```kotlin
@Composable
fun PlaceholderBasicTextFieldSample() {
    var value by rememberSaveable { mutableStateOf("initial value") }
    Box {
        BasicTextField(value = value, onValueChange = { value = it })
        if (value.isEmpty()) {
            Text(text = "Placeholder")
        }
    }
}
```
### TextFieldWithIconSample
```kotlin
@Composable
fun TextFieldWithIconSample() {
    var value by rememberSaveable { mutableStateOf("initial value") }
    BasicTextField(
        value = value,
        onValueChange = { value = it },
        decorationBox = { innerTextField ->
            // Because the decorationBox is used, the whole Row gets the same behaviour as the
            // internal input field would have otherwise. For example, there is no need to add a
            // Modifier.clickable to the Row anymore to bring the text field into focus when user
            // taps on a larger text field area which includes paddings and the icon areas.
            Row(
                Modifier.background(Color.LightGray, RoundedCornerShape(percent = 30))
                    .padding(16.dp)
            ) {
                Icon(Icons.Default.MailOutline, contentDescription = null)
                Spacer(Modifier.width(16.dp))
                innerTextField()
            }
        },
    )
}
```

