Skip to content

Simple Text Field

The simple text field represents a key value field and only supports single-line editable text. This field also supports setting helper, placeholder, or error texts.

Using the Simple Text Field

The simple text field can be used in your app like any traditional composable function:

var textValueState by rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name"
    ),
    trailingIcon = FioriTextFieldIcon(
        FioriIcon(
            iconType = IconType.RESOURCE,
            resId = R.drawable.ic_photo_camera_black_24dp,
            contentDescription = ""
        )
    ),
    value = textValueState,
    onValueChange = {
        textValueState = it
    }
)

var textValueState by rememberSaveable { mutableStateOf("") }
var textFieldValueState by remember { mutableStateOf(TextFieldValue(textValueState)) }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name"
    ),
    trailingIcon = FioriTextFieldIcon(
        FioriIcon(
            iconType = IconType.RESOURCE,
            resId = R.drawable.ic_photo_camera_black_24dp,
            contentDescription = ""
        )
    ),
    value = textFieldValueState,
    onValueChange = {
        textValueState = it.text
        textFieldValueState = it
    }
)

To specify the passed-in value parameter as androidx.compose.ui.text.input.TextFieldValue, you can control the cursor position.

Editable and Non-Editable Modes

This simple text field can be set to be editable or non-editable. When it is set to non-editable, the value field on the text field cannot be edited.

By default, the simple text field is editable. You can control the editability of the text field using the readOnly parameter of the text field function. Unlike editable mode, the simple text field supports multiple lines in non-editable mode. You can also use the readOnlyMaxLines parameter to control it:

var textValueState by rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name"
    ),
    readOnly = true,
    readOnlyMaxLines = 3,
    value = textValueState,
    onValueChange = {
        textValueState = it
    }
)

Helper, Placeholder, and Error Texts

To set the helper, placeholder, or error texts on the text field, use the helperText, placeholder, or errorMessage parameter, respectively in FioriTextFieldContent. To enable the error text and set the text field to be in error state, set the isError parameter to true. When errors are enabled, an error icon is also added to the end of the value field. You should therefore listen for the text value change and update the mutable state value for the isError parameter and the errorMessage parameter (See Listening for Text Value Changes):

var isError by rememberSaveable { mutableStateOf(false) }
var errorMsg by rememberSaveable { mutableStateOf("") }
var textValueState by rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name",
        required = true,
        errorMessage = errorMsg
    ),
    isError = isError,
    value = textValueState,
    onValueChange = {
        textValueState = it
        isError = textValueState.isEmpty()
        errorMsg = if (isError) "Required Field" else ""
    }
)

FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Email",
        placeholder = "Sample@email.com",
        helperText = "Email address"
    ),
    value = textValueState,
    onValueChange = {
        textValueState = it
    }
)

Helper, Placeholder, and Error Texts

Selectable Text

The simple text field allows you to enable or disable the ability to select the value text in non-editable states using the textSelectable parameter. By default, this is true and is only used for the non-editable model. The parameter will be ignored if the readOnly parameter is false.

Listening for Text Value Changes

Similar to the traditional composable function to listen for the change of the text field value, the onValueChange callback is used. You can get the changed text value and update the passed-in mutable state text to let the text field recompose:

var textValueState by rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name"
    ),
    value = textValueState,
    onValueChange = {
        textValueState = it
    }
)

Trailing Icon

The simple text field allows you to attach an icon at the end of the text value field (as a trailing icon) by specifying the trailingIcon parameter of the text field function:

FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name"
    ),
    trailingIcon = FioriTextFieldIcon(
        FioriIcon(
            iconType = IconType.RESOURCE,
            resId = R.drawable.ic_photo_camera_black_24dp,
            contentDescription = ""
        ),
        onClick = { }
    )
)

You can construct the FioriTextFieldIcon object using an icon resources ID or android.graphics.Bitmap. This trailing icon is also clickable when you specify the non-empty onClick or onValueChange callback. The icon will be treated as a toggle if the onValueChange callback is not empty. Otherwise, it will treat it as a button (for accessibility) if the onClick callback is not empty.

Use the interactionState parameter to control the trailing icon behavior when the text field is in error or focus state. You can set this parameter to FioriTextFieldInteractionState.NORMAL or FioriTextFieldInteractionState.INTERACTIVE. FioriTextFieldInteractionState.NORMAL is the default value, where the customized trailing icon will be replaced by an error icon when the text field is in error state, or, when the text field gets focus and has a non-empty text value, it will be replaced by a Clear icon button, which, when clicked, clears the entire input. With the FioriTextFieldInteractionState.INTERACTIVE value, the customized trailing icon has high priority to be displayed in the above two scenarios. See Password text field for additional information.

Special Simple Text Field

There are two special sub-types of the simple text field for password and barcode scanner scenarios.

Password Text Field

The password text field provides password visibility toggle functionality to protect any sensitive information that is required to be entered, such as a password. A visibility toggle button is displayed with the password text field, which, when clicked, toggles the text in the value field to be shown as plain text if it was disguised or, if it was in plain text, to be hidden:

val textValue = rememberSaveable { mutableStateOf("") }
FioriPasswordTextField(
    value = textValue.value,
    onValueChange = { textValue.value = it }
)

val textValue = rememberSaveable { mutableStateOf("") }
FioriPasswordTextField(
    value = textValue.value,
    onValueChange = { textValue.value = it },
    content = FioriTextFieldContent(
        label = "System Passcode",
        placeholder = "Enter your passcode"
    ),
    interactionState = FioriTextFieldInteractionState.NORMAL
)

Without the customized label, the word Password is displayed as the text field label. However, you can construct a FioriTextFieldContent object with a specified label parameter and set it as the value of the content parameter.

Also, by default, the password text field uses FioriTextFieldInteractionState.INTERACTIVE as the interactionState. However, you can set it as FioriTextFieldInteractionState.NORMAL to cause the Clear icon to be displayed when the non-empty text field gets focus. See Trailing Icon for additional information.

Password text field

By default, the password text field will use the default icon as the visibility toggle icon. Use LocalFioriTextFieldSupplier to allow you to use your own icons:

CompositionLocalProvider(LocalFioriTextFieldSupplier provides FioriTextFieldSupplier(
    passwordVisibilityTrailingIcon = FioriTextFieldIcon(
        FioriIcon(iconType = IconType.RESOURCE, resId = R.drawable.ic_view_module_black_24dp, contentDescription = "desc")
    ),
    passwordVisibilityOffTrailingIcon = FioriTextFieldIcon(
        FioriIcon(iconType = IconType.RESOURCE, resId = R.drawable.ic_view_module_black_24dp, contentDescription = "desc")
    )
)) {
    val textValue = rememberSaveable { mutableStateOf("") }
    FioriPasswordTextField(
        value = textValue.value,
        onValueChange = { textValue.value = it }
    )
}

Barcode Scanner Text Field

The barcode scanner text field supports scanning a barcode to acquire relevant information provided by the barcode as input:

val textValue = rememberSaveable { mutableStateOf("") }
FioriBarcodeScannerTextField(
    value = textValue.value,
    onValueChange = { textValue.value = it },
    content = FioriTextFieldContent(
        label = "Barcode",
        placeholder = "Scan a barcode to get a value",
        helperText = "Scan a barcode to get a value"
    )
)

When the user taps the Scan button, a scanning dialog is launched. The scanner detects the barcode and the extracted information is set as the value of the barcode scanner text field.

By default, the barcode scanner text field provides two trailing icons. Setting useAlternativeIcon to true will cause the barcode scanner text field to use the alternate trailing icon. Otherwise, the primary trailing icon is used. You can also specify your own FioriTextFieldIcon object using the trailingIcon parameter and the onClick or onValueChange callback.

The barcode scanner also supports laser scanning on special devices, such as Zebra and Honeywell devices. In these cases, the device laser scanner will be used when the user taps the Scan button and the laser scanner is available. Otherwise, the device camera is used for scanning. You can also use the camera or attach a listener to listen to the barcode result when the device's physical scan button is clicked by configuring the LocalFioriBarcodeScannerManager:

LocalFioriBarcodeScannerManager.current.alwaysUseCamera = true
LocalFioriBarcodeScannerManager.current.resultListener = { barcode ->
    if (barcode != null) {
        value = barcode
    }
}

Barcode scanner text field

Required Field

You may mark a field as a required field by setting required = true, when you construct the FioriTextFieldContent object. This adds an asterisk (*) at the end of the key, which indicates to the user that a value has to be entered. Please note, though, that this is simply a visual indicator, and you have to add your own validation to it. See Listening for Text Value Changes for additional information.

var isError by rememberSaveable { mutableStateOf(false) }
var errorMsg by rememberSaveable { mutableStateOf("") }
var textValueState by rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    content = FioriTextFieldContent(
        label = "Name",
        required = true,
        errorMessage = errorMsg
    ),
    isError = isError,
    value = textValueState,
    onValueChange = {
        textValueState = it
        isError = textValueState.isEmpty()
        errorMsg = if (isError) "Required Field" else ""
    }
)

Required Field

Prefix and Suffix

You can also add a prefix or suffix to the value using the prefixText or suffixText attributes in the FioriTextFieldContent object.

val textValue = rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    value = textValue.value,
    onValueChange = { textValue.value = it },
    content = FioriTextFieldContent(
        label = "Sample Prefix and Suffix",
        prefixText = "$",
        suffixText = "%"
    )
)

Prefix Suffix

Customization

The simple text field offers a several methods for customization using FioriTextFieldDefaults. You can use it to customize the text field's colors, text styles, height and width, etc.

For example, if you wanted to apply a special color and text font style to an individual simple text field, or you don't want start/end padding when your app is running on a phone and tablet, you can customize the text field using FioriTextFieldDefaults:

val textValue = rememberSaveable { mutableStateOf("") }
FioriSimpleTextField(
    value = textValue.value,
    onValueChange = { textValue.value = it },
    content = FioriTextFieldContent(
        label = "Customized Text Field"
    ),
    colors = FioriTextFieldDefaults.colors(
        labelColor = Color.Black,
        focusedLabelColor = Color.Green,
        readOnlyLabelColor = Color.Red,
    ),
    textStyles = FioriTextFieldDefaults.textStyles(
        labelTextStyle = MaterialTheme.typography.caption
    ),
    styles = FioriTextFieldDefaults.styles(
        startPaddingOnPhone = 0.dp,
        endPaddingOnPhone = 0.dp,
        startPaddingOnTablet = 0.dp,
        endPaddingOnTablet = 0.dp
    )
)

Last update: February 20, 2023