diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/field/BitwardenTextField.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/field/BitwardenTextField.kt index 0ee36c4e3..3aba0b91f 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/field/BitwardenTextField.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/components/field/BitwardenTextField.kt @@ -7,11 +7,14 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.KeyboardType @@ -61,10 +64,11 @@ fun BitwardenTextField( shouldAddCustomLineBreaks: Boolean = false, keyboardType: KeyboardType = KeyboardType.Text, isError: Boolean = false, + autoFocus: Boolean = false, visualTransformation: VisualTransformation = VisualTransformation.None, ) { var widthPx by remember { mutableIntStateOf(0) } - + val focusRequester = remember { FocusRequester() } val currentTextStyle = textStyle ?: LocalTextStyle.current val formattedText = if (shouldAddCustomLineBreaks) { value.withLineBreaksAtWidth( @@ -78,7 +82,8 @@ fun BitwardenTextField( OutlinedTextField( modifier = modifier - .onGloballyPositioned { widthPx = it.size.width }, + .onGloballyPositioned { widthPx = it.size.width } + .focusRequester(focusRequester), enabled = enabled, label = { Text(text = label) }, value = formattedText, @@ -113,6 +118,9 @@ fun BitwardenTextField( isError = isError, visualTransformation = visualTransformation, ) + if (autoFocus) { + LaunchedEffect(Unit) { focusRequester.requestFocus() } + } } @Preview diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/PinInputDialog.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/PinInputDialog.kt index 0e927efa7..dd473c0a4 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/PinInputDialog.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/PinInputDialog.kt @@ -108,6 +108,7 @@ fun PinInputDialog( BitwardenTextField( label = stringResource(id = R.string.pin), value = pin, + autoFocus = true, onValueChange = { pin = it }, keyboardType = KeyboardType.Number, modifier = Modifier diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt index 51b66952f..acf046832 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt @@ -2,6 +2,7 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.accountsecurity import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsFocused import androidx.compose.ui.test.assertIsOff import androidx.compose.ui.test.assertIsOn import androidx.compose.ui.test.assertTextEquals @@ -281,6 +282,7 @@ class AccountSecurityScreenTest : BaseComposeTest() { .onAllNodesWithText("PIN") .filterToOne(hasAnyAncestor(isDialog())) .assertIsDisplayed() + .assertIsFocused() composeTestRule .onAllNodesWithText("Cancel") .filterToOne(hasAnyAncestor(isDialog()))