Skip to content

Commit

Permalink
fix: bring back 'show password' button on password text input
Browse files Browse the repository at this point in the history
  • Loading branch information
saleniuk committed May 21, 2024
1 parent 4411ffb commit 5438960
Showing 1 changed file with 32 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicSecureTextField
Expand All @@ -31,14 +32,23 @@ import androidx.compose.foundation.text.input.TextObfuscationMode
import androidx.compose.foundation.text.input.maxLength
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.foundation.text.input.setTextAndPlaceCursorAtEnd
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.input.ImeAction
Expand All @@ -65,7 +75,6 @@ fun WirePasswordTextField(
state: WireTextFieldState = WireTextFieldState.Default,
autoFill: Boolean = false,
inputTransformation: InputTransformation = InputTransformation.maxLength(8000),
textObfuscationMode: TextObfuscationMode = TextObfuscationMode.RevealLastTyped,
imeAction: ImeAction = ImeAction.Default,
onImeAction: (() -> Unit)? = null,
scrollState: ScrollState = rememberScrollState(),
Expand All @@ -81,6 +90,7 @@ fun WirePasswordTextField(
testTag: String = String.EMPTY,
) {
val autoFillType = if (autoFill) WireAutoFillType.Password else WireAutoFillType.None
var passwordVisibility by remember { mutableStateOf(false) }
WireTextFieldLayout(
shouldShowPlaceholder = textState.text.isEmpty(),
placeholderText = placeholderText,
Expand All @@ -94,6 +104,7 @@ fun WirePasswordTextField(
inputMinHeight = inputMinHeight,
shape = shape,
colors = colors,
trailingIcon = { VisibilityIconButton(passwordVisibility) { passwordVisibility = it } },
modifier = modifier.autoFill(autoFillType, textState::setTextAndPlaceCursorAtEnd),
testTag = testTag,
onTap = onTap,
Expand All @@ -104,7 +115,7 @@ fun WirePasswordTextField(
imeAction = imeAction,
onSubmit = { onImeAction?.invoke().let { onImeAction != null } },
inputTransformation = inputTransformation,
textObfuscationMode = textObfuscationMode,
textObfuscationMode = if (passwordVisibility) TextObfuscationMode.Visible else TextObfuscationMode.RevealLastTyped,
scrollState = scrollState,
enabled = state !is WireTextFieldState.Disabled,
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
Expand Down Expand Up @@ -150,6 +161,7 @@ fun WirePasswordTextField(
) {
val textState = remember { TextFieldState(value.text, value.selection) }
val autoFillType = if (autofill) WireAutoFillType.Password else WireAutoFillType.None
var passwordVisibility by remember { mutableStateOf(false) }
WireTextFieldLayout(
shouldShowPlaceholder = textState.text.isEmpty(),
placeholderText = placeholderText,
Expand All @@ -163,6 +175,7 @@ fun WirePasswordTextField(
inputMinHeight = inputMinHeight,
shape = shape,
colors = colors,
trailingIcon = { VisibilityIconButton(passwordVisibility) { passwordVisibility = it } },
modifier = modifier.autoFill(autoFillType, textState::setTextAndPlaceCursorAtEnd),
testTag = testTag,
onTap = onTap,
Expand All @@ -173,6 +186,7 @@ fun WirePasswordTextField(
imeAction = imeAction,
onSubmit = { onImeAction?.invoke().let { onImeAction != null } },
inputTransformation = InputTransformation.maxLength(maxTextLength),
textObfuscationMode = if (passwordVisibility) TextObfuscationMode.Visible else TextObfuscationMode.RevealLastTyped,
scrollState = scrollState,
enabled = state !is WireTextFieldState.Disabled,
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
Expand All @@ -184,6 +198,22 @@ fun WirePasswordTextField(
)
}

@Composable
private fun VisibilityIconButton(isVisible: Boolean, onVisibleChange: (Boolean) -> Unit) {
IconButton(onClick = { onVisibleChange(!isVisible) }) {
Icon(
imageVector = if (isVisible) Icons.Filled.Visibility else Icons.Filled.VisibilityOff,
contentDescription = stringResource(
if (isVisible) R.string.content_description_hide_password
else R.string.content_description_reveal_password
),
modifier = Modifier
.size(20.dp)
.testTag("hidePassword")
)
}
}

@OptIn(ExperimentalFoundationApi::class)
@PreviewMultipleThemes
@Composable
Expand Down

0 comments on commit 5438960

Please sign in to comment.