diff --git a/native/account/registration/password-selection.react.js b/native/account/registration/password-selection.react.js
--- a/native/account/registration/password-selection.react.js
+++ b/native/account/registration/password-selection.react.js
@@ -14,6 +14,7 @@
import type { CoolOrNerdMode } from './registration-types.js';
import type { NavigationRoute } from '../../navigation/route-names.js';
import { useStyles } from '../../themes/colors.js';
+import type { KeyPressEvent } from '../../types/react-native.js';
export type PasswordSelectionParams = {
+userSelections: {
@@ -77,8 +78,52 @@
confirmPasswordInputRef.current?.focus();
}, []);
- /* eslint-disable react-hooks/rules-of-hooks */
+ const iosPasswordBeingAutoFilled = React.useRef(false);
+ const confirmPasswordEmpty = confirmPassword.length === 0;
+ const onPasswordKeyPress = React.useCallback(
+ (event: KeyPressEvent) => {
+ const { key } = event.nativeEvent;
+ // On iOS, paste doesn't trigger onKeyPress, but password autofill does
+ // Password autofill calls onKeyPress with `key` set to the whole password
+ if (
+ key.length > 1 &&
+ key !== 'Backspace' &&
+ key !== 'Enter' &&
+ confirmPasswordEmpty
+ ) {
+ iosPasswordBeingAutoFilled.current = true;
+ }
+ },
+ [confirmPasswordEmpty],
+ );
+
const passwordInputRef = React.useRef();
+ const passwordLength = password.length;
+ const onChangePasswordInput = React.useCallback(
+ (input: string) => {
+ setPassword(input);
+ if (iosPasswordBeingAutoFilled.current) {
+ // On iOS, paste doesn't trigger onKeyPress, but password autofill does
+ iosPasswordBeingAutoFilled.current = false;
+ setConfirmPassword(input);
+ passwordInputRef.current?.blur();
+ } else if (
+ Platform.OS === 'android' &&
+ input.length - passwordLength > 1 &&
+ confirmPasswordEmpty
+ ) {
+ // On Android, password autofill doesn't trigger onKeyPress. Instead we
+ // rely on observing when the password field changes by more than one
+ // character at a time. This means we treat paste the same way as
+ // password autofill
+ setConfirmPassword(input);
+ passwordInputRef.current?.blur();
+ }
+ },
+ [passwordLength, confirmPasswordEmpty],
+ );
+
+ /* eslint-disable react-hooks/rules-of-hooks */
if (Platform.OS === 'android') {
// It's okay to call this hook conditionally because
// the condition is guaranteed to never change
@@ -97,7 +142,7 @@
Pick a password