From 4ffed6fae7ed40d5847af6660e335d3966eb1e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 28 Apr 2026 12:58:12 +0200 Subject: [PATCH 01/12] Split ExpenseReportListItemRow, defer ActionCell, extract Avatar --- .../ListItem/DeferredActionCell.tsx | 35 ++ .../ListItem/ExpenseReportListItemAvatar.tsx | 41 +++ .../ListItem/ExpenseReportListItemRow.tsx | 332 +++--------------- .../ExpenseReportListItemRowNarrow.tsx | 71 ++++ .../ListItem/ExpenseReportListItemRowWide.tsx | 243 +++++++++++++ 5 files changed, 430 insertions(+), 292 deletions(-) create mode 100644 src/components/Search/SearchList/ListItem/DeferredActionCell.tsx create mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx create mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx create mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx diff --git a/src/components/Search/SearchList/ListItem/DeferredActionCell.tsx b/src/components/Search/SearchList/ListItem/DeferredActionCell.tsx new file mode 100644 index 000000000000..8a1e95a00c1e --- /dev/null +++ b/src/components/Search/SearchList/ListItem/DeferredActionCell.tsx @@ -0,0 +1,35 @@ +import React, {useEffect, useState, useTransition} from 'react'; +import {View} from 'react-native'; +import PulsingView from '@components/PulsingView'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import ActionCell from './ActionCell'; +import type {ActionCellProps} from './ActionCell'; + +function DeferredActionCell(actionCellProps: ActionCellProps) { + const styles = useThemeStyles(); + const theme = useTheme(); + const [shouldRender, setShouldRender] = useState(false); + const [, startTransition] = useTransition(); + + useEffect(() => { + startTransition(() => setShouldRender(true)); + }, []); + + if (!shouldRender) { + const sizeStyle = actionCellProps.extraSmall ? styles.buttonExtraSmall : styles.buttonSmall; + return ( + + + + ); + } + + // eslint-disable-next-line react/jsx-props-no-spreading + return ; +} + +export default DeferredActionCell; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx new file mode 100644 index 000000000000..9a7e3ccbb284 --- /dev/null +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx @@ -0,0 +1,41 @@ +import React, {memo} from 'react'; +import {View} from 'react-native'; +import SearchReportAvatar from '@components/ReportActionAvatars/SearchReportAvatar'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; +import type {ExpenseReportListItemType} from './types'; + +type ExpenseReportListItemAvatarProps = { + item: ExpenseReportListItemType; + showTooltip: boolean; + isHovered?: boolean; + isFocused?: boolean; +}; + +function ExpenseReportListItemAvatar({item, showTooltip, isHovered = false, isFocused = false}: ExpenseReportListItemAvatarProps) { + const StyleUtils = useStyleUtils(); + const styles = useThemeStyles(); + const theme = useTheme(); + + const finalAvatarBorderColor = + StyleUtils.getItemBackgroundColorStyle(!!item.isSelected, isFocused || isHovered, !!item.isDisabled, theme.activeComponentBG, theme.hoverComponentBG)?.backgroundColor ?? + theme.highlightBG; + + return ( + + + + ); +} + +export default memo(ExpenseReportListItemAvatar); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx index d6e314ab6134..c5173bce748d 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx @@ -1,31 +1,10 @@ -import React, {Fragment} from 'react'; -import {View} from 'react-native'; +import React from 'react'; import type {StyleProp, ViewStyle} from 'react-native'; -import Checkbox from '@components/Checkbox'; -import Icon from '@components/Icon'; -import SearchReportAvatar from '@components/ReportActionAvatars/SearchReportAvatar'; import type {SearchColumnType} from '@components/Search/types'; -import Text from '@components/Text'; -import {useCurrencyListActions} from '@hooks/useCurrencyList'; -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 DateUtils from '@libs/DateUtils'; -import getBase62ReportID from '@libs/getBase62ReportID'; -import variables from '@styles/variables'; -import CONST from '@src/CONST'; import type {ReportAction} from '@src/types/onyx'; -import ActionCell from './ActionCell'; -import DateCell from './DateCell'; -import ExportedIconCell from './ExportedIconCell'; -import StatusCell from './StatusCell'; -import TextCell from './TextCell'; -import TotalCell from './TotalCell'; +import ExpenseReportListItemRowNarrow from './ExpenseReportListItemRowNarrow'; +import ExpenseReportListItemRowWide from './ExpenseReportListItemRowWide'; import type {ExpenseReportListItemType} from './types'; -import UserInfoCell from './UserInfoCell'; -import WorkspaceCell from './WorkspaceCell'; type ExpenseReportListItemRowProps = { item: ExpenseReportListItemType; @@ -49,285 +28,54 @@ type ExpenseReportListItemRowProps = { function ExpenseReportListItemRow({ item, reportActions, - onCheckboxPress = () => {}, - onButtonPress = () => {}, - isActionLoading, - containerStyle, showTooltip, canSelectMultiple, + isActionLoading, + onButtonPress, + onCheckboxPress, + containerStyle, isSelectAllChecked, isIndeterminate, isDisabledCheckbox, - columns = [], - isHovered = false, - isFocused = false, - isPendingDelete = false, - isLargeScreenWidth = false, + isHovered, + isFocused, + isPendingDelete, + columns, + isLargeScreenWidth, }: ExpenseReportListItemRowProps) { - const StyleUtils = useStyleUtils(); - const styles = useThemeStyles(); - const theme = useTheme(); - const {translate} = useLocalize(); - const {convertToDisplayString} = useCurrencyListActions(); - const expensifyIcons = useMemoizedLazyExpensifyIcons(['ArrowRight']); - - const currency = item.currency ?? CONST.CURRENCY.USD; - const {totalDisplaySpend = 0, nonReimbursableSpend = 0, reimbursableSpend = 0, isAllScanning: isScanning = false} = item; - - const columnComponents = { - [CONST.SEARCH.TABLE_COLUMNS.DATE]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.APPROVED]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.EXPORTED]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.STATUS]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.TITLE]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.FROM]: ( - - {!!item.from && ( - - )} - - ), - [CONST.SEARCH.TABLE_COLUMNS.TO]: ( - - {!!item.to && ( - - )} - - ), - [CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE_TOTAL]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.NON_REIMBURSABLE_TOTAL]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.REPORT_ID]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.ACTION]: ( - - - - ), - [CONST.SEARCH.TABLE_COLUMNS.POLICY_NAME]: ( - - - - ), - }; - - // Calculate the correct border color for avatars based on hover and focus states - const finalAvatarBorderColor = - StyleUtils.getItemBackgroundColorStyle(!!item.isSelected, !!isFocused || !!isHovered, !!item.isDisabled, theme.activeComponentBG, theme.hoverComponentBG)?.backgroundColor ?? - theme.highlightBG; - - if (!isLargeScreenWidth) { - const expenseCount = item.transactionCount ?? item.transactions?.length ?? 0; - const expenseCountText = translate('iou.expenseCount', {count: expenseCount}); - const formattedDate = DateUtils.formatWithUTCTimeZone( - item.created ?? '', - DateUtils.doesDateBelongToAPastYear(item.created ?? '') ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, - ); - - const amountText = isScanning ? translate('iou.receiptStatusTitle') : convertToDisplayString(totalDisplaySpend, currency); - const groupAccessibilityLabel = [item.reportName, amountText, formattedDate, expenseCountText].filter(Boolean).join(', '); + if (isLargeScreenWidth) { return ( - - {!!canSelectMultiple && ( - - )} - - - - {item.reportName ?? ''} - - - {isScanning ? translate('iou.receiptStatusTitle') : convertToDisplayString(totalDisplaySpend, currency)} - - - - {formattedDate} - {expenseCountText} - - - + ); } - return ( - - - {!!canSelectMultiple && ( - - )} - - - - - {columns.map((column) => { - const CellComponent = columnComponents[column as keyof typeof columnComponents]; - return {CellComponent}; - })} - - - + ); } export default ExpenseReportListItemRow; +export type {ExpenseReportListItemRowProps}; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx new file mode 100644 index 000000000000..be8456a77f35 --- /dev/null +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import {View} from 'react-native'; +import Checkbox from '@components/Checkbox'; +import Text from '@components/Text'; +import {useCurrencyListActions} from '@hooks/useCurrencyList'; +import useLocalize from '@hooks/useLocalize'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useThemeStyles from '@hooks/useThemeStyles'; +import DateUtils from '@libs/DateUtils'; +import CONST from '@src/CONST'; +import type {ExpenseReportListItemRowProps} from './ExpenseReportListItemRow'; + +function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSelectMultiple, isSelectAllChecked, isIndeterminate, isDisabledCheckbox}: ExpenseReportListItemRowProps) { + const StyleUtils = useStyleUtils(); + const styles = useThemeStyles(); + const {translate} = useLocalize(); + const {convertToDisplayString} = useCurrencyListActions(); + + const currency = item.currency ?? CONST.CURRENCY.USD; + const {totalDisplaySpend = 0, isAllScanning: isScanning = false} = item; + + const expenseCount = item.transactionCount ?? item.transactions?.length ?? 0; + const expenseCountText = translate('iou.expenseCount', {count: expenseCount}); + const formattedDate = DateUtils.formatWithUTCTimeZone( + item.created ?? '', + DateUtils.doesDateBelongToAPastYear(item.created ?? '') ? CONST.DATE.MONTH_DAY_YEAR_ABBR_FORMAT : CONST.DATE.MONTH_DAY_ABBR_FORMAT, + ); + + const amountText = isScanning ? translate('iou.receiptStatusTitle') : convertToDisplayString(totalDisplaySpend, currency); + const groupAccessibilityLabel = [item.reportName, amountText, formattedDate, expenseCountText].filter(Boolean).join(', '); + + return ( + + {!!canSelectMultiple && ( + + )} + + + + {item.reportName ?? ''} + + {amountText} + + + {formattedDate} + {expenseCountText} + + + + ); +} + +export default ExpenseReportListItemRowNarrow; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx new file mode 100644 index 000000000000..6db17cc1840a --- /dev/null +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx @@ -0,0 +1,243 @@ +import React, {Fragment} from 'react'; +import {View} from 'react-native'; +import Checkbox from '@components/Checkbox'; +import Icon from '@components/Icon'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; +import useStyleUtils from '@hooks/useStyleUtils'; +import useTheme from '@hooks/useTheme'; +import useThemeStyles from '@hooks/useThemeStyles'; +import getBase62ReportID from '@libs/getBase62ReportID'; +import variables from '@styles/variables'; +import CONST from '@src/CONST'; +import DateCell from './DateCell'; +import DeferredActionCell from './DeferredActionCell'; +import ExpenseReportListItemAvatar from './ExpenseReportListItemAvatar'; +import type {ExpenseReportListItemRowProps} from './ExpenseReportListItemRow'; +import ExportedIconCell from './ExportedIconCell'; +import StatusCell from './StatusCell'; +import TextCell from './TextCell'; +import TotalCell from './TotalCell'; +import UserInfoCell from './UserInfoCell'; +import WorkspaceCell from './WorkspaceCell'; + +function ExpenseReportListItemRowWide({ + item, + reportActions, + onCheckboxPress = () => {}, + onButtonPress = () => {}, + isActionLoading, + containerStyle, + showTooltip, + canSelectMultiple, + isSelectAllChecked, + isIndeterminate, + isDisabledCheckbox, + columns = [], + isHovered = false, + isFocused = false, + isPendingDelete = false, +}: ExpenseReportListItemRowProps) { + const StyleUtils = useStyleUtils(); + const styles = useThemeStyles(); + const theme = useTheme(); + const expensifyIcons = useMemoizedLazyExpensifyIcons(['ArrowRight']); + + const currency = item.currency ?? CONST.CURRENCY.USD; + const {totalDisplaySpend = 0, nonReimbursableSpend = 0, reimbursableSpend = 0, isAllScanning: isScanning = false} = item; + + const columnComponents = { + [CONST.SEARCH.TABLE_COLUMNS.DATE]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.SUBMITTED]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.APPROVED]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.EXPORTED]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.STATUS]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.TITLE]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.FROM]: ( + + {!!item.from && ( + + )} + + ), + [CONST.SEARCH.TABLE_COLUMNS.TO]: ( + + {!!item.to && ( + + )} + + ), + [CONST.SEARCH.TABLE_COLUMNS.REIMBURSABLE_TOTAL]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.NON_REIMBURSABLE_TOTAL]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.TOTAL]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.REPORT_ID]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.BASE_62_REPORT_ID]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.EXPORTED_TO]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.ACTION]: ( + + + + ), + [CONST.SEARCH.TABLE_COLUMNS.POLICY_NAME]: ( + + + + ), + }; + + return ( + + + {!!canSelectMultiple && ( + + )} + + + {columns.map((column) => { + const CellComponent = columnComponents[column as keyof typeof columnComponents]; + return {CellComponent}; + })} + + + + ); +} + +export default ExpenseReportListItemRowWide; From 3e8322a27bf2808ee85830d129262d6401051ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 28 Apr 2026 19:12:45 +0200 Subject: [PATCH 02/12] Move ExpenseReportListItemRow to a separate directory --- .../ListItem/ExpenseReportListItem.tsx | 11 +-- .../ListItem/ExpenseReportListItemRow.tsx | 81 ------------------- .../ExpenseReportListItemRowNarrow.tsx | 4 +- .../ExpenseReportListItemRowWide.tsx | 22 ++--- .../ExpenseReportListItemRow/index.tsx | 41 ++++++++++ .../ExpenseReportListItemRow/types.ts | 35 ++++++++ 6 files changed, 90 insertions(+), 104 deletions(-) delete mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx rename src/components/Search/SearchList/ListItem/{ => ExpenseReportListItemRow}/ExpenseReportListItemRowNarrow.tsx (96%) rename src/components/Search/SearchList/ListItem/{ => ExpenseReportListItemRow}/ExpenseReportListItemRowWide.tsx (94%) create mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx create mode 100644 src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx index 1b276009f5a8..190e93110340 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx @@ -304,20 +304,11 @@ function ExpenseReportListItem({ )} @@ -337,7 +328,7 @@ function ExpenseReportListItem({ isHovered={hovered} isFocused={isFocused} isPendingDelete={isPendingDelete} - isLargeScreenWidth={isLargeScreenWidth} + isLargeScreenWidth /> )} {getDescription} diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx deleted file mode 100644 index c5173bce748d..000000000000 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; -import type {StyleProp, ViewStyle} from 'react-native'; -import type {SearchColumnType} from '@components/Search/types'; -import type {ReportAction} from '@src/types/onyx'; -import ExpenseReportListItemRowNarrow from './ExpenseReportListItemRowNarrow'; -import ExpenseReportListItemRowWide from './ExpenseReportListItemRowWide'; -import type {ExpenseReportListItemType} from './types'; - -type ExpenseReportListItemRowProps = { - item: ExpenseReportListItemType; - reportActions?: ReportAction[]; - showTooltip: boolean; - canSelectMultiple?: boolean; - isActionLoading?: boolean; - onButtonPress?: () => void; - onCheckboxPress?: () => void; - containerStyle?: StyleProp; - isSelectAllChecked?: boolean; - isIndeterminate?: boolean; - isDisabledCheckbox?: boolean; - isHovered?: boolean; - isFocused?: boolean; - isPendingDelete?: boolean; - columns?: SearchColumnType[]; - isLargeScreenWidth?: boolean; -}; - -function ExpenseReportListItemRow({ - item, - reportActions, - showTooltip, - canSelectMultiple, - isActionLoading, - onButtonPress, - onCheckboxPress, - containerStyle, - isSelectAllChecked, - isIndeterminate, - isDisabledCheckbox, - isHovered, - isFocused, - isPendingDelete, - columns, - isLargeScreenWidth, -}: ExpenseReportListItemRowProps) { - if (isLargeScreenWidth) { - return ( - - ); - } - return ( - - ); -} - -export default ExpenseReportListItemRow; -export type {ExpenseReportListItemRowProps}; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx similarity index 96% rename from src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx rename to src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx index be8456a77f35..60404820f18c 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowNarrow.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx @@ -8,9 +8,9 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import CONST from '@src/CONST'; -import type {ExpenseReportListItemRowProps} from './ExpenseReportListItemRow'; +import type {ExpenseReportListItemRowNarrowProps} from './types'; -function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSelectMultiple, isSelectAllChecked, isIndeterminate, isDisabledCheckbox}: ExpenseReportListItemRowProps) { +function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSelectMultiple, isSelectAllChecked, isIndeterminate, isDisabledCheckbox}: ExpenseReportListItemRowNarrowProps) { const StyleUtils = useStyleUtils(); const styles = useThemeStyles(); const {translate} = useLocalize(); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx similarity index 94% rename from src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx rename to src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx index 6db17cc1840a..6ad16e82e4ac 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRowWide.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx @@ -9,16 +9,16 @@ import useThemeStyles from '@hooks/useThemeStyles'; import getBase62ReportID from '@libs/getBase62ReportID'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import DateCell from './DateCell'; -import DeferredActionCell from './DeferredActionCell'; -import ExpenseReportListItemAvatar from './ExpenseReportListItemAvatar'; -import type {ExpenseReportListItemRowProps} from './ExpenseReportListItemRow'; -import ExportedIconCell from './ExportedIconCell'; -import StatusCell from './StatusCell'; -import TextCell from './TextCell'; -import TotalCell from './TotalCell'; -import UserInfoCell from './UserInfoCell'; -import WorkspaceCell from './WorkspaceCell'; +import DateCell from '../DateCell'; +import DeferredActionCell from '../DeferredActionCell'; +import ExpenseReportListItemAvatar from '../ExpenseReportListItemAvatar'; +import ExportedIconCell from '../ExportedIconCell'; +import StatusCell from '../StatusCell'; +import TextCell from '../TextCell'; +import TotalCell from '../TotalCell'; +import UserInfoCell from '../UserInfoCell'; +import WorkspaceCell from '../WorkspaceCell'; +import type {ExpenseReportListItemRowWideProps} from './types'; function ExpenseReportListItemRowWide({ item, @@ -36,7 +36,7 @@ function ExpenseReportListItemRowWide({ isHovered = false, isFocused = false, isPendingDelete = false, -}: ExpenseReportListItemRowProps) { +}: ExpenseReportListItemRowWideProps) { const StyleUtils = useStyleUtils(); const styles = useThemeStyles(); const theme = useTheme(); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx new file mode 100644 index 000000000000..d9e6e05a0ad8 --- /dev/null +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import ExpenseReportListItemRowNarrow from './ExpenseReportListItemRowNarrow'; +import ExpenseReportListItemRowWide from './ExpenseReportListItemRowWide'; +import type {ExpenseReportListItemRowProps} from './types'; + +function ExpenseReportListItemRow(props: ExpenseReportListItemRowProps) { + if (props.isLargeScreenWidth) { + return ( + + ); + } + return ( + + ); +} + +export default ExpenseReportListItemRow; +export type {ExpenseReportListItemRowProps, ExpenseReportListItemRowNarrowProps, ExpenseReportListItemRowWideProps} from './types'; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts new file mode 100644 index 000000000000..5f06d13b6926 --- /dev/null +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts @@ -0,0 +1,35 @@ +import type {StyleProp, ViewStyle} from 'react-native'; +import type {SearchColumnType} from '@components/Search/types'; +import type {ReportAction} from '@src/types/onyx'; +import type {ExpenseReportListItemType} from '../types'; + +type ExpenseReportListItemRowNarrowProps = { + item: ExpenseReportListItemType; + canSelectMultiple?: boolean; + onCheckboxPress?: () => void; + isSelectAllChecked?: boolean; + isIndeterminate?: boolean; + isDisabledCheckbox?: boolean; +}; + +type ExpenseReportListItemRowWideProps = { + item: ExpenseReportListItemType; + reportActions?: ReportAction[]; + showTooltip: boolean; + canSelectMultiple?: boolean; + isActionLoading?: boolean; + onButtonPress?: () => void; + onCheckboxPress?: () => void; + containerStyle?: StyleProp; + isSelectAllChecked?: boolean; + isIndeterminate?: boolean; + isDisabledCheckbox?: boolean; + isHovered?: boolean; + isFocused?: boolean; + isPendingDelete?: boolean; + columns?: SearchColumnType[]; +}; + +type ExpenseReportListItemRowProps = (ExpenseReportListItemRowNarrowProps & {isLargeScreenWidth?: false}) | (ExpenseReportListItemRowWideProps & {isLargeScreenWidth: true}); + +export type {ExpenseReportListItemRowProps, ExpenseReportListItemRowNarrowProps, ExpenseReportListItemRowWideProps}; From b564b4dda6c104d404e57f0d0d19971ef6b5a308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 28 Apr 2026 19:23:20 +0200 Subject: [PATCH 03/12] move components arount --- .../ListItem/{ => ActionCell}/DeferredActionCell.tsx | 4 ++-- .../ExpenseReportListItemAvatar.tsx | 4 ++-- .../ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/components/Search/SearchList/ListItem/{ => ActionCell}/DeferredActionCell.tsx (92%) rename src/components/Search/SearchList/ListItem/{ => ExpenseReportListItemRow}/ExpenseReportListItemAvatar.tsx (94%) diff --git a/src/components/Search/SearchList/ListItem/DeferredActionCell.tsx b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx similarity index 92% rename from src/components/Search/SearchList/ListItem/DeferredActionCell.tsx rename to src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx index 8a1e95a00c1e..85c0cedad59b 100644 --- a/src/components/Search/SearchList/ListItem/DeferredActionCell.tsx +++ b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx @@ -3,8 +3,8 @@ import {View} from 'react-native'; import PulsingView from '@components/PulsingView'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; -import ActionCell from './ActionCell'; -import type {ActionCellProps} from './ActionCell'; +import ActionCell from '.'; +import type {ActionCellProps} from '.'; function DeferredActionCell(actionCellProps: ActionCellProps) { const styles = useThemeStyles(); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx similarity index 94% rename from src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx rename to src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx index 9a7e3ccbb284..adaa2a61236d 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemAvatar.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx @@ -1,4 +1,4 @@ -import React, {memo} from 'react'; +import React from 'react'; import {View} from 'react-native'; import SearchReportAvatar from '@components/ReportActionAvatars/SearchReportAvatar'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -38,4 +38,4 @@ function ExpenseReportListItemAvatar({item, showTooltip, isHovered = false, isFo ); } -export default memo(ExpenseReportListItemAvatar); +export default ExpenseReportListItemAvatar; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx index 6ad16e82e4ac..d505878746da 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx @@ -10,14 +10,14 @@ import getBase62ReportID from '@libs/getBase62ReportID'; import variables from '@styles/variables'; import CONST from '@src/CONST'; import DateCell from '../DateCell'; -import DeferredActionCell from '../DeferredActionCell'; -import ExpenseReportListItemAvatar from '../ExpenseReportListItemAvatar'; +import DeferredActionCell from '../ActionCell/DeferredActionCell'; import ExportedIconCell from '../ExportedIconCell'; import StatusCell from '../StatusCell'; import TextCell from '../TextCell'; import TotalCell from '../TotalCell'; import UserInfoCell from '../UserInfoCell'; import WorkspaceCell from '../WorkspaceCell'; +import ExpenseReportListItemAvatar from './ExpenseReportListItemAvatar'; import type {ExpenseReportListItemRowWideProps} from './types'; function ExpenseReportListItemRowWide({ From 1c4c652fd9c61a19b4f5ef585de33db57bcebf96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 28 Apr 2026 19:31:52 +0200 Subject: [PATCH 04/12] remove duplicated code --- .../ListItem/ExpenseReportListItem.tsx | 48 +++++++------------ .../ExpenseReportListItemAvatar.tsx | 2 +- .../ExpenseReportListItemRowNarrow.tsx | 2 +- .../ExpenseReportListItemRow/types.ts | 10 +--- 4 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx index 190e93110340..250bdcd344a4 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx @@ -300,37 +300,23 @@ function ExpenseReportListItem({ statusNum={reportItem.statusNum} /> )} - {!isLargeScreenWidth && ( - - - - )} - {isLargeScreenWidth && ( - - )} + {getDescription} )} diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx index adaa2a61236d..552136043d1e 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx @@ -5,7 +5,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; -import type {ExpenseReportListItemType} from './types'; +import type {ExpenseReportListItemType} from '../types'; type ExpenseReportListItemAvatarProps = { item: ExpenseReportListItemType; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx index 91a7e1829d5f..1d755deee67e 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx @@ -32,7 +32,7 @@ function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSe return ( void; - onCheckboxPress?: () => void; containerStyle?: StyleProp; - isSelectAllChecked?: boolean; - isIndeterminate?: boolean; - isDisabledCheckbox?: boolean; isHovered?: boolean; isFocused?: boolean; isPendingDelete?: boolean; columns?: SearchColumnType[]; }; -type ExpenseReportListItemRowProps = (ExpenseReportListItemRowNarrowProps & {isLargeScreenWidth?: false}) | (ExpenseReportListItemRowWideProps & {isLargeScreenWidth: true}); +type ExpenseReportListItemRowProps = ExpenseReportListItemRowWideProps & {isLargeScreenWidth?: boolean}; export type {ExpenseReportListItemRowProps, ExpenseReportListItemRowNarrowProps, ExpenseReportListItemRowWideProps}; From f9b16acbd57c44a6a7912ab31092cf785744f105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Tue, 28 Apr 2026 19:34:12 +0200 Subject: [PATCH 05/12] fix prettier --- .../ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx index d505878746da..38000e51dac6 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx @@ -9,8 +9,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import getBase62ReportID from '@libs/getBase62ReportID'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import DateCell from '../DateCell'; import DeferredActionCell from '../ActionCell/DeferredActionCell'; +import DateCell from '../DateCell'; import ExportedIconCell from '../ExportedIconCell'; import StatusCell from '../StatusCell'; import TextCell from '../TextCell'; From 1c041db532b14d5920bc090eea749dada6e747e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Wed, 29 Apr 2026 12:19:27 +0200 Subject: [PATCH 06/12] fix lint --- .../ExpenseReportListItemAvatar.tsx | 2 +- .../ExpenseReportListItemRowWide.tsx | 16 ++++++++-------- .../ListItem/ExpenseReportListItemRow/types.ts | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx index 552136043d1e..d833130e645b 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx @@ -1,11 +1,11 @@ import React from 'react'; import {View} from 'react-native'; import SearchReportAvatar from '@components/ReportActionAvatars/SearchReportAvatar'; +import type {ExpenseReportListItemType} from '@components/Search/SearchList/ListItem/types'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; -import type {ExpenseReportListItemType} from '../types'; type ExpenseReportListItemAvatarProps = { item: ExpenseReportListItemType; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx index 38000e51dac6..24e1d2c1d465 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx @@ -2,6 +2,14 @@ import React, {Fragment} from 'react'; import {View} from 'react-native'; import Checkbox from '@components/Checkbox'; import Icon from '@components/Icon'; +import DeferredActionCell from '@components/Search/SearchList/ListItem/ActionCell/DeferredActionCell'; +import DateCell from '@components/Search/SearchList/ListItem/DateCell'; +import ExportedIconCell from '@components/Search/SearchList/ListItem/ExportedIconCell'; +import StatusCell from '@components/Search/SearchList/ListItem/StatusCell'; +import TextCell from '@components/Search/SearchList/ListItem/TextCell'; +import TotalCell from '@components/Search/SearchList/ListItem/TotalCell'; +import UserInfoCell from '@components/Search/SearchList/ListItem/UserInfoCell'; +import WorkspaceCell from '@components/Search/SearchList/ListItem/WorkspaceCell'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; @@ -9,14 +17,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import getBase62ReportID from '@libs/getBase62ReportID'; import variables from '@styles/variables'; import CONST from '@src/CONST'; -import DeferredActionCell from '../ActionCell/DeferredActionCell'; -import DateCell from '../DateCell'; -import ExportedIconCell from '../ExportedIconCell'; -import StatusCell from '../StatusCell'; -import TextCell from '../TextCell'; -import TotalCell from '../TotalCell'; -import UserInfoCell from '../UserInfoCell'; -import WorkspaceCell from '../WorkspaceCell'; import ExpenseReportListItemAvatar from './ExpenseReportListItemAvatar'; import type {ExpenseReportListItemRowWideProps} from './types'; diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts index 600494f97371..791991092fee 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/types.ts @@ -1,7 +1,7 @@ import type {StyleProp, ViewStyle} from 'react-native'; +import type {ExpenseReportListItemType} from '@components/Search/SearchList/ListItem/types'; import type {SearchColumnType} from '@components/Search/types'; import type {ReportAction} from '@src/types/onyx'; -import type {ExpenseReportListItemType} from '../types'; type ExpenseReportListItemRowNarrowProps = { item: ExpenseReportListItemType; From efbf5ab16dc365c169569675b501de5438d33b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Wed, 29 Apr 2026 15:38:24 +0200 Subject: [PATCH 07/12] use deferred value for deferring action cell --- .../ListItem/ActionCell/DeferredActionCell.tsx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx index 85c0cedad59b..657785e7f305 100644 --- a/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx +++ b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx @@ -1,4 +1,4 @@ -import React, {useEffect, useState, useTransition} from 'react'; +import React, {useDeferredValue} from 'react'; import {View} from 'react-native'; import PulsingView from '@components/PulsingView'; import useTheme from '@hooks/useTheme'; @@ -9,12 +9,7 @@ import type {ActionCellProps} from '.'; function DeferredActionCell(actionCellProps: ActionCellProps) { const styles = useThemeStyles(); const theme = useTheme(); - const [shouldRender, setShouldRender] = useState(false); - const [, startTransition] = useTransition(); - - useEffect(() => { - startTransition(() => setShouldRender(true)); - }, []); + const shouldRender = useDeferredValue(true, false); if (!shouldRender) { const sizeStyle = actionCellProps.extraSmall ? styles.buttonExtraSmall : styles.buttonSmall; From 43ff4a981749a4b30e45412262bcd90543ea6da0 Mon Sep 17 00:00:00 2001 From: Olgierd Date: Thu, 7 May 2026 14:12:17 +0200 Subject: [PATCH 08/12] Handle isLargeScreenWidth hook inside the ExpenseReportListItemRow --- .../Search/SearchList/ListItem/ExpenseReportListItem.tsx | 1 - .../SearchList/ListItem/ExpenseReportListItemRow/index.tsx | 5 ++++- .../SearchList/ListItem/ExpenseReportListItemRow/types.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx index 250bdcd344a4..761957981e21 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItem.tsx @@ -315,7 +315,6 @@ function ExpenseReportListItem({ isHovered={hovered} isFocused={isFocused} isPendingDelete={isPendingDelete} - isLargeScreenWidth={isLargeScreenWidth} /> {getDescription} diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx index d9e6e05a0ad8..e4adf93772cb 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/index.tsx @@ -1,10 +1,13 @@ import React from 'react'; +import useResponsiveLayout from '@hooks/useResponsiveLayout'; import ExpenseReportListItemRowNarrow from './ExpenseReportListItemRowNarrow'; import ExpenseReportListItemRowWide from './ExpenseReportListItemRowWide'; import type {ExpenseReportListItemRowProps} from './types'; function ExpenseReportListItemRow(props: ExpenseReportListItemRowProps) { - if (props.isLargeScreenWidth) { + const {isLargeScreenWidth} = useResponsiveLayout(); + + if (isLargeScreenWidth) { return ( Date: Thu, 7 May 2026 17:14:22 +0200 Subject: [PATCH 09/12] Fix typecheck in ExpenseReportListItemRowNarrow by dropping removed StyleUtils helpers from narrow row --- .../ExpenseReportListItemRowNarrow.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx index 1d755deee67e..d0b5d19cefbf 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowNarrow.tsx @@ -4,14 +4,12 @@ import Checkbox from '@components/Checkbox'; import Text from '@components/Text'; import {useCurrencyListActions} from '@hooks/useCurrencyList'; import useLocalize from '@hooks/useLocalize'; -import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import DateUtils from '@libs/DateUtils'; import CONST from '@src/CONST'; import type {ExpenseReportListItemRowNarrowProps} from './types'; function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSelectMultiple, isSelectAllChecked, isIndeterminate, isDisabledCheckbox}: ExpenseReportListItemRowNarrowProps) { - const StyleUtils = useStyleUtils(); const styles = useThemeStyles(); const {translate} = useLocalize(); const {convertToDisplayString} = useCurrencyListActions(); @@ -42,11 +40,11 @@ function ExpenseReportListItemRowNarrow({item, onCheckboxPress = () => {}, canSe onPress={onCheckboxPress} isChecked={isSelectAllChecked} isIndeterminate={isIndeterminate} - containerStyle={[StyleUtils.getCheckboxContainerStyle(20), StyleUtils.getMultiselectListStyles(!!item.isSelected, !!item.isDisabled), styles.m0]} + containerStyle={styles.m0} disabled={isDisabledCheckbox} accessibilityLabel={item.text ?? ''} shouldStopMouseDownPropagation - style={[styles.cursorUnset, StyleUtils.getCheckboxPressableStyle(), isDisabledCheckbox && styles.cursorDisabled]} + style={[styles.cursorUnset, isDisabledCheckbox && styles.cursorDisabled]} sentryLabel={CONST.SENTRY_LABEL.SEARCH.EXPENSE_REPORT_CHECKBOX} /> )} From 83857e2e05c952f9b55ed9d55705ddf1da890f81 Mon Sep 17 00:00:00 2001 From: Olgierd Date: Fri, 8 May 2026 14:10:12 +0200 Subject: [PATCH 10/12] Forward isLargeScreenWidth to ExpenseReportListItemAvatar --- .../ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx | 5 +++-- .../ExpenseReportListItemRowWide.tsx | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx index d833130e645b..7de5b5bc0792 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemAvatar.tsx @@ -12,9 +12,10 @@ type ExpenseReportListItemAvatarProps = { showTooltip: boolean; isHovered?: boolean; isFocused?: boolean; + isLargeScreenWidth?: boolean; }; -function ExpenseReportListItemAvatar({item, showTooltip, isHovered = false, isFocused = false}: ExpenseReportListItemAvatarProps) { +function ExpenseReportListItemAvatar({item, showTooltip, isHovered = false, isFocused = false, isLargeScreenWidth = false}: ExpenseReportListItemAvatarProps) { const StyleUtils = useStyleUtils(); const styles = useThemeStyles(); const theme = useTheme(); @@ -32,7 +33,7 @@ function ExpenseReportListItemAvatar({item, showTooltip, isHovered = false, isFo shouldShowTooltip={showTooltip} subscriptAvatarBorderColor={finalAvatarBorderColor} reportID={item.reportID} - isLargeScreenWidth + isLargeScreenWidth={isLargeScreenWidth} /> ); diff --git a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx index e5a9f405711f..7151ebab9782 100644 --- a/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx +++ b/src/components/Search/SearchList/ListItem/ExpenseReportListItemRow/ExpenseReportListItemRowWide.tsx @@ -52,6 +52,7 @@ function ExpenseReportListItemRowWide({ showTooltip={showTooltip} isHovered={isHovered} isFocused={isFocused} + isLargeScreenWidth /> ), [CONST.SEARCH.TABLE_COLUMNS.DATE]: ( From eb8038d47ff38a64341173591865eaa19ace6000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Musia=C5=82?= Date: Mon, 11 May 2026 17:52:38 +0200 Subject: [PATCH 11/12] deferred action cell is disabled button --- .../ActionCell/DeferredActionCell.tsx | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx index 657785e7f305..13a85cde7fc1 100644 --- a/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx +++ b/src/components/Search/SearchList/ListItem/ActionCell/DeferredActionCell.tsx @@ -1,28 +1,37 @@ import React, {useDeferredValue} from 'react'; -import {View} from 'react-native'; -import PulsingView from '@components/PulsingView'; -import useTheme from '@hooks/useTheme'; +import Button from '@components/Button'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; +import CONST from '@src/CONST'; import ActionCell from '.'; import type {ActionCellProps} from '.'; +import actionTranslationsMap from './actionTranslationsMap'; function DeferredActionCell(actionCellProps: ActionCellProps) { const styles = useThemeStyles(); - const theme = useTheme(); + const {translate} = useLocalize(); const shouldRender = useDeferredValue(true, false); if (!shouldRender) { - const sizeStyle = actionCellProps.extraSmall ? styles.buttonExtraSmall : styles.buttonSmall; + const action = actionCellProps.action ?? CONST.SEARCH.ACTION_TYPES.VIEW; + const shouldUseViewAction = action === CONST.SEARCH.ACTION_TYPES.VIEW || action === CONST.SEARCH.ACTION_TYPES.PAID || action === CONST.SEARCH.ACTION_TYPES.DONE; + const isSuccess = !shouldUseViewAction && action !== CONST.SEARCH.ACTION_TYPES.UNDELETE; + const text = shouldUseViewAction ? translate(actionTranslationsMap[CONST.SEARCH.ACTION_TYPES.VIEW]) : translate(actionTranslationsMap[action]); + return ( - - - +