From 27bf79ee8a0fa303cb5272314f73f111f114f1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Scott=20Rayapoull=C3=A9?= Date: Tue, 22 Aug 2023 15:14:55 +0200 Subject: [PATCH] fix: Make the readonly Textfields not take the focus looked when focused --- .../textfields/DefaultSparkTextFieldColors.kt | 14 ++++++++------ .../components/textfields/SparkTextField.kt | 19 +++++++++++++------ .../textfields/SparkTextFieldImpl.kt | 15 ++++++++------- 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/DefaultSparkTextFieldColors.kt b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/DefaultSparkTextFieldColors.kt index d8ab764e7..76c22ad04 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/DefaultSparkTextFieldColors.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/DefaultSparkTextFieldColors.kt @@ -130,7 +130,7 @@ internal data class DefaultSparkTextFieldColors( * Represents the color used for the leading icon of this text field. * * @param enabled whether the text field is enabled - * @param isError whether the text field's current value is in error + * @param state whether the text field's current value is in error, success or alert * @param interactionSource the [InteractionSource] of this text field. Helps to determine if * the text field is in focus or not */ @@ -156,7 +156,7 @@ internal data class DefaultSparkTextFieldColors( * Represents the color used for the trailing icon of this text field. * * @param enabled whether the text field is enabled - * @param isError whether the text field's current value is in error + * @param state whether the text field's current value is in error, success or alert * @param interactionSource the [InteractionSource] of this text field. Helps to determine if * the text field is in focus or not */ @@ -182,13 +182,15 @@ internal data class DefaultSparkTextFieldColors( * Represents the color used for the border indicator of this text field. * * @param enabled whether the text field is enabled - * @param isError whether the text field's current value is in error + * @param readOnly whether the text field's value can't be edited + * @param state whether the text field's current value is in error, success or alert * @param interactionSource the [InteractionSource] of this text field. Helps to determine if * the text field is in focus or not */ @Composable internal fun indicatorColor( enabled: Boolean, + readOnly: Boolean, state: TextFieldState?, interactionSource: InteractionSource, ): State { @@ -197,7 +199,7 @@ internal data class DefaultSparkTextFieldColors( val targetValue = when { !enabled -> disabledIndicatorColor state != null -> state.color() - focused -> focusedIndicatorColor + focused && !readOnly -> focusedIndicatorColor else -> unfocusedIndicatorColor } return if (enabled) { @@ -233,7 +235,7 @@ internal data class DefaultSparkTextFieldColors( * Represents the color used for the label of this text field. * * @param enabled whether the text field is enabled - * @param isError whether the text field's current value is in error + * @param state whether the text field's current value is in error, success or alert * @param interactionSource the [InteractionSource] of this text field. Helps to determine if * the text field is in focus or not */ @@ -280,7 +282,7 @@ internal data class DefaultSparkTextFieldColors( /** * Represents the color used for the cursor of this text field. * - * @param isError whether the text field's current value is in error + * @param state whether the text field's current value is in error, success or alert */ @Composable internal fun cursorColor(state: TextFieldState?): State { diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextField.kt b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextField.kt index fe0502db0..15c1f54c0 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextField.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextField.kt @@ -157,6 +157,7 @@ internal fun SparkTextField( label = { Label(text = label, required = required) }, interactionSource = interactionSource, colors = colors, + readOnly = readOnly, placeholder = { PlaceHolder(text = placeholder) }, supportingText = supportingTextComposable, counter = counterComposable, @@ -168,6 +169,7 @@ internal fun SparkTextField( ) { OutlinedBorderContainerBox( enabled, + readOnly, state, interactionSource, colors, @@ -255,6 +257,7 @@ internal fun SparkTextField( label = { Label(text = label, required = required) }, interactionSource = interactionSource, colors = colors, + readOnly = readOnly, placeholder = { PlaceHolder(text = placeholder) }, supportingText = supportingTextComposable, counter = counterComposable, @@ -266,6 +269,7 @@ internal fun SparkTextField( ) { OutlinedBorderContainerBox( enabled, + readOnly, state, interactionSource, colors, @@ -283,7 +287,8 @@ internal fun SparkTextField( * [OutlinedBorderContainerBox]. The [SparkTextField] applies it automatically. * * @param enabled whether the text field is enabled - * @param isError whether the text field's current value is in error + * @param readOnly whether the text field's value can't be edited + * @param state whether the text field's current value is in error, success or alert * @param interactionSource the [InteractionSource] of this text field. Helps to determine if * the text field is in focus or not * @param colors [TextFieldColors] used to resolve colors of the text field @@ -292,6 +297,7 @@ internal fun SparkTextField( @Composable private fun OutlinedBorderContainerBox( enabled: Boolean, + readOnly: Boolean, state: TextFieldState?, interactionSource: InteractionSource, colors: DefaultSparkTextFieldColors, @@ -299,6 +305,7 @@ private fun OutlinedBorderContainerBox( val shape = if (LocalLegacyStyle.current) SparkTheme.shapes.extraSmall else SparkTheme.shapes.large val borderStroke = animateBorderStrokeAsState( enabled, + readOnly, state, interactionSource, colors, @@ -310,23 +317,23 @@ private fun OutlinedBorderContainerBox( ) } -@OptIn(ExperimentalMaterial3Api::class) @Composable private fun animateBorderStrokeAsState( enabled: Boolean, + readOnly: Boolean, state: TextFieldState?, interactionSource: InteractionSource, colors: DefaultSparkTextFieldColors, ): State { val focused by interactionSource.collectIsFocusedAsState() - val indicatorColor = colors.indicatorColor(enabled, state, interactionSource) - val targetThickness = if (focused || state != null) { + val indicatorColor = colors.indicatorColor(enabled, readOnly, state, interactionSource) + val targetThickness = if ((focused || state != null) && !readOnly) { OutlinedTextFieldDefaults.FocusedBorderThickness } else { OutlinedTextFieldDefaults.UnfocusedBorderThickness } - val animatedThickness = if (enabled) { - animateDpAsState(targetThickness, tween(durationMillis = 150)) + val animatedThickness = if (enabled && !readOnly) { + animateDpAsState(targetThickness, tween(durationMillis = 150), label = "borderThickness") } else { rememberUpdatedState(OutlinedTextFieldDefaults.UnfocusedBorderThickness) } diff --git a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextFieldImpl.kt b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextFieldImpl.kt index 2aed0fdd3..fb469456d 100644 --- a/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextFieldImpl.kt +++ b/spark/src/main/kotlin/com/adevinta/spark/components/textfields/SparkTextFieldImpl.kt @@ -36,7 +36,6 @@ import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.paddingFromBaseline -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.LocalContentColor import androidx.compose.material3.OutlinedTextFieldDefaults import androidx.compose.material3.ProvideTextStyle @@ -74,7 +73,6 @@ import com.adevinta.spark.SparkTheme /** * Implementation of the [TextField] */ -@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun SparkDecorationBox( value: String, @@ -83,6 +81,7 @@ internal fun SparkDecorationBox( label: @Composable (() -> Unit)?, interactionSource: InteractionSource, colors: DefaultSparkTextFieldColors, + readOnly: Boolean, placeholder: @Composable (() -> Unit)? = null, supportingText: @Composable (() -> Unit)? = null, counter: @Composable (() -> Unit)? = null, @@ -106,7 +105,7 @@ internal fun SparkDecorationBox( val isFocused = interactionSource.collectIsFocusedAsState().value val inputState = when { - isFocused -> InputPhase.Focused + isFocused && !readOnly -> InputPhase.Focused transformedText.isEmpty() -> InputPhase.UnfocusedEmpty else -> InputPhase.UnfocusedNotEmpty } @@ -258,11 +257,13 @@ internal fun Decoration( contentColor: Color, typography: TextStyle? = null, content: @Composable - @ComposableOpenTarget(index = 0) () -> Unit, // ktlint-disable annotation + @ComposableOpenTarget(index = 0) + () -> Unit, ) { - val colorAndEmphasis: @Composable () -> Unit = @Composable { - CompositionLocalProvider(LocalContentColor provides contentColor, content = content) - } + val colorAndEmphasis: @Composable () -> Unit = + @Composable { + CompositionLocalProvider(LocalContentColor provides contentColor, content = content) + } if (typography != null) ProvideTextStyle(typography, colorAndEmphasis) else colorAndEmphasis() }