Skip to content

Commit 10fbf03

Browse files
authored
Merge pull request #59087 from margelo/chore/remove-should-delay-focus-prop-from-native-input
chore: remove shouldDelayFocus prop from text input
2 parents 5207012 + db085ce commit 10fbf03

File tree

16 files changed

+42
-103
lines changed

16 files changed

+42
-103
lines changed

src/components/MagicCodeInput.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import {Gesture, GestureDetector} from 'react-native-gesture-handler';
66
import useNetwork from '@hooks/useNetwork';
77
import useStyleUtils from '@hooks/useStyleUtils';
88
import useThemeStyles from '@hooks/useThemeStyles';
9-
import * as Browser from '@libs/Browser';
10-
import * as ValidationUtils from '@libs/ValidationUtils';
9+
import {isMobileChrome, isMobileSafari} from '@libs/Browser';
10+
import {isNumeric} from '@libs/ValidationUtils';
1111
import CONST from '@src/CONST';
1212
import FormHelpMessage from './FormHelpMessage';
1313
import Text from './Text';
@@ -28,9 +28,6 @@ type MagicCodeInputProps = {
2828
/** Should the input auto focus */
2929
autoFocus?: boolean;
3030

31-
/** Whether we should wait before focusing the TextInput, useful when using transitions */
32-
shouldDelayFocus?: boolean;
33-
3431
/** Error text to display */
3532
errorText?: string;
3633

@@ -78,7 +75,7 @@ const decomposeString = (value: string, length: number): string[] => {
7875
let arr = value
7976
.split('')
8077
.slice(0, length)
81-
.map((v) => (ValidationUtils.isNumeric(v) ? v : CONST.MAGIC_CODE_EMPTY_CHAR));
78+
.map((v) => (isNumeric(v) ? v : CONST.MAGIC_CODE_EMPTY_CHAR));
8279
if (arr.length < length) {
8380
arr = arr.concat(Array(length - arr.length).fill(CONST.MAGIC_CODE_EMPTY_CHAR));
8481
}
@@ -98,7 +95,6 @@ function MagicCodeInput(
9895
value = '',
9996
name = '',
10097
autoFocus = true,
101-
shouldDelayFocus = false,
10298
errorText = '',
10399
shouldSubmitOnComplete = true,
104100
onChangeText: onChangeTextProp = () => {},
@@ -179,7 +175,7 @@ function MagicCodeInput(
179175
const validateAndSubmit = () => {
180176
const numbers = decomposeString(value, maxLength);
181177
// eslint-disable-next-line @typescript-eslint/no-use-before-define
182-
if (wasSubmitted || !shouldSubmitOnComplete || numbers.filter((n) => ValidationUtils.isNumeric(n)).length !== maxLength || isOffline) {
178+
if (wasSubmitted || !shouldSubmitOnComplete || numbers.filter((n) => isNumeric(n)).length !== maxLength || isOffline) {
183179
return;
184180
}
185181
if (!wasSubmitted) {
@@ -226,7 +222,7 @@ function MagicCodeInput(
226222
shouldFocusLast.current = false;
227223
// TapGestureHandler works differently on mobile web and native app
228224
// On web gesture handler doesn't block interactions with textInput below so there is no need to run `focus()` manually
229-
if (!Browser.isMobileChrome() && !Browser.isMobileSafari()) {
225+
if (!isMobileChrome() && !isMobileSafari()) {
230226
inputRef.current?.focus();
231227
}
232228
setInputAndIndex(index);
@@ -247,7 +243,7 @@ function MagicCodeInput(
247243
* might happen later than the next call to onChangeText).
248244
*/
249245
const onChangeText = (textValue?: string) => {
250-
if (!textValue?.length || !ValidationUtils.isNumeric(textValue)) {
246+
if (!textValue?.length || !isNumeric(textValue)) {
251247
return;
252248
}
253249

@@ -313,7 +309,7 @@ function MagicCodeInput(
313309
return;
314310
}
315311

316-
const hasInputs = numbers.filter((n) => ValidationUtils.isNumeric(n)).length !== 0;
312+
const hasInputs = numbers.filter((n) => isNumeric(n)).length !== 0;
317313

318314
// Fill the array with empty characters if there are no inputs.
319315
if (focusedIndex === 0 && !hasInputs) {
@@ -408,7 +404,6 @@ function MagicCodeInput(
408404
value={input}
409405
hideFocusedState
410406
autoComplete={input.length === 0 ? autoComplete : undefined}
411-
shouldDelayFocus={input.length === 0 && shouldDelayFocus}
412407
keyboardType={CONST.KEYBOARD_TYPE.NUMBER_PAD}
413408
onChangeText={onChangeText}
414409
onKeyPress={onKeyPress}

src/components/PDFView/PDFPasswordForm.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types';
88
import useLocalize from '@hooks/useLocalize';
99
import useResponsiveLayout from '@hooks/useResponsiveLayout';
1010
import useThemeStyles from '@hooks/useThemeStyles';
11-
import * as Browser from '@libs/Browser';
12-
import shouldDelayFocus from '@libs/shouldDelayFocus';
11+
import {getBrowser} from '@libs/Browser';
1312
import CONST from '@src/CONST';
1413
import type {TranslationPaths} from '@src/languages/types';
1514
import PDFInfoMessage from './PDFInfoMessage';
@@ -121,7 +120,7 @@ function PDFPasswordForm({isFocused, isPasswordInvalid = false, shouldShowLoadin
121120
* This is a workaround to bypass Safari's autofill odd behaviour.
122121
* This tricks the browser not to fill the username somewhere else and still fill the password correctly.
123122
*/
124-
autoComplete={Browser.getBrowser() === CONST.BROWSER.SAFARI ? 'username' : 'off'}
123+
autoComplete={getBrowser() === CONST.BROWSER.SAFARI ? 'username' : 'off'}
125124
autoCorrect={false}
126125
textContentType="password"
127126
onChangeText={updatePassword}
@@ -131,7 +130,6 @@ function PDFPasswordForm({isFocused, isPasswordInvalid = false, shouldShowLoadin
131130
onFocus={() => onPasswordFieldFocused?.(true)}
132131
onBlur={() => onPasswordFieldFocused?.(false)}
133132
autoFocus
134-
shouldDelayFocus={shouldDelayFocus}
135133
secureTextEntry
136134
/>
137135
<Button

src/components/RoomNameInput/index.native.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ import {modifyRoomName} from '@libs/RoomNameInputUtils';
99
import CONST from '@src/CONST';
1010
import type RoomNameInputProps from './types';
1111

12-
function RoomNameInput(
13-
{disabled = false, autoFocus = false, shouldDelayFocus = false, isFocused, value, onBlur, onChangeText, onInputChange, ...props}: RoomNameInputProps,
14-
ref: ForwardedRef<BaseTextInputRef>,
15-
) {
12+
function RoomNameInput({disabled = false, autoFocus = false, isFocused, value, onBlur, onChangeText, onInputChange, ...props}: RoomNameInputProps, ref: ForwardedRef<BaseTextInputRef>) {
1613
const {translate} = useLocalize();
1714

1815
/**
@@ -45,7 +42,6 @@ function RoomNameInput(
4542
value={value?.substring(1)} // Since the room name always starts with a prefix, we omit the first character to avoid displaying it twice.
4643
onBlur={(event) => isFocused && onBlur?.(event)}
4744
autoFocus={isFocused && autoFocus}
48-
shouldDelayFocus={shouldDelayFocus}
4945
autoCapitalize="none"
5046
onChange={setModifiedRoomName}
5147
keyboardType={keyboardType} // this is a bit hacky solution to a RN issue https://github.com/facebook/react-native/issues/27449

src/components/RoomNameInput/index.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ import type {BaseTextInputRef} from '@src/components/TextInput/BaseTextInput/typ
99
import CONST from '@src/CONST';
1010
import type RoomNameInputProps from './types';
1111

12-
function RoomNameInput(
13-
{disabled = false, autoFocus = false, shouldDelayFocus = false, isFocused, value = '', onBlur, onChangeText, onInputChange, ...props}: RoomNameInputProps,
14-
ref: ForwardedRef<BaseTextInputRef>,
15-
) {
12+
function RoomNameInput({disabled = false, autoFocus = false, isFocused, value = '', onBlur, onChangeText, onInputChange, ...props}: RoomNameInputProps, ref: ForwardedRef<BaseTextInputRef>) {
1613
const {translate} = useLocalize();
1714
const [selection, setSelection] = useState<Selection>({start: value.length - 1, end: value.length - 1});
1815

@@ -57,7 +54,6 @@ function RoomNameInput(
5754
value={value?.substring(1)} // Since the room name always starts with a prefix, we omit the first character to avoid displaying it twice.
5855
onBlur={(event) => isFocused && onBlur?.(event)}
5956
autoFocus={isFocused && autoFocus}
60-
shouldDelayFocus={shouldDelayFocus}
6157
autoCapitalize="none"
6258
onChange={setModifiedRoomName}
6359
onSelectionChange={(event) => setSelection(event.nativeEvent.selection)}

src/components/RoomNameInput/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ type RoomNameInputProps = {
1111
inputID?: string;
1212
onBlur?: (event: NativeSyntheticEvent<TextInputFocusEventData>) => void;
1313
autoFocus?: boolean;
14-
shouldDelayFocus?: boolean;
1514
isFocused: boolean;
1615
};
1716

src/components/Search/SearchAutocompleteInput.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import useThemeStyles from '@hooks/useThemeStyles';
2020
import {parseFSAttributes} from '@libs/Fullstory';
2121
import runOnLiveMarkdownRuntime from '@libs/runOnLiveMarkdownRuntime';
2222
import {getAutocompleteCategories, getAutocompleteTags, parseForLiveMarkdown} from '@libs/SearchAutocompleteUtils';
23-
import shouldDelayFocus from '@libs/shouldDelayFocus';
2423
import variables from '@styles/variables';
2524
import CONST from '@src/CONST';
2625
import ONYXKEYS from '@src/ONYXKEYS';
@@ -107,23 +106,23 @@ function SearchAutocompleteInput(
107106
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
108107
const {shouldUseNarrowLayout} = useResponsiveLayout();
109108

110-
const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST);
109+
const [currencyList] = useOnyx(ONYXKEYS.CURRENCY_LIST, {canBeMissing: false});
111110
const currencyAutocompleteList = Object.keys(currencyList ?? {}).filter((currencyCode) => !currencyList?.[currencyCode]?.retired);
112111
const currencySharedValue = useSharedValue(currencyAutocompleteList);
113112

114-
const [allPolicyCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_CATEGORIES);
113+
const [allPolicyCategories] = useOnyx(ONYXKEYS.COLLECTION.POLICY_CATEGORIES, {canBeMissing: false});
115114
const categoryAutocompleteList = useMemo(() => {
116115
return getAutocompleteCategories(allPolicyCategories, activeWorkspaceID);
117116
}, [activeWorkspaceID, allPolicyCategories]);
118117
const categorySharedValue = useSharedValue(categoryAutocompleteList);
119118

120-
const [allPoliciesTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS);
119+
const [allPoliciesTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS, {canBeMissing: false});
121120
const tagAutocompleteList = useMemo(() => {
122121
return getAutocompleteTags(allPoliciesTags, activeWorkspaceID);
123122
}, [activeWorkspaceID, allPoliciesTags]);
124123
const tagSharedValue = useSharedValue(tagAutocompleteList);
125124

126-
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST);
125+
const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST, {canBeMissing: false});
127126
const emailList = Object.keys(loginList ?? {});
128127
const emailListSharedValue = useSharedValue(emailList);
129128

@@ -209,7 +208,6 @@ function SearchAutocompleteInput(
209208
value={localValue}
210209
onChangeText={handleChangeText}
211210
autoFocus={autoFocus}
212-
shouldDelayFocus={shouldDelayFocus}
213211
caretHidden={caretHidden}
214212
loadingSpinnerStyle={[styles.mt0, styles.mr2]}
215213
role={CONST.ROLE.PRESENTATION}

src/components/TextInput/BaseTextInput/implementation/index.native.tsx

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ function BaseTextInput(
4646
containerStyles,
4747
inputStyle,
4848
forceActiveLabel = false,
49-
autoFocus = false,
5049
disableKeyboard = false,
5150
autoGrow = false,
5251
autoGrowExtraSpace = 0,
@@ -56,7 +55,6 @@ function BaseTextInput(
5655
maxLength = undefined,
5756
hint = '',
5857
onInputChange = () => {},
59-
shouldDelayFocus = false,
6058
multiline = false,
6159
autoCorrect = true,
6260
prefixCharacter = '',
@@ -113,18 +111,6 @@ function BaseTextInput(
113111

114112
useHtmlPaste(input, undefined, isMarkdownEnabled);
115113

116-
// AutoFocus with delay is executed manually, otherwise it's handled by the TextInput's autoFocus native prop
117-
useEffect(() => {
118-
if (!autoFocus || !shouldDelayFocus || !input.current) {
119-
return;
120-
}
121-
122-
const focusTimeout = setTimeout(() => input.current?.focus(), CONST.ANIMATED_TRANSITION);
123-
return () => clearTimeout(focusTimeout);
124-
// We only want this to run on mount
125-
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps
126-
}, []);
127-
128114
const animateLabel = useCallback(
129115
(translateY: number, scale: number) => {
130116
labelScale.set(withSpring(scale, {overshootClamping: false}));
@@ -354,7 +340,6 @@ function BaseTextInput(
354340
}}
355341
// eslint-disable-next-line
356342
{...inputProps}
357-
autoFocus={autoFocus && !shouldDelayFocus}
358343
autoCorrect={inputProps.secureTextEntry ? false : autoCorrect}
359344
placeholder={placeholderValue}
360345
placeholderTextColor={placeholderTextColor ?? theme.placeholderText}

src/components/TextInput/BaseTextInput/implementation/index.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ function BaseTextInput(
4949
containerStyles,
5050
inputStyle,
5151
forceActiveLabel = false,
52-
autoFocus = false,
5352
disableKeyboard = false,
5453
autoGrow = false,
5554
autoGrowHeight = false,
@@ -58,7 +57,6 @@ function BaseTextInput(
5857
maxLength = undefined,
5958
hint = '',
6059
onInputChange = () => {},
61-
shouldDelayFocus = false,
6260
multiline = false,
6361
shouldInterceptSwipe = false,
6462
autoCorrect = true,
@@ -120,14 +118,10 @@ function BaseTextInput(
120118
// AutoFocus which only works on mount:
121119
useEffect(() => {
122120
// We are manually managing focus to prevent this issue: https://github.com/Expensify/App/issues/4514
123-
if (!autoFocus || !input.current) {
121+
if (!inputProps.autoFocus || !input.current) {
124122
return;
125123
}
126124

127-
if (shouldDelayFocus) {
128-
const focusTimeout = setTimeout(() => input?.current?.focus(), CONST.ANIMATED_TRANSITION);
129-
return () => clearTimeout(focusTimeout);
130-
}
131125
input.current.focus();
132126
// We only want this to run on mount
133127
// eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps

src/components/TextInput/BaseTextInput/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,6 @@ type CustomBaseTextInputProps = {
9494
/** Callback to update the value on Form when input is used in the Form component. */
9595
onInputChange?: (value: string) => void;
9696

97-
/** Whether we should wait before focusing the TextInput, useful when using transitions */
98-
shouldDelayFocus?: boolean;
99-
10097
/** Indicate whether input is multiline */
10198
multiline?: boolean;
10299

src/libs/shouldDelayFocus/index.native.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/libs/shouldDelayFocus/index.ts

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/libs/shouldDelayFocus/types.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/BaseTwoFactorAuthForm.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type BaseTwoFactorAuthFormProps = {
2121
function BaseTwoFactorAuthForm({autoComplete, validateInsteadOfDisable}: BaseTwoFactorAuthFormProps, ref: ForwardedRef<BaseTwoFactorAuthFormRef>) {
2222
const {translate} = useLocalize();
2323
const [formError, setFormError] = useState<{twoFactorAuthCode?: string}>({});
24-
const [account] = useOnyx(ONYXKEYS.ACCOUNT);
24+
const [account] = useOnyx(ONYXKEYS.ACCOUNT, {canBeMissing: false});
2525
const [twoFactorAuthCode, setTwoFactorAuthCode] = useState('');
2626
const inputRef = useRef<MagicCodeInputHandle | null>(null);
2727
const shouldClearData = account?.needsTwoFactorAuthSetup ?? false;
@@ -88,7 +88,6 @@ function BaseTwoFactorAuthForm({autoComplete, validateInsteadOfDisable}: BaseTwo
8888
onFulfill={validateAndSubmitForm}
8989
errorText={formError.twoFactorAuthCode ?? getLatestErrorMessage(account)}
9090
ref={inputRef}
91-
shouldDelayFocus
9291
/>
9392
);
9493
}

0 commit comments

Comments
 (0)