# InputTransformation

Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+class:androidx.compose.foundation.text.input.InputTransformation) Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0) Common/All
- Cmn

  ```
  fun interface InputTransformation
  ```
Known direct subclasses [InputTransformation.Companion](https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.Companion)

|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.Companion` |   |

*** ** * ** ***

A function that is ran after every change made to a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldState` by user input and can change or reject that input.

Input transformations are ran after hardware and software keyboard events, when text is pasted or dropped into the field, or when an accessibility service changes the text.

To chain filters together, call `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)`.

Prebuilt filters are provided for common filter operations. See:

- `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`.`https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)``()`

- `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`.`https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)``()`

- `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`.`https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).allCaps(androidx.compose.ui.text.intl.Locale)``()`

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.delete
import androidx.compose.foundation.text.input.insert
import androidx.compose.material3.Text
import androidx.compose.runtime.remember

// 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)
        },
)
```

## Summary

| ### Nested types |
|---|
| `object https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.Companion : https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` |

| ### Public companion functions |
|---|---|---|
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.TextFieldBuffer).transformInput()()` The transform operation. | Cmn |

| ### Public functions |
|---|---|---|
| `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/SemanticsPropertyReceiver.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).applySemantics()()` Optional semantics configuration that can update certain characteristics of the applied TextField, e.g. `https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).maxTextLength()`. | Cmn |
| `https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.TextFieldBuffer).transformInput()()` The transform operation. | Cmn |

| ### Public properties |
|---|---|---|
| `open https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/KeyboardOptions?` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#keyboardOptions()` Optional `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/KeyboardOptions` that will be used as the default keyboard options for configuring the IME. | Cmn |

| ### Extension functions |
|---|---|---|
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).allCaps(androidx.compose.ui.text.intl.Locale)(locale: https://developer.android.com/reference/kotlin/androidx/compose/ui/text/intl/Locale)` Returns a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` that forces all text to be uppercase. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).byValue(kotlin.Function2)( transformation: (current: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char-sequence/index.html, proposed: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char-sequence/index.html) -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-char-sequence/index.html )` Creates an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` from a function that accepts both the current and proposed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequence` and returns the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequence` to use for the field. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.[maxLength](https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).maxLength(kotlin.Int))(maxLength: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` **This function is deprecated.** Use maxLengthTrim to truncate excess characters or maxLengthReject to reject input exceeding maxLength. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)(maxLength: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Rejects input changes that would cause the total length of the text field to exceed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)` characters. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)(maxLength: https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html)` Limits the total length of the text field to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)` characters by truncating inserted characters. | Cmn |
| `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation.https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)(next: https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation)` Creates a filter chain that will run `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)` after this. | Cmn |

## Public companion functions

### TextFieldBuffer.transformInput

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:transformInput)

```
open fun TextFieldBuffer.transformInput(): Unit
```

The transform operation. For more information see the documentation on `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`.

This function is scoped to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer`, a buffer that can be changed in-place to alter or reject the changes or set the selection.

To reject all changes in the scoped `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer`, call `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer#revertAllChanges()`.

When multiple `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`s are linked together, the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.TextFieldBuffer).transformInput()` function of the first transformation is invoked before the second one. Once the changes are made to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer` by the initial `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` in the chain, the same instance of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer` is forwarded to the subsequent transformation in the chain. Note that `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer#originalValue()` never changes while the buffer is passed along the chain. This sequence persists until the chain reaches its conclusion.

## Public functions

### SemanticsPropertyReceiver.applySemantics

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:applySemantics) Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0)

```
open fun SemanticsPropertyReceiver.applySemantics(): Unit
```

Optional semantics configuration that can update certain characteristics of the applied TextField, e.g. `https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).maxTextLength()`.

### TextFieldBuffer.transformInput

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:transformInput) Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0)

```
fun TextFieldBuffer.transformInput(): Unit
```

The transform operation. For more information see the documentation on `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`.

This function is scoped to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer`, a buffer that can be changed in-place to alter or reject the changes or set the selection.

To reject all changes in the scoped `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer`, call `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer#revertAllChanges()`.

When multiple `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation`s are linked together, the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.TextFieldBuffer).transformInput()` function of the first transformation is invoked before the second one. Once the changes are made to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer` by the initial `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` in the chain, the same instance of `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer` is forwarded to the subsequent transformation in the chain. Note that `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldBuffer#originalValue()` never changes while the buffer is passed along the chain. This sequence persists until the chain reaches its conclusion.

## Public properties

### keyboardOptions

Cmn Added in [1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0)

```
open val keyboardOptions: KeyboardOptions?
```

Optional `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/KeyboardOptions` that will be used as the default keyboard options for configuring the IME. The options passed directly to the text field composable will always override this.

## Extension functions

### InputTransformation.allCaps

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:allCaps)

```
fun InputTransformation.allCaps(locale: Locale): InputTransformation
```

Returns a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` that forces all text to be uppercase.

This transformation automatically configures the keyboard to capitalize all characters.

| Parameters |
|---|---|
| `locale: https://developer.android.com/reference/kotlin/androidx/compose/ui/text/intl/Locale` | The `https://developer.android.com/reference/kotlin/androidx/compose/ui/text/intl/Locale` in which to perform the case conversion. |

### InputTransformation.byValue

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:byValue)

```
fun InputTransformation.byValue(
    transformation: (current: CharSequence, proposed: CharSequence) -> CharSequence
): InputTransformation
```

Creates an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` from a function that accepts both the current and proposed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequence` and returns the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/TextFieldCharSequence` to use for the field.

`https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).byValue(kotlin.Function2)` can return either `current`, `proposed`, or a completely different value.

The selection or cursor will be updated automatically. For more control of selection implement `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` directly.

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.byValue
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.sp

val state = remember { TextFieldState() }
BasicTextField(
    state,
    // Reject whitespace.
    inputTransformation =
        InputTransformation.byValue { current, proposed ->
            if ("""\s""".toRegex() in proposed) current else proposed
        },
)
```

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.byValue
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.unit.sp

val state = remember { TextFieldState() }
BasicTextField(
    state,
    // Convert tabs to spaces.
    inputTransformation =
        InputTransformation.byValue { _, proposed ->
            proposed.replace("""\t""".toRegex(), "  ")
        },
)
```

### InputTransformation.maxLength

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:maxLength)

```
fun InputTransformation.[maxLength](https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation#(androidx.compose.foundation.text.input.InputTransformation).maxLength(kotlin.Int))(maxLength: Int): InputTransformation
```

> [!CAUTION]
> **This function is deprecated.**   
> Use maxLengthTrim to truncate excess characters or maxLengthReject to reject input exceeding maxLength, use this instead:
>
> ```kotlin
> this.maxLengthReject(maxLength)
> ```

Returns `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` that rejects input which causes the total length of the text field to be more than `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLength(kotlin.Int)` characters.

This transformation also sets the maximum text length for accessibility services. When using an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/OutputTransformation` that adds decorating characters, the announced maximum length may need to be adjusted to account for those characters. See the linked sample for an example of a custom `maxLength` filter that does this.

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.OutputTransformation
import androidx.compose.foundation.text.input.TextFieldBuffer
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.delete
import androidx.compose.foundation.text.input.insert
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.maxTextLength

val state = remember { TextFieldState() }
BasicTextField(
    state,
    inputTransformation =
        object : InputTransformation {
            override fun SemanticsPropertyReceiver.applySemantics() {
                // The output transformation formats "1234567890" to "(123) 456-7890",
                // which is 14 characters long. We set the accessibility maximum length
                // to 14 so screen readers announce the correct limit.
                maxTextLength = 14
            }

            override fun TextFieldBuffer.transformInput() {
                if (length > 10) {
                    delete(10, length)
                }
            }
        },
    outputTransformation =
        OutputTransformation {
            if (length > 0) insert(0, "(")
            if (length > 4) insert(4, ") ")
            if (length > 9) insert(9, "-")
        },
)
```

### InputTransformation.maxLengthReject

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:maxLengthReject)

```
fun InputTransformation.maxLengthReject(maxLength: Int): InputTransformation
```

Rejects input changes that would cause the total length of the text field to exceed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)` characters.

When text is inserted (e.g. by typing or pasting) that would cause the total length to exceed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)`, the entire edit operation is rejected and reverted, leaving the existing text unchanged. For example, pasting "12345" into a text field that already has 8 characters and a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthReject(kotlin.Int)` of 10 will reject the paste completely, leaving the original 8 characters unchanged.

This transformation sets the maximum text length for accessibility services. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/OutputTransformation` does not affect this limit. When using an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/OutputTransformation` that adds decorating characters, set `https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).maxTextLength()` manually in a custom `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` to include those characters in the announced limit.

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.OutputTransformation
import androidx.compose.foundation.text.input.TextFieldBuffer
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.delete
import androidx.compose.foundation.text.input.insert
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.maxTextLength

val state = remember { TextFieldState() }
BasicTextField(
    state,
    inputTransformation =
        object : InputTransformation {
            override fun SemanticsPropertyReceiver.applySemantics() {
                // The output transformation formats "1234567890" to "(123) 456-7890",
                // which is 14 characters long. We set the accessibility maximum length
                // to 14 so screen readers announce the correct limit.
                maxTextLength = 14
            }

            override fun TextFieldBuffer.transformInput() {
                if (length > 10) {
                    delete(10, length)
                }
            }
        },
    outputTransformation =
        OutputTransformation {
            if (length > 0) insert(0, "(")
            if (length > 4) insert(4, ") ")
            if (length > 9) insert(9, "-")
        },
)
```

### InputTransformation.maxLengthTrim

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:maxLengthTrim)

```
fun InputTransformation.maxLengthTrim(maxLength: Int): InputTransformation
```

Limits the total length of the text field to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)` characters by truncating inserted characters.

When text is inserted (e.g. by typing or pasting) that would cause the total length to exceed `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)`, only enough inserted characters are kept to fill the text field up to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)`, and excess characters are trimmed and discarded. For example, pasting "12345" into a text field that already has 8 characters and a `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).maxLengthTrim(kotlin.Int)` of 10 will insert only "12", resulting in 10 characters.

This transformation sets the maximum text length for accessibility services. `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/OutputTransformation` does not affect this limit. When using an `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/OutputTransformation` that adds decorating characters, set `https://developer.android.com/reference/kotlin/androidx/compose/ui/semantics/package-summary#(androidx.compose.ui.semantics.SemanticsPropertyReceiver).maxTextLength()` manually in a custom `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` to include those characters in the announced limit.

```kotlin
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.OutputTransformation
import androidx.compose.foundation.text.input.TextFieldBuffer
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.delete
import androidx.compose.foundation.text.input.insert
import androidx.compose.material3.Text
import androidx.compose.runtime.remember
import androidx.compose.ui.semantics.SemanticsPropertyReceiver
import androidx.compose.ui.semantics.maxTextLength

val state = remember { TextFieldState() }
BasicTextField(
    state,
    inputTransformation =
        object : InputTransformation {
            override fun SemanticsPropertyReceiver.applySemantics() {
                // The output transformation formats "1234567890" to "(123) 456-7890",
                // which is 14 characters long. We set the accessibility maximum length
                // to 14 so screen readers announce the correct limit.
                maxTextLength = 14
            }

            override fun TextFieldBuffer.transformInput() {
                if (length > 10) {
                    delete(10, length)
                }
            }
        },
    outputTransformation =
        OutputTransformation {
            if (length > 0) insert(0, "(")
            if (length > 4) insert(4, ") ")
            if (length > 9) insert(9, "-")
        },
)
```

### InputTransformation.then

Cmn Artifact: [androidx.compose.foundation:foundation](https://developer.android.com/jetpack/androidx/releases/compose-foundation) [View Source](https://cs.android.com/search?q=file:androidx/compose/foundation/text/input/InputTransformation.kt+function:then)

```
fun InputTransformation.then(next: InputTransformation): InputTransformation
```

Creates a filter chain that will run `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)` after this. Filters are applied sequentially, so any changes made by this filter will be visible to `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)`.

The returned filter will use the `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/KeyboardOptions` from `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/package-summary#(androidx.compose.foundation.text.input.InputTransformation).then(androidx.compose.foundation.text.input.InputTransformation)` if non-null, otherwise it will use the options from this transformation.

```kotlin
import androidx.compose.foundation.text.input.InputTransformation
import androidx.compose.foundation.text.input.then

val removeFirstEFilter = InputTransformation {
    val index = asCharSequence().indexOf('e')
    if (index != -1) {
        replace(index, index + 1, "")
    }
}
val printECountFilter = InputTransformation {
    println("found ${asCharSequence().count { it == 'e' }} 'e's in the string")
}

// Returns a filter that always prints 0 e's.
removeFirstEFilter.then(printECountFilter)

// Returns a filter that prints the number of e's before the first one is removed.
printECountFilter.then(removeFirstEFilter)
```

| Parameters |
|---|---|
| `next: https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` | The `https://developer.android.com/reference/kotlin/androidx/compose/foundation/text/input/InputTransformation` that will be ran after this one. |