diff --git a/assets/images/coins.svg b/assets/images/coins.svg
index 3c12b4720526..3cf1c0e38204 100644
--- a/assets/images/coins.svg
+++ b/assets/images/coins.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/assets/images/credit-card-multiple.svg b/assets/images/credit-card-multiple.svg
deleted file mode 100644
index 93573995e18a..000000000000
--- a/assets/images/credit-card-multiple.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/assets/images/multifactorAuthentication/fingerprint.svg b/assets/images/multifactorAuthentication/fingerprint.svg
index 6dbc03eb27e6..f6712ca78e14 100644
--- a/assets/images/multifactorAuthentication/fingerprint.svg
+++ b/assets/images/multifactorAuthentication/fingerprint.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/assets/images/paycheck.svg b/assets/images/paycheck.svg
deleted file mode 100644
index 30e03272ec5d..000000000000
--- a/assets/images/paycheck.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/assets/images/user-arrow-left.svg b/assets/images/user-arrow-left.svg
deleted file mode 100644
index 987b13b3cbe6..000000000000
--- a/assets/images/user-arrow-left.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/CONST/index.ts b/src/CONST/index.ts
index fcc44cadff3e..fcc1a8fe04b0 100644
--- a/src/CONST/index.ts
+++ b/src/CONST/index.ts
@@ -276,9 +276,6 @@ const CONST = {
POPOVER_DATE_RANGE_WIDTH: 672,
POPOVER_DATE_MAX_HEIGHT: 366,
POPOVER_DATE_MIN_HEIGHT: 322,
- ADVANCED_FILTERS_POPOVER_HEIGHT: 520,
- ADVANCED_FILTERS_POPOVER_WIDTH: 582,
- ADVANCED_FILTERS_CONTENT_WIDTH: 331,
TOOLTIP_ANIMATION_DURATION: 500,
DROPDOWN_SCROLL_THRESHOLD: 5,
// Multiplier for gyroscope animation in order to make it a bit more subtle
@@ -9300,7 +9297,6 @@ const CONST = {
ADVANCED_FILTER_ITEM: 'Search-AdvancedFilterItem',
SAVE_SEARCH_BUTTON: 'Search-SaveSearchButton',
VIEW_RESULTS_BUTTON: 'Search-ViewResultsButton',
- CLEAR_FILTERS_BUTTON: 'Search-ClearFiltersButton',
ACTION_CELL_VIEW: 'Search-ActionCellView',
ACTION_CELL_PAY: 'Search-ActionCellPay',
ACTION_CELL_ACTION: 'Search-ActionCellAction',
diff --git a/src/components/Icon/chunks/expensify-icons.chunk.ts b/src/components/Icon/chunks/expensify-icons.chunk.ts
index e531d321f8db..821fb37ef966 100644
--- a/src/components/Icon/chunks/expensify-icons.chunk.ts
+++ b/src/components/Icon/chunks/expensify-icons.chunk.ts
@@ -70,7 +70,6 @@ import Copy from '@assets/images/copy.svg';
import CreditCardExclamation from '@assets/images/credit-card-exclamation.svg';
import CreditCardHourglass from '@assets/images/credit-card-hourglass.svg';
import CreditCardLock from '@assets/images/credit-card-lock.svg';
-import CreditCardMultiple from '@assets/images/credit-card-multiple.svg';
import CreditCardWithPlaneHourglass from '@assets/images/credit-card-with-plane-hourglass.svg';
import CreditCardWithPlane from '@assets/images/credit-card-with-plane.svg';
import CreditCard from '@assets/images/creditcard.svg';
@@ -187,7 +186,6 @@ import OfflineCloud from '@assets/images/offline-cloud.svg';
import Offline from '@assets/images/offline.svg';
import Paperclip from '@assets/images/paperclip.svg';
import Pause from '@assets/images/pause.svg';
-import Paycheck from '@assets/images/paycheck.svg';
import Pencil from '@assets/images/pencil.svg';
import Percent from '@assets/images/percent.svg';
import Phone from '@assets/images/phone.svg';
@@ -251,7 +249,6 @@ import TreasureChest from '@assets/images/treasure-chest.svg';
import Unlock from '@assets/images/unlock.svg';
import UploadAlt from '@assets/images/upload-alt.svg';
import Upload from '@assets/images/upload.svg';
-import UserArrowLeft from '@assets/images/user-arrow-left.svg';
import UserCheck from '@assets/images/user-check.svg';
import UserEye from '@assets/images/user-eye.svg';
import UserLock from '@assets/images/user-lock.svg';
@@ -329,7 +326,6 @@ const Expensicons = {
ConnectionComplete,
Copy,
CreditCard,
- CreditCardMultiple,
Crop,
CreditCardHourglass,
CreditCardExclamation,
@@ -431,7 +427,6 @@ const Expensicons = {
OdometerEnd,
Paperclip,
Pause,
- Paycheck,
Pencil,
Percent,
Phone,
@@ -477,7 +472,6 @@ const Expensicons = {
Upload,
UploadAlt,
User,
- UserArrowLeft,
UserCheck,
Users,
VideoSlash,
diff --git a/src/components/PopoverWithMeasuredContent/index.tsx b/src/components/PopoverWithMeasuredContent/index.tsx
index 29f369ab9da4..9c063dce4982 100644
--- a/src/components/PopoverWithMeasuredContent/index.tsx
+++ b/src/components/PopoverWithMeasuredContent/index.tsx
@@ -11,7 +11,7 @@ import type PopoverWithMeasuredContentProps from './types';
* This component is a perf optimization, it return BOTTOM_DOCKED early, for small screens avoiding Popover measurement logic calculations.
* It defers rendering of PopoverWithMeasuredContentBase to idle time to avoid blocking more priority UI updates with measurements.
*/
-function PopoverWithMeasuredContent({shouldWrapModalChildrenInScrollViewIfBottomDockedInLandscapeMode, smallScreenModalType, ...props}: PopoverWithMeasuredContentProps) {
+function PopoverWithMeasuredContent({shouldWrapModalChildrenInScrollViewIfBottomDockedInLandscapeMode, ...props}: PopoverWithMeasuredContentProps) {
// eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth
const {isSmallScreenWidth} = useResponsiveLayout();
@@ -32,7 +32,7 @@ function PopoverWithMeasuredContent({shouldWrapModalChildrenInScrollViewIfBottom
return (
& {
/** Whether to skip re-measurement when becoming visible (for components with static dimensions) */
shouldSkipRemeasurement?: boolean;
-
- /** The modal type for modal when rendered in small screen */
- smallScreenModalType?: BaseModalProps['type'];
};
export default PopoverWithMeasuredContentProps;
diff --git a/src/components/SafeTriangle/index.native.tsx b/src/components/SafeTriangle/index.native.tsx
deleted file mode 100644
index 3e39c794c481..000000000000
--- a/src/components/SafeTriangle/index.native.tsx
+++ /dev/null
@@ -1,11 +0,0 @@
-import type SafeTriangleProps from './types';
-
-/**
- * A component that provides a "safe triangle" wrapper.
- * On native platforms, hover interactions are not applicable, so this is a no-op wrapper.
- */
-function SafeTriangle({children}: SafeTriangleProps) {
- return children;
-}
-
-export default SafeTriangle;
diff --git a/src/components/SafeTriangle/index.tsx b/src/components/SafeTriangle/index.tsx
deleted file mode 100644
index 64ad15112770..000000000000
--- a/src/components/SafeTriangle/index.tsx
+++ /dev/null
@@ -1,194 +0,0 @@
-import React, {useEffect, useRef, useState} from 'react';
-import {View} from 'react-native';
-import {Polygon, Svg} from 'react-native-svg';
-import useThemeStyles from '@hooks/useThemeStyles';
-import {isMobile} from '@libs/Browser';
-import htmlDivElementRef from '@src/types/utils/htmlDivElementRef';
-import type SafeTriangleProps from './types';
-
-type Point = [number, number];
-
-type SafeTriangleOverlayProps = {
- submenuRef: React.RefObject;
- containerRef: React.RefObject;
-};
-
-type Rect = {
- top: number;
- left: number;
- width: number;
- height: number;
-};
-
-/** Time in ms before the safe triangle is cleared after cursor stops moving toward submenu */
-const SAFE_TRIANGLE_CLEAR_DELAY_MS = 50;
-
-const OFFSET = 2;
-
-function isPointInPolygon(point: Point, polygon: Point[]) {
- const [x, y] = point;
- let isInside = false;
- const length = polygon.length;
- for (let i = 0, j = length - 1; i < length; j = i++) {
- const [xi, yi] = polygon.at(i) ?? [0, 0];
- const [xj, yj] = polygon.at(j) ?? [0, 0];
- const intersect = yi >= y !== yj >= y && x <= ((xj - xi) * (y - yi)) / (yj - yi) + xi;
- if (intersect) {
- isInside = !isInside;
- }
- }
- return isInside;
-}
-
-function SafeTriangleOverlay({submenuRef, containerRef}: SafeTriangleOverlayProps) {
- const styles = useThemeStyles();
-
- const [points, setPoints] = useState(null);
- const [svgRect, setSvgRect] = useState(null);
-
- const apexRef = useRef(null);
- const lastCursorPosition = useRef(null);
- const lastCursorTime = useRef(0);
- const timeoutRef = useRef(undefined);
-
- const getCursorSpeed = (x: number, y: number): number | null => {
- const currentTime = performance.now();
- const elapsedTime = currentTime - lastCursorTime.current;
-
- if (lastCursorPosition.current === null || elapsedTime === 0) {
- lastCursorPosition.current = [x, y];
- lastCursorTime.current = currentTime;
- return null;
- }
-
- const deltaX = x - lastCursorPosition.current[0];
- const deltaY = y - lastCursorPosition.current[1];
- const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
- const speed = distance / elapsedTime; // px / ms
-
- lastCursorPosition.current = [x, y];
- lastCursorTime.current = currentTime;
-
- return speed;
- };
-
- const clearTriangle = () => {
- setPoints(null);
- setSvgRect(null);
- apexRef.current = null;
- };
-
- const onMouseMove = (event: MouseEvent) => {
- clearTimeout(timeoutRef.current);
-
- const {clientX, clientY} = event;
- const speed = getCursorSpeed(clientX, clientY);
-
- if (!submenuRef.current) {
- clearTriangle();
- return;
- }
-
- const rect = submenuRef.current.getBoundingClientRect();
- if (!rect) {
- clearTriangle();
- return;
- }
-
- // If speed is slow, update the apex to the current cursor position
- if (speed === null || speed < 0.1) {
- apexRef.current = [clientX, clientY];
- }
-
- const [x, y] = apexRef.current ?? [clientX, clientY];
-
- // Create a polygon from apex to the submenu's left edge
- const cursorPoint: Point = [0, y - rect.top];
- // We subtract OFFSET from x-coordinates to account for the offset in the container's left style
- const topLeftSubMenuPoint: Point = [rect.left - x - OFFSET, 0];
- const bottomLeftSubMenuPoint: Point = [rect.left - x - OFFSET, rect.bottom - rect.top];
-
- const polygon = [cursorPoint, topLeftSubMenuPoint, bottomLeftSubMenuPoint];
-
- // Check if the current mouse position is within the safe triangle
- // The polygon points are relative to [x + OFFSET, rect.top], so we adjust the mouse position accordingly
- const isSafe = isPointInPolygon([clientX - x + OFFSET, clientY - rect.top], polygon);
-
- if (isSafe) {
- const pointsString = polygon.map((p) => p.join(',')).join(' ');
- setPoints(pointsString);
- setSvgRect({
- top: rect.top,
- left: x + OFFSET,
- height: rect.height,
- width: rect.left - x - OFFSET,
- });
- timeoutRef.current = setTimeout(clearTriangle, SAFE_TRIANGLE_CLEAR_DELAY_MS);
- } else {
- clearTriangle();
- }
- };
-
- useEffect(() => {
- const container = htmlDivElementRef(containerRef).current;
- if (!container) {
- return;
- }
-
- container.addEventListener('mousemove', onMouseMove, true);
-
- return () => {
- container.removeEventListener('mousemove', onMouseMove, true);
- clearTimeout(timeoutRef.current);
- };
- }, [onMouseMove, containerRef]);
-
- if (!points || !svgRect) {
- return null;
- }
-
- return (
-
- );
-}
-
-/**
- * A component that creates a "safe triangle" area between the cursor and a submenu.
- * This prevents the submenu from switching when the user moves the cursor
- * diagonally towards the submenu by rendering an invisible SVG overlay.
- */
-function SafeTriangle({submenuRef, children}: SafeTriangleProps) {
- const styles = useThemeStyles();
- const containerRef = useRef(null);
-
- if (isMobile()) {
- return children;
- }
-
- return (
-
- {children}
-
-
- );
-}
-
-export default SafeTriangle;
diff --git a/src/components/SafeTriangle/types.ts b/src/components/SafeTriangle/types.ts
deleted file mode 100644
index 5173cbb3acb7..000000000000
--- a/src/components/SafeTriangle/types.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import type {View} from 'react-native';
-
-type SafeTriangleProps = {
- submenuRef: React.RefObject;
- children: React.ReactNode;
-};
-
-export default SafeTriangleProps;
diff --git a/src/components/Search/FilterComponents/CardSelector.tsx b/src/components/Search/FilterComponents/CardSelector.tsx
index ab786d71123f..5f7e280426f4 100644
--- a/src/components/Search/FilterComponents/CardSelector.tsx
+++ b/src/components/Search/FilterComponents/CardSelector.tsx
@@ -2,10 +2,9 @@ import React, {useEffect} from 'react';
import {View} from 'react-native';
import ActivityIndicator from '@components/ActivityIndicator';
import {usePersonalDetails} from '@components/OnyxListItemProvider';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import CardListItem from '@components/SelectionList/ListItem/CardListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
-import type {TextInputOptions} from '@components/SelectionList/types';
+import type {Section} from '@components/SelectionList/SelectionListWithSections/types';
import {useCompanyCardFeedIcons} from '@hooks/useCompanyCardIcons';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
@@ -24,12 +23,12 @@ import ONYXKEYS from '@src/ONYXKEYS';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
import ListFilterView from './ListFilterViewWrapper';
-type CardSelectorProps = SearchFilterSelectionListProps & {
+type CardSelectorProps = {
value: string[] | undefined;
onChange: (cards: string[]) => void;
};
-function CardSelector({value = [], selectionListTextInputStyle, selectionListStyle, autoFocus, footer, onChange}: CardSelectorProps) {
+function CardSelector({value = [], onChange}: CardSelectorProps) {
const theme = useTheme();
const styles = useThemeStyles();
const {translate} = useLocalize();
@@ -42,6 +41,7 @@ function CardSelector({value = [], selectionListTextInputStyle, selectionListSty
const [customCardNames] = useOnyx(ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES);
const [workspaceCardFeeds, workspaceCardFeedsMetadata] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST);
const [searchTerm, debouncedSearchTerm, setSearchTerm] = useDebouncedState('');
+ const [searchAdvancedFiltersForm, searchAdvancedFiltersFormMetadata] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM);
const personalDetails = usePersonalDetails();
useEffect(() => {
@@ -72,30 +72,36 @@ function CardSelector({value = [], selectionListTextInputStyle, selectionListSty
!!item.cardName?.toLocaleLowerCase().includes(debouncedSearchTerm.toLocaleLowerCase()) ||
(item.isVirtual && translate('workspace.expensifyCard.virtual').toLocaleLowerCase().includes(debouncedSearchTerm.toLocaleLowerCase()));
- const selectedData = [...individualCardsSectionData, ...closedCardsSectionData].filter((item) => item.isSelected && searchFunction(item));
- const unselectedIndividualCardsData = individualCardsSectionData.filter((item) => !item.isSelected && searchFunction(item));
- const unselectedClosedCardsData = closedCardsSectionData.filter((item) => !item.isSelected && searchFunction(item));
-
- const itemCount = selectedData.length + unselectedIndividualCardsData.length + unselectedClosedCardsData.length;
- const sectionHeaderCount = unselectedClosedCardsData.length > 0 ? 1 : 0;
-
- const sections = [
- {
- title: undefined,
- data: selectedData,
- sectionIndex: 0,
- },
- {
- title: undefined,
- data: unselectedIndividualCardsData,
- sectionIndex: 1,
- },
- {
- title: translate('search.filters.card.closedCards'),
- data: unselectedClosedCardsData,
- sectionIndex: 2,
- },
- ];
+ let sections: Array> = [];
+ let itemCount = 0;
+ let sectionHeaderCount = 0;
+
+ if (searchAdvancedFiltersForm) {
+ const selectedData = [...individualCardsSectionData, ...closedCardsSectionData].filter((item) => item.isSelected && searchFunction(item));
+ const unselectedIndividualCardsData = individualCardsSectionData.filter((item) => !item.isSelected && searchFunction(item));
+ const unselectedClosedCardsData = closedCardsSectionData.filter((item) => !item.isSelected && searchFunction(item));
+
+ itemCount = selectedData.length + unselectedIndividualCardsData.length + unselectedClosedCardsData.length;
+ sectionHeaderCount = unselectedClosedCardsData.length > 0 ? 1 : 0;
+
+ sections = [
+ {
+ title: undefined,
+ data: selectedData,
+ sectionIndex: 0,
+ },
+ {
+ title: undefined,
+ data: unselectedIndividualCardsData,
+ sectionIndex: 1,
+ },
+ {
+ title: translate('search.filters.card.closedCards'),
+ data: unselectedClosedCardsData,
+ sectionIndex: 2,
+ },
+ ];
+ }
const updateNewCards = (item: CardFilterItem) => {
if (!item.keyForList) {
@@ -111,18 +117,14 @@ function CardSelector({value = [], selectionListTextInputStyle, selectionListSty
}
};
- const textInputOptions: TextInputOptions = {
+ const textInputOptions = {
value: searchTerm,
label: translate('common.search'),
onChangeText: setSearchTerm,
headerMessage: debouncedSearchTerm.trim() && sections.every((section) => !section.data.length) ? translate('common.noResultsFound') : '',
- style: {
- containerStyle: selectionListTextInputStyle,
- },
- disableAutoFocus: !autoFocus,
};
- const isLoadingOnyxData = isLoadingOnyxValue(userCardListMetadata, workspaceCardFeedsMetadata);
+ const isLoadingOnyxData = isLoadingOnyxValue(userCardListMetadata, workspaceCardFeedsMetadata, searchAdvancedFiltersFormMetadata);
const shouldShowLoadingState = isLoadingOnyxData || (!areCardsLoaded && !isOffline);
const reasonAttributes: SkeletonSpanReasonAttributes = {context: 'SearchFiltersCardPage', isLoadingFromOnyx: isLoadingOnyxData};
@@ -152,8 +154,6 @@ function CardSelector({value = [], selectionListTextInputStyle, selectionListSty
textInputOptions={textInputOptions}
shouldStopPropagation
canSelectMultiple
- style={selectionListStyle}
- footerContent={footer}
/>
)}
diff --git a/src/components/Search/FilterComponents/CategorySelector.tsx b/src/components/Search/FilterComponents/CategorySelector.tsx
index 27ce0a2626fb..57ef195d60fe 100644
--- a/src/components/Search/FilterComponents/CategorySelector.tsx
+++ b/src/components/Search/FilterComponents/CategorySelector.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import type {OnyxCollection} from 'react-native-onyx';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import {getDecodedCategoryName} from '@libs/CategoryUtils';
@@ -12,12 +11,12 @@ import {getEmptyObject} from '@src/types/utils/EmptyObject';
import getEmptyArray from '@src/types/utils/getEmptyArray';
import MultiSelect from './MultiSelect';
-type CategorySelectorProps = SearchFilterSelectionListProps & {
+type CategorySelectorProps = {
value: string[] | undefined;
onChange: (categories: string[]) => void;
};
-function CategorySelector({value = [], selectionListTextInputStyle, selectionListStyle, autoFocus, footer, onChange}: CategorySelectorProps) {
+function CategorySelector({value = [], onChange}: CategorySelectorProps) {
const {translate} = useLocalize();
const [policyIDs = getEmptyArray()] = useOnyx(ONYXKEYS.FORMS.SEARCH_ADVANCED_FILTERS_FORM, {selector: filterPolicyIDSelector});
const [personalPolicyID] = useOnyx(ONYXKEYS.PERSONAL_POLICY_ID);
@@ -78,11 +77,7 @@ function CategorySelector({value = [], selectionListTextInputStyle, selectionLis
value={selectedCategoriesItems}
items={categoryItems}
isSearchable={categoryItems.length >= CONST.STANDARD_LIST_ITEM_LIMIT}
- autoFocus={autoFocus}
searchPlaceholder={translate('common.category')}
- selectionListTextInputStyle={selectionListTextInputStyle}
- selectionListStyle={selectionListStyle}
- footer={footer}
onChange={(categories) => onChange(categories.map((category) => category.value))}
/>
);
diff --git a/src/components/Search/FilterComponents/CurrencySelector.tsx b/src/components/Search/FilterComponents/CurrencySelector.tsx
index 84ff911b10df..9a8e1a3374ec 100644
--- a/src/components/Search/FilterComponents/CurrencySelector.tsx
+++ b/src/components/Search/FilterComponents/CurrencySelector.tsx
@@ -1,15 +1,14 @@
import React from 'react';
import {useCurrencyListActions, useCurrencyListState} from '@components/CurrencyListContextProvider';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import {getCurrencyOptions} from '@libs/SearchUIUtils';
import MultiSelect from './MultiSelect';
-type CurrencySelectorProps = SearchFilterSelectionListProps & {
+type CurrencySelectorProps = {
value: string[] | undefined;
onChange: (item: string[]) => void;
};
-function CurrencySelector({value = [], selectionListTextInputStyle, selectionListStyle, autoFocus, footer, onChange}: CurrencySelectorProps) {
+function CurrencySelector({value = [], onChange}: CurrencySelectorProps) {
const {currencyList} = useCurrencyListState();
const {getCurrencySymbol} = useCurrencyListActions();
const currencyOptions = getCurrencyOptions(currencyList, getCurrencySymbol);
@@ -19,11 +18,7 @@ function CurrencySelector({value = [], selectionListTextInputStyle, selectionLis
onChange(currencies.map((currency) => currency.value))}
/>
);
diff --git a/src/components/Search/FilterComponents/ExportedToSelector.tsx b/src/components/Search/FilterComponents/ExportedToSelector.tsx
index 07378885dca2..e167f637da8c 100644
--- a/src/components/Search/FilterComponents/ExportedToSelector.tsx
+++ b/src/components/Search/FilterComponents/ExportedToSelector.tsx
@@ -2,7 +2,6 @@ import React from 'react';
import {View} from 'react-native';
import type {TupleToUnion} from 'type-fest';
import Icon from '@components/Icon';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
@@ -21,7 +20,7 @@ import getEmptyArray from '@src/types/utils/getEmptyArray';
import type IconAsset from '@src/types/utils/IconAsset';
import MultiSelect from './MultiSelect';
-type ExportedToSelectorProps = SearchFilterSelectionListProps & {
+type ExportedToSelectorProps = {
value: string[] | undefined;
onChange: (exportedTo: string[]) => void;
};
@@ -31,7 +30,7 @@ const STANDARD_EXPORT_TEMPLATE_ID_TO_DISPLAY_LABEL: Record = {
[CONST.REPORT.EXPORT_OPTIONS.EXPENSE_LEVEL_EXPORT]: CONST.REPORT.EXPORT_OPTION_LABELS.EXPENSE_LEVEL_EXPORT,
};
-function ExportedToSelector({value = [], selectionListTextInputStyle, selectionListStyle, autoFocus, footer, onChange}: ExportedToSelectorProps) {
+function ExportedToSelector({value = [], onChange}: ExportedToSelectorProps) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const StyleUtils = useStyleUtils();
@@ -137,10 +136,6 @@ function ExportedToSelector({value = [], selectionListTextInputStyle, selectionL
value={selectedExportedTo}
items={exportedToPickerOptions}
isSearchable={exportedToPickerOptions.length >= CONST.STANDARD_LIST_ITEM_LIMIT}
- autoFocus={autoFocus}
- selectionListTextInputStyle={selectionListTextInputStyle}
- selectionListStyle={selectionListStyle}
- footer={footer}
onChange={(exportedTo) => onChange(exportedTo.map((e) => e.value))}
/>
);
diff --git a/src/components/Search/FilterComponents/FeedSelector.tsx b/src/components/Search/FilterComponents/FeedSelector.tsx
index 18028166c34b..7b53977b0f7c 100644
--- a/src/components/Search/FilterComponents/FeedSelector.tsx
+++ b/src/components/Search/FilterComponents/FeedSelector.tsx
@@ -1,16 +1,15 @@
import React, {useEffect} from 'react';
import useFilterFeedData from '@components/Search/hooks/useFilterFeedData';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import useNetwork from '@hooks/useNetwork';
import {openSearchCardFiltersPage} from '@libs/actions/Search';
import MultiSelect from './MultiSelect';
-type FeedSelectorProps = SearchFilterSelectionListProps & {
+type FeedSelectorProps = {
value: string[] | undefined;
onChange: (item: string[]) => void;
};
-function FeedSelector({value, selectionListStyle, footer, onChange}: FeedSelectorProps) {
+function FeedSelector({value, onChange}: FeedSelectorProps) {
const {isOffline} = useNetwork();
const {feedOptions, feedValue} = useFilterFeedData(value);
@@ -25,8 +24,6 @@ function FeedSelector({value, selectionListStyle, footer, onChange}: FeedSelecto
onChange(feeds.map((feed) => feed.value))}
/>
);
diff --git a/src/components/Search/FilterComponents/InSelector.tsx b/src/components/Search/FilterComponents/InSelector.tsx
index 56ecbe1b0139..f75003429607 100644
--- a/src/components/Search/FilterComponents/InSelector.tsx
+++ b/src/components/Search/FilterComponents/InSelector.tsx
@@ -1,10 +1,8 @@
import React, {useEffect} from 'react';
import {usePersonalDetails} from '@components/OnyxListItemProvider';
import {useOptionsList} from '@components/OptionListContextProvider';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import InviteMemberListItem from '@components/SelectionList/ListItem/InviteMemberListItem';
import SelectionListWithSections from '@components/SelectionList/SelectionListWithSections';
-import type {TextInputOptions} from '@components/SelectionList/types';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
@@ -24,7 +22,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
import passthroughPolicyTagListSelector from '@src/selectors/PolicyTagList';
import ListFilterView from './ListFilterViewWrapper';
-type InSelectorProps = SearchFilterSelectionListProps & {
+type InSelectorProps = {
value: string[] | undefined;
onChange: (ins: string[]) => void;
};
@@ -41,7 +39,7 @@ function getSelectedOptionData(option: Option & Pick): O
return {...option, isSelected: true, keyForList: option.keyForList ?? option.reportID};
}
-function InSelector({value = [], selectionListTextInputStyle, selectionListStyle, autoFocus, footer, onChange}: InSelectorProps) {
+function InSelector({value = [], onChange}: InSelectorProps) {
const {translate} = useLocalize();
const personalDetails = usePersonalDetails();
const {options, areOptionsInitialized} = useOptionsList();
@@ -154,15 +152,11 @@ function InSelector({value = [], selectionListTextInputStyle, selectionListStyle
const isLoadingNewOptions = !!isSearchingForReports;
const shouldShowLoadingPlaceholder = !areOptionsInitialized || !value || !personalDetails;
- const textInputOptions: TextInputOptions = {
+ const textInputOptions = {
value: searchTerm,
label: translate('common.search'),
onChangeText: setSearchTerm,
headerMessage,
- style: {
- containerStyle: selectionListTextInputStyle,
- },
- disableAutoFocus: !autoFocus,
};
const itemCount = sections.flatMap((section) => section.data).length;
@@ -182,8 +176,6 @@ function InSelector({value = [], selectionListTextInputStyle, selectionListStyle
isLoadingNewOptions={isLoadingNewOptions}
shouldShowLoadingPlaceholder={shouldShowLoadingPlaceholder}
shouldShowTextInput
- style={selectionListStyle}
- footerContent={footer}
/>
);
diff --git a/src/components/Search/FilterComponents/MultiSelect.tsx b/src/components/Search/FilterComponents/MultiSelect.tsx
index a9d95f113275..585072ed130f 100644
--- a/src/components/Search/FilterComponents/MultiSelect.tsx
+++ b/src/components/Search/FilterComponents/MultiSelect.tsx
@@ -2,11 +2,9 @@ import React, {useState} from 'react';
import type {ReactNode} from 'react';
import {View} from 'react-native';
import ActivityIndicator from '@components/ActivityIndicator';
-import type {SearchFilterSelectionListProps} from '@components/Search/types';
import SelectionList from '@components/SelectionList';
import MultiSelectListItem from '@components/SelectionList/ListItem/MultiSelectListItem';
import type {ListItem} from '@components/SelectionList/ListItem/types';
-import type {TextInputOptions} from '@components/SelectionList/types';
import useDebouncedState from '@hooks/useDebouncedState';
import useLocalize from '@hooks/useLocalize';
import useTheme from '@hooks/useTheme';
@@ -23,7 +21,7 @@ type MultiSelectItem = {
leftElement?: ReactNode;
};
-type MultiSelectProps = SearchFilterSelectionListProps & {
+type MultiSelectProps = {
/** The list of all items to show up in the list */
items: Array>;
@@ -41,23 +39,9 @@ type MultiSelectProps = SearchFilterSelectionListProps & {
/** Whether the data for the popover is loading */
loading?: boolean;
-
- /** Whether the text input should be auto-focused or not. Defaults to true. */
- autoFocus?: boolean;
};
-function MultiSelect({
- loading,
- value,
- items,
- isSearchable,
- searchPlaceholder,
- selectionListTextInputStyle,
- selectionListStyle,
- autoFocus = true,
- footer,
- onChange,
-}: MultiSelectProps) {
+function MultiSelect({loading, value, items, isSearchable, searchPlaceholder, onChange}: MultiSelectProps) {
const theme = useTheme();
const {translate} = useLocalize();
const styles = useThemeStyles();
@@ -93,15 +77,11 @@ function MultiSelect({
}
};
- const textInputOptions: TextInputOptions = {
+ const textInputOptions = {
value: searchTerm,
label: isSearchable ? (searchPlaceholder ?? translate('common.search')) : undefined,
onChangeText: setSearchTerm,
headerMessage,
- style: {
- containerStyle: selectionListTextInputStyle,
- },
- disableAutoFocus: !autoFocus,
};
const reasonAttributes: SkeletonSpanReasonAttributes = {context: 'MultiSelectDataLoading'};
@@ -126,8 +106,7 @@ function MultiSelect({
ListItem={MultiSelectListItem}
onSelectRow={updateSelectedItems}
textInputOptions={textInputOptions}
- style={{contentContainerStyle: [styles.pb0], ...selectionListStyle}}
- footerContent={footer}
+ style={{contentContainerStyle: [styles.pb0]}}
/>
)}
diff --git a/src/components/Search/FilterComponents/ReportField/ReportFieldList.tsx b/src/components/Search/FilterComponents/ReportField/ReportFieldList.tsx
index 3daac4752d80..c013bb9491ba 100644
--- a/src/components/Search/FilterComponents/ReportField/ReportFieldList.tsx
+++ b/src/components/Search/FilterComponents/ReportField/ReportFieldList.tsx
@@ -4,24 +4,22 @@ import type {PolicyReportField} from '@src/types/onyx';
type ReportFieldListProps = {
field: PolicyReportField;
- value: string | undefined;
- allowDeselect?: boolean;
- onChange: (newValue: string | undefined) => void;
+ value: string;
+ onChange: (newValue: string) => void;
};
-function ReportFieldList({field, value, allowDeselect, onChange}: ReportFieldListProps) {
+function ReportFieldList({field, value, onChange}: ReportFieldListProps) {
const items = field.values.map((fieldValue) => ({
value: fieldValue,
text: fieldValue,
}));
- const selectedValue = value ? {text: value, value} : undefined;
+ const selectedValue = {text: value, value};
return (
onChange(item?.value)}
+ onChange={(item) => onChange(item.value)}
hasHeader
/>
);
diff --git a/src/components/Search/FilterComponents/ReportField/ReportFieldText.tsx b/src/components/Search/FilterComponents/ReportField/ReportFieldText.tsx
index 98ca3365f13c..73a082a986d3 100644
--- a/src/components/Search/FilterComponents/ReportField/ReportFieldText.tsx
+++ b/src/components/Search/FilterComponents/ReportField/ReportFieldText.tsx
@@ -6,7 +6,7 @@ import type {PolicyReportField} from '@src/types/onyx';
type ReportFieldTextProps = {
field: PolicyReportField;
- value: string | undefined;
+ value: string;
onChange: (newValue: string) => void;
};
@@ -20,7 +20,7 @@ function ReportFieldText({field, value, onChange}: ReportFieldTextProps) {
onChangeText={onChange}
accessibilityLabel={field.name}
role={CONST.ROLE.PRESENTATION}
- containerStyles={[styles.ph5, styles.pv2]}
+ containerStyles={[styles.ph5, styles.mb2]}
/>
);
}
diff --git a/src/components/Search/FilterComponents/ReportField/index.tsx b/src/components/Search/FilterComponents/ReportField/index.tsx
index 6d446634a043..9cbb07164099 100644
--- a/src/components/Search/FilterComponents/ReportField/index.tsx
+++ b/src/components/Search/FilterComponents/ReportField/index.tsx
@@ -1,5 +1,5 @@
import React, {useImperativeHandle, useRef, useState} from 'react';
-import type {StyleProp, ViewStyle} from 'react-native';
+import {View} from 'react-native';
import type {OnyxCollection} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
@@ -35,16 +35,13 @@ type ReportFieldBaseProps = {
ref: React.Ref;
values: ReportFieldValues | undefined;
selectedField: PolicyReportField | null;
- allowDeselectSingleSelection?: boolean;
- style?: StyleProp;
onFieldSelected: (field: PolicyReportField | null) => void;
};
type SelectedReportFieldProps = {
ref: React.Ref;
field: PolicyReportField;
- value: string | undefined;
- allowDeselectSingleSelection?: boolean;
+ value: string;
};
type SelectedDateReportFieldProps = {
@@ -64,8 +61,8 @@ function getFilterKey(fieldName: string) {
return `${CONST.SEARCH.REPORT_FIELD.DEFAULT_PREFIX}${suffix}` as const;
}
-function SelectedReportField({ref, field, value: initialValue, allowDeselectSingleSelection}: SelectedReportFieldProps) {
- const [value, setValue] = useState(initialValue);
+function SelectedReportField({ref, field, value: initialValue}: SelectedReportFieldProps) {
+ const [value, setValue] = useState(initialValue);
const fieldType = field.type as Exclude, typeof CONST.REPORT_FIELD_TYPES.FORMULA | typeof CONST.REPORT_FIELD_TYPES.DATE>;
const UpdateReportFieldComponent = {
@@ -91,7 +88,6 @@ function SelectedReportField({ref, field, value: initialValue, allowDeselectSing
);
@@ -133,6 +129,7 @@ function SelectedDateReportField({ref, field, value: initialValue, selectedDateM
isDateModifierSelected: () => !!selectedDateModifier,
applySelectedFieldAndGoBack: () => {
dateFilterRef.current?.save();
+ onDateModifierSelected(null);
},
resetSelectedFieldAndGoBack: () => {
if (selectedDateModifier === CONST.SEARCH.DATE_MODIFIERS.RANGE) {
@@ -177,7 +174,7 @@ function SelectedDateReportField({ref, field, value: initialValue, selectedDateM
);
}
-function ReportFieldBase({ref, values: initialValues = {}, selectedField, allowDeselectSingleSelection, style, onFieldSelected}: ReportFieldBaseProps) {
+function ReportFieldBase({ref, values: initialValues = {}, selectedField, onFieldSelected}: ReportFieldBaseProps) {
const {translate, localeCompare} = useLocalize();
const styles = useThemeStyles();
const policyReportFieldsSelector = (policies: OnyxCollection) => createAllPolicyReportFieldsSelector(policies, localeCompare);
@@ -190,7 +187,7 @@ function ReportFieldBase({ref, values: initialValues = {}, selectedField, allowD
const getValue = (fieldName: string) => {
const filterKey = getFilterKey(fieldName);
- return values[filterKey]?.trim();
+ return values[filterKey]?.trim() ?? '';
};
const getDateValue = (fieldName: string) => {
@@ -260,7 +257,7 @@ function ReportFieldBase({ref, values: initialValues = {}, selectedField, allowD
if (selectedField) {
return (
- <>
+
{!selectedDateModifier && (
)}
- >
+
);
}
@@ -297,7 +293,7 @@ function ReportFieldBase({ref, values: initialValues = {}, selectedField, allowD
});
return (
-
+
{listItems.map((item) => (