Text Field
A text field component with placeholders, transformations, and text styling hooks.
View Markdownimport 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.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.RectangleShape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composeunstyled.LocalTextStyle
import com.composeunstyled.Text
import com.composeunstyled.TextInput
import com.composeunstyled.UnstyledTextField
import com.composeunstyled.demo.borderToken
import com.composeunstyled.demo.colors
import com.composeunstyled.demo.contentToken
import com.composeunstyled.demo.surfaceToken
import com.composeunstyled.theme.Theme
@Preview
@Composable
fun TextFieldDemo() {
val displayName = rememberTextFieldState()
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(Theme[colors][contentToken]),
textStyle = LocalTextStyle.current.copy(
color = Theme[colors][contentToken],
fontSize = 14.sp,
lineHeight = 20.sp,
),
) {
Column {
Text(
"Display Name",
modifier = Modifier.padding(bottom = 8.dp),
color = Theme[colors][contentToken],
fontSize = 16.sp,
lineHeight = 24.sp,
)
TextInput(
Modifier
.fillMaxWidth()
.background(Theme[colors][surfaceToken], RectangleShape)
.border(1.dp, Theme[colors][borderToken], RectangleShape)
.padding(horizontal = 16.dp, vertical = 12.dp),
placeholder = {
Text(
"Alex",
color = Theme[colors][contentToken].copy(0.6f),
fontSize = 14.sp,
lineHeight = 20.sp,
)
},
)
}
}
}
}
}
}Features
- State-based text input
- Placeholder slot
- Input and output transformations
- Text and selection style parameters
Installation
implementation("com.composables:composeunstyled-text-field:2.9.2")Anatomy
UnstyledTextField(state = state) {
TextInput()
}Concepts
UnstyledTextFieldrepresents the text field container.TextInputrenders 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()
}Styling selected text
By default, selection colors are unspecified. Use the selectionColors parameter to set the
selection handle and background colors:
UnstyledTextField(
state = state,
selectionColors = TextSelectionColors(
handleColor = Color.Black,
backgroundColor = Color.Black.copy(alpha = 0.4f),
),
) {
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. |
selectionColors |
TextSelectionColors |
Colors to use for text selection handles and background. Defaults to unspecified colors. |
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. |