Compose Unstyled 2.0 is out! Check the official announcement blog ->

Text Field

A text field component with placeholders, transformations, and text styling hooks.

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composeunstyled.TextInput
import com.composeunstyled.UnstyledTextField

@Composable
fun TextFieldDemo() {
  val displayName = rememberTextFieldState()
  val fieldShape = RoundedCornerShape(8.dp)

  Box(
    modifier = Modifier
      .fillMaxSize()
      .padding(horizontal = 16.dp)
      .padding(top = 16.dp)
      .imePadding(),
    contentAlignment = Alignment.Center,
  ) {
    Box(
      modifier = Modifier
        .widthIn(max = 500.dp),
      contentAlignment = Alignment.Center,
    ) {
      Column(
        horizontalAlignment = Alignment.CenterHorizontally,
      ) {
        UnstyledTextField(
          state = displayName,
          modifier = Modifier.fillMaxWidth(),
          lineLimits = TextFieldLineLimits.SingleLine,
          cursorBrush = SolidColor(Color.Black),
          textStyle = TextStyle(
            color = Color.Black,
            fontSize = 14.sp,
            lineHeight = 20.sp,
          ),
        ) {
          Column {
            BasicText(
              "Display Name",
              modifier = Modifier.padding(bottom = 8.dp),
              style = TextStyle(
                color = Color.Black,
                fontSize = 16.sp,
                lineHeight = 24.sp,
              ),
            )
            TextInput(
              Modifier
                .fillMaxWidth()
                .background(Color(0xFFF8FAFC), fieldShape)
                .border(1.dp, Color(0xFFCACACA), fieldShape)
                .padding(horizontal = 16.dp, vertical = 12.dp),
              placeholder = {
                BasicText(
                  "Alex",
                  style = TextStyle(
                    color = Color.Black.copy(0.6f),
                    fontSize = 14.sp,
                    lineHeight = 20.sp,
                  ),
                )
              },
            )
          }
        }
      }
    }
  }
}

Features

  • State-based text input
  • Placeholder slot
  • Input and output transformations
  • Text style parameters

Installation

implementation("com.composables:composeunstyled-text-field")

Anatomy

UnstyledTextField(state = state) {
  TextInput()
}

Concepts

  • UnstyledTextField represents the text field container.
  • TextInput renders the editable text and optional placeholder.

Accessibility

Use accessibilityLabel when the text field does not include a readable label in its content.

Code Examples

Adding placeholder text

Use the placeholder parameter on TextInput to render content while the field is empty:

val state = rememberTextFieldState()

UnstyledTextField(state = state) {
  TextInput(
    placeholder = {
      BasicText("Email")
    },
  )
}

Creating a single-line text field

Use the lineLimits parameter to restrict input to one line:

UnstyledTextField(
  state = state,
  lineLimits = TextFieldLineLimits.SingleLine,
) {
  TextInput()
}

Setting the keyboard type

Use the keyboardOptions parameter to request a specific software keyboard:

UnstyledTextField(
  state = state,
  keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
) {
  TextInput()
}

Styling entered text

Use the text style parameters to set the style of the editable text:

UnstyledTextField(
  state = state,
  fontWeight = FontWeight.Medium,
  textColor = Color.Black,
) {
  TextInput()
}

Labeling an icon-only text field

Use the accessibilityLabel parameter when the visible text field has no text label:

UnstyledTextField(
  state = state,
  accessibilityLabel = "Search",
) {
  TextInput()
}

API Reference

UnstyledTextField

Parameter Type Description
state TextFieldState The TextFieldState that manages the text field's content.
modifier Modifier Modifier to be applied to the text input.
enabled Boolean
accessibilityLabel String?
readOnly Boolean
cursorBrush Brush The brush to use for the cursor.
textStyle TextStyle Style to apply to the text.
textAlign TextAlign Alignment of the text.
lineHeight TextUnit Height of each line of text.
fontSize TextUnit Size of the font.
letterSpacing TextUnit Spacing between letters.
fontWeight FontWeight? Weight of the font.
fontFamily FontFamily? Family of the font.
textDecoration TextDecoration?
lineLimits TextFieldLineLimits
inputTransformation InputTransformation?
outputTransformation OutputTransformation?
onTextLayout (Density.(getResult: () -> TextLayoutResult?) -> Unit)?
onKeyboardAction KeyboardActionHandler? Handler for keyboard actions.
keyboardOptions KeyboardOptions Options for the keyboard.
interactionSource MutableInteractionSource? Interaction source for the text field.
textColor Color Color of the text.
scrollState ScrollState Scroll state for the text field.
content TextFieldScope.() -> Unit Content composable that defines the text field's appearance.

TextFieldScope.TextInput

Parameter Type Description
modifier Modifier Modifier to be applied to the text input.
placeholder (() -> Unit)? Placeholder composable when the field is empty.