---
title: "KeyboardOptions"
description: "Defines keyboard configuration options for TextFields."
type: "class"
---
## API Reference

> Source set: Common

```kotlin
public class KeyboardOptions(
    public val capitalization: KeyboardCapitalization = KeyboardCapitalization.Unspecified,
    public val autoCorrectEnabled: Boolean? = null,
    public val keyboardType: KeyboardType = KeyboardType.Unspecified,
    public val imeAction: ImeAction = ImeAction.Unspecified,
    public val platformImeOptions: PlatformImeOptions? = null,
    public val showKeyboardOnFocus: Boolean? = null,
    @get:Suppress("NullableCollection") public val hintLocales: LocaleList? = null,
)
```

Defines keyboard configuration options for TextFields.

Represents specific layout, capitalization, and system action hints sent to the Input Method
Editor (IME/software keyboard) on focus gain.

Soft keyboards make best-effort attempts to comply with the options provided here. Key layouts
and flag behaviors are ultimately determined by the active IME implementation.

#### Parameters

| | |
| --- | --- |
| capitalization | informs the keyboard whether to automatically capitalize characters, words, or sentences. Only applicable to text-based [KeyboardType](/jetpack-compose/androidx.compose.ui/ui-text/classes/KeyboardType)s such as [KeyboardType.Text](/jetpack-compose/androidx.compose.ui/ui/properties/text), `KeyboardType.Ascii`, or `KeyboardType.PostalAddress`. It is ignored by soft keyboards when paired with numeric layouts (like `KeyboardType.Number` or `KeyboardType.Decimal`). |
| autoCorrectEnabled | informs the keyboard whether to enable auto-correct suggestions. Only applicable to text-based [KeyboardType](/jetpack-compose/androidx.compose.ui/ui-text/classes/KeyboardType)s such as [KeyboardType.Text](/jetpack-compose/androidx.compose.ui/ui/properties/text), `KeyboardType.Email`, or `KeyboardType.Uri`. Keyboards ignore this value for numeric keypads. A null value (the default parameter value) expresses that soft keyboard default configurations should apply. |
| keyboardType | keyboard keypad layout to be displayed in the focused text field. Honored by keyboards to display tailored key selections (e.g., phone dialer characters for `KeyboardType.Phone`, decimal separator buttons for `KeyboardType.Decimal`, or masked numeric pads for `KeyboardType.NumberPassword`). |
| imeAction | action button displayed on the soft keyboard (e.g., search, send, next, done, etc.). This action is honored by the software keyboard and may display custom icons (like a magnifying glass for `ImeAction.Search`). When the text field allows multi-line inputs, the keyboard typically displays a return key instead of the action icon requested here. |
| platformImeOptions | platform-specific IME options (like private IME commands). |
| showKeyboardOnFocus | when true, the soft keyboard shows immediately on text field focus gain. When false, the soft keyboard is hidden until the user taps the text field. A null value (the default parameter value) enables showing the keyboard automatically on focus gain. Note: This option is only supported by TextFieldState-based TextFields (like BasicTextField) and is ignored by legacy TextFields. |
| hintLocales | list of languages for IMEs. Provides a localized hint to help multilingual keyboards automatically shift their keyboard language based on the active field's context. |

## Properties

### autoCorrect

> Source set: Common

```kotlin
@Deprecated("Please use the autoCorrectEnabled property.", level = DeprecationLevel.WARNING)
    public val autoCorrect: Boolean
```

### shouldShowKeyboardOnFocus

> Source set: Common

```kotlin
@Deprecated(
        "Included for binary compatibility. Use showKeyboardOnFocus.",
        level = DeprecationLevel.HIDDEN,
    )
    public val shouldShowKeyboardOnFocus: Boolean
```

## Functions

### copy

> Source set: Common

```kotlin
public fun copy(
        capitalization: KeyboardCapitalization = this.capitalization,
        @Suppress("AutoBoxing") autoCorrectEnabled: Boolean? = this.autoCorrectEnabled,
        keyboardType: KeyboardType = this.keyboardType,
        imeAction: ImeAction = this.imeAction,
        platformImeOptions: PlatformImeOptions? = this.platformImeOptions,
        @Suppress("AutoBoxing") showKeyboardOnFocus: Boolean? = null,
        hintLocales: LocaleList? = null,
    ): KeyboardOptions
```

Returns a copy of this object with the values passed to this method.

Note that if an unspecified (null) value is passed explicitly to this method, it will replace
any actually-specified value. This differs from the behavior of `merge`, which will never
take an unspecified value over a specified one.

### copy

> Source set: Common

```kotlin
@Deprecated(
        "Please use the copy function that takes an autoCorrectEnabled parameter.",
        level = DeprecationLevel.HIDDEN,
        replaceWith =
            ReplaceWith(
                "copy(" +
                    "capitalization = capitalization, " +
                    "autoCorrectEnabled = autoCorrect, " +
                    "keyboardType = keyboardType, " +
                    "imeAction = imeAction," +
                    "platformImeOptions = platformImeOptions, " +
                    "showKeyboardOnFocus = showKeyboardOnFocus ?: true," +
                    "hintLocales = hintLocales" +
                    ")"
            ),
    )
    public fun copy(
        capitalization: KeyboardCapitalization = this.capitalization,
        autoCorrect: Boolean = this.autoCorrectOrDefault,
        keyboardType: KeyboardType = this.keyboardType,
        imeAction: ImeAction = this.imeAction,
        platformImeOptions: PlatformImeOptions? = this.platformImeOptions,
        @Suppress("AutoBoxing") showKeyboardOnFocus: Boolean? = this.showKeyboardOnFocusOrDefault,
        hintLocales: LocaleList? = this.hintLocales,
    ): KeyboardOptions
```

### copy

> Source set: Common

```kotlin
@Deprecated("Maintained for binary compatibility", level = DeprecationLevel.HIDDEN)
    public fun copy(
        capitalization: KeyboardCapitalization = this.capitalization,
        autoCorrect: Boolean = this.autoCorrectOrDefault,
        keyboardType: KeyboardType = this.keyboardType,
        imeAction: ImeAction = this.imeAction,
        platformImeOptions: PlatformImeOptions? = this.platformImeOptions,
    ): KeyboardOptions
```

### copy

> Source set: Common

```kotlin
@Deprecated(
        "Please use the new copy function that takes optional platformImeOptions parameter.",
        level = DeprecationLevel.HIDDEN,
    )
    public fun copy(
        capitalization: KeyboardCapitalization = this.capitalization,
        autoCorrect: Boolean = this.autoCorrectOrDefault,
        keyboardType: KeyboardType = this.keyboardType,
        imeAction: ImeAction = this.imeAction,
    ): KeyboardOptions
```

### equals

> Source set: Common

```kotlin
override fun equals(other: Any?): Boolean
```

### hashCode

> Source set: Common

```kotlin
override fun hashCode(): Int
```

### toString

> Source set: Common

```kotlin
override fun toString(): String
```

### merge

> Source set: Common

```kotlin
public fun merge(other: KeyboardOptions?): KeyboardOptions
```

Returns a new [KeyboardOptions](/jetpack-compose/androidx.compose.foundation/foundation/classes/KeyboardOptions/api) that is a combination of this options and a given `other`
options.

`other`s null or `Unspecified` properties are replaced with the non-null properties of this
object.

If the either this or `other` is null, returns the non-null one.

## Members

### Companion

> Source set: Common

```kotlin
public companion object
```

## Properties

### Default

> Source set: Common

```kotlin
@Stable public val Default: KeyboardOptions = KeyboardOptions()
```

Provides default [KeyboardOptions](/jetpack-compose/androidx.compose.foundation/foundation/classes/KeyboardOptions/api). See parameter descriptions for default values.

## Code Examples

### RegistrationFormSample

```kotlin
/**
 * A complete profile registration screen sample. Shows how to handle standard name entries, login
 * emails, physical mailing address lines, secure password visibility eye-icon togglers, and natural
 * language biography summaries.
 */
@Sampled
@Composable
fun RegistrationFormSample() {
    val nameState = rememberTextFieldState()
    val emailState = rememberTextFieldState()
    val passwordState = rememberTextFieldState()
    var isPasswordVisible by remember { mutableStateOf(false) }
    val urlState = rememberTextFieldState()
    val addressState = rememberTextFieldState()
    val biographyState = rememberTextFieldState()

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        modifier = Modifier.padding(16.dp).fillMaxWidth(),
    ) {
        // 1. PersonName Input (Auto-Capitalizes Words)
        OutlinedTextField(
            state = nameState,
            label = { Text("Full Name") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.PersonName,
                    capitalization = KeyboardCapitalization.Words,
                    imeAction = ImeAction.Next, // Soft keyboard automatically moves focus on Next
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 2. Email Input (Restricted layout showing '@' and '.', auto-capitalization disabled)
        OutlinedTextField(
            state = emailState,
            label = { Text("Email") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.Email,
                    capitalization = KeyboardCapitalization.None,
                    imeAction = ImeAction.Next,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 3. Password Input with Eye-Icon Toggle (masked vs visible password layouts,
        // capitalizations disabled)
        Row(verticalAlignment = Alignment.CenterVertically) {
            OutlinedSecureTextField(
                state = passwordState,
                label = { Text("Password") },
                textObfuscationMode =
                    if (isPasswordVisible) TextObfuscationMode.Visible
                    else TextObfuscationMode.System,
                keyboardOptions =
                    KeyboardOptions(
                        keyboardType =
                            if (isPasswordVisible) KeyboardType.PasswordVisible
                            else KeyboardType.Password,
                        capitalization = KeyboardCapitalization.None,
                        imeAction = ImeAction.Next,
                    ),
                modifier = Modifier.weight(0.7f),
            )
            Spacer(Modifier.width(8.dp))
            TextButton(
                onClick = { isPasswordVisible = !isPasswordVisible },
                modifier = Modifier.weight(0.3f),
            ) {
                Text(if (isPasswordVisible) "Hide" else "Show")
            }
        }

        // 4. Uri Input (Prominent '/' and '.com' keys, auto-capitalization disabled)
        OutlinedTextField(
            state = urlState,
            label = { Text("Homepage URL") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.Uri,
                    capitalization = KeyboardCapitalization.None,
                    imeAction = ImeAction.Next,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 5. PostalAddress Input (Auto-Capitalizes Words, prompts standard shipping keys)
        OutlinedTextField(
            state = addressState,
            label = { Text("Shipping Address") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.PostalAddress,
                    capitalization = KeyboardCapitalization.Words,
                    imeAction = ImeAction.Next,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 6. Free-Text Biography Input (Auto-Capitalizes Sentences, multi-line active)
        OutlinedTextField(
            state = biographyState,
            label = { Text("Biography") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.Text,
                    capitalization = KeyboardCapitalization.Sentences,
                    imeAction =
                        ImeAction.Done, // Soft keyboard automatically dismisses keyboard on Done
                ),
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

/**
 * A register cashier checkout panel sample. Shows how to build secure cashier PIN rows, automatic
 * dollar currency amounts input formatters, integer item quantities, customer phone dialers, and
 * capitalized promo voucher entry lines.
 */
```

### CheckoutRegisterFormSample

```kotlin
@Sampled
@Composable
fun CheckoutRegisterFormSample() {
    val cashierPinState = rememberTextFieldState()
    val qtyState = rememberTextFieldState()
    val phoneState = rememberTextFieldState()
    val couponState = rememberTextFieldState()
    val balanceOffsetState = rememberTextFieldState()

    val pinLength = 4

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        modifier = Modifier.padding(16.dp).fillMaxWidth(),
    ) {
        // 1. NumberPassword PIN Entry (Masked secure numeric pad (0-9))
        OutlinedSecureTextField(
            state = cashierPinState,
            label = { Text("Enter Cashier PIN (OTP)") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.NumberPassword,
                    imeAction = ImeAction.Next,
                ),
            inputTransformation =
                InputTransformation.byValue { _, proposed -> proposed.filter { it.isDigit() } }
                    .maxLength(pinLength),
            modifier = Modifier.fillMaxWidth(),
        )

        // 2. Number Plain Integer Input (Pure numeric key entry for quantities)
        OutlinedTextField(
            state = qtyState,
            label = { Text("Item Quantity Count") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Next),
            inputTransformation =
                InputTransformation.byValue { _, proposed -> proposed.filter { it.isDigit() } },
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 4. Phone Contact Entry (Displays telephony dialer keyboard with '+', '*', '#')
        OutlinedTextField(
            state = phoneState,
            label = { Text("Customer Loyalty Phone Number") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Phone, imeAction = ImeAction.Next),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 5. Ascii / KeyboardCapitalization.Characters (Uppercase restricted ASCII promo vouchers)
        OutlinedTextField(
            state = couponState,
            label = { Text("Promo Coupon Code") },
            inputTransformation = InputTransformation.allCaps(Locale.current),
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.Ascii,
                    capitalization = KeyboardCapitalization.Characters,
                    autoCorrectEnabled = false,
                    imeAction = ImeAction.Next,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 6. DecimalSigned Shared Offset Balance Adjustments (Allows decimal coordinates and
        // negative/positive signs)
        OutlinedTextField(
            state = balanceOffsetState,
            label = { Text("Add Balance Offset (Debits/Credits)") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.DecimalSigned,
                    imeAction = ImeAction.Done,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

/**
 * An alarm clock, timer, and calendar event scheduler card sample. Shows how to handle geographic
 * date selectors, preset time clocks, and combined scheduling timestamps.
 */
```

### DateTimeSchedulerFormSample

```kotlin
@Sampled
@Composable
fun DateTimeSchedulerFormSample() {
    val birthState = rememberTextFieldState()
    val timerState = rememberTextFieldState()
    val meetingState = rememberTextFieldState()

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        modifier = Modifier.padding(16.dp).fillMaxWidth(),
    ) {
        // 1. Date Input (Prompt numeric layout tailored for dates containing '/' or '-')
        OutlinedTextField(
            state = birthState,
            label = { Text("Birthdate (YYYY/MM/DD)") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Date, imeAction = ImeAction.Next),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 2. Time Input (Prompt numeric layout tailored for times containing ':')
        OutlinedTextField(
            state = timerState,
            label = { Text("Timer Preset Clock (HH:MM)") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Time, imeAction = ImeAction.Next),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 3. DateTime Input (Prompts clock-calendar layout option)
        OutlinedTextField(
            state = meetingState,
            label = { Text("Combined Meeting Timestamp (YYYY/MM/DD HH:MM)") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.DateTime, imeAction = ImeAction.Done),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

/**
 * Demonstrates search filters, phonetic translation entries, and specialty masked numeric keypads.
 */
```

### SpecialtyInputsFormSample

```kotlin
@Sampled
@Composable
fun SpecialtyInputsFormSample() {
    val filterState = rememberTextFieldState()
    val phoneticState = rememberTextFieldState()
    val maskedCoordsState = rememberTextFieldState()
    val maskedBalanceState = rememberTextFieldState()
    val maskedPasskeyState = rememberTextFieldState()

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        modifier = Modifier.padding(16.dp).fillMaxWidth(),
    ) {
        // 1. Filter Input (Optimized list filtering, auto-capitalization/suggestions disabled)
        OutlinedTextField(
            state = filterState,
            label = { Text("Search Query") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.Filter,
                    capitalization = KeyboardCapitalization.None,
                    imeAction = ImeAction.Next,
                ),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 2. Phonetic Input (For phonetic readings/pronunciations, e.g. phonetic names in contacts)
        OutlinedTextField(
            state = phoneticState,
            label = { Text("Phonetic Name") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Phonetic, imeAction = ImeAction.Next),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        // 3. DecimalPassword Input (Masked numeric pad showing decimal separators)
        OutlinedSecureTextField(
            state = maskedCoordsState,
            label = { Text("Secure Decimal Value") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.DecimalPassword,
                    imeAction = ImeAction.Next,
                ),
            modifier = Modifier.fillMaxWidth(),
        )

        // 4. NumberPasswordSigned Input (Masked numeric pad showing positive/negative signs)
        OutlinedSecureTextField(
            state = maskedBalanceState,
            label = { Text("Secure Signed Value") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.NumberPasswordSigned,
                    imeAction = ImeAction.Next,
                ),
            modifier = Modifier.fillMaxWidth(),
        )

        // 5. DecimalPasswordSigned Input (Masked numeric pad showing both decimals and signs)
        OutlinedSecureTextField(
            state = maskedPasskeyState,
            label = { Text("Secure Decimal Signed Value") },
            keyboardOptions =
                KeyboardOptions(
                    keyboardType = KeyboardType.DecimalPasswordSigned,
                    imeAction = ImeAction.Done,
                ),
            modifier = Modifier.fillMaxWidth(),
        )
    }
}
```

### PinCodeEntryRowSample

```kotlin
@Sampled
@Composable
fun PinCodeEntryRowSample() {
    val pinState = rememberTextFieldState()
    val pinLength = 4

    BasicSecureTextField(
        state = pinState,
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword),
        inputTransformation =
            InputTransformation.byValue { _, proposed -> proposed.filter { it.isDigit() } }
                .maxLength(pinLength),
        decorator = { innerTextField ->
            Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
                repeat(pinLength) { index ->
                    val char = pinState.text.getOrNull(index)
                    Box(
                        modifier =
                            Modifier.size(48.dp)
                                .border(
                                    1.dp,
                                    if (pinState.text.length == index) Color.Blue else Color.Gray,
                                    RoundedCornerShape(8.dp),
                                ),
                        contentAlignment = Alignment.Center,
                    ) {
                        if (char != null) {
                            Text("●")
                        }
                    }
                }
            }
        },
    )
}

/**
 * Decimal input fields for entering coordinates. Prompts soft keyboards to show a decimal point
 * key.
 */
```

### DecimalInputSample

```kotlin
@Sampled
@Composable
fun DecimalInputSample() {
    val latitudeState = rememberTextFieldState("37.7749")
    val longitudeState = rememberTextFieldState("-122.4194")

    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        OutlinedTextField(
            state = latitudeState,
            label = { Text("Latitude") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Decimal, imeAction = ImeAction.Next),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )

        OutlinedTextField(
            state = longitudeState,
            label = { Text("Longitude") },
            keyboardOptions =
                KeyboardOptions(keyboardType = KeyboardType.Decimal, imeAction = ImeAction.Done),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )
    }
}

/**
 * An integer item count settings field. Shows error validation warning text when non-digits or
 * invalid counts are inputted.
 */
```

### ItemCountSettingsSample

```kotlin
@Sampled
@Composable
fun ItemCountSettingsSample() {
    val countState = rememberTextFieldState("100")
    val isError by remember {
        derivedStateOf {
            val parsed = countState.text.toString().toIntOrNull()
            parsed == null || parsed <= 0
        }
    }

    Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
        OutlinedTextField(
            state = countState,
            label = { Text("List Item Display Count") },
            isError = isError,
            keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
            lineLimits = TextFieldLineLimits.SingleLine,
            modifier = Modifier.fillMaxWidth(),
        )
        if (isError) {
            Text("Value must be a positive integer", color = Color.Red)
        }
    }
}
```
