From 373ece508e3dcf1d592a4e1ba030e9607f3182e6 Mon Sep 17 00:00:00 2001 From: Eskalifer1 Date: Fri, 2 Jan 2026 02:38:17 +0200 Subject: [PATCH 1/4] fix:67907: autoFocus input on perDiem tab --- src/components/DestinationPicker.tsx | 9 ++++++-- src/pages/iou/request/IOURequestStartPage.tsx | 21 ++++++++++++++++++- .../step/IOURequestStepDestination.tsx | 20 ++++++++++++++++-- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/components/DestinationPicker.tsx b/src/components/DestinationPicker.tsx index d32d594a38ea..72c948385589 100644 --- a/src/components/DestinationPicker.tsx +++ b/src/components/DestinationPicker.tsx @@ -1,4 +1,5 @@ import React, {useMemo} from 'react'; +import type {ForwardedRef} from 'react'; import useDebouncedState from '@hooks/useDebouncedState'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -12,15 +13,17 @@ import ONYXKEYS from '@src/ONYXKEYS'; // eslint-disable-next-line no-restricted-imports import SelectionList from './SelectionListWithSections'; import RadioListItem from './SelectionListWithSections/RadioListItem'; -import type {ListItem} from './SelectionListWithSections/types'; +import type {ListItem, SelectionListHandle} from './SelectionListWithSections/types'; type DestinationPickerProps = { policyID: string; selectedDestination?: string; onSubmit: (item: ListItem & {currency: string}) => void; + ref?: ForwardedRef; + textInputAutoFocus?: boolean; }; -function DestinationPicker({selectedDestination, policyID, onSubmit}: DestinationPickerProps) { +function DestinationPicker({selectedDestination, policyID, onSubmit, ref, textInputAutoFocus = false}: DestinationPickerProps) { const policy = usePolicy(policyID); const customUnit = getPerDiemCustomUnit(policy); const [policyRecentlyUsedDestinations] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_DESTINATIONS}${policyID}`, {canBeMissing: true}); @@ -71,6 +74,7 @@ function DestinationPicker({selectedDestination, policyID, onSubmit}: Destinatio return ( ); } diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 7f63c18c3699..5beb9614402f 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -6,6 +6,7 @@ import DragAndDropProvider from '@components/DragAndDrop/Provider'; import FocusTrapContainerElement from '@components/FocusTrap/FocusTrapContainerElement'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import {useProductTrainingContext} from '@components/ProductTrainingContext'; +import type {AnimatedTextInputRef} from '@components/RNTextInput'; import ScreenWrapper from '@components/ScreenWrapper'; import TabSelector from '@components/TabSelector/TabSelector'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; @@ -85,6 +86,8 @@ function IOURequestStartPage({ const [nvpDismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING, {canBeMissing: true}); const hasOnlyPersonalPolicies = useMemo(() => hasOnlyPersonalPoliciesUtil(allPolicies), [allPolicies]); + const perDiemInputRef = useRef(null); + const tabTitles = { [CONST.IOU.TYPE.REQUEST]: translate('iou.createExpense'), [CONST.IOU.TYPE.SUBMIT]: translate('iou.createExpense'), @@ -97,6 +100,17 @@ function IOURequestStartPage({ [CONST.IOU.TYPE.CREATE]: translate('iou.createExpense'), }; + const onTabSelectFocusHandler = ({index}: {index: number}) => { + // We requestAnimationFrame since the function is called in the animate block in the web implementation + // which fixes a locked animation glitch when swiping between tabs, and aligns with the native implementation internal delay + requestAnimationFrame(() => { + // 2 - PerDiem + if (index === 2) { + perDiemInputRef.current?.focus(); + } + }); + }; + const isFromGlobalCreate = isEmptyObject(report?.reportID); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); const policiesWithPerDiemEnabledAndHasRates = useMemo( @@ -222,6 +236,8 @@ function IOURequestStartPage({ useHandleBackButton(onBackButtonPress); + const shouldShowWorkspaceSelectForPerDiem = moreThanOnePerDiemExist && !hasCurrentPolicyPerDiemEnabled; + return ( {() => ( - {moreThanOnePerDiemExist && !hasCurrentPolicyPerDiemEnabled ? ( + {shouldShowWorkspaceSelectForPerDiem ? ( ) : ( void; +}; + type IOURequestStepDestinationProps = WithWritableReportOrNotFoundProps & WithFullTransactionOrNotFoundProps & { openedFromStartPage?: boolean; explicitPolicyID?: string; + shouldAutoFocusInput?: boolean; + ref: ForwardedRef; }; function IOURequestStepDestination({ @@ -57,6 +63,8 @@ function IOURequestStepDestination({ transaction, openedFromStartPage = false, explicitPolicyID, + shouldAutoFocusInput = true, + ref, }: IOURequestStepDestinationProps) { const [policy, policyMetadata] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${explicitPolicyID ?? getIOURequestPolicyID(transaction, report)}`, {canBeMissing: false}); const personalPolicy = usePersonalPolicy(); @@ -70,6 +78,12 @@ function IOURequestStepDestination({ const illustrations = useMemoizedLazyIllustrations(['EmptyStateExpenses']); const {translate} = useLocalize(); + const destinationSelectionListRef = useRef(null); + + useImperativeHandle(ref, () => ({ + focus: destinationSelectionListRef.current?.focusTextInput, + })); + // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = isEmptyObject(policy); @@ -195,6 +209,8 @@ function IOURequestStepDestination({ )} {!shouldShowEmptyState && !isLoading && !shouldShowOfflineView && !!policy?.id && ( Date: Fri, 2 Jan 2026 02:45:17 +0200 Subject: [PATCH 2/4] fix eslint --- src/pages/iou/request/IOURequestStartPage.tsx | 5 +++-- src/pages/iou/request/step/IOURequestStepDestination.tsx | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 5beb9614402f..cb61fe0da408 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -105,9 +105,10 @@ function IOURequestStartPage({ // which fixes a locked animation glitch when swiping between tabs, and aligns with the native implementation internal delay requestAnimationFrame(() => { // 2 - PerDiem - if (index === 2) { - perDiemInputRef.current?.focus(); + if (index !== 2) { + return; } + perDiemInputRef.current?.focus(); }); }; diff --git a/src/pages/iou/request/step/IOURequestStepDestination.tsx b/src/pages/iou/request/step/IOURequestStepDestination.tsx index 7d0ba14a1129..3a41c3a4880d 100644 --- a/src/pages/iou/request/step/IOURequestStepDestination.tsx +++ b/src/pages/iou/request/step/IOURequestStepDestination.tsx @@ -1,4 +1,5 @@ -import React, {ForwardedRef, useEffect, useImperativeHandle, useRef} from 'react'; +import React, {useEffect, useImperativeHandle, useRef} from 'react'; +import type {ForwardedRef} from 'react'; import {InteractionManager, View} from 'react-native'; import ActivityIndicator from '@components/ActivityIndicator'; import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; From 2b8c329cd65abd75b50a689570c954eaa5012506 Mon Sep 17 00:00:00 2001 From: Eskalifer1 Date: Fri, 16 Jan 2026 11:17:33 +0200 Subject: [PATCH 3/4] fix:67907: Fix focus handling for per diem input and comment out conditional rendering --- src/pages/iou/request/IOURequestStartPage.tsx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index e6fd50d3427e..8d302b5c67e0 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -110,7 +110,7 @@ function IOURequestStartPage({ if (index !== 2) { return; } - perDiemInputRef.current?.focus(); + perDiemInputRef.current?.focus?.(); }); }; @@ -338,29 +338,29 @@ function IOURequestStartPage({ )} )} - {!!shouldShowPerDiemOption && ( - - {() => ( - - {shouldShowWorkspaceSelectForPerDiem ? ( - - ) : ( - - )} - - )} - - )} + {/* {!!shouldShowPerDiemOption && ( */} + + {() => ( + + {shouldShowWorkspaceSelectForPerDiem ? ( + + ) : ( + + )} + + )} + + {/* )} */} ) : ( Date: Fri, 16 Jan 2026 11:19:04 +0200 Subject: [PATCH 4/4] fix: show dynamic perDiem tab --- src/pages/iou/request/IOURequestStartPage.tsx | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/pages/iou/request/IOURequestStartPage.tsx b/src/pages/iou/request/IOURequestStartPage.tsx index 8d302b5c67e0..4288e7130970 100644 --- a/src/pages/iou/request/IOURequestStartPage.tsx +++ b/src/pages/iou/request/IOURequestStartPage.tsx @@ -338,29 +338,29 @@ function IOURequestStartPage({ )} )} - {/* {!!shouldShowPerDiemOption && ( */} - - {() => ( - - {shouldShowWorkspaceSelectForPerDiem ? ( - - ) : ( - - )} - - )} - - {/* )} */} + {!!shouldShowPerDiemOption && ( + + {() => ( + + {shouldShowWorkspaceSelectForPerDiem ? ( + + ) : ( + + )} + + )} + + )} ) : (