diff --git a/src/components/AddPaymentCard/PaymentCardChangeCurrencyForm.tsx b/src/components/AddPaymentCard/PaymentCardChangeCurrencyForm.tsx
index c047d0341e9e..1b1b8204a810 100644
--- a/src/components/AddPaymentCard/PaymentCardChangeCurrencyForm.tsx
+++ b/src/components/AddPaymentCard/PaymentCardChangeCurrencyForm.tsx
@@ -6,7 +6,7 @@ import InputWrapper from '@components/Form/InputWrapper';
import type {FormInputErrors, FormOnyxValues} from '@components/Form/types';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import TextInput from '@components/TextInput';
import useLocalize from '@hooks/useLocalize';
import usePermissions from '@hooks/usePermissions';
@@ -132,12 +132,14 @@ function PaymentCardChangeCurrencyForm({changeBillingCurrency, isSecurityCodeReq
{
selectCurrency(option.value);
}}
style={{containerStyle: styles.mhn5}}
+ initiallyFocusedItemKey={currency}
customListHeader={}
+ shouldStopPropagation
/>
);
diff --git a/src/components/AddPaymentCard/PaymentCardCurrencyModal.tsx b/src/components/AddPaymentCard/PaymentCardCurrencyModal.tsx
index e657d4fc8012..85d0483db6d9 100644
--- a/src/components/AddPaymentCard/PaymentCardCurrencyModal.tsx
+++ b/src/components/AddPaymentCard/PaymentCardCurrencyModal.tsx
@@ -4,7 +4,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
@@ -67,10 +67,11 @@ function PaymentCardCurrencyModal({isVisible, currencies, currentCurrency = CONS
/>
{
onCurrencyChange(option.value);
}}
+ initiallyFocusedItemKey={currentCurrency}
showScrollIndicator
/>
diff --git a/src/components/AddPlaidBankAccount.tsx b/src/components/AddPlaidBankAccount.tsx
index 203048bb62fb..c68624505d5a 100644
--- a/src/components/AddPlaidBankAccount.tsx
+++ b/src/components/AddPlaidBankAccount.tsx
@@ -251,11 +251,9 @@ function AddPlaidBankAccount({
return (
-
- {translate(isDisplayedInWalletFlow ? 'walletPage.chooseYourBankAccount' : 'bankAccount.chooseAnAccount')}
-
- {!!text && {text}}
-
+ {translate(isDisplayedInWalletFlow ? 'walletPage.chooseYourBankAccount' : 'bankAccount.chooseAnAccount')}
+ {!!text && {text}}
+
- {`${translate('bankAccount.chooseAnAccountBelow')}:`}
+ {`${translate('bankAccount.chooseAnAccountBelow')}:`}
diff --git a/src/components/ApproverSelectionList.tsx b/src/components/ApproverSelectionList.tsx
index 0c15ceecfbf6..9723f4402178 100644
--- a/src/components/ApproverSelectionList.tsx
+++ b/src/components/ApproverSelectionList.tsx
@@ -168,7 +168,6 @@ function ApproverSelectionList({
shouldUpdateFocusedIndex={shouldUpdateFocusedIndex}
showScrollIndicator
isRowMultilineSupported
- shouldShowRadioButton
/>
diff --git a/src/components/BaseVacationDelegateSelectionComponent.tsx b/src/components/BaseVacationDelegateSelectionComponent.tsx
index c52f0ae4185b..f95dc2420c5a 100644
--- a/src/components/BaseVacationDelegateSelectionComponent.tsx
+++ b/src/components/BaseVacationDelegateSelectionComponent.tsx
@@ -187,7 +187,6 @@ function BaseVacationDelegateSelectionComponent({
onEndReached={onListEndReached}
shouldSingleExecuteRowSelect
shouldShowTextInput
- shouldShowRadioButton
/>
)}
diff --git a/src/components/CategoryPicker.tsx b/src/components/CategoryPicker.tsx
index 703d6589dc48..7e47123f71c2 100644
--- a/src/components/CategoryPicker.tsx
+++ b/src/components/CategoryPicker.tsx
@@ -11,7 +11,7 @@ import {getHeaderMessageForNonUserList} from '@libs/OptionsListUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
import SelectionListWithSections from './SelectionList/SelectionListWithSections';
import type {ListItem} from './SelectionList/types';
@@ -80,7 +80,7 @@ function CategoryPicker({selectedCategory, policyID, onSubmit, addBottomSafeArea
= CONST.STANDARD_LIST_ITEM_LIMIT}
textInputOptions={textInputOptions}
initiallyFocusedItemKey={selectedOptionKey}
diff --git a/src/components/CountryPicker/CountrySelectorModal.tsx b/src/components/CountryPicker/CountrySelectorModal.tsx
index 36db43f2e08c..a2f7e0fffeeb 100644
--- a/src/components/CountryPicker/CountrySelectorModal.tsx
+++ b/src/components/CountryPicker/CountrySelectorModal.tsx
@@ -3,7 +3,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -90,7 +90,7 @@ function CountrySelectorModal({isVisible, currentCountry, onCountrySelected, onC
data={searchResults}
textInputOptions={textInputOptions}
onSelectRow={onCountrySelected}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={currentCountry}
shouldSingleExecuteRowSelect
shouldStopPropagation
diff --git a/src/components/CurrencySelectionList/index.tsx b/src/components/CurrencySelectionList/index.tsx
index dc65c1f84f34..160ce3443de8 100644
--- a/src/components/CurrencySelectionList/index.tsx
+++ b/src/components/CurrencySelectionList/index.tsx
@@ -1,10 +1,9 @@
import {Str} from 'expensify-common';
import React, {useState} from 'react';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
import {useCurrencyListActions, useCurrencyListState} from '@hooks/useCurrencyList';
import useLocalize from '@hooks/useLocalize';
-import useThemeStyles from '@hooks/useThemeStyles';
import getMatchScore from '@libs/getMatchScore';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import type {CurrencyListItem, CurrencySelectionListProps} from './types';
@@ -23,7 +22,6 @@ function CurrencySelectionList({
const {getCurrencySymbol} = useCurrencyListActions();
const [searchValue, setSearchValue] = useState('');
const {translate} = useLocalize();
- const styles = useThemeStyles();
const getUnselectedOptions = (options: CurrencyListItem[]) => options.filter((option) => !option.isSelected);
const currencyOptions: CurrencyListItem[] = Object.entries(currencyList).reduce((acc, [currencyCode, currencyInfo]) => {
@@ -103,11 +101,8 @@ function CurrencySelectionList({
// eslint-disable-next-line react/jsx-props-no-spreading
{...restProps}
sections={sections}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
onSelectRow={onSelect}
- style={{
- listItemWrapperStyle: styles.optionRow,
- }}
textInputOptions={textInputOptions}
shouldShowTextInput={!!searchInputLabel}
shouldSingleExecuteRowSelect
diff --git a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx
index aca37cb1114f..26b2909899d2 100644
--- a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx
+++ b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx
@@ -4,7 +4,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
@@ -81,7 +81,7 @@ function YearPickerModal({isVisible, years, currentYear = new Date().getFullYear
/>
{
Keyboard.dismiss();
onYearChange?.(option.value);
diff --git a/src/components/DestinationPicker.tsx b/src/components/DestinationPicker.tsx
index 919606205438..0cf54b0efaa0 100644
--- a/src/components/DestinationPicker.tsx
+++ b/src/components/DestinationPicker.tsx
@@ -10,7 +10,7 @@ import type {Destination} from '@libs/PerDiemRequestUtils';
import {getPerDiemCustomUnit} from '@libs/PolicyUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
import SelectionListWithSections from './SelectionList/SelectionListWithSections';
import type {ListItem, SelectionListWithSectionsHandle} from './SelectionList/types';
@@ -80,7 +80,7 @@ function DestinationPicker({selectedDestination, policyID, onSubmit, ref}: Desti
shouldShowTextInput={shouldShowTextInput}
textInputOptions={textInputOptions}
onSelectRow={onSubmit}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={selectedOptionKey}
shouldHideKeyboardOnScroll={false}
shouldUpdateFocusedIndex
diff --git a/src/components/FeedbackSurvey.tsx b/src/components/FeedbackSurvey.tsx
index 99189d8faab2..492614d2e984 100644
--- a/src/components/FeedbackSurvey.tsx
+++ b/src/components/FeedbackSurvey.tsx
@@ -108,21 +108,19 @@ function FeedbackSurvey({title, description, onSubmit, optionRowStyles, footerTe
isSubmitButtonVisible={false}
enabledWhenOffline={enabledWhenOffline}
>
-
-
- {title}
- {description}
-
+
+ {title}
+ {description}
{!!reason && (
-
+ <>
{translate('feedbackSurvey.additionalInfoTitle')}
-
+ >
)}
diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx
index 45ffc6bc31c1..6edffb9e7467 100644
--- a/src/components/MoneyRequestConfirmationList.tsx
+++ b/src/components/MoneyRequestConfirmationList.tsx
@@ -78,7 +78,7 @@ import MoneyRequestAmountInput from './MoneyRequestAmountInput';
import MoneyRequestConfirmationListFooter from './MoneyRequestConfirmationListFooter';
import {PressableWithFeedback} from './Pressable';
import {useProductTrainingContext} from './ProductTrainingContext';
-import NewChatListItem from './Search/NewChatListItem';
+import UserListItem from './SelectionList/ListItem/UserListItem';
import SelectionListWithSections from './SelectionList/SelectionListWithSections';
import type {Section} from './SelectionList/SelectionListWithSections/types';
import SettlementButton from './SettlementButton';
@@ -1398,7 +1398,7 @@ function MoneyRequestConfirmationList({
sections={sections}
- ListItem={NewChatListItem}
+ ListItem={UserListItem}
onSelectRow={navigateToParticipantPage}
shouldSingleExecuteRowSelect
shouldPreventDefaultFocusOnSelectRow
diff --git a/src/components/OptionsPicker/OptionItem.tsx b/src/components/OptionsPicker/OptionItem.tsx
index a6b7cbe45a2d..aa792e146ef8 100644
--- a/src/components/OptionsPicker/OptionItem.tsx
+++ b/src/components/OptionsPicker/OptionItem.tsx
@@ -3,7 +3,7 @@ import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import Icon from '@components/Icon';
import {PressableWithFeedback} from '@components/Pressable';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
+import SelectCircle from '@components/SelectCircle';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -55,15 +55,9 @@ function OptionItem({title, icon, onPress, isSelected = false, isDisabled, style
/>
{(isSelected || !isDisabled) && (
- onPress?.()}
- accessibilityLabel={translate(title)}
+
)}
diff --git a/src/components/PushRowWithModal/PushRowModal.tsx b/src/components/PushRowWithModal/PushRowModal.tsx
index e8017c553f41..a2f94504d49a 100644
--- a/src/components/PushRowWithModal/PushRowModal.tsx
+++ b/src/components/PushRowWithModal/PushRowModal.tsx
@@ -3,7 +3,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import searchOptions from '@libs/searchOptions';
@@ -99,7 +99,7 @@ function PushRowModal({isVisible, selectedOption, onOptionChange, onClose, optio
/>
{
setLocalValue(item.value);
onInputChange(item.value);
diff --git a/src/components/Search/FilterComponents/DatePresetFilterBase.tsx b/src/components/Search/FilterComponents/DatePresetFilterBase.tsx
index 3d37f9c8cadf..5ef860d7c7d6 100644
--- a/src/components/Search/FilterComponents/DatePresetFilterBase.tsx
+++ b/src/components/Search/FilterComponents/DatePresetFilterBase.tsx
@@ -189,7 +189,7 @@ function DatePresetFilterBase({
}}
onSelectRow={() => setDateValue(CONST.SEARCH.DATE_MODIFIERS.ON, preset)}
keyForList={preset}
- wrapperStyle={(styles.flexReset, styles.optionRowCompact)}
+ wrapperStyle={styles.flexReset}
/>
))}
{shouldShowHorizontalRule && (
diff --git a/src/components/Search/NewChatListItem.tsx b/src/components/Search/NewChatListItem.tsx
deleted file mode 100644
index 23bcf12d452d..000000000000
--- a/src/components/Search/NewChatListItem.tsx
+++ /dev/null
@@ -1,137 +0,0 @@
-import {Str} from 'expensify-common';
-import React from 'react';
-import {View} from 'react-native';
-import Icon from '@components/Icon';
-import ReportActionAvatars from '@components/ReportActionAvatars';
-import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
-import type {ListItem, UserListItemProps} from '@components/SelectionList/ListItem/types';
-import Text from '@components/Text';
-import TextWithTooltip from '@components/TextWithTooltip';
-import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
-import useLocalize from '@hooks/useLocalize';
-import useOnyx from '@hooks/useOnyx';
-import useStyleUtils from '@hooks/useStyleUtils';
-import useTheme from '@hooks/useTheme';
-import useThemeStyles from '@hooks/useThemeStyles';
-import getButtonState from '@libs/getButtonState';
-import CONST from '@src/CONST';
-import ONYXKEYS from '@src/ONYXKEYS';
-
-function NewChatListItem({
- item,
- isFocused,
- showTooltip,
- isDisabled,
- canSelectMultiple,
- onSelectRow,
- onDismissError,
- shouldPreventEnterKeySubmit,
- rightHandSideComponent,
- onFocus,
- shouldSyncFocus,
- wrapperStyle,
- pressableStyle,
-}: UserListItemProps) {
- const styles = useThemeStyles();
- const theme = useTheme();
- const StyleUtils = useStyleUtils();
- const {translate} = useLocalize();
- const icons = useMemoizedLazyExpensifyIcons(['ArrowRight']);
-
- const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
- const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
- const hoveredBackgroundColor = !!styles.sidebarLinkHover && 'backgroundColor' in styles.sidebarLinkHover ? styles.sidebarLinkHover.backgroundColor : theme.sidebar;
-
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- some utils that are used to get reportID return empty string "", which would make subscription to the whole collection with nullish coalescing operator, example of this could be found in NewChatPage.tsx where some hooks return reportID as empty strings
- const [isReportInOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${item.reportID || undefined}`, {
- selector: (report) => !!report,
- });
-
- const reportExists = isReportInOnyx && !!item.reportID;
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
- const itemAccountID = Number(item.accountID || item.icons?.at(1)?.id) || 0;
-
- const isThereOnlyWorkspaceIcon = item.icons?.length === 1 && item.icons?.at(0)?.type === CONST.ICON_TYPE_WORKSPACE;
- const shouldUseIconPolicyID = !item.reportID && !item.accountID && !item.policyID;
- const policyID = isThereOnlyWorkspaceIcon && shouldUseIconPolicyID ? String(item.icons?.at(0)?.id) : item.policyID;
-
- return (
- {translate('workspace.people.invitedBySecondaryLogin', item.invitedSecondaryLogin)}
- ) : undefined
- }
- keyForList={item.keyForList}
- onFocus={onFocus}
- shouldSyncFocus={shouldSyncFocus}
- >
- {(hovered?: boolean) => (
- <>
- {(!!reportExists || !!itemAccountID || !!policyID) && (
-
- )}
-
-
- {!!item.alternateText && (
-
- )}
-
- {!!item.rightElement && item.rightElement}
- {!!item.shouldShowRightCaret && (
-
-
-
- )}
- >
- )}
-
- );
-}
-
-NewChatListItem.displayName = 'NewChatListItem';
-
-export default NewChatListItem;
diff --git a/src/components/Search/SearchAutocompleteList.tsx b/src/components/Search/SearchAutocompleteList.tsx
index 4cee5c49b5d5..2af5a351b24f 100644
--- a/src/components/Search/SearchAutocompleteList.tsx
+++ b/src/components/Search/SearchAutocompleteList.tsx
@@ -5,6 +5,7 @@ import {OptionsListStateContext, useOptionsList} from '@components/OptionListCon
import OptionsListSkeletonView from '@components/OptionsListSkeletonView';
import type {AnimatedTextInputRef} from '@components/RNTextInput';
import type {ListItem as NewListItem, UserListItemProps} from '@components/SelectionList/ListItem/types';
+import UserListItem from '@components/SelectionList/ListItem/UserListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
import type {Section, SelectionListWithSectionsHandle} from '@components/SelectionList/SelectionListWithSections/types';
import useAutocompleteSuggestions from '@hooks/useAutocompleteSuggestions';
@@ -35,7 +36,6 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type {CardFeeds, CardList, PersonalDetailsList, Policy, Report} from '@src/types/onyx';
import {getEmptyObject} from '@src/types/utils/EmptyObject';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
-import NewChatListItem from './NewChatListItem';
import type {SearchQueryItem, SearchQueryListItemProps} from './SearchList/ListItem/SearchQueryListItem';
import SearchQueryListItem, {isSearchQueryItem} from './SearchList/ListItem/SearchQueryListItem';
import {getSubstitutionMapKey} from './SearchRouter/getQueryWithSubstitutions';
@@ -118,39 +118,14 @@ function SearchRouterItem(props: UserListItemProps | Searc
);
}
- const {
- item,
- isFocused,
- showTooltip,
- isDisabled,
- canSelectMultiple,
- onSelectRow,
- onDismissError,
- shouldPreventEnterKeySubmit,
- rightHandSideComponent,
- onFocus,
- shouldSyncFocus,
- wrapperStyle,
- } = props;
- const fsClass = FS.getChatFSClass((item as SearchOption | undefined)?.item);
+ const fsClass = FS.getChatFSClass((props.item as SearchOption | undefined)?.item);
return (
-
);
}
diff --git a/src/components/Search/SearchList/BaseSearchList/index.tsx b/src/components/Search/SearchList/BaseSearchList/index.tsx
index 8addfae872d7..43b77898839f 100644
--- a/src/components/Search/SearchList/BaseSearchList/index.tsx
+++ b/src/components/Search/SearchList/BaseSearchList/index.tsx
@@ -3,13 +3,13 @@ import {FlashList} from '@shopify/flash-list';
import React, {useCallback, useEffect, useMemo, useRef} from 'react';
import type {NativeSyntheticEvent} from 'react-native';
import Animated from 'react-native-reanimated';
-import type {SearchListItem} from '@components/Search/SearchList/ListItem/types';
import type {ExtendedTargetedEvent} from '@components/SelectionList/ListItem/types';
import useArrowKeyFocusManager from '@hooks/useArrowKeyFocusManager';
import useKeyboardShortcut from '@hooks/useKeyboardShortcut';
import {isMobileChrome} from '@libs/Browser';
import {addKeyDownPressListener, removeKeyDownPressListener} from '@libs/KeyboardShortcut/KeyDownPressListener';
import CONST from '@src/CONST';
+import type {SearchListItem} from '../ListItem/types';
import type BaseSearchListProps from './types';
const AnimatedFlashListComponent = Animated.createAnimatedComponent(FlashList);
@@ -53,7 +53,7 @@ function BaseSearchList({
onFocusedIndexChange: (index: number) => {
scrollToIndex?.(index);
},
- setHasKeyBeenPressed,
+ ...(!hasKeyBeenPressed.current && {setHasKeyBeenPressed}),
isFocused,
captureOnInputs: false,
});
diff --git a/src/components/Search/SearchList/ListItem/CardListItem.tsx b/src/components/Search/SearchList/ListItem/CardListItem.tsx
new file mode 100644
index 000000000000..112eb6823c2a
--- /dev/null
+++ b/src/components/Search/SearchList/ListItem/CardListItem.tsx
@@ -0,0 +1,185 @@
+import {Str} from 'expensify-common';
+import React, {useCallback} from 'react';
+import {View} from 'react-native';
+import Avatar from '@components/Avatar';
+import Checkbox from '@components/Checkbox';
+import Icon from '@components/Icon';
+import PlaidCardFeedIcon from '@components/PlaidCardFeedIcon';
+import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
+import type {BaseListItemProps} from '@components/SelectionList/ListItem/types';
+import type {ListItem} from '@components/SelectionList/types';
+import TextWithTooltip from '@components/TextWithTooltip';
+import UserDetailsTooltip from '@components/UserDetailsTooltip';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
+import useLocalize from '@hooks/useLocalize';
+import useStyleUtils from '@hooks/useStyleUtils';
+import useTheme from '@hooks/useTheme';
+import useThemeStyles from '@hooks/useThemeStyles';
+import variables from '@styles/variables';
+import CONST from '@src/CONST';
+import type {PersonalDetails} from '@src/types/onyx';
+import type {BankIcon} from '@src/types/onyx/Bank';
+
+type AdditionalCardProps = {
+ shouldShowOwnersAvatar?: boolean;
+ cardOwnerPersonalDetails?: PersonalDetails;
+ bankIcon?: BankIcon;
+ lastFourPAN?: string;
+ isVirtual?: boolean;
+ cardName?: string;
+ plaidUrl?: string;
+};
+type CardListItemProps = BaseListItemProps;
+
+function CardListItem({
+ item,
+ isFocused,
+ showTooltip,
+ isDisabled,
+ canSelectMultiple,
+ onSelectRow,
+ onCheckboxPress,
+ onDismissError,
+ rightHandSideComponent,
+ onFocus,
+ shouldSyncFocus,
+}: CardListItemProps) {
+ const icons = useMemoizedLazyExpensifyIcons(['FallbackAvatar']);
+ const styles = useThemeStyles();
+ const StyleUtils = useStyleUtils();
+ const {translate} = useLocalize();
+ const theme = useTheme();
+
+ const handleCheckboxPress = useCallback(() => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ }, [item, onCheckboxPress, onSelectRow]);
+
+ const ownersAvatar = {
+ source: item.cardOwnerPersonalDetails?.avatar ?? icons.FallbackAvatar,
+ id: item.cardOwnerPersonalDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID,
+ type: CONST.ICON_TYPE_AVATAR,
+ name: item.cardOwnerPersonalDetails?.displayName ?? '',
+ fallbackIcon: item.cardOwnerPersonalDetails?.fallbackIcon,
+ };
+
+ const subtitleText =
+ `${item.lastFourPAN ? `${item.lastFourPAN}` : ''}` +
+ `${item.cardName ? ` ${CONST.DOT_SEPARATOR} ${item.cardName}` : ''}` +
+ `${item.isVirtual ? ` ${CONST.DOT_SEPARATOR} ${translate('workspace.expensifyCard.virtual')}` : ''}`;
+
+ return (
+
+ <>
+ {!!item.bankIcon && (
+
+ {item.shouldShowOwnersAvatar ? (
+
+
+
+
+
+
+
+ {!!item?.plaidUrl && (
+
+ )}
+ {!item?.plaidUrl && (
+
+ )}
+
+
+ ) : (
+ <>
+ {!!item?.plaidUrl && }
+ {!item?.plaidUrl && (
+
+ )}
+ >
+ )}
+
+ )}
+
+
+
+ {!!subtitleText && (
+
+ )}
+
+
+ {!!canSelectMultiple && !item.isDisabled && (
+
+ )}
+ >
+
+ );
+}
+
+export default CardListItem;
+export type {AdditionalCardProps};
diff --git a/src/components/Search/SearchList/ListItem/UserSelectionListItem.tsx b/src/components/Search/SearchList/ListItem/UserSelectionListItem.tsx
new file mode 100644
index 000000000000..84af26998ed4
--- /dev/null
+++ b/src/components/Search/SearchList/ListItem/UserSelectionListItem.tsx
@@ -0,0 +1,152 @@
+import {Str} from 'expensify-common';
+import React, {useCallback, useMemo} from 'react';
+import {View} from 'react-native';
+import Avatar from '@components/Avatar';
+import Icon from '@components/Icon';
+import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
+import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
+import type {UserSelectionListItemProps} from '@components/SelectionList/ListItem/types';
+import type {ListItem} from '@components/SelectionList/types';
+import TextWithTooltip from '@components/TextWithTooltip';
+import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
+import useLocalize from '@hooks/useLocalize';
+import useStyleUtils from '@hooks/useStyleUtils';
+import useTheme from '@hooks/useTheme';
+import useThemeStyles from '@hooks/useThemeStyles';
+import {areEmailsFromSamePrivateDomain} from '@libs/LoginUtils';
+import {getDisplayNameForParticipant} from '@libs/ReportUtils';
+import CONST from '@src/CONST';
+
+function UserSelectionListItem({
+ item,
+ isFocused,
+ showTooltip,
+ isDisabled,
+ canSelectMultiple,
+ onSelectRow,
+ onCheckboxPress,
+ onDismissError,
+ shouldPreventEnterKeySubmit,
+ rightHandSideComponent,
+ onFocus,
+ shouldSyncFocus,
+ wrapperStyle,
+ pressableStyle,
+}: UserSelectionListItemProps) {
+ const styles = useThemeStyles();
+ const theme = useTheme();
+ const StyleUtils = useStyleUtils();
+ const currentUserPersonalDetails = useCurrentUserPersonalDetails();
+ const icons = useMemoizedLazyExpensifyIcons(['Checkmark']);
+ const {formatPhoneNumber} = useLocalize();
+
+ const handleCheckboxPress = useCallback(() => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ }, [item, onCheckboxPress, onSelectRow]);
+
+ const userHandle = useMemo(() => {
+ const login = item.login ?? '';
+
+ // If the emails are not in the same private domain, we just return the users email
+ if (!areEmailsFromSamePrivateDomain(login, currentUserPersonalDetails.login ?? '')) {
+ return Str.removeSMSDomain(login);
+ }
+
+ // Otherwise, the emails are a part of the same private domain, so we can remove the domain and just show username
+ return login.split('@').at(0);
+ }, [currentUserPersonalDetails.login, item.login]);
+
+ const userDisplayName = useMemo(() => {
+ /* eslint-disable @typescript-eslint/prefer-nullish-coalescing -- need || to handle empty string from getDisplayNameForParticipant */
+ return (
+ getDisplayNameForParticipant({
+ accountID: item.accountID ?? CONST.DEFAULT_NUMBER_ID,
+ formatPhoneNumber,
+ }) ||
+ item.text ||
+ ''
+ );
+ /* eslint-enable @typescript-eslint/prefer-nullish-coalescing */
+ }, [formatPhoneNumber, item.accountID, item.text]);
+
+ return (
+
+
+ {!!item.icons?.length && (
+
+
+
+ )}
+
+
+
+ {!!userHandle && (
+
+ )}
+
+
+
+
+ {!!item.isSelected && (
+
+ )}
+
+
+
+ {!!item.rightElement && item.rightElement}
+
+
+ );
+}
+
+export default UserSelectionListItem;
diff --git a/src/components/Search/SortableHeaderText.tsx b/src/components/Search/SortableHeaderText.tsx
index 3a2305194261..88191f284553 100644
--- a/src/components/Search/SortableHeaderText.tsx
+++ b/src/components/Search/SortableHeaderText.tsx
@@ -3,6 +3,7 @@ import {View} from 'react-native';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import Icon from '@components/Icon';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
+import type {SortOrder} from '@components/Search/types';
import Text from '@components/Text';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useTheme from '@hooks/useTheme';
@@ -10,7 +11,6 @@ import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import type IconAsset from '@src/types/utils/IconAsset';
import type WithSentryLabel from '@src/types/utils/SentryLabel';
-import type {SortOrder} from './types';
type SearchTableHeaderColumnProps = WithSentryLabel & {
text: string;
diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx
index 92e23f44b0c6..2280563fa322 100644
--- a/src/components/SelectionList/BaseSelectionList.tsx
+++ b/src/components/SelectionList/BaseSelectionList.tsx
@@ -17,7 +17,6 @@ import useScrollEnabled from '@hooks/useScrollEnabled';
import useSingleExecution from '@hooks/useSingleExecution';
import {focusedItemRef} from '@hooks/useSyncFocus/useSyncFocusImplementation';
import useThemeStyles from '@hooks/useThemeStyles';
-import {addKeyDownPressListener, removeKeyDownPressListener} from '@libs/KeyboardShortcut/KeyDownPressListener';
import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan';
import CONST from '@src/CONST';
import getEmptyArray from '@src/types/utils/getEmptyArray';
@@ -90,10 +89,9 @@ function BaseSelectionList({
shouldPreventDefaultFocusOnSelectRow = false,
shouldShowTextInput = !!textInputOptions?.label,
shouldClearInputOnSelect = false,
- shouldHighlightSelectedItem,
+ shouldHighlightSelectedItem = true,
shouldUseDefaultRightHandSideCheckmark,
shouldDisableHoverStyle = false,
- shouldShowRadioButton,
setShouldDisableHoverStyle = () => {},
}: SelectionListProps) {
const styles = useThemeStyles();
@@ -159,12 +157,6 @@ function BaseSelectionList({
hasKeyBeenPressed.current = true;
}, []);
- useEffect(() => {
- addKeyDownPressListener(setHasKeyBeenPressed);
-
- return () => removeKeyDownPressListener(setHasKeyBeenPressed);
- }, [setHasKeyBeenPressed]);
-
const scrollToIndex = useCallback(
(index: number) => {
// Bounds check: ensure index is valid for current data
@@ -371,7 +363,6 @@ function BaseSelectionList({
shouldSyncFocus={!isTextInputFocusedRef.current && hasKeyBeenPressed.current}
shouldDisableHoverStyle={shouldDisableHoverStyle}
shouldShowRightCaret={shouldShowRightCaret}
- shouldShowRadioButton={shouldShowRadioButton}
/>
);
};
diff --git a/src/components/SelectionList/ListItem/BaseListItem.tsx b/src/components/SelectionList/ListItem/BaseListItem.tsx
index adc4ab538c71..cee2367d5c24 100644
--- a/src/components/SelectionList/ListItem/BaseListItem.tsx
+++ b/src/components/SelectionList/ListItem/BaseListItem.tsx
@@ -5,7 +5,6 @@ import Icon from '@components/Icon';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import type {PressableWithFeedbackProps} from '@components/Pressable/PressableWithFeedback';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
import getAccessibilityLabel from '@components/SelectionList/utils/getAccessibilityLabel';
import useHover from '@hooks/useHover';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
@@ -83,8 +82,9 @@ function BaseListItem({
onFocus = () => {},
hoverStyle,
onLongPressRow,
- shouldUseDefaultRightHandSideCheckmark = false,
- shouldHighlightSelectedItem = false,
+ testID,
+ shouldUseDefaultRightHandSideCheckmark = true,
+ shouldHighlightSelectedItem = true,
shouldDisableHoverStyle,
shouldShowRightCaret = false,
accessible,
@@ -121,10 +121,12 @@ function BaseListItem({
return rightHandSideComponent;
};
- const shouldShowCheckbox = !canSelectMultiple && !rightHandSideComponent && shouldUseDefaultRightHandSideCheckmark;
+ const shouldShowCheckmark = !canSelectMultiple && !!item.isSelected && !rightHandSideComponent && shouldUseDefaultRightHandSideCheckmark;
const shouldShowRBRIndicator = (!item.isSelected || !!item.canShowSeveralIndicators) && !!item.brickRoadIndicator && shouldDisplayRBR;
+ const shouldShowHiddenCheckmark = shouldShowRBRIndicator && !shouldShowCheckmark && !!item.canShowSeveralIndicators;
+
const {role, tabIndex, accessibilityState, accessibleAndAccessibilityLabel} = getAccessibilityProps({
role: accessibilityRole,
accessible,
@@ -190,20 +192,15 @@ function BaseListItem({
accessibilityState={accessibilityState}
onMouseLeave={handleMouseLeave}
wrapperStyle={pressableWrapperStyle}
+ testID={`${CONST.BASE_LIST_ITEM_TEST_ID}${item.keyForList}`}
>
@@ -219,16 +216,17 @@ function BaseListItem({
)}
- {shouldShowCheckbox && (
+ {(shouldShowCheckmark || shouldShowHiddenCheckmark) && (
-
+
+
+
)}
diff --git a/src/components/SelectionList/ListItem/CardListItem.tsx b/src/components/SelectionList/ListItem/CardListItem.tsx
index 20dfdc48191f..3672043f5963 100644
--- a/src/components/SelectionList/ListItem/CardListItem.tsx
+++ b/src/components/SelectionList/ListItem/CardListItem.tsx
@@ -2,9 +2,9 @@ import {Str} from 'expensify-common';
import React from 'react';
import {View} from 'react-native';
import Avatar from '@components/Avatar';
+import Checkbox from '@components/Checkbox';
import Icon from '@components/Icon';
import PlaidCardFeedIcon from '@components/PlaidCardFeedIcon';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
import TextWithTooltip from '@components/TextWithTooltip';
import UserDetailsTooltip from '@components/UserDetailsTooltip';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
@@ -49,6 +49,14 @@ function CardListItem({
const {translate} = useLocalize();
const theme = useTheme();
+ const handleCheckboxPress = () => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ };
+
const ownersAvatar = {
source: item.cardOwnerPersonalDetails?.avatar ?? icons.FallbackAvatar,
id: item.cardOwnerPersonalDetails?.accountID ?? CONST.DEFAULT_NUMBER_ID,
@@ -158,9 +166,11 @@ function CardListItem({
{!!canSelectMultiple && !item.isDisabled && (
-
diff --git a/src/components/SelectionList/ListItem/InviteMemberListItem.tsx b/src/components/SelectionList/ListItem/InviteMemberListItem.tsx
index dbf02f781ee6..8c3c111b6ffa 100644
--- a/src/components/SelectionList/ListItem/InviteMemberListItem.tsx
+++ b/src/components/SelectionList/ListItem/InviteMemberListItem.tsx
@@ -1,9 +1,10 @@
import {Str} from 'expensify-common';
import React, {useCallback} from 'react';
import {View} from 'react-native';
+import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import {useProductTrainingContext} from '@components/ProductTrainingContext';
import ReportActionAvatars from '@components/ReportActionAvatars';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
+import SelectCircle from '@components/SelectCircle';
import {ListItemFocusContext} from '@components/SelectionList/ListItemFocusContext';
import Text from '@components/Text';
import TextWithTooltip from '@components/TextWithTooltip';
@@ -39,7 +40,6 @@ function InviteMemberListItem({
canShowProductTrainingTooltip = true,
index = 0,
sectionIndex = 0,
- shouldShowRadioButton = true,
}: InviteMemberListItemProps) {
const styles = useThemeStyles();
const theme = useTheme();
@@ -61,8 +61,7 @@ function InviteMemberListItem({
const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
const hoveredBackgroundColor = !!styles.sidebarLinkHover && 'backgroundColor' in styles.sidebarLinkHover ? styles.sidebarLinkHover.backgroundColor : theme.sidebar;
- // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- we need to check if the item is disabled and if the checkbox or radio button should be shown
- const shouldShowCheckbox = !item.isDisabled && (canSelectMultiple || shouldShowRadioButton);
+ const shouldShowCheckBox = canSelectMultiple && !item.isDisabled;
const handleCheckboxPress = useCallback(() => {
if (onCheckboxPress) {
@@ -98,7 +97,7 @@ function InviteMemberListItem({
keyForList={item.keyForList}
onFocus={onFocus}
shouldSyncFocus={shouldSyncFocus}
- shouldDisplayRBR={!shouldShowCheckbox}
+ shouldDisplayRBR={!shouldShowCheckBox}
testID={item.text}
>
{(hovered?: boolean) => (
@@ -156,14 +155,20 @@ function InviteMemberListItem({
)}
{!!item.rightElement && {item.rightElement}}
- {!!shouldShowCheckbox && (
-
+ sentryLabel={CONST.SENTRY_LABEL.LIST_ITEM.INVITE_MEMBER_CHECKBOX}
+ >
+
+
)}
diff --git a/src/components/SelectionList/ListItem/ListItemRenderer.tsx b/src/components/SelectionList/ListItem/ListItemRenderer.tsx
index 618b1583afd8..1d7b34385a9a 100644
--- a/src/components/SelectionList/ListItem/ListItemRenderer.tsx
+++ b/src/components/SelectionList/ListItem/ListItemRenderer.tsx
@@ -16,8 +16,7 @@ type ListItemRendererProps = Omit['singleExecution'];
titleStyles?: StyleProp;
titleContainerStyles?: StyleProp;
- shouldHighlightSelectedItem?: boolean;
- shouldShowRadioButton?: boolean;
+ shouldHighlightSelectedItem: boolean;
};
function ListItemRenderer({
@@ -53,7 +52,6 @@ function ListItemRenderer({
shouldHighlightSelectedItem,
shouldDisableHoverStyle,
shouldShowRightCaret,
- shouldShowRadioButton,
errorRowStyles,
}: ListItemRendererProps) {
const handleOnCheckboxPress = () => {
@@ -113,7 +111,6 @@ function ListItemRenderer({
shouldHighlightSelectedItem={shouldHighlightSelectedItem}
shouldDisableHoverStyle={shouldDisableHoverStyle}
shouldShowRightCaret={shouldShowRightCaret}
- shouldShowRadioButton={shouldShowRadioButton}
/>
{item.footerContent && item.footerContent}
>
diff --git a/src/components/SelectionList/ListItem/MultiSelectListItem.tsx b/src/components/SelectionList/ListItem/MultiSelectListItem.tsx
index d1bde21eb269..10bf72dab7d0 100644
--- a/src/components/SelectionList/ListItem/MultiSelectListItem.tsx
+++ b/src/components/SelectionList/ListItem/MultiSelectListItem.tsx
@@ -1,7 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import Avatar from '@components/Avatar';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
+import Checkbox from '@components/Checkbox';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
import RadioListItem from './RadioListItem';
@@ -26,17 +26,17 @@ function MultiSelectListItem({
shouldSyncFocus,
wrapperStyle,
titleStyles,
- accessibilityState,
- shouldHighlightSelectedItem = false,
}: MultiSelectListItemProps) {
const styles = useThemeStyles();
const icon = item.icons?.at(0);
const checkboxComponent = useCallback(() => {
return (
- onSelectRow(item)}
/>
);
}, [item, onSelectRow]);
@@ -87,8 +87,6 @@ function MultiSelectListItem({
shouldSyncFocus={shouldSyncFocus}
wrapperStyle={computedWrapperStyle}
titleStyles={titleStyles}
- accessibilityState={accessibilityState}
- shouldHighlightSelectedItem={shouldHighlightSelectedItem}
/>
);
}
diff --git a/src/components/SelectionList/ListItem/RadioListItem.tsx b/src/components/SelectionList/ListItem/RadioListItem.tsx
index 5de7832b02b1..dbf969f7ceff 100644
--- a/src/components/SelectionList/ListItem/RadioListItem.tsx
+++ b/src/components/SelectionList/ListItem/RadioListItem.tsx
@@ -26,6 +26,7 @@ function RadioListItem({
wrapperStyle,
titleStyles,
shouldHighlightSelectedItem = true,
+ shouldDisableHoverStyle,
accessibilityRole,
shouldUseDefaultRightHandSideComponent,
}: RadioListItemProps) {
@@ -70,6 +71,7 @@ function RadioListItem({
shouldSyncFocus={shouldSyncFocus}
pendingAction={item.pendingAction}
shouldHighlightSelectedItem={shouldHighlightSelectedItem}
+ shouldDisableHoverStyle={shouldDisableHoverStyle}
accessibilityRole={accessibilityRole}
>
<>
diff --git a/src/components/SelectionList/ListItem/SingleSelectListItem.tsx b/src/components/SelectionList/ListItem/SingleSelectListItem.tsx
index 6ae4040f45fc..b1fd53063dde 100644
--- a/src/components/SelectionList/ListItem/SingleSelectListItem.tsx
+++ b/src/components/SelectionList/ListItem/SingleSelectListItem.tsx
@@ -1,5 +1,5 @@
import React, {useCallback} from 'react';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
+import Checkbox from '@components/Checkbox';
import useThemeStyles from '@hooks/useThemeStyles';
import RadioListItem from './RadioListItem';
import type {ListItem, SingleSelectListItemProps} from './types';
@@ -23,20 +23,18 @@ function SingleSelectListItem({
shouldSyncFocus,
wrapperStyle,
titleStyles,
- shouldHighlightSelectedItem = false,
- rightHandSideComponent = undefined,
- shouldShowRadioButton = true,
- accessibilityState,
+ shouldHighlightSelectedItem = true,
}: SingleSelectListItemProps) {
const styles = useThemeStyles();
const radioCheckboxComponent = useCallback(() => {
return (
- onSelectRow(item)}
/>
);
}, [item, onSelectRow]);
@@ -48,7 +46,7 @@ function SingleSelectListItem({
isFocused={isFocused}
showTooltip={showTooltip}
isDisabled={isDisabled}
- rightHandSideComponent={rightHandSideComponent ?? radioCheckboxComponent}
+ rightHandSideComponent={radioCheckboxComponent}
onSelectRow={onSelectRow}
onDismissError={onDismissError}
shouldPreventEnterKeySubmit={shouldPreventEnterKeySubmit}
@@ -57,11 +55,9 @@ function SingleSelectListItem({
alternateTextNumberOfLines={alternateTextNumberOfLines}
onFocus={onFocus}
shouldSyncFocus={shouldSyncFocus}
- wrapperStyle={[styles.optionRow, wrapperStyle]}
+ wrapperStyle={[styles.optionRowCompact, wrapperStyle]}
titleStyles={titleStyles}
shouldHighlightSelectedItem={shouldHighlightSelectedItem}
- shouldShowRadioButton={shouldShowRadioButton}
- accessibilityState={accessibilityState}
/>
);
}
diff --git a/src/components/SelectionList/ListItem/TableListItem.tsx b/src/components/SelectionList/ListItem/TableListItem.tsx
index d3b610cc37be..ec40a586e273 100644
--- a/src/components/SelectionList/ListItem/TableListItem.tsx
+++ b/src/components/SelectionList/ListItem/TableListItem.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {View} from 'react-native';
+import Checkbox from '@components/Checkbox';
import ReportActionAvatars from '@components/ReportActionAvatars';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
import TextWithTooltip from '@components/TextWithTooltip';
import useAnimatedHighlightStyle from '@hooks/useAnimatedHighlightStyle';
import useStyleUtils from '@hooks/useStyleUtils';
@@ -42,6 +42,14 @@ function TableListItem({
const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
const hoveredBackgroundColor = styles.sidebarLinkHover?.backgroundColor ? styles.sidebarLinkHover.backgroundColor : theme.sidebar;
+ const handleCheckboxPress = () => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ };
+
return (
({
{(hovered) => (
<>
{!!canSelectMultiple && (
- ({
- item,
- isFocused,
- showTooltip,
- isDisabled,
- onSelectRow,
- onCheckboxPress,
- onFocus,
- shouldSyncFocus,
- accessibilityState,
-}: TravelDomainListItemProps) {
+function TravelDomainListItem({item, isFocused, showTooltip, isDisabled, onSelectRow, onCheckboxPress, onFocus, shouldSyncFocus}: TravelDomainListItemProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
+
+ const handleCheckboxPress = useCallback(() => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ }, [item, onCheckboxPress, onSelectRow]);
const showRecommendedTag = item.isRecommended ?? false;
return (
@@ -35,17 +35,21 @@ function TravelDomainListItem({
keyForList={item.keyForList}
onFocus={onFocus}
shouldSyncFocus={shouldSyncFocus}
- accessibilityState={accessibilityState}
>
<>
-
+
+
+
({
shouldUseDefaultRightHandSideCheckmark,
forwardedFSClass,
shouldDisableHoverStyle,
- shouldShowRadioButton,
}: UserListItemProps) {
const icons = useMemoizedLazyExpensifyIcons(['ArrowRight', 'Checkmark'] as const);
const styles = useThemeStyles();
@@ -54,6 +53,14 @@ function UserListItem({
const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
const hoveredBackgroundColor = !!styles.sidebarLinkHover && 'backgroundColor' in styles.sidebarLinkHover ? styles.sidebarLinkHover.backgroundColor : theme.sidebar;
+ const handleCheckboxPress = useCallback(() => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ }, [item, onCheckboxPress, onSelectRow]);
+
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- some utils that are used to get reportID return empty string "", which would make subscription to the whole collection with nullish coalescing operator, example of this could be found in NewChatPage.tsx where some hooks return reportID as empty strings
const [isReportInOnyx] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${item.reportID || undefined}`, {
selector: reportExistsSelector,
@@ -92,7 +99,6 @@ function UserListItem({
{translate('workspace.people.invitedBySecondaryLogin', item.invitedSecondaryLogin)}
) : undefined
}
- shouldUseDefaultRightHandSideCheckmark={false}
keyForList={item.keyForList}
onFocus={onFocus}
shouldSyncFocus={shouldSyncFocus}
@@ -110,13 +116,26 @@ function UserListItem({
style={[styles.flex1, styles.flexRow, styles.alignItemsCenter]}
>
{!shouldUseDefaultRightHandSideCheckmark && !!canSelectMultiple && (
-
+ onPress={handleCheckboxPress}
+ style={[styles.cursorUnset, StyleUtils.getCheckboxPressableStyle(), item.isDisabledCheckbox && styles.cursorDisabled, styles.mr3]}
+ >
+
+ {!!item.isSelected && (
+
+ )}
+
+
)}
{(!!reportExists || !!itemAccountID || !!policyID) && (
({
/>
)}
- {((!!shouldUseDefaultRightHandSideCheckmark && !!canSelectMultiple) || !!shouldShowRadioButton) && (
-
+ onPress={handleCheckboxPress}
+ style={[styles.cursorUnset, StyleUtils.getCheckboxPressableStyle(), item.isDisabledCheckbox && styles.cursorDisabled, styles.ml3]}
+ >
+
+ {!!item.isSelected && (
+
+ )}
+
+
)}
);
diff --git a/src/components/SelectionList/ListItem/UserSelectionListItem.tsx b/src/components/SelectionList/ListItem/UserSelectionListItem.tsx
index 81ab3e0726f1..c64895411d90 100644
--- a/src/components/SelectionList/ListItem/UserSelectionListItem.tsx
+++ b/src/components/SelectionList/ListItem/UserSelectionListItem.tsx
@@ -1,11 +1,15 @@
import {Str} from 'expensify-common';
-import React, {useMemo} from 'react';
+import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import Avatar from '@components/Avatar';
-import SelectionCheckbox from '@components/SelectionList/components/SelectionCheckbox';
+import Icon from '@components/Icon';
+import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
import TextWithTooltip from '@components/TextWithTooltip';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
+import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
+import useStyleUtils from '@hooks/useStyleUtils';
+import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import {areEmailsFromSamePrivateDomain} from '@libs/LoginUtils';
import {getDisplayNameForParticipant} from '@libs/ReportUtils';
@@ -30,9 +34,20 @@ function UserSelectionListItem({
pressableStyle,
}: UserSelectionListItemProps) {
const styles = useThemeStyles();
+ const theme = useTheme();
+ const StyleUtils = useStyleUtils();
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
+ const icons = useMemoizedLazyExpensifyIcons(['Checkmark']);
const {formatPhoneNumber} = useLocalize();
+ const handleCheckboxPress = useCallback(() => {
+ if (onCheckboxPress) {
+ onCheckboxPress(item);
+ } else {
+ onSelectRow(item);
+ }
+ }, [item, onCheckboxPress, onSelectRow]);
+
const userHandle = useMemo(() => {
const login = item.login ?? '';
@@ -100,13 +115,25 @@ function UserSelectionListItem({
)}
-
+ onPress={handleCheckboxPress}
+ style={[styles.cursorUnset, StyleUtils.getCheckboxPressableStyle(), item.isDisabledCheckbox && styles.cursorDisabled, !!item.rightElement && styles.mr3]}
+ >
+
+ {!!item.isSelected && (
+
+ )}
+
+
{!!item.rightElement && item.rightElement}
diff --git a/src/components/SelectionList/ListItem/types.ts b/src/components/SelectionList/ListItem/types.ts
index 98d9700a76ca..286759246408 100644
--- a/src/components/SelectionList/ListItem/types.ts
+++ b/src/components/SelectionList/ListItem/types.ts
@@ -219,9 +219,6 @@ type CommonListItemProps = {
/** Whether product training tooltips can be displayed */
canShowProductTrainingTooltip?: boolean;
-
- /** Whether to show the radio button */
- shouldShowRadioButton?: boolean;
} & TRightHandSideComponent &
WithSentryLabel;
diff --git a/src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx b/src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx
index 693b9dae3776..29dc9f607c47 100644
--- a/src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx
+++ b/src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx
@@ -76,8 +76,7 @@ function BaseSelectionListWithSections({
isRowMultilineSupported = false,
titleNumberOfLines,
shouldUseDefaultRightHandSideComponent,
- shouldDisableHoverStyle,
- shouldShowRadioButton,
+ shouldDisableHoverStyle = false,
setShouldDisableHoverStyle = () => {},
canShowProductTrainingTooltip,
}: SelectionListWithSectionsProps) {
@@ -356,6 +355,7 @@ function BaseSelectionListWithSections({
singleExecution={singleExecution}
canShowProductTrainingTooltip={canShowProductTrainingTooltip}
shouldSyncFocus={!isTextInputFocusedRef.current && hasKeyBeenPressed.current}
+ shouldHighlightSelectedItem
shouldIgnoreFocus={shouldIgnoreFocus}
wrapperStyle={style?.listItemWrapperStyle}
titleStyles={style?.listItemTitleStyles}
@@ -363,7 +363,6 @@ function BaseSelectionListWithSections({
titleNumberOfLines={titleNumberOfLines}
shouldUseDefaultRightHandSideComponent={shouldUseDefaultRightHandSideComponent}
shouldDisableHoverStyle={shouldDisableHoverStyle}
- shouldShowRadioButton={shouldShowRadioButton}
/>
);
}
diff --git a/src/components/SelectionList/components/SelectionCheckbox.tsx b/src/components/SelectionList/components/SelectionCheckbox.tsx
deleted file mode 100644
index b452d0b56eb6..000000000000
--- a/src/components/SelectionList/components/SelectionCheckbox.tsx
+++ /dev/null
@@ -1,64 +0,0 @@
-import React from 'react';
-import type {StyleProp, ViewStyle} from 'react-native';
-import Checkbox from '@components/Checkbox';
-import type {ListItem} from '@components/SelectionList/ListItem/types';
-import CONST from '@src/CONST';
-
-type SelectionCheckboxProps = {
- /** The item to render the checkbox for */
- item: TItem;
-
- /** Callback to fire when the item is pressed */
- onSelectRow: (item: TItem) => void;
-
- /** Custom accessibility label for the checkbox */
- accessibilityLabel?: string;
-
- /** Whether the checkbox should have circular border radius (for single-select style) */
- isCircular?: boolean;
-
- /** Whether the checkbox is disabled */
- disabled?: boolean;
-
- /** Additional styles for the checkbox */
- style?: StyleProp;
-
- /** Additional styles for the checkbox container */
- containerStyle?: StyleProp;
-
- /** Whether to stop mouse down event propagation */
- shouldStopMouseDownPropagation?: boolean;
-
- /** Test ID for the checkbox */
- testID?: string;
-};
-
-function SelectionCheckbox({
- item,
- onSelectRow,
- accessibilityLabel,
- isCircular = false,
- disabled,
- style,
- containerStyle,
- shouldStopMouseDownPropagation,
- testID,
-}: SelectionCheckboxProps) {
- return (
- onSelectRow(item)}
- disabled={disabled}
- style={style}
- containerStyle={containerStyle}
- shouldStopMouseDownPropagation={shouldStopMouseDownPropagation}
- sentryLabel={CONST.SENTRY_LABEL.USER_LIST_ITEM.CHECKBOX}
- testID={testID}
- />
- );
-}
-
-export default SelectionCheckbox;
diff --git a/src/components/SelectionList/types.ts b/src/components/SelectionList/types.ts
index 87b6ea50be04..8b6b8eca5300 100644
--- a/src/components/SelectionList/types.ts
+++ b/src/components/SelectionList/types.ts
@@ -115,9 +115,6 @@ type BaseSelectionListProps = {
/** Whether to set the hover style */
setShouldDisableHoverStyle?: React.Dispatch>;
-
- /** Whether to show the radio button */
- shouldShowRadioButton?: boolean;
};
/**
diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx
index 5490bb568676..503888f8239c 100644
--- a/src/components/SelectionScreen.tsx
+++ b/src/components/SelectionScreen.tsx
@@ -17,7 +17,9 @@ import HeaderWithBackButton from './HeaderWithBackButton';
import OfflineWithFeedback from './OfflineWithFeedback';
import ScreenWrapper from './ScreenWrapper';
import SelectionList from './SelectionList';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import type RadioListItem from './SelectionList/ListItem/RadioListItem';
+import type TableListItem from './SelectionList/ListItem/TableListItem';
+import type UserListItem from './SelectionList/ListItem/UserListItem';
import type {ListItem} from './SelectionList/types';
type SelectorType = ListItem & {
@@ -45,6 +47,9 @@ type SelectionScreenProps = {
/** Sections for the section list */
data: Array>;
+ /** Default renderer for every item in the list */
+ listItem: typeof RadioListItem | typeof UserListItem | typeof TableListItem;
+
/** The style is applied for the wrap component of list item */
listItemWrapperStyle?: StyleProp;
@@ -115,6 +120,7 @@ function SelectionScreen({
listEmptyContent,
listFooterContent,
data,
+ listItem,
listItemWrapperStyle,
initiallyFocusedOptionKey,
onSelectRow,
@@ -164,7 +170,7 @@ function SelectionScreen({
>
{prompt}
@@ -33,7 +33,6 @@ function SingleChoiceQuestion({prompt, errorText, possibleAnswers, currentQuesti
key={currentQuestionIndex}
onPress={onInputChange}
errorText={errorText}
- radioButtonStyle={[styles.optionRowCompact, styles.ph5]}
forwardedFSClass={forwardedFSClass}
/>
>
diff --git a/src/components/StatePicker/StateSelectorModal.tsx b/src/components/StatePicker/StateSelectorModal.tsx
index eaad784b256c..d03e8183ca30 100644
--- a/src/components/StatePicker/StateSelectorModal.tsx
+++ b/src/components/StatePicker/StateSelectorModal.tsx
@@ -4,7 +4,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -90,7 +90,7 @@ function StateSelectorModal({isVisible, currentState, onStateSelected, onClose,
/>
- {title}
- {description}
+ {title}
+ {description}
);
diff --git a/src/components/TagPicker.tsx b/src/components/TagPicker.tsx
index 8efe216af8ae..8cc6712b360d 100644
--- a/src/components/TagPicker.tsx
+++ b/src/components/TagPicker.tsx
@@ -11,7 +11,7 @@ import {getTagArrayFromName} from '@libs/TransactionUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import type {PolicyTag, PolicyTags} from '@src/types/onyx';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
import SelectionListWithSections from './SelectionList/SelectionListWithSections';
type TagPickerProps = {
@@ -137,7 +137,7 @@ function TagPicker({
return (
diff --git a/src/components/UnitPicker.tsx b/src/components/UnitPicker.tsx
index cf75a423dec2..31c9e42e9ee5 100644
--- a/src/components/UnitPicker.tsx
+++ b/src/components/UnitPicker.tsx
@@ -5,7 +5,7 @@ import {getUnitTranslationKey} from '@libs/WorkspacesSettingsUtils';
import CONST from '@src/CONST';
import type {Unit} from '@src/types/onyx/Policy';
import SelectionList from './SelectionList';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
type UnitItemType = {
value: Unit;
@@ -38,7 +38,7 @@ function UnitPicker({defaultValue, onOptionSelected}: UnitPickerProps) {
return (
unit.isSelected)?.keyForList}
/>
diff --git a/src/components/ValuePicker/ValueSelectionList.tsx b/src/components/ValuePicker/ValueSelectionList.tsx
index 906dbb140eaa..cde868808598 100644
--- a/src/components/ValuePicker/ValueSelectionList.tsx
+++ b/src/components/ValuePicker/ValueSelectionList.tsx
@@ -1,6 +1,6 @@
import React, {useMemo} from 'react';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ValueSelectionListProps} from './types';
function ValueSelectionList({
@@ -25,7 +25,7 @@ function ValueSelectionList({
shouldStopPropagation
shouldShowTooltips={shouldShowTooltips}
shouldUpdateFocusedIndex
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
addBottomSafeAreaPadding={addBottomSafeAreaPadding}
disableKeyboardShortcuts={disableKeyboardShortcuts}
alternateNumberOfSupportedLines={alternateNumberOfSupportedLines}
diff --git a/src/components/WorkspaceMemberRoleList.tsx b/src/components/WorkspaceMemberRoleList.tsx
index 432dd71ff5ae..1263e0d38d8c 100644
--- a/src/components/WorkspaceMemberRoleList.tsx
+++ b/src/components/WorkspaceMemberRoleList.tsx
@@ -11,7 +11,7 @@ import type {Route} from '@src/ROUTES';
import type {Policy} from '@src/types/onyx';
import HeaderWithBackButton from './HeaderWithBackButton';
import SelectionList from './SelectionList';
-import SingleSelectListItem from './SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from './SelectionList/ListItem/RadioListItem';
import type {ListItem} from './SelectionList/types';
type ListItemType = ListItem> & {
@@ -70,7 +70,7 @@ function WorkspaceMemberRoleList({role, policy, navigateBackTo = undefined, isLo
item.isSelected)?.keyForList}
diff --git a/src/components/WorkspaceMembersSelectionList.tsx b/src/components/WorkspaceMembersSelectionList.tsx
index 93131d36f982..5bdfc3fe0d73 100644
--- a/src/components/WorkspaceMembersSelectionList.tsx
+++ b/src/components/WorkspaceMembersSelectionList.tsx
@@ -97,7 +97,6 @@ function WorkspaceMembersSelectionList({policyID, selectedApprover, setApprover}
addBottomSafeAreaPadding
showScrollIndicator
isRowMultilineSupported
- shouldShowRadioButton
/>
);
}
diff --git a/src/libs/CardFeedUtils.ts b/src/libs/CardFeedUtils.ts
index 639d4b8bc8ca..2b0b3cec08ac 100644
--- a/src/libs/CardFeedUtils.ts
+++ b/src/libs/CardFeedUtils.ts
@@ -1,6 +1,6 @@
import type {OnyxCollection} from 'react-native-onyx';
import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider';
-import type {AdditionalCardProps} from '@components/SelectionList/ListItem/CardListItem';
+import type {AdditionalCardProps} from '@components/Search/SearchList/ListItem/CardListItem';
import type {FeedKeysWithAssignedCards} from '@hooks/useFeedKeysWithAssignedCards';
import type IllustrationsType from '@styles/theme/illustrations/types';
import CONST from '@src/CONST';
diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts
index 051a6dbca666..4c0e76a1336b 100644
--- a/src/libs/OptionsListUtils/index.ts
+++ b/src/libs/OptionsListUtils/index.ts
@@ -3494,7 +3494,6 @@ export type {
Option,
OptionList,
OptionTree,
- OptionWithKey,
Options,
OrderOptionsConfig,
OrderReportOptionsConfig,
diff --git a/src/libs/ReportFieldOptionsListUtils.ts b/src/libs/ReportFieldOptionsListUtils.ts
index 3788f14c8f4c..8c35443508fa 100644
--- a/src/libs/ReportFieldOptionsListUtils.ts
+++ b/src/libs/ReportFieldOptionsListUtils.ts
@@ -1,21 +1,22 @@
import type {LocalizedTranslate} from '@components/LocaleContextProvider';
-import type {OptionWithKey} from './OptionsListUtils';
+import type {Option} from './OptionsListUtils';
import type {OptionData} from './ReportUtils';
import tokenizedSearch from './tokenizedSearch';
+type ReportFieldOption = Option & {keyForList: string};
+
/**
* Transforms the provided report field options into option objects.
*
* @param reportFieldOptions - an initial report field options array
*/
-function getReportFieldOptions(reportFieldOptions: string[], isSelected = false): OptionWithKey[] {
+function getReportFieldOptions(reportFieldOptions: string[]): ReportFieldOption[] {
return reportFieldOptions.map((name) => ({
text: name,
keyForList: name,
searchText: name,
tooltipText: name,
isDisabled: false,
- isSelected,
}));
}
diff --git a/src/pages/Debug/ConstantPicker.tsx b/src/pages/Debug/ConstantPicker.tsx
index 9ecbfaf374d6..fd39d6928aac 100644
--- a/src/pages/Debug/ConstantPicker.tsx
+++ b/src/pages/Debug/ConstantPicker.tsx
@@ -1,7 +1,7 @@
import isObject from 'lodash/isObject';
import React, {useMemo, useState} from 'react';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import useLocalize from '@hooks/useLocalize';
import tokenizedSearch from '@libs/tokenizedSearch';
@@ -67,7 +67,7 @@ function ConstantPicker({formType, fieldName, fieldValue, onSubmit}: ConstantPic
data={sections}
textInputOptions={textInputOptions}
onSelectRow={onSubmit}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={selectedOptionKey}
/>
);
diff --git a/src/pages/Debug/Report/DebugReportActions.tsx b/src/pages/Debug/Report/DebugReportActions.tsx
index 1f7f5fc4aeb9..45a0f70a06a2 100644
--- a/src/pages/Debug/Report/DebugReportActions.tsx
+++ b/src/pages/Debug/Report/DebugReportActions.tsx
@@ -3,7 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx';
import Button from '@components/Button';
import ScrollView from '@components/ScrollView';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useMappedPersonalDetails, {personalDetailMapper} from '@hooks/useMappedPersonalDetails';
@@ -135,7 +135,7 @@ function DebugReportActions({reportID}: DebugReportActionsProps) {
style={{listItemTitleStyles: styles.fontWeightNormal}}
textInputOptions={textInputOptions}
onSelectRow={(item) => Navigation.navigate(ROUTES.DEBUG_REPORT_ACTION.getRoute(reportID, item.reportActionID))}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
/>
);
diff --git a/src/pages/EditReportFieldDropdown.tsx b/src/pages/EditReportFieldDropdown.tsx
index f681869f9117..79ff44e9bf76 100644
--- a/src/pages/EditReportFieldDropdown.tsx
+++ b/src/pages/EditReportFieldDropdown.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import Icon from '@components/Icon';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
import type {ListItem} from '@components/SelectionList/types';
import useDebouncedState from '@hooks/useDebouncedState';
@@ -29,11 +29,10 @@ type EditReportFieldDropdownPageProps = {
function EditReportFieldDropdown({onSubmit, fieldKey, fieldValue, fieldOptions}: EditReportFieldDropdownPageProps) {
const [recentlyUsedReportFields] = useOnyx(ONYXKEYS.RECENTLY_USED_REPORT_FIELDS);
const [searchValue, debouncedSearchValue, setSearchValue] = useDebouncedState('');
+ const theme = useTheme();
const {translate, localeCompare} = useLocalize();
const recentlyUsedOptions = recentlyUsedReportFields?.[fieldKey]?.sort(localeCompare) ?? [];
const icons = useMemoizedLazyExpensifyIcons(['Checkmark'] as const);
- const theme = useTheme();
-
const itemRightSideComponent = (item: ListItem) => {
if (item.text === fieldValue) {
return (
@@ -76,7 +75,7 @@ function EditReportFieldDropdown({onSubmit, fieldKey, fieldValue, fieldOptions}:
return (
onSubmit({[fieldKey]: !option?.text || fieldValue === option.text ? '' : option.text})}
diff --git a/src/pages/EnablePayments/AddBankAccount/substeps/PlaidStep.tsx b/src/pages/EnablePayments/AddBankAccount/substeps/PlaidStep.tsx
index 716f4d4e1099..a09c84bc2825 100644
--- a/src/pages/EnablePayments/AddBankAccount/substeps/PlaidStep.tsx
+++ b/src/pages/EnablePayments/AddBankAccount/substeps/PlaidStep.tsx
@@ -57,7 +57,7 @@ function PlaidStep({onNext}: SubStepProps) {
onSubmit={handleNextPress}
scrollContextEnabled
submitButtonText={translate('common.next')}
- style={[styles.flexGrow1]}
+ style={[styles.mh5, styles.flexGrow1]}
isSubmitButtonVisible={(plaidData?.bankAccounts ?? []).length > 0}
shouldHideFixErrorsAlert
>
diff --git a/src/pages/EnablePayments/IdologyQuestions.tsx b/src/pages/EnablePayments/IdologyQuestions.tsx
index 36b5b9cbeab3..b74e85cb49a5 100644
--- a/src/pages/EnablePayments/IdologyQuestions.tsx
+++ b/src/pages/EnablePayments/IdologyQuestions.tsx
@@ -117,8 +117,7 @@ function IdologyQuestions({questions, idNumber}: IdologyQuestionsProps) {
key={currentQuestionIndex}
validate={validate}
scrollContextEnabled
- style={[styles.flexGrow1]}
- submitButtonStyles={styles.mh5}
+ style={[styles.flexGrow1, styles.ph5]}
submitButtonText={translate('common.saveAndContinue')}
shouldHideFixErrorsAlert
>
@@ -135,7 +134,7 @@ function IdologyQuestions({questions, idNumber}: IdologyQuestionsProps) {
onInputChange={() => {}}
forwardedFSClass={CONST.FULLSTORY.CLASS.MASK}
/>
-
+
toggleOption(item)}
+ disabled={item.isDisabled}
+ role={CONST.ROLE.CHECKBOX}
accessibilityLabel={item.text ? translate('selectionList.userSelected', item.text) : ''}
- containerStyle={[styles.ml5]}
- />
+ style={[styles.flexRow, styles.alignItemsCenter, styles.ml5, styles.optionSelectCircle]}
+ >
+
+
);
}
const buttonInnerStyles = isFocused ? styles.buttonDefaultHovered : {};
@@ -486,7 +493,7 @@ function NewChatPage({ref}: NewChatPageProps) {
>
ref={selectionListRef}
- ListItem={NewChatListItem}
+ ListItem={UserListItem}
sections={areOptionsInitialized ? sections : getEmptyArray>()}
onSelectRow={selectOption}
shouldShowTextInput
diff --git a/src/pages/NewReportWorkspaceSelectionPage.tsx b/src/pages/NewReportWorkspaceSelectionPage.tsx
index acdcd8b64d80..2a981d3bf937 100644
--- a/src/pages/NewReportWorkspaceSelectionPage.tsx
+++ b/src/pages/NewReportWorkspaceSelectionPage.tsx
@@ -283,7 +283,6 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag
onSelectRow={selectPolicy}
textInputOptions={textInputOptions}
shouldShowLoadingPlaceholder={fetchStatus.status === 'loading' || !didScreenTransitionEnd}
- shouldShowRadioButton
/>
>
)}
diff --git a/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx b/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx
index 7e84ed11f5c6..8f99f144bb2a 100644
--- a/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx
+++ b/src/pages/OnboardingAccounting/BaseOnboardingAccounting.tsx
@@ -1,4 +1,4 @@
-import React, {useEffect, useState} from 'react';
+import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import Button from '@components/Button';
import FixedFooter from '@components/FixedFooter';
@@ -128,56 +128,58 @@ function BaseOnboardingAccounting({shouldUseNativeStyles, route}: BaseOnboarding
setOnboardingPolicyID(paidGroupPolicy.id);
}, [paidGroupPolicy, onboardingPolicyID]);
- const createAccountingOption = (integration: Integration): OnboardingListItem => {
- const icon = expensifyIcons[integration.iconName] as IconAsset | undefined;
- return {
- keyForList: integration.key ?? 'none',
- text: translate(integration.translationKey),
+ const accountingOptions: OnboardingListItem[] = useMemo(() => {
+ const createAccountingOption = (integration: Integration): OnboardingListItem => {
+ const icon = expensifyIcons[integration.iconName] as IconAsset | undefined;
+ return {
+ keyForList: integration.key ?? 'none',
+ text: translate(integration.translationKey),
+ leftElement: (
+
+ ),
+ isSelected: userReportedIntegration === integration.key,
+ };
+ };
+
+ const noneAccountingOption: OnboardingListItem = {
+ keyForList: 'none',
+ text: translate('onboarding.accounting.none'),
leftElement: (
),
- isSelected: userReportedIntegration === integration.key,
+ isSelected: userReportedIntegration === null,
};
- };
-
- const noneAccountingOption: OnboardingListItem = {
- keyForList: 'none',
- text: translate('onboarding.accounting.none'),
- leftElement: (
-
- ),
- isSelected: userReportedIntegration === null,
- };
- const othersAccountingOption: OnboardingListItem = {
- keyForList: 'other',
- text: translate('workspace.accounting.other'),
- leftElement: (
-
- ),
- isSelected: userReportedIntegration === 'other',
- };
+ const othersAccountingOption: OnboardingListItem = {
+ keyForList: 'other',
+ text: translate('workspace.accounting.other'),
+ leftElement: (
+
+ ),
+ isSelected: userReportedIntegration === 'other',
+ };
- const accountingOptions: OnboardingListItem[] = [...integrations.map(createAccountingOption), othersAccountingOption, noneAccountingOption];
+ return [...integrations.map(createAccountingOption), othersAccountingOption, noneAccountingOption];
+ }, [StyleUtils, styles.mr3, styles.onboardingSmallIcon, theme.icon, translate, userReportedIntegration, expensifyIcons]);
- const handleContinue = () => {
+ const handleContinue = useCallback(() => {
if (userReportedIntegration === undefined) {
setError(translate('onboarding.errorSelection'));
return;
@@ -187,23 +189,23 @@ function BaseOnboardingAccounting({shouldUseNativeStyles, route}: BaseOnboarding
// Navigate to the next onboarding step interested features with the selected integration
Navigation.navigate(ROUTES.ONBOARDING_INTERESTED_FEATURES.getRoute(route.params?.backTo));
- };
+ }, [translate, userReportedIntegration, route.params?.backTo]);
- const handleIntegrationSelect = (integrationKey: OnboardingListItem['keyForList']) => {
+ const handleIntegrationSelect = useCallback((integrationKey: OnboardingListItem['keyForList']) => {
setUserReportedIntegration(integrationKey === 'none' ? null : integrationKey);
setError('');
- };
+ }, []);
- function renderOption(item: OnboardingListItem) {
- return (
+ const renderOption = useCallback(
+ (item: OnboardingListItem) => (
handleIntegrationSelect(item.keyForList)}
accessibilityLabel={item.text}
sentryLabel={CONST.SENTRY_LABEL.ONBOARDING.ACCOUNTING_SELECT_INTEGRATION}
accessible={false}
- hoverStyle={styles.hoveredComponentBG}
- style={[styles.onboardingAccountingItem, isSmallScreenWidth && styles.flexBasis100]}
+ hoverStyle={!item.isSelected ? styles.hoveredComponentBG : undefined}
+ style={[styles.onboardingAccountingItem, isSmallScreenWidth && styles.flexBasis100, item.isSelected && styles.activeComponentBG]}
>
- );
- }
+ ),
+ [
+ handleIntegrationSelect,
+ isSmallScreenWidth,
+ styles.alignItemsCenter,
+ styles.flexBasis100,
+ styles.flexRow,
+ styles.flexRowReverse,
+ styles.ml0,
+ styles.onboardingAccountingItem,
+ styles.textStrong,
+ styles.hoveredComponentBG,
+ styles.activeComponentBG,
+ ],
+ );
return (
item.keyForList === selectedCompanySize)?.keyForList}
shouldUpdateFocusedIndex
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
footerContent={footerContent}
style={{listItemWrapperStyle: onboardingIsMediumOrLargerScreenWidth ? [styles.pl8, styles.pr8] : []}}
/>
diff --git a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
index 156682bbbc85..0259a336648f 100644
--- a/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
+++ b/src/pages/ReimbursementAccount/USD/BankInfo/subSteps/Plaid.tsx
@@ -76,8 +76,7 @@ function Plaid({onNext, setUSDBankAccountStep}: PlaidProps) {
onSubmit={handleNextPress}
scrollContextEnabled
submitButtonText={translate('common.next')}
- style={[styles.flexGrow1]}
- submitButtonStyles={[styles.mh5]}
+ style={[styles.mh5, styles.flexGrow1]}
isSubmitButtonVisible={(plaidData?.bankAccounts ?? []).length > 0}
shouldHideFixErrorsAlert
>
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
index 81715c013b26..113bd42714d6 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/IndustryCode/IndustryCodeSelector.tsx
@@ -1,7 +1,7 @@
import React, {useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {ALL_NAICS, NAICS, NAICS_MAPPING_WITH_ID} from '@src/NAICS';
@@ -71,7 +71,7 @@ function IndustryCodeSelector({onInputChange, value, errorText}: IndustryCodeSel
{
setSearchValue(item.value);
setShouldDisplayChildItems(true);
diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/BusinessTypePicker/BusinessTypeSelectorModal.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/BusinessTypePicker/BusinessTypeSelectorModal.tsx
index 8d908957e636..63c9f8031470 100644
--- a/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/BusinessTypePicker/BusinessTypeSelectorModal.tsx
+++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/subSteps/TypeBusiness/BusinessTypePicker/BusinessTypeSelectorModal.tsx
@@ -3,7 +3,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
@@ -69,7 +69,7 @@ function BusinessTypeSelectorModal({isVisible, currentBusinessType, onBusinessTy
onSelectRow={onBusinessTypeSelected}
shouldSingleExecuteRowSelect
shouldStopPropagation
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
/>
diff --git a/src/pages/ReportChangeApproverPage.tsx b/src/pages/ReportChangeApproverPage.tsx
index 4b859c619d40..11b9635a4457 100644
--- a/src/pages/ReportChangeApproverPage.tsx
+++ b/src/pages/ReportChangeApproverPage.tsx
@@ -6,7 +6,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import RenderHTML from '@components/RenderHTML';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useEnvironment from '@hooks/useEnvironment';
@@ -150,7 +150,7 @@ function ReportChangeApproverPage({report, policy, isLoadingReportData}: ReportC
/>
{
if (!option.keyForList) {
diff --git a/src/pages/ReportParticipantRoleSelectionPage.tsx b/src/pages/ReportParticipantRoleSelectionPage.tsx
index e855a76d4e09..a988f0aa694e 100644
--- a/src/pages/ReportParticipantRoleSelectionPage.tsx
+++ b/src/pages/ReportParticipantRoleSelectionPage.tsx
@@ -4,7 +4,7 @@ import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -66,7 +66,7 @@ function ReportParticipantRoleSelectionPage({report, route}: ReportParticipantRo
item.isSelected)?.keyForList}
diff --git a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersWithdrawalTypePage.tsx b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersWithdrawalTypePage.tsx
index dddc432740d6..60f9aa282439 100644
--- a/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersWithdrawalTypePage.tsx
+++ b/src/pages/Search/SearchAdvancedFiltersPage/SearchFiltersWithdrawalTypePage.tsx
@@ -63,7 +63,6 @@ function SearchFiltersWithdrawalTypePage() {
ListItem={SingleSelectListItem}
onSelectRow={updateSelectedItem}
shouldSingleExecuteRowSelect
- style={{listItemWrapperStyle: styles.optionRowCompact}}
/>
diff --git a/src/pages/Share/ShareDetailsPage.tsx b/src/pages/Share/ShareDetailsPage.tsx
index 24b7fcd8f87a..eaea655ef94a 100644
--- a/src/pages/Share/ShareDetailsPage.tsx
+++ b/src/pages/Share/ShareDetailsPage.tsx
@@ -10,7 +10,7 @@ import {usePersonalDetails} from '@components/OnyxListItemProvider';
import {PressableWithoutFeedback} from '@components/Pressable';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
-import NewChatListItem from '@components/Search/NewChatListItem';
+import UserListItem from '@components/SelectionList/ListItem/UserListItem';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import useAncestors from '@hooks/useAncestors';
@@ -207,7 +207,7 @@ function ShareDetailsPage({route}: ShareDetailsPageProps) {
{translate('common.to')}
- ({stepNames, label, optio
diff --git a/src/pages/inbox/report/ReportDetailsExportPage.tsx b/src/pages/inbox/report/ReportDetailsExportPage.tsx
index 2b1fed2deaed..08abf2e7d883 100644
--- a/src/pages/inbox/report/ReportDetailsExportPage.tsx
+++ b/src/pages/inbox/report/ReportDetailsExportPage.tsx
@@ -4,6 +4,7 @@ import ConfirmationPage from '@components/ConfirmationPage';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import {ModalActions} from '@components/Modal/Global/ModalContext';
import ScreenWrapper from '@components/ScreenWrapper';
+import UserListItem from '@components/SelectionList/ListItem/UserListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import useConfirmModal from '@hooks/useConfirmModal';
@@ -127,6 +128,7 @@ function ReportDetailsExportPage({route}: ReportDetailsExportPageProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="ReportDetailsExportPage"
data={exportSelectorOptions}
+ listItem={UserListItem}
shouldBeBlocked={false}
onBackButtonPress={() => Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(reportID, backTo))}
title="common.export"
diff --git a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx
index d1a6455ec5e8..3b0e987b6093 100644
--- a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx
+++ b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx
@@ -3,7 +3,7 @@ import React, {useMemo, useState} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import FormHelpMessage from '@components/FormHelpMessage';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import {useCurrencyListActions} from '@hooks/useCurrencyList';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
@@ -204,7 +204,7 @@ function IOURequestStepDistanceRate({
selectDistanceRate(value ?? '')}
shouldSingleExecuteRowSelect
initiallyFocusedItemKey={initiallyFocusedOption}
diff --git a/src/pages/settings/Preferences/LanguagePage.tsx b/src/pages/settings/Preferences/LanguagePage.tsx
index ace307d307a9..a1a0ce81e1ed 100644
--- a/src/pages/settings/Preferences/LanguagePage.tsx
+++ b/src/pages/settings/Preferences/LanguagePage.tsx
@@ -3,7 +3,7 @@ import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOffli
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
import useLocalize from '@hooks/useLocalize';
import Navigation from '@libs/Navigation/Navigation';
@@ -54,7 +54,7 @@ function LanguagePage() {
locale.isSelected)?.keyForList}
diff --git a/src/pages/settings/Preferences/PriorityModePage.tsx b/src/pages/settings/Preferences/PriorityModePage.tsx
index 9ce79bc230c1..50e9355cdba5 100644
--- a/src/pages/settings/Preferences/PriorityModePage.tsx
+++ b/src/pages/settings/Preferences/PriorityModePage.tsx
@@ -3,7 +3,7 @@ import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
@@ -56,7 +56,7 @@ function PriorityModePage() {
{translate('priorityModePage.explainerText')}
mode.isSelected)?.keyForList}
diff --git a/src/pages/settings/Preferences/ThemePage.tsx b/src/pages/settings/Preferences/ThemePage.tsx
index 78e79322adc9..5a5bc77346c9 100644
--- a/src/pages/settings/Preferences/ThemePage.tsx
+++ b/src/pages/settings/Preferences/ThemePage.tsx
@@ -4,7 +4,7 @@ import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
import Switch from '@components/Switch';
import Text from '@components/Text';
@@ -67,7 +67,7 @@ function ThemePage() {
theme.isSelected)?.keyForList}
diff --git a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.tsx b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.tsx
index 9ba4a37bdbb4..d67d3488e4d2 100644
--- a/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.tsx
+++ b/src/pages/settings/Profile/CustomStatus/StatusClearAfterPage.tsx
@@ -5,7 +5,7 @@ import type {LocalizedTranslate} from '@components/LocaleContextProvider';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
@@ -190,7 +190,7 @@ function StatusClearAfterPage() {
() => (
{translate('pronounsPage.isShownOnProfile')}
tz.text === timezone.selected)?.keyForList}
diff --git a/src/pages/settings/Report/DynamicVisibilityPage.tsx b/src/pages/settings/Report/DynamicVisibilityPage.tsx
index ace3e37dd92c..1edc72dd93f5 100644
--- a/src/pages/settings/Report/DynamicVisibilityPage.tsx
+++ b/src/pages/settings/Report/DynamicVisibilityPage.tsx
@@ -4,7 +4,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import {ModalActions} from '@components/Modal/Global/ModalContext';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useConfirmModal from '@hooks/useConfirmModal';
import useDynamicBackPath from '@hooks/useDynamicBackPath';
import useLocalize from '@hooks/useLocalize';
@@ -92,7 +92,7 @@ function DynamicVisibilityPage({report}: DynamicVisibilityProps) {
}}
shouldSingleExecuteRowSelect
initiallyFocusedItemKey={visibilityOptions.find((visibility) => visibility.isSelected)?.keyForList}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
/>
diff --git a/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx b/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx
index b8f86ca373bf..07331f73a6b0 100644
--- a/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx
+++ b/src/pages/settings/Report/DynamicWriteCapabilityPage.tsx
@@ -4,7 +4,7 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDynamicBackPath from '@hooks/useDynamicBackPath';
import useLocalize from '@hooks/useLocalize';
import useReportIsArchived from '@hooks/useReportIsArchived';
@@ -56,7 +56,7 @@ function DynamicWriteCapabilityPage({report, policy}: DynamicWriteCapabilityPage
/>
updateWriteCapability(option.value)}
shouldSingleExecuteRowSelect
initiallyFocusedItemKey={selectedOptionKey}
diff --git a/src/pages/settings/Report/NotificationPreferencePage.tsx b/src/pages/settings/Report/NotificationPreferencePage.tsx
index a38c48258010..fbd62472e9d9 100644
--- a/src/pages/settings/Report/NotificationPreferencePage.tsx
+++ b/src/pages/settings/Report/NotificationPreferencePage.tsx
@@ -5,7 +5,7 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useLocalize from '@hooks/useLocalize';
import useReportIsArchived from '@hooks/useReportIsArchived';
@@ -62,7 +62,7 @@ function NotificationPreferencePage({report}: NotificationPreferencePageProps) {
/>
updateNotificationPreferenceForReportAction(option.value)}
shouldSingleExecuteRowSelect
initiallyFocusedItemKey={notificationPreferenceOptions.find((locale) => locale.isSelected)?.keyForList}
diff --git a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
index 01a389108113..4adec3d12e24 100644
--- a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx
@@ -112,9 +112,8 @@ function AddDelegatePage() {
}}
shouldShowLoadingPlaceholder={!areOptionsInitialized}
isLoadingNewOptions={!!isSearchingForReports}
- onEndReached={onListEndReached}
shouldShowTextInput
- shouldShowRadioButton
+ onEndReached={onListEndReached}
/>
diff --git a/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx
index e497fd9f25b1..e2b2c71abb4e 100644
--- a/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx
@@ -3,7 +3,7 @@ import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useLocalize from '@hooks/useLocalize';
@@ -71,7 +71,7 @@ function SelectDelegateRolePage({route}: SelectDelegateRolePageProps) {
Navigation.navigate(ROUTES.SETTINGS_DELEGATE_CONFIRM.getRoute(login, option.value));
}}
data={roleOptions}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
/>
diff --git a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
index 640e5cd1d392..a704506cacc8 100644
--- a/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
+++ b/src/pages/settings/Security/AddDelegate/UpdateDelegateRole/UpdateDelegateRolePage.tsx
@@ -4,7 +4,7 @@ import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useLocalize from '@hooks/useLocalize';
@@ -79,7 +79,7 @@ function UpdateDelegateRolePage({route}: UpdateDelegateRolePageProps) {
Navigation.navigate(ROUTES.SETTINGS_UPDATE_DELEGATE_ROLE_CONFIRM_MAGIC_CODE.getRoute(login, option?.value));
}}
data={roleOptions}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
/>
diff --git a/src/pages/settings/Subscription/DisableAutoRenewSurveyPage/index.tsx b/src/pages/settings/Subscription/DisableAutoRenewSurveyPage/index.tsx
index 8cf311e6b3b0..4da2af7be9db 100644
--- a/src/pages/settings/Subscription/DisableAutoRenewSurveyPage/index.tsx
+++ b/src/pages/settings/Subscription/DisableAutoRenewSurveyPage/index.tsx
@@ -6,7 +6,7 @@ import ScrollView from '@components/ScrollView';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
-import {updateSubscriptionAutoRenew} from '@userActions/Subscription';
+import * as Subscription from '@userActions/Subscription';
import type {FeedbackSurveyOptionID} from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
@@ -15,7 +15,7 @@ function DisableAutoRenewSurveyPage() {
const styles = useThemeStyles();
const handleSubmit = (key: FeedbackSurveyOptionID, additionalNote?: string) => {
- updateSubscriptionAutoRenew(false, key, additionalNote);
+ Subscription.updateSubscriptionAutoRenew(false, key, additionalNote);
Navigation.goBack();
};
@@ -36,6 +36,7 @@ function DisableAutoRenewSurveyPage() {
title={translate('subscription.subscriptionSettings.helpUsImprove')}
description={translate('subscription.subscriptionSettings.whatsMainReason')}
onSubmit={handleSubmit}
+ optionRowStyles={styles.flex1}
/>
diff --git a/src/pages/settings/Subscription/RequestEarlyCancellationPage/index.tsx b/src/pages/settings/Subscription/RequestEarlyCancellationPage/index.tsx
index 3e9a78708cf8..82fa8fa1cbe3 100644
--- a/src/pages/settings/Subscription/RequestEarlyCancellationPage/index.tsx
+++ b/src/pages/settings/Subscription/RequestEarlyCancellationPage/index.tsx
@@ -89,13 +89,14 @@ function RequestEarlyCancellationPage() {
title={translate('subscription.subscriptionSettings.helpUsImprove')}
description={translate('subscription.requestEarlyCancellation.subtitle')}
onSubmit={handleSubmit}
+ optionRowStyles={styles.flex1}
footerText={{acknowledgementText}}
isNoteRequired
isLoading={isLoading}
enabledWhenOffline={false}
/>
),
- [acknowledgementText, isLoading, styles.mb2, styles.mt4, translate],
+ [acknowledgementText, isLoading, styles.flex1, styles.mb2, styles.mt4, translate],
);
const contentMap: Partial> = {
diff --git a/src/pages/settings/Wallet/ChooseTransferAccountPage.tsx b/src/pages/settings/Wallet/ChooseTransferAccountPage.tsx
index f66e27602a67..d69ebade16b1 100644
--- a/src/pages/settings/Wallet/ChooseTransferAccountPage.tsx
+++ b/src/pages/settings/Wallet/ChooseTransferAccountPage.tsx
@@ -7,7 +7,7 @@ import getBankIcon from '@components/Icon/BankIcons';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
@@ -110,7 +110,7 @@ function ChooseTransferAccountPage() {
{
const accountType = value?.bankAccount?.accountType;
const accountData = value?.bankAccount?.accountData;
diff --git a/src/pages/settings/Wallet/CountrySelectionList.tsx b/src/pages/settings/Wallet/CountrySelectionList.tsx
index c90581745dc3..30c39317c1f6 100644
--- a/src/pages/settings/Wallet/CountrySelectionList.tsx
+++ b/src/pages/settings/Wallet/CountrySelectionList.tsx
@@ -2,7 +2,7 @@ import React, {useState} from 'react';
import {View} from 'react-native';
import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useNetwork from '@hooks/useNetwork';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -76,7 +76,7 @@ function CountrySelectionList({isEditing, selectedCountry, countries, onCountryS
item.isSelected)?.keyForList}
diff --git a/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx b/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx
index 714e8cb1a789..4fef9a6419de 100644
--- a/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx
+++ b/src/pages/workspace/WorkspaceOverviewPlanTypePage.tsx
@@ -8,7 +8,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Icon from '@components/Icon';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
@@ -137,7 +137,7 @@ function WorkspaceOverviewPlanTypePage({policy}: WithPolicyProps) {
{
setCurrentPlan(option.value);
}}
diff --git a/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx b/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx
index 30de249b6547..422fe57497c1 100644
--- a/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx
+++ b/src/pages/workspace/accounting/intacct/SageIntacctEntityPage.tsx
@@ -1,4 +1,5 @@
import React from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -46,6 +47,7 @@ function SageIntacctEntityPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctEntityPage"
data={options}
+ listItem={RadioListItem}
onSelectRow={saveSelection}
initiallyFocusedOptionKey={options?.find((mode) => mode.isSelected)?.keyForList}
onBackButtonPress={() => Navigation.dismissModal()}
diff --git a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAccountingMethodPage.tsx b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAccountingMethodPage.tsx
index e97c01211396..226315c5f954 100644
--- a/src/pages/workspace/accounting/intacct/advanced/SageIntacctAccountingMethodPage.tsx
+++ b/src/pages/workspace/accounting/intacct/advanced/SageIntacctAccountingMethodPage.tsx
@@ -2,6 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -64,6 +65,7 @@ function SageIntacctAccountingMethodPage({policy}: WithPolicyConnectionsProps) {
headerTitleAlreadyTranslated={translate('workspace.sageIntacct.accountingMethods.label')}
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExpenseReportApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/intacct/advanced/SageIntacctPaymentAccountPage.tsx b/src/pages/workspace/accounting/intacct/advanced/SageIntacctPaymentAccountPage.tsx
index b906bcde9afd..3502694bb8c7 100644
--- a/src/pages/workspace/accounting/intacct/advanced/SageIntacctPaymentAccountPage.tsx
+++ b/src/pages/workspace/accounting/intacct/advanced/SageIntacctPaymentAccountPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -56,6 +57,7 @@ function SageIntacctPaymentAccountPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctPaymentAccountPage"
data={vendorSelectorOptions ?? []}
+ listItem={RadioListItem}
onSelectRow={updateDefaultVendor}
initiallyFocusedOptionKey={vendorSelectorOptions.find((mode) => mode.isSelected)?.keyForList}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_SAGE_INTACCT_ADVANCED.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx
index 069407c9da39..a8427290ff18 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDatePage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -70,6 +71,7 @@ function SageIntacctDatePage({policy}: WithPolicyProps) {
title="workspace.sageIntacct.exportDate.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExportDate(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx
index 595e378ec61a..63cac22d6ca3 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctDefaultVendorPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -100,6 +101,7 @@ function SageIntacctDefaultVendorPage() {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctDefaultVendorPage"
data={vendorSelectorOptions ?? []}
+ listItem={RadioListItem}
onSelectRow={updateDefaultVendor}
initiallyFocusedOptionKey={vendorSelectorOptions.find((mode) => mode.isSelected)?.keyForList}
headerContent={listHeaderComponent}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx
index 237ccfa4c15e..03ae19b04d74 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableCreditCardAccountPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -67,6 +68,7 @@ function SageIntacctNonReimbursableCreditCardAccountPage({policy}: WithPolicyCon
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctNonReimbursableCreditCardAccountPage"
data={creditCardSelectorOptions ?? []}
+ listItem={RadioListItem}
onSelectRow={updateCreditCardAccount}
initiallyFocusedOptionKey={creditCardSelectorOptions.find((mode) => mode.isSelected)?.keyForList}
onBackButtonPress={goBack}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx
index a11dac3f6389..2c6e558c3006 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctNonReimbursableExpensesDestinationPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback} from 'react';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -57,6 +58,7 @@ function SageIntacctNonReimbursableExpensesDestinationPage({policy}: WithPolicyC
displayName="SageIntacctNonReimbursableExpensesDestinationPage"
title="workspace.accounting.exportAs"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectDestination(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx
index faec53df8bda..f84da6131ad1 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctPreferredExporterPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import isEmpty from 'lodash/isEmpty';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -101,6 +102,7 @@ function SageIntacctPreferredExporterPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctPreferredExporterPage"
data={data}
+ listItem={RadioListItem}
headerContent={headerContent}
onSelectRow={selectExporter}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx
index 5c2cdb7bf82f..6215ea532bc2 100644
--- a/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx
+++ b/src/pages/workspace/accounting/intacct/export/SageIntacctReimbursableExpensesDestinationPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback} from 'react';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -61,6 +62,7 @@ function SageIntacctReimbursableExpensesDestinationPage({policy}: WithPolicyConn
displayName="SageIntacctReimbursableExpensesDestinationPage"
title="workspace.accounting.exportAs"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectDestination(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/intacct/import/DimensionTypeSelector.tsx b/src/pages/workspace/accounting/intacct/import/DimensionTypeSelector.tsx
index 8cea931b560d..afd458e7e943 100644
--- a/src/pages/workspace/accounting/intacct/import/DimensionTypeSelector.tsx
+++ b/src/pages/workspace/accounting/intacct/import/DimensionTypeSelector.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
@@ -52,7 +52,7 @@ function DimensionTypeSelector({errorText = '', value = '', onInputChange}: Dime
{translate('workspace.common.displayedAs')}
{selectionOptions.map((option) => (
- option.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx
index a7346ecd0582..7481d00e8c16 100644
--- a/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx
+++ b/src/pages/workspace/accounting/intacct/import/SageIntacctMappingsTypePage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -80,6 +81,7 @@ function SageIntacctMappingsTypePage({route}: SageIntacctMappingsTypePageProps)
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="SageIntacctMappingsTypePage"
data={selectionOptions}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.SAGE_INTACCT}
onSelectRow={updateMapping}
initiallyFocusedOptionKey={mappings?.[mappingName]}
diff --git a/src/pages/workspace/accounting/netsuite/NetSuiteSubsidiarySelector.tsx b/src/pages/workspace/accounting/netsuite/NetSuiteSubsidiarySelector.tsx
index ed7f9784fa00..dede5431670e 100644
--- a/src/pages/workspace/accounting/netsuite/NetSuiteSubsidiarySelector.tsx
+++ b/src/pages/workspace/accounting/netsuite/NetSuiteSubsidiarySelector.tsx
@@ -1,6 +1,7 @@
import React, {useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -86,6 +87,7 @@ function NetSuiteSubsidiarySelector({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteSubsidiarySelector"
data={subsidiaryListSections}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.NETSUITE}
onSelectRow={updateSubsidiary}
initiallyFocusedOptionKey={netsuiteConfig?.subsidiaryID ?? subsidiaryListSections?.at(0)?.keyForList}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx
index 3c79fd2f5c2d..2a87dfce9ff3 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteAccountingMethodPage.tsx
@@ -2,6 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -70,6 +71,7 @@ function NetSuiteAccountingMethodPage({policy, route}: WithPolicyConnectionsProp
title="workspace.netsuite.advancedConfig.accountingMethods.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExpenseReportApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteApprovalAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteApprovalAccountSelectPage.tsx
index 572fa3e8dbcd..4b5fb3848d5c 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteApprovalAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteApprovalAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -76,6 +77,7 @@ function NetSuiteApprovalAccountSelectPage({policy}: WithPolicyConnectionsProps)
displayName="NetSuiteApprovalAccountSelectPage"
headerContent={headerContent}
data={netsuiteApprovalAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateCollectionAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteCollectionAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteCollectionAccountSelectPage.tsx
index 99ae1bdf1b13..11ac2d64d7dc 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteCollectionAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteCollectionAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -74,6 +75,7 @@ function NetSuiteCollectionAccountSelectPage({policy}: WithPolicyConnectionsProp
displayName="NetSuiteCollectionAccountSelectPage"
headerContent={headerContent}
data={netsuiteCollectionAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateCollectionAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteExpenseReportApprovalLevelSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteExpenseReportApprovalLevelSelectPage.tsx
index 5b2eb09fa429..2302aba38e6c 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteExpenseReportApprovalLevelSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteExpenseReportApprovalLevelSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -58,6 +59,7 @@ function NetSuiteExpenseReportApprovalLevelSelectPage({policy}: WithPolicyConnec
title="workspace.netsuite.advancedConfig.exportReportsTo.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExpenseReportApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteJournalEntryApprovalLevelSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteJournalEntryApprovalLevelSelectPage.tsx
index 98f32ca34b49..0f0cf14a6075 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteJournalEntryApprovalLevelSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteJournalEntryApprovalLevelSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -58,6 +59,7 @@ function NetSuiteJournalEntryApprovalLevelSelectPage({policy}: WithPolicyConnect
title="workspace.netsuite.advancedConfig.exportJournalsTo.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectJournalApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteReimbursementAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteReimbursementAccountSelectPage.tsx
index d94fbb31accf..c3c86c2ac9f0 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteReimbursementAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteReimbursementAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -74,6 +75,7 @@ function NetSuiteReimbursementAccountSelectPage({policy}: WithPolicyConnectionsP
displayName="NetSuiteReimbursementAccountSelectPage"
headerContent={headerContent}
data={netsuiteReimbursableAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateReimbursementAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_ADVANCED.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteVendorBillApprovalLevelSelectPage.tsx b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteVendorBillApprovalLevelSelectPage.tsx
index b38e462cc68e..520d84e8ac87 100644
--- a/src/pages/workspace/accounting/netsuite/advanced/NetSuiteVendorBillApprovalLevelSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/advanced/NetSuiteVendorBillApprovalLevelSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -58,6 +59,7 @@ function NetSuiteVendorBillApprovalLevelSelectPage({policy}: WithPolicyConnectio
title="workspace.netsuite.advancedConfig.exportVendorBillsTo.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectVendorBillApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteDateSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteDateSelectPage.tsx
index 5e2b918fc2d1..da754ee2b9f1 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteDateSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteDateSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -70,6 +71,7 @@ function NetSuiteDateSelectPage({policy}: WithPolicyConnectionsProps) {
title="workspace.netsuite.exportDate.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExportDate(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesDestinationSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesDestinationSelectPage.tsx
index 4eb5ebbfecb7..822fd1e71346 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesDestinationSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesDestinationSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useState} from 'react';
import type {ValueOf} from 'type-fest';
import ConfirmModal from '@components/ConfirmModal';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -79,6 +80,7 @@ function NetSuiteExportExpensesDestinationSelectPage({policy}: WithPolicyConnect
displayName="NetSuiteExportExpensesDestinationSelectPage"
title="workspace.accounting.exportAs"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectDestination(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesJournalPostingPreferenceSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesJournalPostingPreferenceSelectPage.tsx
index f82289e52eeb..5c2badb091af 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesJournalPostingPreferenceSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesJournalPostingPreferenceSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback} from 'react';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -64,6 +65,7 @@ function NetSuiteExportExpensesJournalPostingPreferenceSelectPage({policy}: With
displayName="NetSuiteExportExpensesJournalPostingPreferenceSelectPage"
title="workspace.netsuite.journalPostingPreference.label"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectPostingPreference(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesPayableAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesPayableAccountSelectPage.tsx
index 40ec9d2cc26b..d0cb687b0e30 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesPayableAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesPayableAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -78,6 +79,7 @@ function NetSuiteExportExpensesPayableAccountSelectPage({policy}: WithPolicyConn
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteExportExpensesPayableAccountSelectPage"
data={netsuitePayableAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updatePayableAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={goBack}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesVendorSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesVendorSelectPage.tsx
index 21914f5585aa..95d20e1c452b 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesVendorSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteExportExpensesVendorSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -72,6 +73,7 @@ function NetSuiteExportExpensesVendorSelectPage({policy}: WithPolicyConnectionsP
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteExportExpensesVendorSelectPage"
data={netsuiteVendorOptions}
+ listItem={RadioListItem}
onSelectRow={updateDefaultVendor}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={goBack}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemPreferenceSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemPreferenceSelectPage.tsx
index 8bf6c1258d6e..6fbd6ab23ad4 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemPreferenceSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemPreferenceSelectPage.tsx
@@ -6,7 +6,7 @@ import ConnectionLayout from '@components/ConnectionLayout';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem, SelectionListHandle} from '@components/SelectionList/types';
import type {SelectorType} from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -103,7 +103,7 @@ function NetSuiteInvoiceItemPreferenceSelectPage({policy}: WithPolicyConnections
onSelectRow={(selection: SelectorType) => {
selectInvoicePreference(selection as MenuListItem);
}}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
showScrollIndicator
shouldUpdateFocusedIndex
initiallyFocusedItemKey={options.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemSelectPage.tsx
index 410e530fd4b9..ad350c55360d 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteInvoiceItemSelectPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -59,6 +60,7 @@ function NetSuiteInvoiceItemSelectPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteInvoiceItemSelectPage"
data={netsuiteInvoiceItemOptions}
+ listItem={RadioListItem}
onSelectRow={updateInvoiceItem}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_INVOICE_ITEM_PREFERENCE_SELECT.getRoute(policyID), {compareParams: false})}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx
index 1de500018e0a..e6f4f85c3ee8 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuitePreferredExporterSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import isEmpty from 'lodash/isEmpty';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -98,6 +99,7 @@ function NetSuitePreferredExporterSelectPage({policy}: WithPolicyConnectionsProp
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuitePreferredExporterSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={headerContent}
onSelectRow={selectExporter}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteProvincialTaxPostingAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteProvincialTaxPostingAccountSelectPage.tsx
index 456e1b7f1b6d..6f81824a5e6e 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteProvincialTaxPostingAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteProvincialTaxPostingAccountSelectPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -65,6 +66,7 @@ function NetSuiteProvincialTaxPostingAccountSelectPage({policy}: WithPolicyConne
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteProvincialTaxPostingAccountSelectPage"
data={netsuiteTaxAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateTaxAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_EXPORT.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteReceivableAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteReceivableAccountSelectPage.tsx
index 0239ae546b0c..7cdfa5e1f698 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteReceivableAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteReceivableAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -70,6 +71,7 @@ function NetSuiteReceivableAccountSelectPage({policy}: WithPolicyConnectionsProp
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteReceivableAccountSelectPage"
data={netsuiteReceivableAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateReceivableAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={goBack}
diff --git a/src/pages/workspace/accounting/netsuite/export/NetSuiteTaxPostingAccountSelectPage.tsx b/src/pages/workspace/accounting/netsuite/export/NetSuiteTaxPostingAccountSelectPage.tsx
index d4a904aab190..6f43dfc97299 100644
--- a/src/pages/workspace/accounting/netsuite/export/NetSuiteTaxPostingAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/export/NetSuiteTaxPostingAccountSelectPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -67,6 +68,7 @@ function NetSuiteTaxPostingAccountSelectPage({policy}: WithPolicyConnectionsProp
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteTaxPostingAccountSelectPage"
data={netsuiteTaxAccountOptions}
+ listItem={RadioListItem}
onSelectRow={updateTaxAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_NETSUITE_EXPORT.getRoute(policyID))}
diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx
index a5f743bb0ec5..e365e8d95b37 100644
--- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx
+++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomFieldMappingPicker.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
@@ -40,7 +40,7 @@ function NetSuiteCustomFieldMappingPicker({value, errorText, onInputChange}: Net
onSelectRow={(selected) => {
onInputChange?.(selected.value);
}}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG}
shouldSingleExecuteRowSelect
shouldUpdateFocusedIndex
diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomListSelectorModal.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomListSelectorModal.tsx
index 6decd613ed64..98c9fddc69fb 100644
--- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomListSelectorModal.tsx
+++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomListSelectorModal.tsx
@@ -4,7 +4,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import type {CustomListSelectorType} from '@pages/workspace/accounting/netsuite/types';
@@ -92,7 +92,7 @@ function NetSuiteCustomListSelectorModal({isVisible, currentCustomListValue, onC
data={options}
textInputOptions={textInputOptions}
onSelectRow={onCustomListSelected}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={currentCustomListValue}
shouldSingleExecuteRowSelect
shouldStopPropagation
diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomSegmentMappingPicker.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomSegmentMappingPicker.tsx
index 538c4c582c5f..1ef9c0d4faae 100644
--- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomSegmentMappingPicker.tsx
+++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomFieldNew/NetSuiteCustomSegmentMappingPicker.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import {View} from 'react-native';
import FormHelpMessage from '@components/FormHelpMessage';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
@@ -44,7 +44,7 @@ function NetSuiteCustomSegmentMappingPicker({value, errorText, onInputChange}: N
onSelectRow={(selected) => {
onInputChange?.(selected.value);
}}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={value ?? CONST.INTEGRATION_ENTITY_MAP_TYPES.TAG}
shouldSingleExecuteRowSelect
shouldUpdateFocusedIndex
diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomersOrProjectSelectPage.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomersOrProjectSelectPage.tsx
index 84d3198ccf56..e3b96d5d9025 100644
--- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomersOrProjectSelectPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportCustomersOrProjectSelectPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -67,6 +68,7 @@ function NetSuiteImportCustomersOrProjectSelectPage({policy}: WithPolicyConnecti
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteImportCustomersOrProjectSelectPage"
data={inputSectionData}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.NETSUITE}
onSelectRow={(selection: SelectorType) => updateImportMapping(selection as ImportListItem)}
initiallyFocusedOptionKey={inputSectionData.find((inputOption) => inputOption.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportMappingPage.tsx b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportMappingPage.tsx
index 414acde28a18..40fb57c6d571 100644
--- a/src/pages/workspace/accounting/netsuite/import/NetSuiteImportMappingPage.tsx
+++ b/src/pages/workspace/accounting/netsuite/import/NetSuiteImportMappingPage.tsx
@@ -2,6 +2,7 @@ import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {TupleToUnion, ValueOf} from 'type-fest';
import RenderHTML from '@components/RenderHTML';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -99,6 +100,7 @@ function NetSuiteImportMappingPage({
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="NetSuiteImportMappingPage"
data={inputSectionData}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.NETSUITE}
onSelectRow={(selection: SelectorType) => updateImportMapping(selection as ImportListItem)}
initiallyFocusedOptionKey={inputSectionData.find((inputOption) => inputOption.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbd/advanced/QuickbooksDesktopAccountingMethodPage.tsx b/src/pages/workspace/accounting/qbd/advanced/QuickbooksDesktopAccountingMethodPage.tsx
index c328a3476bb4..c681b746adfa 100644
--- a/src/pages/workspace/accounting/qbd/advanced/QuickbooksDesktopAccountingMethodPage.tsx
+++ b/src/pages/workspace/accounting/qbd/advanced/QuickbooksDesktopAccountingMethodPage.tsx
@@ -2,6 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -68,6 +69,7 @@ function QuickbooksDesktopAccountingMethodPage({policy}: WithPolicyConnectionsPr
headerTitleAlreadyTranslated={translate('workspace.qbd.accountingMethods.label')}
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectAccountingMethod(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage.tsx
index 03392b2ea453..fb9020742fc7 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage.tsx
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -101,6 +102,7 @@ function QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage({policy}: With
displayName="QuickbooksDesktopCompanyCardExpenseAccountSelectCardPage"
title="workspace.accounting.exportAs"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExportCompanyCard(selection as MenuItem)}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectPage.tsx
index eb312b1cdc2e..9bc0ef26c0e2 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopCompanyCardExpenseAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -86,6 +87,7 @@ function QuickbooksDesktopCompanyCardExpenseAccountSelectPage({policy}: WithPoli
headerTitleAlreadyTranslated={getQBDNonReimbursableExportAccountType(translate, nonReimbursable)}
headerContent={nonReimbursable ? {translate(`workspace.qbd.accounts.${nonReimbursable}AccountDescription`)} : null}
data={data}
+ listItem={RadioListItem}
onSelectRow={selectExportAccount}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopExportDateSelectPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopExportDateSelectPage.tsx
index 4943c97428fa..a50c96055e47 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopExportDateSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopExportDateSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -67,6 +68,7 @@ function QuickbooksDesktopExportDateSelectPage({policy}: WithPolicyConnectionsPr
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopExportDateSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={{translate('workspace.qbd.exportDate.description')}}
onBackButtonPress={goBack}
onSelectRow={selectExportDate}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopNonReimbursableDefaultVendorSelectPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopNonReimbursableDefaultVendorSelectPage.tsx
index e3e635ab711e..178ccdea04bd 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopNonReimbursableDefaultVendorSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopNonReimbursableDefaultVendorSelectPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -73,6 +74,7 @@ function QuickbooksDesktopNonReimbursableDefaultVendorSelectPage({policy}: WithP
displayName="QuickbooksDesktopNonReimbursableDefaultVendorSelectPage"
title="workspace.accounting.defaultVendor"
data={data}
+ listItem={RadioListItem}
onSelectRow={selectVendor}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseAccountSelectPage.tsx
index ee60cb315d51..b4d6928a0f06 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -108,6 +109,7 @@ function QuickbooksDesktopOutOfPocketExpenseAccountSelectPage({policy}: WithPoli
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopOutOfPocketExpenseAccountSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={{description}}
onBackButtonPress={goBack}
onSelectRow={selectExportAccount}
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseEntitySelectPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseEntitySelectPage.tsx
index a8df2ab9d9ee..8a797b28a188 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseEntitySelectPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopOutOfPocketExpenseEntitySelectPage.tsx
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -99,6 +100,7 @@ function QuickbooksDesktopOutOfPocketExpenseEntitySelectPage({policy}: WithPolic
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopOutOfPocketExpenseEntitySelectPage"
data={filteredData}
+ listItem={RadioListItem}
onBackButtonPress={goBack}
onSelectRow={(selection: SelectorType) => selectExportEntity(selection as MenuItem)}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopPreferredExporterConfigurationPage.tsx b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopPreferredExporterConfigurationPage.tsx
index 0a5d36097760..d6d1efb0e4de 100644
--- a/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopPreferredExporterConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/qbd/export/QuickbooksDesktopPreferredExporterConfigurationPage.tsx
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -93,6 +94,7 @@ function QuickbooksDesktopPreferredExporterConfigurationPage({policy}: WithPolic
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopPreferredExporterConfigurationPage"
data={data}
+ listItem={RadioListItem}
headerContent={headerContent}
onBackButtonPress={goBack}
onSelectRow={selectExporter}
diff --git a/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopClassesDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopClassesDisplayedAsPage.tsx
index 595abac9b560..f13f1be974fc 100644
--- a/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopClassesDisplayedAsPage.tsx
+++ b/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopClassesDisplayedAsPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -57,6 +58,7 @@ function QuickbooksDesktopClassesDisplayedAsPage({policy}: WithPolicyConnections
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopClassesDisplayedAsPage"
data={data}
+ listItem={RadioListItem}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_CLASSES.getRoute(policyID))}
onSelectRow={selectDisplayedAs}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopCustomersDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopCustomersDisplayedAsPage.tsx
index 97b49e4437de..ff780be88174 100644
--- a/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopCustomersDisplayedAsPage.tsx
+++ b/src/pages/workspace/accounting/qbd/import/QuickbooksDesktopCustomersDisplayedAsPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -57,6 +58,7 @@ function QuickbooksDesktopCustomersDisplayedAsPage({policy}: WithPolicyConnectio
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksDesktopCustomersDisplayedAsPage"
data={data}
+ listItem={RadioListItem}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_DESKTOP_CUSTOMERS.getRoute(policyID))}
onSelectRow={selectDisplayedAs}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx
index b62c2ca4b720..e0f8e2ef6e05 100644
--- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -82,6 +83,7 @@ function QuickbooksAccountSelectPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksAccountSelectPage"
data={qboOnlineSelectorOptions}
+ listItem={RadioListItem}
headerContent={listHeaderComponent}
onSelectRow={saveSelection}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx
index fb8b979799de..a5ae2291733d 100644
--- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx
+++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAccountingMethodPage.tsx
@@ -2,6 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -69,6 +70,7 @@ function QuickbooksAccountingMethodPage({policy, route}: WithPolicyConnectionsPr
headerTitleAlreadyTranslated={translate('workspace.qbo.accountingMethods.label')}
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExpenseReportApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx
index 84947ca34ef0..06948484b317 100644
--- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksInvoiceAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -83,6 +84,7 @@ function QuickbooksInvoiceAccountSelectPage({policy}: WithPolicyConnectionsProps
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksInvoiceAccountSelectPage"
data={qboOnlineSelectorOptions}
+ listItem={RadioListItem}
headerContent={listHeaderComponent}
onSelectRow={updateAccount}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx
index 0760c6ad344b..06845f56789b 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -102,6 +103,7 @@ function QuickbooksCompanyCardExpenseAccountSelectCardPage({policy}: WithPolicyC
displayName="QuickbooksCompanyCardExpenseAccountSelectCardPage"
title="workspace.accounting.exportAs"
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExportCompanyCard(selection as MenuItem)}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx
index ebea42dc1e2d..08e0b0380dad 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -101,6 +102,7 @@ function QuickbooksCompanyCardExpenseAccountSelectPage({policy}: WithPolicyConne
) : null
}
data={data}
+ listItem={RadioListItem}
onSelectRow={selectExportAccount}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportDateSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportDateSelectPage.tsx
index 2fc100da1566..41e63071e89e 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportDateSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportDateSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -60,6 +61,7 @@ function QuickbooksExportDateSelectPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksExportDateSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={{translate('workspace.qbo.exportDate.description')}}
onBackButtonPress={goBack}
onSelectRow={selectExportDate}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx
index 5586ee019ad8..d8621a0d09fa 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportInvoiceAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -82,6 +83,7 @@ function QuickbooksExportInvoiceAccountSelectPage({policy}: WithPolicyConnection
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksExportInvoiceAccountSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={{translate('workspace.qbo.exportInvoicesDescription')}}
onBackButtonPress={goBack}
onSelectRow={selectExportInvoice}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelPayableAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelPayableAccountSelectPage.tsx
index bddfa435a0f5..7c36dca21d85 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelPayableAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelPayableAccountSelectPage.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -71,6 +72,7 @@ function QuickbooksExportTravelPayableAccountSelectPage({policy}: WithPolicyConn
displayName="QuickbooksExportTravelPayableAccountSelectPage"
title="workspace.qbo.travelInvoicingPayableAccount"
data={data}
+ listItem={RadioListItem}
onSelectRow={selectAccount}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelVendorSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelVendorSelectPage.tsx
index d94f42400dca..e7d62b23fd7d 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelVendorSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksExportTravelVendorSelectPage.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -65,6 +66,7 @@ function QuickbooksExportTravelVendorSelectPage({policy}: WithPolicyConnectionsP
displayName="QuickbooksExportTravelVendorSelectPage"
title="workspace.qbo.travelInvoicingVendor"
data={data}
+ listItem={RadioListItem}
onSelectRow={selectVendor}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx
index bc535c9b2c4f..2250c2cbf202 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx
@@ -1,5 +1,6 @@
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset';
@@ -70,6 +71,7 @@ function QuickbooksNonReimbursableDefaultVendorSelectPage({policy}: WithPolicyCo
displayName="QuickbooksNonReimbursableDefaultVendorSelectPage"
title="workspace.accounting.defaultVendor"
data={data}
+ listItem={RadioListItem}
onSelectRow={selectVendor}
shouldSingleExecuteRowSelect
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx
index 57c679b89094..4e9b0aef5598 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseAccountSelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -120,6 +121,7 @@ function QuickbooksOutOfPocketExpenseAccountSelectPage({policy}: WithPolicyConne
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksOutOfPocketExpenseAccountSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={{description}}
onBackButtonPress={goBack}
onSelectRow={selectExportAccount}
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx
index 65812ba7db96..73a953ed3018 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo, useState} from 'react';
import {View} from 'react-native';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -129,6 +130,7 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksOutOfPocketExpenseEntitySelectPage"
data={filteredData}
+ listItem={RadioListItem}
onBackButtonPress={goBack}
onSelectRow={(selection: SelectorType) => selectExportEntity(selection as MenuItem)}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksPreferredExporterConfigurationPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksPreferredExporterConfigurationPage.tsx
index 61167b2acc36..a9ec3f6ae3c2 100644
--- a/src/pages/workspace/accounting/qbo/export/QuickbooksPreferredExporterConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/qbo/export/QuickbooksPreferredExporterConfigurationPage.tsx
@@ -1,5 +1,6 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -86,6 +87,7 @@ function QuickbooksPreferredExporterConfigurationPage({policy}: WithPolicyConnec
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksPreferredExporterConfigurationPage"
data={data}
+ listItem={RadioListItem}
headerContent={headerContent}
onBackButtonPress={goBack}
onSelectRow={selectExporter}
diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx
index 2998d6c34faa..962b562403c3 100644
--- a/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx
+++ b/src/pages/workspace/accounting/qbo/import/QuickbooksClassesDisplayedAsPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -64,6 +65,7 @@ function QuickbooksClassesDisplayedAsPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksClassesDisplayedAsPage"
data={data}
+ listItem={RadioListItem}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CLASSES.getRoute(policyID))}
onSelectRow={selectDisplayedAs}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx
index a52c4cd2374a..8f9f47e7a43c 100644
--- a/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx
+++ b/src/pages/workspace/accounting/qbo/import/QuickbooksCustomersDisplayedAsPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -64,6 +65,7 @@ function QuickbooksCustomersDisplayedAsPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksCustomersDisplayedAsPage"
data={data}
+ listItem={RadioListItem}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_CUSTOMERS.getRoute(policyID))}
onSelectRow={(selection) => selectDisplayedAs(selection as CardListItem)}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx
index 6636c20fddf4..301fedb1d051 100644
--- a/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx
+++ b/src/pages/workspace/accounting/qbo/import/QuickbooksLocationsDisplayedAsPage.tsx
@@ -1,4 +1,5 @@
import React, {useCallback, useMemo} from 'react';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import useLocalize from '@hooks/useLocalize';
@@ -70,6 +71,7 @@ function QuickbooksLocationsDisplayedAsPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="QuickbooksLocationsDisplayedAsPage"
data={data}
+ listItem={RadioListItem}
onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_LOCATIONS.getRoute(policyID))}
onSelectRow={(selection) => selectDisplayedAs(selection as CardListItem)}
shouldSingleExecuteRowSelect
diff --git a/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx
index e420c2071ccd..517506ed80e1 100644
--- a/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx
+++ b/src/pages/workspace/accounting/reconciliation/ReconciliationAccountSettingsPage.tsx
@@ -3,7 +3,7 @@ import {View} from 'react-native';
import ConnectionLayout from '@components/ConnectionLayout';
import RenderHTML from '@components/RenderHTML';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useDefaultFundID from '@hooks/useDefaultFundID';
import useEnvironment from '@hooks/useEnvironment';
@@ -110,7 +110,7 @@ function ReconciliationAccountSettingsPage({route}: ReconciliationAccountSetting
selectBankAccount(value)}
- ListItem={SingleSelectListItem}
+ ListItem={RadioListItem}
initiallyFocusedItemKey={paymentBankAccountID?.toString()}
/>
diff --git a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
index f4e3ebd9828d..d9b4e40ba34f 100644
--- a/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroMapTrackingCategoryConfigurationPage.tsx
@@ -1,6 +1,7 @@
import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
@@ -100,6 +101,7 @@ function XeroMapTrackingCategoryConfigurationPage({policy}: WithPolicyProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroMapTrackingCategoryConfigurationPage"
data={optionsList}
+ listItem={RadioListItem}
onSelectRow={updateMapping}
initiallyFocusedOptionKey={optionsList.find((option) => option.isSelected)?.keyForList}
headerContent={listHeaderComponent}
diff --git a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
index 7e0ee0e56092..cd9c7084777a 100644
--- a/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
+++ b/src/pages/workspace/accounting/xero/XeroOrganizationConfigurationPage.tsx
@@ -1,6 +1,7 @@
import React, {useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -84,6 +85,7 @@ function XeroOrganizationConfigurationPage({
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroOrganizationConfigurationPage"
data={sections}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.XERO}
onSelectRow={saveSelection}
initiallyFocusedOptionKey={currentXeroOrganization?.id}
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroAccountingMethodPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroAccountingMethodPage.tsx
index d6a958958d22..4d9d131e85f2 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroAccountingMethodPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroAccountingMethodPage.tsx
@@ -2,6 +2,7 @@ import {CONST as COMMON_CONST} from 'expensify-common';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -69,6 +70,7 @@ function XeroAccountingMethodPage({policy, route}: WithPolicyConnectionsProps) {
headerTitleAlreadyTranslated={translate('workspace.xero.accountingMethods.label')}
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExpenseReportApprovalLevel(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
index 13c6fb3e68c9..b5ac786369f1 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroBillPaymentAccountSelectorPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -68,6 +69,7 @@ function XeroBillPaymentAccountSelectorPage({policy}: WithPolicyConnectionsProps
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroBillPaymentAccountSelectorPage"
data={xeroSelectorOptions}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.XERO}
shouldBeBlocked={!syncReimbursedReports}
onSelectRow={updateAccount}
diff --git a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
index cd743a8cf5d9..b94b98409446 100644
--- a/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/advanced/XeroInvoiceAccountSelectorPage.tsx
@@ -1,6 +1,7 @@
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -68,6 +69,7 @@ function XeroInvoiceAccountSelectorPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroInvoiceAccountSelectorPage"
data={xeroSelectorOptions}
+ listItem={RadioListItem}
connectionName={CONST.POLICY.CONNECTIONS.NAME.XERO}
shouldBeBlocked={!syncReimbursedReports}
onSelectRow={updateAccount}
diff --git a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
index 29ee2be5714d..031e89d6a43d 100644
--- a/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroBankAccountSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {SelectorType} from '@components/SelectionScreen';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -84,6 +85,7 @@ function XeroBankAccountSelectPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroBankAccountSelectPage"
data={xeroSelectorOptions}
+ listItem={RadioListItem}
onSelectRow={updateBankAccount}
initiallyFocusedOptionKey={initiallyFocusedOptionKey}
headerContent={listHeaderComponent}
diff --git a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
index 58e144d8f589..a502c94b767b 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPreferredExporterSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import isEmpty from 'lodash/isEmpty';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import Text from '@components/Text';
@@ -100,6 +101,7 @@ function XeroPreferredExporterSelectPage({policy}: WithPolicyConnectionsProps) {
featureName={CONST.POLICY.MORE_FEATURES.ARE_CONNECTIONS_ENABLED}
displayName="XeroPreferredExporterSelectPage"
data={data}
+ listItem={RadioListItem}
headerContent={headerContent}
onSelectRow={selectExporter}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillDateSelectPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillDateSelectPage.tsx
index ab11e04eae04..630798d09eba 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillDateSelectPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillDateSelectPage.tsx
@@ -2,6 +2,7 @@ import {useRoute} from '@react-navigation/native';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -69,6 +70,7 @@ function XeroPurchaseBillDateSelectPage({policy}: WithPolicyConnectionsProps) {
title="workspace.xero.exportDate.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectExportDate(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
index 0e6427730e78..f3d9547be48e 100644
--- a/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
+++ b/src/pages/workspace/accounting/xero/export/XeroPurchaseBillStatusSelectorPage.tsx
@@ -3,6 +3,7 @@ import isEmpty from 'lodash/isEmpty';
import React, {useCallback, useMemo} from 'react';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
@@ -81,6 +82,7 @@ function XeroPurchaseBillStatusSelectorPage({policy}: WithPolicyConnectionsProps
title="workspace.xero.invoiceStatus.label"
headerContent={headerContent}
data={data}
+ listItem={RadioListItem}
onSelectRow={(selection: SelectorType) => selectPurchaseBillStatus(selection as MenuListItem)}
initiallyFocusedOptionKey={data.find((mode) => mode.isSelected)?.keyForList}
policyID={policyID}
diff --git a/src/pages/workspace/categories/CategoryDefaultTaxRatePage.tsx b/src/pages/workspace/categories/CategoryDefaultTaxRatePage.tsx
index 26fc0978847b..7f838bfe380b 100644
--- a/src/pages/workspace/categories/CategoryDefaultTaxRatePage.tsx
+++ b/src/pages/workspace/categories/CategoryDefaultTaxRatePage.tsx
@@ -2,7 +2,7 @@ import React, {useCallback, useMemo} from 'react';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
@@ -83,13 +83,12 @@ function CategoryDefaultTaxRatePage({
/>
diff --git a/src/pages/workspace/categories/CategoryRequireItemizedReceiptsOverPage.tsx b/src/pages/workspace/categories/CategoryRequireItemizedReceiptsOverPage.tsx
index e4f4a530926c..a0f360f58882 100644
--- a/src/pages/workspace/categories/CategoryRequireItemizedReceiptsOverPage.tsx
+++ b/src/pages/workspace/categories/CategoryRequireItemizedReceiptsOverPage.tsx
@@ -3,7 +3,7 @@ import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import usePolicyData from '@hooks/usePolicyData';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -92,7 +92,7 @@ function CategoryRequireItemizedReceiptsOverPage({
/>
{
if (typeof item.value === 'number') {
if (item.value === 0 && policyCategories?.[categoryName]?.maxAmountNoReceipt !== 0) {
diff --git a/src/pages/workspace/categories/CategoryRequireReceiptsOverPage.tsx b/src/pages/workspace/categories/CategoryRequireReceiptsOverPage.tsx
index 7e345e636498..f27cb2eb23ae 100644
--- a/src/pages/workspace/categories/CategoryRequireReceiptsOverPage.tsx
+++ b/src/pages/workspace/categories/CategoryRequireReceiptsOverPage.tsx
@@ -3,7 +3,7 @@ import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import usePolicyData from '@hooks/usePolicyData';
import useThemeStyles from '@hooks/useThemeStyles';
@@ -92,7 +92,7 @@ function CategoryRequireReceiptsOverPage({
/>
{
if (typeof item.value === 'number') {
if (item.value === CONST.DISABLED_MAX_EXPENSE_VALUE && policyCategories?.[categoryName]?.maxAmountNoItemizedReceipt !== CONST.DISABLED_MAX_EXPENSE_VALUE) {
diff --git a/src/pages/workspace/categories/ExpenseLimitTypeSelector/ExpenseLimitTypeSelectorModal.tsx b/src/pages/workspace/categories/ExpenseLimitTypeSelector/ExpenseLimitTypeSelectorModal.tsx
index b61d9ff2e9a6..a749ec22246d 100644
--- a/src/pages/workspace/categories/ExpenseLimitTypeSelector/ExpenseLimitTypeSelectorModal.tsx
+++ b/src/pages/workspace/categories/ExpenseLimitTypeSelector/ExpenseLimitTypeSelectorModal.tsx
@@ -3,7 +3,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Modal from '@components/Modal';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import CONST from '@src/CONST';
@@ -59,7 +59,7 @@ function ExpenseLimitTypeSelectorModal({isVisible, currentExpenseLimitType, onEx
/>
onExpenseLimitTypeSelected(item.value)}
shouldSingleExecuteRowSelect
style={{containerStyle: [styles.pt3]}}
diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardAccountSelectCardPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardAccountSelectCardPage.tsx
index a681d20ce63c..aece0570ceee 100644
--- a/src/pages/workspace/companyCards/WorkspaceCompanyCardAccountSelectCardPage.tsx
+++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardAccountSelectCardPage.tsx
@@ -2,6 +2,7 @@ import React, {useState} from 'react';
import {View} from 'react-native';
import BlockingView from '@components/BlockingViews/BlockingView';
import RenderHTML from '@components/RenderHTML';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import SelectionScreen from '@components/SelectionScreen';
import type {SelectorType} from '@components/SelectionScreen';
import useCardFeeds from '@hooks/useCardFeeds';
@@ -104,6 +105,7 @@ function WorkspaceCompanyCardAccountSelectCardPage({route}: WorkspaceCompanyCard
featureName={CONST.POLICY.MORE_FEATURES.ARE_COMPANY_CARDS_ENABLED}
displayName="WorkspaceCompanyCardAccountSelectCardPage"
data={searchedListOptions ?? []}
+ listItem={RadioListItem}
textInputOptions={{
label: translate('common.search'),
value: searchText,
diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx
index 9104583aedfe..55f766922240 100644
--- a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx
+++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx
@@ -7,7 +7,7 @@ import MenuItem from '@components/MenuItem';
import PlaidCardFeedIcon from '@components/PlaidCardFeedIcon';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import useCardFeedErrors from '@hooks/useCardFeedErrors';
import type {CombinedCardFeed, CompanyCardFeedWithDomainID} from '@hooks/useCardFeeds';
@@ -132,7 +132,7 @@ function WorkspaceCompanyCardFeedSelectorPage({route}: WorkspaceCompanyCardFeedS
onBackButtonPress={goBack}
/>
{
setLocalTypeSelected(value);
setHasError(false);
diff --git a/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx b/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
index 683ede519804..9adeaf2dd486 100644
--- a/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
+++ b/src/pages/workspace/companyCards/addNew/CardTypeStep.tsx
@@ -7,7 +7,7 @@ import Icon from '@components/Icon';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import {useCompanyCardBankIcons} from '@hooks/useCompanyCardIcons';
import useLocalize from '@hooks/useLocalize';
@@ -148,7 +148,7 @@ function CardTypeStep() {
{translate('workspace.companyCards.addNewCard.yourCardProvider')}
{
setLocalTypeSelected(value);
setIsError(false);
diff --git a/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx b/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx
index fa7d9bd067e6..01dbbbc669b2 100644
--- a/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx
+++ b/src/pages/workspace/companyCards/addNew/SelectBankStep.tsx
@@ -7,7 +7,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Icon from '@components/Icon';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import {useCompanyCardBankIcons} from '@hooks/useCompanyCardIcons';
import useLocalize from '@hooks/useLocalize';
@@ -114,7 +114,7 @@ function SelectBankStep() {
{translate('workspace.companyCards.addNewCard.whoIsYourBankAccount')}
{
setLocalBankSelected(value);
setHasError(false);
diff --git a/src/pages/workspace/companyCards/addNew/SelectCountryStep.tsx b/src/pages/workspace/companyCards/addNew/SelectCountryStep.tsx
index ea351893a07f..6aac0599a93b 100644
--- a/src/pages/workspace/companyCards/addNew/SelectCountryStep.tsx
+++ b/src/pages/workspace/companyCards/addNew/SelectCountryStep.tsx
@@ -5,7 +5,7 @@ import FormHelpMessage from '@components/FormHelpMessage';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import {useCurrencyListState} from '@hooks/useCurrencyList';
import useDebouncedState from '@hooks/useDebouncedState';
@@ -116,7 +116,7 @@ function SelectCountryStep({policyID}: CountryStepProps) {
{translate('workspace.companyCards.addNewCard.whereIsYourBankLocated')}
{
setSelectedCountry(countryOption.value ?? null);
}}
diff --git a/src/pages/workspace/companyCards/addNew/SelectFeedType.tsx b/src/pages/workspace/companyCards/addNew/SelectFeedType.tsx
index bfc863df863f..533b311da076 100644
--- a/src/pages/workspace/companyCards/addNew/SelectFeedType.tsx
+++ b/src/pages/workspace/companyCards/addNew/SelectFeedType.tsx
@@ -6,7 +6,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import RenderHTML from '@components/RenderHTML';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
@@ -107,7 +107,7 @@ function SelectFeedType() {
{
setLocalTypeSelected(value);
diff --git a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx
index 8f6e360b9d6e..c102b4336a8a 100644
--- a/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx
+++ b/src/pages/workspace/companyCards/assignCard/AssigneeStep.tsx
@@ -237,7 +237,6 @@ function AssigneeStep({route}: AssigneeStepProps) {
disableMaintainingScrollPosition
shouldUpdateFocusedIndex
addBottomSafeAreaPadding
- shouldShowRadioButton
/>
);
diff --git a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx
index 39317e2e5612..769b8497621a 100644
--- a/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx
+++ b/src/pages/workspace/companyCards/assignCard/CardSelectionStep.tsx
@@ -8,7 +8,7 @@ import InteractiveStepWrapper from '@components/InteractiveStepWrapper';
import PlaidCardFeedIcon from '@components/PlaidCardFeedIcon';
import RenderHTML from '@components/RenderHTML';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useBottomSafeSafeAreaPaddingStyle from '@hooks/useBottomSafeSafeAreaPaddingStyle';
import useCardFeeds from '@hooks/useCardFeeds';
@@ -174,7 +174,7 @@ function CardSelectionStep({route}: CardSelectionStepProps) {
) : (
handleSelectCard(value)}
initiallyFocusedItemKey={cardSelected}
textInputOptions={textInputOptions}
diff --git a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardSelectorPage.tsx b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardSelectorPage.tsx
index c6625e8a5950..341025219486 100644
--- a/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardSelectorPage.tsx
+++ b/src/pages/workspace/expensifyCard/WorkspaceExpensifyCardSelectorPage.tsx
@@ -3,7 +3,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import Icon from '@components/Icon';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import useDefaultFundID from '@hooks/useDefaultFundID';
import useExpensifyCardFeeds from '@hooks/useExpensifyCardFeeds';
@@ -85,7 +85,7 @@ function WorkspaceExpensifyCardSelectorPage({route}: WorkspaceExpensifyCardSelec
onBackButtonPress={goBack}
/>
{translate('workspace.expensifyCard.settlementFrequencyDescription')}
updateSettlementFrequency(value)}
initiallyFocusedItemKey={selectedFrequency}
shouldUpdateFocusedIndex
diff --git a/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx b/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx
index cf766ec37501..89e667d6e28a 100644
--- a/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx
+++ b/src/pages/workspace/expensifyCard/issueNew/AssigneeStep.tsx
@@ -211,7 +211,6 @@ function AssigneeStep({policy, stepNames, startStepIndex, route}: AssigneeStepPr
disableMaintainingScrollPosition
shouldUpdateFocusedIndex
addBottomSafeAreaPadding
- shouldShowRadioButton
/>
);
diff --git a/src/pages/workspace/reports/InitialListValueSelector/ReportFieldsInitialListValuePicker.tsx b/src/pages/workspace/reports/InitialListValueSelector/ReportFieldsInitialListValuePicker.tsx
index e57a8b862b06..c2f4cb437f68 100644
--- a/src/pages/workspace/reports/InitialListValueSelector/ReportFieldsInitialListValuePicker.tsx
+++ b/src/pages/workspace/reports/InitialListValueSelector/ReportFieldsInitialListValuePicker.tsx
@@ -1,6 +1,6 @@
import React, {useMemo} from 'react';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
type ReportFieldsInitialListValuePickerProps = {
@@ -36,7 +36,7 @@ function ReportFieldsInitialListValuePicker({listValues, disabledOptions, value,
return (
onValueChange(item.value)}
initiallyFocusedItemKey={listValueOptions.find((listValue) => listValue.isSelected)?.keyForList}
addBottomSafeAreaPadding
diff --git a/src/pages/workspace/reports/ReportFieldTypePicker/index.tsx b/src/pages/workspace/reports/ReportFieldTypePicker/index.tsx
index df8a4907fc13..e1573e04473c 100644
--- a/src/pages/workspace/reports/ReportFieldTypePicker/index.tsx
+++ b/src/pages/workspace/reports/ReportFieldTypePicker/index.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import {getReportFieldAlternativeTextTranslationKey, getReportFieldTypeTranslationKey} from '@libs/WorkspaceReportFieldUtils';
import CONST from '@src/CONST';
@@ -43,7 +43,7 @@ function ReportFieldTypePicker({defaultValue, onOptionSelected}: ReportFieldType
return (
{
setPolicyBillableMode(policyID, item.value);
Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack);
diff --git a/src/pages/workspace/rules/RulesReimbursableDefaultPage.tsx b/src/pages/workspace/rules/RulesReimbursableDefaultPage.tsx
index 065a4dcc0a56..00f215fa0667 100644
--- a/src/pages/workspace/rules/RulesReimbursableDefaultPage.tsx
+++ b/src/pages/workspace/rules/RulesReimbursableDefaultPage.tsx
@@ -2,7 +2,7 @@ import React from 'react';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import usePolicy from '@hooks/usePolicy';
@@ -56,7 +56,7 @@ function RulesReimbursableDefaultPage({
{
setPolicyReimbursableMode(policyID, item.value, policy?.defaultReimbursable, policy?.disabledFields?.reimbursable);
Navigation.setNavigationActionToMicrotaskQueue(Navigation.goBack);
diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx
index 17cbe5df9fc7..0b94b5a3e8a7 100644
--- a/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx
+++ b/src/pages/workspace/workflows/WorkspaceAutoReportingFrequencyPage.tsx
@@ -7,7 +7,7 @@ import MenuItem from '@components/MenuItem';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {getLatestErrorField} from '@libs/ErrorUtils';
@@ -134,11 +134,12 @@ function WorkspaceAutoReportingFrequencyPage({policy, route}: WorkspaceAutoRepor
contentContainerStyle={styles.flex1}
>
diff --git a/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx b/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx
index c45a8debd9f3..167c6cfeb448 100644
--- a/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx
+++ b/src/pages/workspace/workflows/WorkspaceAutoReportingMonthlyOffsetPage.tsx
@@ -4,7 +4,7 @@ import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
-import SingleSelectListItem from '@components/SelectionList/ListItem/SingleSelectListItem';
+import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import Navigation from '@libs/Navigation/Navigation';
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
@@ -105,7 +105,7 @@ function WorkspaceAutoReportingMonthlyOffsetPage({policy, route}: WorkspaceAutoR
})),
);
-jest.mock('@hooks/useKeyboardShortcut', () => jest.fn());
+let arrowUpCallback = () => {};
+let arrowDownCallback = () => {};
+jest.mock('@hooks/useKeyboardShortcut', () => (key: {shortcutKey: string}, callback: () => void) => {
+ if (key.shortcutKey === 'ArrowUp') {
+ arrowUpCallback = callback;
+ } else if (key.shortcutKey === 'ArrowDown') {
+ arrowDownCallback = callback;
+ }
+});
describe('BaseSelectionList', () => {
const onSelectRowMock = jest.fn();
@@ -319,63 +328,41 @@ describe('BaseSelectionList', () => {
expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}3`)).toBeTruthy();
});
- it('should render items from multiple sections', () => {
- (NativeNavigation.useIsFocused as jest.Mock).mockReturnValue(true);
- const sectionA = Array.from({length: 5}, (_, index) => ({
- text: `Section A Item ${index}`,
- keyForList: `a-${index}`,
- isSelected: false,
- }));
- const sectionB = Array.from({length: 5}, (_, index) => ({
- text: `Section B Item ${index}`,
- keyForList: `b-${index}`,
- isSelected: false,
- }));
-
+ it('should focus next/previous item relative to focused item when arrow keys are pressed', async () => {
render(
,
);
- // Items from both sections should be rendered
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}a-0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}a-4`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}b-0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}b-4`)).toBeTruthy();
- });
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toHaveStyle({backgroundColor: colors.productDark400});
- it('should handle item press from second section correctly', () => {
- (NativeNavigation.useIsFocused as jest.Mock).mockReturnValue(true);
- const sectionA = [{text: 'A0', keyForList: 'a-0', isSelected: false}];
- const sectionB = [{text: 'B0', keyForList: 'b-0', isSelected: false}];
+ // eslint-disable-next-line testing-library/no-unnecessary-act
+ act(() => {
+ arrowDownCallback();
+ });
- render(
- ,
- );
+ // The item that gets focused will be the one following the currently focused item
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}2`)).toHaveStyle({backgroundColor: colors.productDark300});
+ });
- fireEvent.press(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}b-0`));
- expect(onSelectRowMock).toHaveBeenCalledWith(expect.objectContaining({keyForList: 'b-0', text: 'B0'}));
- });
+ act(() => {
+ arrowUpCallback();
+ arrowUpCallback();
+ });
- it('should render empty list without crashing when all sections are empty', () => {
- render(
- ,
- );
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toHaveStyle({backgroundColor: colors.productDark300});
+ });
+
+ act(() => {
+ arrowDownCallback();
+ });
- expect(screen.queryByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeNull();
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toHaveStyle({backgroundColor: colors.productDark400});
+ });
});
});
diff --git a/tests/unit/BaseSelectionListTest.tsx b/tests/unit/BaseSelectionListTest.tsx
index 884984929593..db1a2893c3e9 100644
--- a/tests/unit/BaseSelectionListTest.tsx
+++ b/tests/unit/BaseSelectionListTest.tsx
@@ -1,96 +1,31 @@
-import * as NativeNavigation from '@react-navigation/native';
-import {fireEvent, render, screen} from '@testing-library/react-native';
-import React, {useState} from 'react';
+import {act, fireEvent, render, screen, waitFor} from '@testing-library/react-native';
import type ReactNative from 'react-native';
import OnyxListItemProvider from '@components/OnyxListItemProvider';
import BaseSelectionList from '@components/SelectionList/BaseSelectionList';
+import BaseListItem from '@components/SelectionList/ListItem/BaseListItem';
import RadioListItem from '@components/SelectionList/ListItem/RadioListItem';
import type {ListItem} from '@components/SelectionList/types';
import type Navigation from '@libs/Navigation/Navigation';
+import colors from '@styles/theme/colors';
import CONST from '@src/CONST';
-// Captures scrollToIndex calls so tests can assert on scroll behaviour
-const mockScrollToIndex = jest.fn();
-
-// Mock FlashList
+// FlashList requires layout events to render items; mock it with FlatList for tests
jest.mock('@shopify/flash-list', () => {
- const ReactLocal = jest.requireActual('react');
const RN = jest.requireActual('react-native');
-
- const FlashList = ReactLocal.forwardRef<
- {scrollToIndex: (params: {index: number}) => void},
- Omit, 'children'> & {
- data?: unknown[];
- renderItem?: (info: {item: unknown; index: number; target: string}) => React.ReactNode;
- keyExtractor?: (item: unknown, index: number) => string;
- ListHeaderComponent?: React.ReactNode;
- ListFooterComponent?: React.ReactNode;
- getItemType?: unknown;
- extraData?: unknown;
- initialScrollIndex?: number;
- onEndReached?: unknown;
- onEndReachedThreshold?: unknown;
- ListFooterComponentStyle?: unknown;
- }
- >(
- (
- {
- data,
- renderItem,
- keyExtractor,
- ListHeaderComponent,
- ListFooterComponent,
- getItemType: _getItemType,
- extraData: _extraData,
- initialScrollIndex: _initialScrollIndex,
- onEndReached: _onEndReached,
- onEndReachedThreshold: _onEndReachedThreshold,
- ListFooterComponentStyle: _ListFooterComponentStyle,
- ...scrollViewProps
- },
- ref,
- ) => {
- ReactLocal.useImperativeHandle(ref, () => ({scrollToIndex: mockScrollToIndex}));
-
- return ReactLocal.createElement(
- RN.ScrollView,
- scrollViewProps,
- ListHeaderComponent ?? null,
- ...(data ?? []).map((item, index) =>
- ReactLocal.createElement(ReactLocal.Fragment, {key: keyExtractor?.(item, index) ?? String(index)}, renderItem?.({item, index, target: 'Cell'})),
- ),
- ListFooterComponent ?? null,
- );
- },
- );
-
- return {FlashList};
+ return {
+ FlashList: RN.FlatList,
+ };
});
-type BaseSelectionListTestProps = {
+type BaseSelectionListSections = {
data: TItem[];
canSelectMultiple?: boolean;
- searchText?: string;
- setSearchText?: (searchText: string) => void;
- isDisabled?: boolean;
};
-const mockItems = Array.from({length: 10}, (_, index) => ({
- text: `Item ${index}`,
- keyForList: `${index}`,
- isSelected: index === 1,
-}));
-
-const largeMockItems = Array.from({length: 100}, (_, index) => ({
+const mockSections = Array.from({length: 10}, (_, index) => ({
text: `Item ${index}`,
keyForList: `${index}`,
- isSelected: index === 1,
-}));
-
-const largeMockItemsWithSelectedFromSecondPage = Array.from({length: 100}, (_, index) => ({
- text: `Item ${index}`,
- keyForList: `${index}`,
- isSelected: index === 70,
+ isSelected: index === 0,
}));
jest.mock('@src/components/ConfirmedRoute.tsx');
@@ -110,209 +45,104 @@ jest.mock('@hooks/useLocalize', () =>
})),
);
-jest.mock('@hooks/useKeyboardShortcut', () => jest.fn());
+let arrowUpCallback = () => {};
+let arrowDownCallback = () => {};
+jest.mock('@hooks/useKeyboardShortcut', () => (key: {shortcutKey: string}, callback: () => void) => {
+ if (key.shortcutKey === 'ArrowUp') {
+ arrowUpCallback = callback;
+ } else if (key.shortcutKey === 'ArrowDown') {
+ arrowDownCallback = callback;
+ }
+});
describe('BaseSelectionList', () => {
const onSelectRowMock = jest.fn();
- beforeEach(() => {
- onSelectRowMock.mockClear();
- mockScrollToIndex.mockClear();
- });
-
- function SelectionListRenderer(props: BaseSelectionListTestProps) {
- const {data, canSelectMultiple, setSearchText, searchText, isDisabled} = props;
- const focusedKey = data.find((item) => item.isSelected)?.keyForList;
+ function BaseListItemRenderer(props: BaseSelectionListSections) {
+ const {data, canSelectMultiple} = props;
+ const focusedKey = data.find((item) => item.isSelected)?.keyForList ?? undefined;
return (
);
}
- it('should not trigger item press if screen is not focused', () => {
- (NativeNavigation.useIsFocused as jest.Mock).mockReturnValue(false);
- render();
- fireEvent.press(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`));
- expect(onSelectRowMock).toHaveBeenCalledTimes(0);
- });
-
- it('should handle item press correctly', () => {
- (NativeNavigation.useIsFocused as jest.Mock).mockReturnValue(true);
- render();
-
- fireEvent.press(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`));
- expect(onSelectRowMock).toHaveBeenCalledWith(
- expect.objectContaining({
- ...mockItems.at(1),
- }),
- );
- });
-
- it('should update selected item on rerender', () => {
- (NativeNavigation.useIsFocused as jest.Mock).mockReturnValue(true);
- const updatedMockItems = mockItems.map((item) => ({
- ...item,
- isSelected: item.keyForList === '2',
- }));
- const {rerender} = render();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toBeSelected();
- rerender();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}2`)).toBeSelected();
- });
-
- it('should render all items', () => {
+ it('should focus next/previous item relative to focused item when arrow keys are pressed', async () => {
render(
- ,
- );
-
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}99`)).toBeTruthy();
- });
-
- it('should render all items when they fit within initial render limit', () => {
- render(
- ,
- );
-
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}9`)).toBeTruthy();
- });
-
- it('does not lose items when only selection changes', () => {
- const {rerender} = render(
- ,
);
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}99`)).toBeTruthy();
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toHaveStyle({backgroundColor: colors.productDark400});
- rerender(
- ({...item, isSelected: index === 3}))}
- canSelectMultiple={false}
- />,
- );
+ // eslint-disable-next-line testing-library/no-unnecessary-act
+ act(() => {
+ arrowDownCallback();
+ });
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}99`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}3`)).toBeSelected();
- });
+ // The item that gets focused will be the one following the currently focused item
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toHaveStyle({backgroundColor: colors.productDark300});
+ });
- it('should still render items when text input changes', () => {
- const {rerender} = render(
- ,
- );
+ act(() => {
+ arrowUpCallback();
+ arrowUpCallback();
+ });
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}9`)).toHaveStyle({backgroundColor: colors.productDark300});
+ });
- rerender(
- ({...item, isSelected: index === 3}))}
- canSelectMultiple={false}
- searchText="Item"
- />,
- );
+ act(() => {
+ arrowDownCallback();
+ });
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}3`)).toBeTruthy();
+ await waitFor(() => {
+ expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toHaveStyle({backgroundColor: colors.productDark400});
+ });
});
- it('should search for an item then scroll back to preselected item when search is cleared', () => {
- function SearchableListWrapper() {
- const [searchText, setSearchText] = useState('');
-
- const filteredItems = searchText
- ? largeMockItemsWithSelectedFromSecondPage.filter((item) => item.text.toLowerCase().includes(searchText.toLowerCase()))
- : largeMockItemsWithSelectedFromSecondPage;
-
- return (
-
- );
- }
-
- render();
-
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}70`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}70`)).toBeSelected();
-
- fireEvent.changeText(screen.getByTestId('selection-list-text-input'), 'Item 0');
-
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeTruthy();
- expect(screen.queryByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}70`)).toBeFalsy();
- expect(screen.queryByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`)).toBeFalsy();
-
- fireEvent.changeText(screen.getByTestId('selection-list-text-input'), '');
-
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}70`)).toBeTruthy();
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}70`)).toBeSelected();
- });
-
- it('should render the selection-list testID', () => {
- render(
- ,
- );
-
- expect(screen.getByTestId('selection-list')).toBeTruthy();
- });
-
- it('should mark all items as not selected when none are selected', () => {
- const noSelectionItems = mockItems.map((item) => ({...item, isSelected: false}));
-
+ it('should not call preventDefault on mouseDown when the target is an INPUT element', () => {
render(
- ,
- );
-
- for (const item of noSelectionItems) {
- expect(screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}${item.keyForList}`)).not.toBeSelected();
- }
- });
-
- it('should render empty list without crashing when data is empty', () => {
- render(
- ,
+
+ {}}
+ showTooltip={false}
+ isFocused={false}
+ keyForList="1"
+ >
+
+
+ ,
);
- expect(screen.queryByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}0`)).toBeNull();
+ const preventDefault = jest.fn();
+ const listItem = screen.getByTestId(`${CONST.BASE_LIST_ITEM_TEST_ID}1`);
+
+ // Test case 1: Target is INPUT
+ fireEvent(listItem, 'mouseDown', {
+ target: {tagName: CONST.ELEMENT_NAME.INPUT},
+ preventDefault,
+ });
+ expect(preventDefault).not.toHaveBeenCalled();
+
+ // Test case 2: Target is NOT INPUT (e.g., DIV)
+ fireEvent(listItem, 'mouseDown', {
+ target: {tagName: CONST.ELEMENT_NAME.DIV},
+ preventDefault,
+ });
+ expect(preventDefault).toHaveBeenCalled();
});
});