Text Field

A themable component to build text fields with the styling of your choice.

Supports placeholders, leading and trailing slots out of the box along with accessibility labels (visual or not).

Installation

repositories {
    mavenCentral()
}

dependencies {
    implementation("com.composables:core:1.37.0")
}

Basic Example

To create a text field, use the TextField component and use the TextInput() component within its content scope.

The TextField itself groups together every part of the text field in order to make sense for screen reader technology.

Other than the TextInput which handles the part of the text field the user can enter text at, it can contain elements such as Text for a visual label.

var text by remember { mutableStateOf("") }

TextField(
    value = text,
    onValueChange = { text = it },
    singleLine = true
) {
    TextInput()
}

Styling

Every component in Compose Unstyled is renderless. They handle all UX pattern logic, internal state, accessibility ( according to ARIA standards), and keyboard interactions for you, but they do not render any UI to the screen.

This is by design so that you can style your components exactly to your needs.

Most of the time, styling is done using Modifiers of your choice. However, sometimes this is not enough due to the order of the Modifiers affecting the visual outcome.

For such cases we provide specific styling parameters.

Code Examples

Consistent typography through your app

It is recommended to use the provided LocalTextStyle in order to maintain consistent text styling across your app.

If you need to override a text style for specific cases, you can either override a specific parameter via the Text modifier or pass an entire different style via the style parameter:

CompositionLocalProvider(LocalTextStyle provides TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Medium)) {
    Column {
        // this text field will use the provided Text Style
        TextField(
            value = "",
            onValueChange = { /* TODO */ },
        ) {
            // the provided text style will be used in the text input 
            TextInput()
        }
        Text("So will this text")

        Text("This text is also styled, but slightly modified", letterSpacing = 2.sp)

        Text("This text is completely different", style = TextStyle())
    }
}

Specifying Input Type

You can specify the input type for the TextField using the keyboardOptions parameter. For example, to specify an email input type:

TextField(
    value = "",
    onValueChange = { /* TODO */ },
    modifier = Modifier.fillMaxWidth(),
    placeholder = "Email",
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email)
) {
    InputText()
}

Adding a Trailing Icon

You can add a trailing icon to the TextField to provide additional functionality, such as toggling password visibility:

var password by remember { mutableStateOf("") }
var showPassword by remember { mutableStateOf(false) }

TextField(
    value = password,
    onValueChange = { password = it },
) {
    TextInput(
        placeholder = { Text("Password") },
        trailing = {
            Button(
                onClick = { showPassword = !showPassword },
                backgroundColor = Color.Transparent,
                contentPadding = PaddingValues(4.dp),
                shape = RoundedCornerShape(4.dp)
            ) {
                Icon(
                    imageVector = if (showPassword) EyeOff else Eye,
                    contentDescription = if (showPassword) "Hide password" else "Show password",
                    tint = Color(0xFF757575)
                )
            }
        }
    )
}

Handling Password Input

To handle password input, you can use the visualTransformation parameter to obscure the text:

var password by remember { mutableStateOf("") }
var showPassword by remember { mutableStateOf(false) }

TextField(
    value = password,
    onValueChange = { password = it },
    visualTransformation = if (showPassword) VisualTransformation.None else PasswordVisualTransformation(),
) {
    TextInput(
        placeholder = { Text("Password") },
        trailing = {
            Button(
                onClick = { showPassword = !showPassword },
                backgroundColor = Color.Transparent,
                contentPadding = PaddingValues(4.dp),
                shape = RoundedCornerShape(4.dp)
            ) {
                Icon(
                    imageVector = if (showPassword) EyeOff else Eye,
                    contentDescription = if (showPassword) "Hide password" else "Show password",
                    tint = Color(0xFF757575)
                )
            }
        }
    )
}

Adding an Invisible Label

You can add an invisible label to your text field for accessibility purposes.

This is particularly useful when you want to provide context for screen readers without showing a visual label:

TextField(
    value = "",
    onValueChange = { /* TODO */ },
) {
    TextInput(
        label = "Email address", // This label is only visible to screen readers
        placeholder = { Text("Enter your email") }
    )
}

Component API

TextField

ParameterDescription
valueThe current text in the text field.
onValueChangeCallback when the text changes.
modifierModifier to be applied to the text field.
editableWhether the text field is editable.
cursorBrushThe brush to use for the cursor.
textStyleStyle to apply to the text.
textAlignAlignment of the text.
lineHeightHeight of each line of text.
fontSizeSize of the font.
letterSpacingSpacing between letters.
fontWeightWeight of the font.
fontFamilyFamily of the font.
singleLineWhether the text field is single line.
minLinesMinimum number of lines to display.
maxLinesMaximum number of lines to display.
keyboardActionsActions for the keyboard.
keyboardOptionsOptions for the keyboard.
visualTransformationVisual transformation for the text.
interactionSourceInteraction source for the text field.
contentContent composable that defines the text field's appearance.

TextFieldScope.TextInput

ParameterDescription
modifierModifier to be applied to the text input.
shapeShape of the text input.
backgroundColorBackground color of the text input.
contentColorColor of the text content.
labelAccessibility label for the text input.
placeholderPlaceholder composable when the field is empty.
leadingLeading composable to display.
trailingTrailing composable to display.
verticalAlignmentVertical alignment of the content.

Icons and other icons

You can find the icons used in our examples and many other icons at composeicons.com.