| /* |
| * Copyright 2020 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package androidx.compose.foundation.text |
| |
| import androidx.compose.foundation.Interaction |
| import androidx.compose.foundation.InteractionState |
| import androidx.compose.runtime.Composable |
| import androidx.compose.runtime.getValue |
| import androidx.compose.runtime.mutableStateOf |
| import androidx.compose.runtime.remember |
| import androidx.compose.runtime.setValue |
| import androidx.compose.ui.Modifier |
| import androidx.compose.ui.graphics.Brush |
| import androidx.compose.ui.graphics.Color |
| import androidx.compose.ui.graphics.SolidColor |
| import androidx.compose.ui.text.SoftwareKeyboardController |
| import androidx.compose.ui.text.TextLayoutResult |
| import androidx.compose.ui.text.TextStyle |
| import androidx.compose.ui.text.input.ImeAction |
| import androidx.compose.ui.text.input.KeyboardType |
| import androidx.compose.ui.text.input.TextFieldValue |
| import androidx.compose.ui.text.input.VisualTransformation |
| |
| /** |
| * Basic composable that enables users to edit text via hardware or software keyboard, but |
| * provides no decorations like hint or placeholder. |
| * |
| * Whenever the user edits the text, [onValueChange] is called with the most up to date state |
| * represented by [String] with which developer is expected to update their state. |
| * |
| * Unlike [TextFieldValue] overload, this composable does not let the developer to control |
| * selection, cursor and text composition information. Please check [TextFieldValue] and |
| * corresponding [BasicTextField] overload for more information. |
| * |
| * It is crucial that the value provided in the [onValueChange] is fed back into [BasicTextField] in |
| * order to have the final state of the text being displayed. |
| * |
| * Example usage: |
| * @sample androidx.compose.foundation.samples.BasicTextFieldWithStringSample |
| * |
| * Please keep in mind that [onValueChange] is useful to be informed about the latest state of the |
| * text input by users, however it is generally not recommended to modify the value that you get |
| * via [onValueChange] callback. Any change to this value may result in a context reset and end |
| * up with input session restart. Such a scenario would cause glitches in the UI or text input |
| * experience for users. |
| * |
| * This composable provides basic text editing functionality, however does not include any |
| * decorations such as borders, hints/placeholder. A design system based implementation such as |
| * Material Design Filled text field is typically what is needed to cover most of the needs. This |
| * composable is designed to be used when a custom implementation for different design system is |
| * needed. |
| * |
| * For example, if you need to include a placeholder in your TextField, you can write a composable |
| * using the decoration box like this: |
| * @sample androidx.compose.foundation.samples.PlaceholderBasicTextFieldSample |
| * |
| * If you want to add decorations to your text field, such as icon or similar, and increase the |
| * hit target area, use the decoration box: |
| * @sample androidx.compose.foundation.samples.TextFieldWithIconSample |
| * |
| * @param value the input [String] text to be shown in the text field |
| * @param onValueChange the callback that is triggered when the input service updates the text. An |
| * updated text comes as a parameter of the callback |
| * @param modifier optional [Modifier] for this text field. |
| * @param enabled controls the enabled state of the [BasicTextField]. When `false`, the text |
| * field will be neither editable nor focusable, the input of the text field will not be selectable |
| * @param readOnly controls the editable state of the [BasicTextField]. When `true`, the text |
| * field can not be modified, however, a user can focus it and copy text from it. Read-only text |
| * fields are usually used to display pre-filled forms that user can not edit |
| * @param textStyle Style configuration that applies at character level such as color, font etc. |
| * @param keyboardOptions software keyboard options that contains configuration such as |
| * [KeyboardType] and [ImeAction]. |
| * @param keyboardActions when the input service emits an IME action, the corresponding callback |
| * is called. Note that this IME action may be different from what you specified in |
| * [KeyboardOptions.imeAction]. |
| * @param singleLine when set to true, this text field becomes a single horizontally scrolling |
| * text field instead of wrapping onto multiple lines. The keyboard will be informed to not show |
| * the return key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the |
| * maxLines attribute will be automatically set to 1. |
| * @param maxLines the maximum height in terms of maximum number of visible lines. Should be |
| * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be |
| * set to 1 if [singleLine] is set to true. |
| * @param visualTransformation The visual transformation filter for changing the visual |
| * representation of the input. By default no visual transformation is applied. |
| * @param onTextLayout Callback that is executed when a new text layout is calculated. |
| * @param onTextInputStarted Callback that is executed when the initialization has done for |
| * communicating with platform text input service, e.g. software keyboard on Android. Called with |
| * [SoftwareKeyboardController] instance which can be used for requesting input show/hide software |
| * keyboard. |
| * @param interactionState the [InteractionState] representing the different [Interaction]s |
| * present on this TextField. You can create and pass in your own remembered [InteractionState] |
| * if you want to read the [InteractionState] and customize the appearance / behavior of this |
| * TextField in different [Interaction]s. |
| * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified] |
| * provided, there will be no cursor drawn |
| * @param decorationBox Composable lambda that allows to add decorations around text field, such |
| * as icon, placeholder, helper messages or similar, and automatically increase the hit target area |
| * of the text field. To allow you to control the placement of the inner text field relative to your |
| * decorations, the text field implementation will pass in a framework-controlled composable |
| * parameter "innerTextField" to the decorationBox lambda you provide. You must call |
| * innerTextField exactly once. |
| */ |
| @Composable |
| fun BasicTextField( |
| value: String, |
| onValueChange: (String) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| readOnly: Boolean = false, |
| textStyle: TextStyle = TextStyle.Default, |
| keyboardOptions: KeyboardOptions = KeyboardOptions.Default, |
| keyboardActions: KeyboardActions = KeyboardActions.Default, |
| singleLine: Boolean = false, |
| maxLines: Int = Int.MAX_VALUE, |
| visualTransformation: VisualTransformation = VisualTransformation.None, |
| onTextLayout: (TextLayoutResult) -> Unit = {}, |
| onTextInputStarted: (SoftwareKeyboardController) -> Unit = {}, |
| interactionState: InteractionState = remember { InteractionState() }, |
| cursorBrush: Brush = SolidColor(Color.Black), |
| decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit = |
| @Composable { innerTextField -> innerTextField() } |
| ) { |
| var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value)) } |
| val textFieldValue = textFieldValueState.copy(text = value) |
| |
| BasicTextField( |
| value = textFieldValue, |
| onValueChange = { |
| textFieldValueState = it |
| if (value != it.text) { |
| onValueChange(it.text) |
| } |
| }, |
| modifier = modifier, |
| enabled = enabled, |
| readOnly = readOnly, |
| textStyle = textStyle, |
| keyboardOptions = keyboardOptions, |
| keyboardActions = keyboardActions, |
| maxLines = maxLines, |
| visualTransformation = visualTransformation, |
| onTextLayout = onTextLayout, |
| onTextInputStarted = onTextInputStarted, |
| cursorBrush = cursorBrush, |
| interactionState = interactionState, |
| singleLine = singleLine, |
| decorationBox = decorationBox |
| ) |
| } |
| |
| /** |
| * Basic composable that enables users to edit text via hardware or software keyboard, but |
| * provides no decorations like hint or placeholder. |
| * |
| * Whenever the user edits the text, [onValueChange] is called with the most up to date state |
| * represented by [TextFieldValue]. [TextFieldValue] contains the text entered by user, as well |
| * as selection, cursor and text composition information. Please check [TextFieldValue] for the |
| * description of its contents. |
| * |
| * It is crucial that the value provided in the [onValueChange] is fed back into [BasicTextField] in |
| * order to have the final state of the text being displayed. |
| * |
| * Example usage: |
| * @sample androidx.compose.foundation.samples.BasicTextFieldSample |
| * |
| * Please keep in mind that [onValueChange] is useful to be informed about the latest state of the |
| * text input by users, however it is generally not recommended to modify the values in the |
| * [TextFieldValue] that you get via [onValueChange] callback. Any change to the values in |
| * [TextFieldValue] may result in a context reset and end up with input session restart. Such |
| * a scenario would cause glitches in the UI or text input experience for users. |
| * |
| * This composable provides basic text editing functionality, however does not include any |
| * decorations such as borders, hints/placeholder. A design system based implementation such as |
| * Material Design Filled text field is typically what is needed to cover most of the needs. This |
| * composable is designed to be used when a custom implementation for different design system is |
| * needed. |
| * |
| * For example, if you need to include a placeholder in your TextField, you can write a composable |
| * using the decoration box like this: |
| * @sample androidx.compose.foundation.samples.PlaceholderBasicTextFieldSample |
| * |
| * |
| * If you want to add decorations to your text field, such as icon or similar, and increase the |
| * hit target area, use the decoration box: |
| * @sample androidx.compose.foundation.samples.TextFieldWithIconSample |
| * |
| * @param value The [androidx.compose.ui.text.input.TextFieldValue] to be shown in the |
| * [BasicTextField]. |
| * @param onValueChange Called when the input service updates the values in [TextFieldValue]. |
| * @param modifier optional [Modifier] for this text field. |
| * @param enabled controls the enabled state of the [BasicTextField]. When `false`, the text |
| * field will be neither editable nor focusable, the input of the text field will not be selectable |
| * @param readOnly controls the editable state of the [BasicTextField]. When `true`, the text |
| * field can not be modified, however, a user can focus it and copy text from it. Read-only text |
| * fields are usually used to display pre-filled forms that user can not edit |
| * @param textStyle Style configuration that applies at character level such as color, font etc. |
| * @param keyboardOptions software keyboard options that contains configuration such as |
| * [KeyboardType] and [ImeAction]. |
| * @param keyboardActions when the input service emits an IME action, the corresponding callback |
| * is called. Note that this IME action may be different from what you specified in |
| * [KeyboardOptions.imeAction]. |
| * @param singleLine when set to true, this text field becomes a single horizontally scrolling |
| * text field instead of wrapping onto multiple lines. The keyboard will be informed to not show |
| * the return key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the |
| * maxLines attribute will be automatically set to 1. |
| * @param maxLines the maximum height in terms of maximum number of visible lines. Should be |
| * equal or greater than 1. Note that this parameter will be ignored and instead maxLines will be |
| * set to 1 if [singleLine] is set to true. |
| * @param visualTransformation The visual transformation filter for changing the visual |
| * representation of the input. By default no visual transformation is applied. |
| * @param onTextLayout Callback that is executed when a new text layout is calculated. |
| * @param onTextInputStarted Callback that is executed when the initialization has done for |
| * communicating with platform text input service, e.g. software keyboard on Android. Called with |
| * [SoftwareKeyboardController] instance which can be used for requesting input show/hide software |
| * keyboard. |
| * @param interactionState The [InteractionState] representing the different [Interaction]s |
| * present on this TextField. You can create and pass in your own remembered [InteractionState] |
| * if you want to read the [InteractionState] and customize the appearance / behavior of this |
| * TextField in different [Interaction]s. |
| * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified] |
| * provided, there will be no cursor drawn |
| * @param decorationBox Composable lambda that allows to add decorations around text field, such |
| * as icon, placeholder, helper messages or similar, and automatically increase the hit target area |
| * of the text field. To allow you to control the placement of the inner text field relative to your |
| * decorations, the text field implementation will pass in a framework-controlled composable |
| * parameter "innerTextField" to the decorationBox lambda you provide. You must call |
| * innerTextField exactly once. |
| */ |
| @Composable |
| fun BasicTextField( |
| value: TextFieldValue, |
| onValueChange: (TextFieldValue) -> Unit, |
| modifier: Modifier = Modifier, |
| enabled: Boolean = true, |
| readOnly: Boolean = false, |
| textStyle: TextStyle = TextStyle.Default, |
| keyboardOptions: KeyboardOptions = KeyboardOptions.Default, |
| keyboardActions: KeyboardActions = KeyboardActions.Default, |
| singleLine: Boolean = false, |
| maxLines: Int = Int.MAX_VALUE, |
| visualTransformation: VisualTransformation = VisualTransformation.None, |
| onTextLayout: (TextLayoutResult) -> Unit = {}, |
| onTextInputStarted: (SoftwareKeyboardController) -> Unit = {}, |
| interactionState: InteractionState = remember { InteractionState() }, |
| cursorBrush: Brush = SolidColor(Color.Black), |
| decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit = |
| @Composable { innerTextField -> innerTextField() } |
| ) { |
| CoreTextField( |
| value = value, |
| onValueChange = onValueChange, |
| modifier = modifier, |
| textStyle = textStyle, |
| visualTransformation = visualTransformation, |
| onTextLayout = onTextLayout, |
| interactionState = interactionState, |
| onTextInputStarted = onTextInputStarted, |
| cursorBrush = cursorBrush, |
| imeOptions = keyboardOptions.toImeOptions(singleLine = singleLine), |
| keyboardActions = keyboardActions, |
| softWrap = !singleLine, |
| maxLines = if (singleLine) 1 else maxLines, |
| decorationBox = decorationBox, |
| enabled = enabled, |
| readOnly = readOnly |
| ) |
| } |