# PlatformTextInputModifierNode

Artifact: [androidx.compose.ui:ui](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/platform/PlatformTextInputModifierNode.kt+class:androidx.compose.ui.platform.PlatformTextInputModifierNode) Added in [1.6.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.6.0) Common/AllAndroid/JVM
- Cmn

  ```
  interface PlatformTextInputModifierNode : DelegatableNode
  ```

*** ** * ** ***

A modifier node that can connect to the platform's text input IME system. To initiate a text input session, call `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.platform.PlatformTextInputModifierNode).establishTextInputSession(kotlin.coroutines.SuspendFunction1)`.

```kotlin
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusEventModifierNode
import androidx.compose.ui.focus.FocusState
import androidx.compose.ui.platform.PlatformTextInputMethodRequest
import androidx.compose.ui.platform.PlatformTextInputModifierNode
import androidx.compose.ui.platform.PlatformTextInputSession
import androidx.compose.ui.platform.establishTextInputSession

class PlatformTextInputModifierNodeSample :
    Modifier.Node(), FocusEventModifierNode, PlatformTextInputModifierNode {

    private var focusedJob: Job? = null

    override fun onFocusEvent(focusState: FocusState) {
        focusedJob?.cancel()
        focusedJob =
            if (focusState.isFocused) {
                // establishTextInputSession is a suspend function, so it must be called from a
                // coroutine. Launching it into this modifier node's coroutine scope ensures the
                // session will automatically be torn down when the node is detached.
                coroutineScope.launch {
                    // This will automatically cancel any currently-active session.
                    establishTextInputSession {
                        launch {
                            // TODO: Observe text field state, call into system to update it as
                            //  required by the platform.
                        }

                        // Call out to a platform-specific expect/actual function to create the
                        // platform-specific request.
                        val request: PlatformTextInputMethodRequest = createInputRequest()
                        startInputMethod(request)
                    }
                }
            } else {
                null
            }
    }

    // This would probably be an expect/actual function.
    private fun PlatformTextInputSession.createInputRequest(): PlatformTextInputMethodRequest {
        TODO("Create platform-specific request")
    }
}
```

## Summary

| ### Extension functions |
|---|---|---|
| `suspend https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-nothing/index.html` | `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputModifierNode.https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputModifierNode#(androidx.compose.ui.platform.PlatformTextInputModifierNode).establishTextInputSession(kotlin.coroutines.SuspendFunction1)( block: suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputSessionScope.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-nothing/index.html )` Starts a new text input session and suspends until the session is closed. | Cmn |

### Inherited functions

From [androidx.compose.ui.node.DelegatableNode](https://developer.android.com/reference/kotlin/androidx/compose/ui/node/DelegatableNode) `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` `@https://developer.android.com/reference/kotlin/androidx/annotation/EmptySuper
https://developer.android.com/reference/kotlin/androidx/compose/ui/node/DelegatableNode#onDensityChange()()`

Invoked when the density changes for this node.
Cmn `open https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html` `@https://developer.android.com/reference/kotlin/androidx/annotation/EmptySuper
https://developer.android.com/reference/kotlin/androidx/compose/ui/node/DelegatableNode#onLayoutDirectionChange()()`

Invoked when the layout direction changes for this node.
Cmn

### Inherited properties

From [androidx.compose.ui.node.DelegatableNode](https://developer.android.com/reference/kotlin/androidx/compose/ui/node/DelegatableNode) `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.Node` `https://developer.android.com/reference/kotlin/androidx/compose/ui/node/DelegatableNode#node()`

A reference of the `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.Node` that holds this node's position in the node hierarchy.
Cmn

## Extension functions

### PlatformTextInputModifierNode.establishTextInputSession

Cmn Artifact: [androidx.compose.ui:ui](https://developer.android.com/jetpack/androidx/releases/compose-ui) [View Source](https://cs.android.com/search?q=file:androidx/compose/ui/platform/PlatformTextInputModifierNode.kt+function:establishTextInputSession)

```
suspend fun PlatformTextInputModifierNode.establishTextInputSession(
    block: suspend PlatformTextInputSessionScope.() -> Nothing
): Nothing
```

Starts a new text input session and suspends until the session is closed.

The `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.platform.PlatformTextInputModifierNode).establishTextInputSession(kotlin.coroutines.SuspendFunction1)` function must call `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputSession#startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest)` to actually show and initiate the connection with the input method. If it does not, the session will end when this function returns without showing the input method.

If this function is called while another session is active, the sessions will not overlap. The new session will interrupt the old one, which will be cancelled and allowed to finish running any cancellation tasks (e.g. `finally` blocks) before running the new `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/package-summary#(androidx.compose.ui.platform.PlatformTextInputModifierNode).establishTextInputSession(kotlin.coroutines.SuspendFunction1)` function.

The session will be closed when:

- The session function throws an exception.

- The requesting coroutine is cancelled.

- Another session is started via this method, either from the same modifier or a different one. The session may remain open when:

- The system closes the connection. This behavior currently only exists on Android depending on OS version. Android platform may intermittently close the active connection to immediately start it back again. In these cases the session will not be prematurely closed, so that it can serve the follow-up requests.

This function should only be called from the modifier node's `https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.Node#coroutineScope()`. If it is not, the session will *not* automatically be closed if the modifier is detached.

```kotlin
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusEventModifierNode
import androidx.compose.ui.focus.FocusState
import androidx.compose.ui.platform.PlatformTextInputMethodRequest
import androidx.compose.ui.platform.PlatformTextInputModifierNode
import androidx.compose.ui.platform.PlatformTextInputSession
import androidx.compose.ui.platform.establishTextInputSession

class PlatformTextInputModifierNodeSample :
    Modifier.Node(), FocusEventModifierNode, PlatformTextInputModifierNode {

    private var focusedJob: Job? = null

    override fun onFocusEvent(focusState: FocusState) {
        focusedJob?.cancel()
        focusedJob =
            if (focusState.isFocused) {
                // establishTextInputSession is a suspend function, so it must be called from a
                // coroutine. Launching it into this modifier node's coroutine scope ensures the
                // session will automatically be torn down when the node is detached.
                coroutineScope.launch {
                    // This will automatically cancel any currently-active session.
                    establishTextInputSession {
                        launch {
                            // TODO: Observe text field state, call into system to update it as
                            //  required by the platform.
                        }

                        // Call out to a platform-specific expect/actual function to create the
                        // platform-specific request.
                        val request: PlatformTextInputMethodRequest = createInputRequest()
                        startInputMethod(request)
                    }
                }
            } else {
                null
            }
    }

    // This would probably be an expect/actual function.
    private fun PlatformTextInputSession.createInputRequest(): PlatformTextInputMethodRequest {
        TODO("Create platform-specific request")
    }
}
```

| Parameters |
|---|---|
| `block: suspend https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputSessionScope.() -> https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-nothing/index.html` | A suspend function that will be called when the session is started and that must call `https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/PlatformTextInputSession#startInputMethod(androidx.compose.ui.platform.PlatformTextInputMethodRequest)` to actually show and initiate the connection with the input method. |