From 4daf536fc91e64930c62937f067ef3ab2bd5a1b9 Mon Sep 17 00:00:00 2001 From: Shawn Borton Date: Fri, 24 Jul 2026 12:43:56 -0400 Subject: [PATCH] Facelift: hover/active colors for menus, tabs, LHN and section spacing --- src/components/HeaderWithBackButton/index.tsx | 10 +- src/components/HeaderWithBackButton/types.ts | 10 +- .../OptionRowLHN/OptionRow/Pressable.tsx | 4 +- .../OptionRowLHN/useOptionRowChrome.ts | 4 +- src/components/MenuItem.tsx | 18 +- .../MenuItemHoverBackgroundContext.ts | 9 + src/components/Section/index.tsx | 173 +++++++++--------- src/components/TabSelector/getBackground.ts | 6 +- src/components/WorkspaceListLayout.tsx | 22 ++- src/pages/Search/SearchTypeMenuItem.tsx | 3 +- src/pages/TeachersUnite/SaveTheWorldPage.tsx | 5 +- src/pages/domain/Admins/DomainAdminsPage.tsx | 4 +- src/pages/domain/BaseDomainMembersPage.tsx | 7 - src/pages/domain/DomainInitialPage.tsx | 1 + src/pages/domain/DomainSamlPage.tsx | 4 +- src/pages/domain/Groups/DomainGroupsPage.tsx | 4 +- .../domain/Members/DomainMembersPage.tsx | 4 +- src/pages/home/AnnouncementSection.tsx | 3 + src/pages/home/DiscoverSection.tsx | 3 + src/pages/home/HomePage.tsx | 6 +- .../UpcomingTravelItem.tsx | 1 + src/pages/home/YourSpendSection/CardRow.tsx | 1 + .../home/YourSpendSection/SpendSummaryRow.tsx | 1 + src/pages/settings/AboutPage/AboutPage.tsx | 8 +- src/pages/settings/Agents/AgentsPage.tsx | 4 +- src/pages/settings/Copilot/CopilotPage.tsx | 5 +- src/pages/settings/HelpPage/HelpPage.tsx | 5 +- .../settings/Preferences/PreferencesPage.tsx | 5 +- src/pages/settings/Profile/ProfilePage.tsx | 8 +- src/pages/settings/Rules/ExpenseRulesPage.tsx | 4 +- .../Security/SecuritySettingsPage.tsx | 6 +- .../Subscription/SubscriptionSettingsPage.tsx | 5 +- .../Troubleshoot/TroubleshootPage.tsx | 6 +- .../settings/Wallet/WalletPage/index.tsx | 5 +- src/pages/workspace/WorkspaceInitialPage.tsx | 2 + src/pages/workspace/WorkspaceMembersPage.tsx | 4 +- .../WorkspaceMoreFeaturesPage/index.tsx | 2 - src/pages/workspace/WorkspaceOverviewPage.tsx | 6 +- .../accounting/PolicyAccountingPage.tsx | 6 +- .../categories/WorkspaceCategoriesPage.tsx | 4 +- .../WorkspaceCompanyCardsPage.tsx | 3 - .../distanceRates/PolicyDistanceRatesPage.tsx | 6 +- .../WorkspaceExpensifyCardListPage.tsx | 4 +- .../WorkspaceExpensifyCardPageEmptyState.tsx | 7 +- src/pages/workspace/hr/WorkspaceHRPage.tsx | 6 +- .../invoices/WorkspaceInvoicesPage.tsx | 5 +- .../perDiem/WorkspacePerDiemPage.tsx | 4 +- .../WorkspaceReceiptPartnersPage.tsx | 8 +- .../reports/WorkspaceReportsPage.tsx | 6 +- .../workspace/rooms/WorkspaceRoomsPage.tsx | 4 +- src/pages/workspace/rules/PolicyRulesPage.tsx | 6 +- .../workspace/rules/PolicyRulesPageRevamp.tsx | 6 +- .../workspace/tags/WorkspaceTagsPage.tsx | 4 +- .../workspace/taxes/WorkspaceTaxesPage.tsx | 4 +- .../WorkspaceTimeTrackingPage.tsx | 5 +- .../workspace/travel/GetStartedTravel.tsx | 55 +++--- .../workspace/travel/PolicyTravelPage.tsx | 12 +- .../vendors/WorkspaceVendorsPage.tsx | 3 - .../workflows/WorkspaceWorkflowsPage.tsx | 6 +- src/styles/index.ts | 22 ++- src/styles/variables.ts | 5 +- 61 files changed, 277 insertions(+), 292 deletions(-) create mode 100644 src/components/MenuItemHoverBackgroundContext.ts diff --git a/src/components/HeaderWithBackButton/index.tsx b/src/components/HeaderWithBackButton/index.tsx index 36ee9567d2b0..4185b3aa129a 100755 --- a/src/components/HeaderWithBackButton/index.tsx +++ b/src/components/HeaderWithBackButton/index.tsx @@ -49,6 +49,8 @@ function HeaderWithBackButton({ onThreeDotsButtonPress = () => {}, report, policyAvatar, + policyAvatarSize = CONST.AVATAR_SIZE.DEFAULT, + titleStyles, shouldShowReportAvatarWithDisplay = false, shouldDisplayStatus, shouldShowBackButton = true, @@ -157,7 +159,7 @@ function HeaderWithBackButton({
& { /** Policy avatar to display in the header */ policyAvatar?: Icon; + /** Size of the policy avatar. Defaults to CONST.AVATAR_SIZE.DEFAULT */ + policyAvatarSize?: ValueOf; + + /** Additional styles to apply to the title text */ + titleStyles?: StyleProp; + /** Additional styles to add to the component */ style?: StyleProp; diff --git a/src/components/LHNOptionsList/OptionRowLHN/OptionRow/Pressable.tsx b/src/components/LHNOptionsList/OptionRowLHN/OptionRow/Pressable.tsx index 3061cb623992..1ffab36aefd3 100644 --- a/src/components/LHNOptionsList/OptionRowLHN/OptionRow/Pressable.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN/OptionRow/Pressable.tsx @@ -167,8 +167,8 @@ function Pressable({optionItem, isOptionFocused, onSelectRow, onLayout, onHoverI styles.sidebarLink, styles.sidebarLinkInnerLHN, StyleUtils.getBackgroundColorStyle(theme.sidebar), - isOptionFocused ? styles.sidebarLinkActive : null, - (hovered || isContextMenuActive) && !isOptionFocused ? styles.sidebarLinkHover : null, + isOptionFocused ? StyleUtils.getBackgroundColorStyle(theme.hoverComponentBG) : null, + (hovered || isContextMenuActive) && !isOptionFocused ? StyleUtils.getBackgroundColorStyle(theme.highlightBG) : null, ]} role={CONST.ROLE.BUTTON} accessibilityLabel={accessibilityLabelWithContextMenuHint} diff --git a/src/components/LHNOptionsList/OptionRowLHN/useOptionRowChrome.ts b/src/components/LHNOptionsList/OptionRowLHN/useOptionRowChrome.ts index c6cf4d1f5d3d..ff8491641676 100644 --- a/src/components/LHNOptionsList/OptionRowLHN/useOptionRowChrome.ts +++ b/src/components/LHNOptionsList/OptionRowLHN/useOptionRowChrome.ts @@ -44,8 +44,8 @@ function useOptionRowChrome({isOptionFocused, viewMode}: UseOptionRowChromeParam ); const contentContainerStyles = isInFocusMode ? [styles.flex1, styles.flexRow, styles.overflowHidden, StyleUtils.getCompactContentContainerStyles()] : [styles.flex1]; - const hoveredBackgroundColor = !!styles.sidebarLinkHover && 'backgroundColor' in styles.sidebarLinkHover ? styles.sidebarLinkHover.backgroundColor : theme.sidebar; - const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor; + const hoveredBackgroundColor = theme.highlightBG; + const focusedBackgroundColor = theme.hoverComponentBG; let avatarBackgroundColor: ColorValue = theme.sidebar; if (isOptionFocused) { diff --git a/src/components/MenuItem.tsx b/src/components/MenuItem.tsx index aea0caaee36f..5bc245d3fd96 100644 --- a/src/components/MenuItem.tsx +++ b/src/components/MenuItem.tsx @@ -35,7 +35,7 @@ import type {GestureResponderEvent, Role, StyleProp, TextStyle, ViewStyle} from import type {AnimatedStyle} from 'react-native-reanimated'; import type {ValueOf} from 'type-fest'; -import React, {useEffect, useMemo, useRef} from 'react'; +import React, {useContext, useEffect, useMemo, useRef} from 'react'; import {View} from 'react-native'; import type {DisplayNameWithTooltip} from './DisplayNames/types'; @@ -53,6 +53,7 @@ import Hoverable from './Hoverable'; import Icon from './Icon'; import InlineIcon from './Icon/InlineIcon'; import {useMenuItemGroupActions, useMenuItemGroupState} from './MenuItemGroup'; +import MenuItemHoverBackgroundContext from './MenuItemHoverBackgroundContext'; import PlaidCardFeedIcon from './PlaidCardFeedIcon'; import PressableWithSecondaryInteraction from './PressableWithSecondaryInteraction'; import RadioButton from './RadioButton'; @@ -313,6 +314,9 @@ type MenuItemBaseProps = ForwardedFSClassProps & /** Should we remove the hover background color of the menu item */ shouldRemoveHoverBackground?: boolean; + /** Overrides the hover background color; falls back to the default hover background when omitted */ + hoverBackgroundColor?: string; + rightIconAccountID?: number | string; iconAccountID?: number; @@ -576,6 +580,7 @@ function MenuItem({ shouldGreyOutWhenDisabled = true, shouldRemoveBackground = false, shouldRemoveHoverBackground = false, + hoverBackgroundColor, shouldUseDefaultCursorWhenDisabled = false, shouldShowLoadingSpinnerIcon = false, isAnonymousAction = false, @@ -634,6 +639,8 @@ function MenuItem({ const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); + const cardHoverBackgroundColor = useContext(MenuItemHoverBackgroundContext); + const effectiveHoverBackgroundColor = hoverBackgroundColor ?? cardHoverBackgroundColor; const combinedStyle = [styles.popoverMenuItem, style]; // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {shouldUseNarrowLayout, isSmallScreenWidth} = useResponsiveLayout(); @@ -896,7 +903,14 @@ function MenuItem({ StyleUtils.getButtonBackgroundColorStyle(getButtonState(focused || isHovered, pressed, success, disabled, interactive), true), ...(Array.isArray(wrapperStyle) ? wrapperStyle : [wrapperStyle]), shouldGreyOutWhenDisabled && disabled && styles.buttonOpacityDisabled, - isHovered && interactive && !focused && !pressed && !shouldRemoveBackground && !shouldRemoveHoverBackground && styles.hoveredComponentBG, + focused && interactive && !pressed && !shouldRemoveBackground && styles.hoveredComponentBG, + isHovered && + interactive && + !focused && + !pressed && + !shouldRemoveBackground && + !shouldRemoveHoverBackground && + (effectiveHoverBackgroundColor ? StyleUtils.getBackgroundColorStyle(effectiveHoverBackgroundColor) : styles.highlightBG), ] as StyleProp } disabledStyle={shouldUseDefaultCursorWhenDisabled && [styles.cursorDefault]} diff --git a/src/components/MenuItemHoverBackgroundContext.ts b/src/components/MenuItemHoverBackgroundContext.ts new file mode 100644 index 000000000000..a8994bc61ee0 --- /dev/null +++ b/src/components/MenuItemHoverBackgroundContext.ts @@ -0,0 +1,9 @@ +import {createContext} from 'react'; + +/** + * Hover background color for MenuItems rendered inside a container card (e.g. Section), so a hovered row + * stands out from the card background. Undefined outside a card, where MenuItems use their default hover. + */ +const MenuItemHoverBackgroundContext = createContext(undefined); + +export default MenuItemHoverBackgroundContext; diff --git a/src/components/Section/index.tsx b/src/components/Section/index.tsx index 8f8e538e5dba..bc55a3805dab 100644 --- a/src/components/Section/index.tsx +++ b/src/components/Section/index.tsx @@ -1,6 +1,7 @@ import ImageSVG from '@components/ImageSVG'; import Lottie from '@components/Lottie'; import type DotLottieAnimation from '@components/LottieAnimations/types'; +import MenuItemHoverBackgroundContext from '@components/MenuItemHoverBackgroundContext'; import type {MenuItemWithLink} from '@components/MenuItemList'; import MenuItemList from '@components/MenuItemList'; import Text from '@components/Text'; @@ -144,94 +145,102 @@ function Section({ const lottieIllustration = isLottie ? illustration : undefined; return ( - - {banner} - {cardLayout === CARD_LAYOUT.ICON_ON_TOP && ( - - )} - {!!illustration && ( - - - {isLottie ? ( - + + {banner} + {cardLayout === CARD_LAYOUT.ICON_ON_TOP && ( + + )} + {!!illustration && ( + + + {isLottie ? ( + + ) : ( + + )} + + {overlayContent?.()} + + )} + + + {cardLayout === CARD_LAYOUT.ICON_ON_LEFT && ( + - ) : ( - + {renderTitle + ? renderTitle() + : !!title && ( + + {title} + + )} + + {cardLayout === CARD_LAYOUT.ICON_ON_RIGHT && ( + )} - {overlayContent?.()} - - )} - - - {cardLayout === CARD_LAYOUT.ICON_ON_LEFT && ( - - )} - - {renderTitle - ? renderTitle() - : !!title && ( - - {title} - - )} - - {cardLayout === CARD_LAYOUT.ICON_ON_RIGHT && ( - - )} - - - {renderSubtitle - ? renderSubtitle?.() - : !!subtitle && ( - - {subtitle} - - )} - {children} - - {!!menuItems && } + {renderSubtitle + ? renderSubtitle?.() + : !!subtitle && ( + + {subtitle} + + )} + + {children} + + {!!menuItems && } + - + ); } diff --git a/src/components/TabSelector/getBackground.ts b/src/components/TabSelector/getBackground.ts index 0c0f27b602c6..4d5ca848ba93 100644 --- a/src/components/TabSelector/getBackground.ts +++ b/src/components/TabSelector/getBackground.ts @@ -11,15 +11,15 @@ function getBackgroundColor({routesLength, tabIndex, affectedTabs, theme, positi return position.interpolate({ inputRange, outputRange: inputRange.map((i) => { - return affectedTabs.includes(tabIndex) && i === tabIndex ? theme.border : theme.appBG; + return affectedTabs.includes(tabIndex) && i === tabIndex ? theme.hoverComponentBG : theme.appBG; }), }) as unknown as Animated.AnimatedInterpolation; } - return affectedTabs.includes(tabIndex) && isActive ? theme.border : theme.appBG; + return affectedTabs.includes(tabIndex) && isActive ? theme.hoverComponentBG : theme.appBG; } - return theme.border; + return theme.hoverComponentBG; } export default getBackgroundColor; diff --git a/src/components/WorkspaceListLayout.tsx b/src/components/WorkspaceListLayout.tsx index e3db24ab0ac9..701fa149eebf 100644 --- a/src/components/WorkspaceListLayout.tsx +++ b/src/components/WorkspaceListLayout.tsx @@ -83,17 +83,19 @@ export default function WorkspaceListLayout({children, activeTabKey, headerButto {!shouldDisplayButtonsInSeparateLine && headerButton} - - - {shouldDisplayButtonsInSeparateLine && headerButton} + + + + {shouldDisplayButtonsInSeparateLine && headerButton} + + + {children} + {!shouldUseNarrowLayout && } - - {children} - {!shouldUseNarrowLayout && } diff --git a/src/pages/Search/SearchTypeMenuItem.tsx b/src/pages/Search/SearchTypeMenuItem.tsx index ddb635c62db7..834dd7261193 100644 --- a/src/pages/Search/SearchTypeMenuItem.tsx +++ b/src/pages/Search/SearchTypeMenuItem.tsx @@ -85,7 +85,8 @@ function SearchTypeMenuItem({title, icon, badgeText, focused = false, onPress}: styles.sectionMenuItem(shouldUseNarrowLayout), styles.searchTypeMenuItemPadding, StyleUtils.getButtonBackgroundColorStyle(getButtonState(focused || hovered, pressed, false, false, true), true), - hovered && !focused && !pressed && styles.hoveredComponentBG, + focused && !pressed && styles.hoveredComponentBG, + hovered && !focused && !pressed && styles.highlightBG, ]} > {({hovered, pressed}) => ( diff --git a/src/pages/TeachersUnite/SaveTheWorldPage.tsx b/src/pages/TeachersUnite/SaveTheWorldPage.tsx index fbeee069313f..215c39b3b054 100644 --- a/src/pages/TeachersUnite/SaveTheWorldPage.tsx +++ b/src/pages/TeachersUnite/SaveTheWorldPage.tsx @@ -10,7 +10,6 @@ import SectionSubtitleHTML from '@components/SectionSubtitleHTML'; import useConfirmModal from '@hooks/useConfirmModal'; import useDocumentTitle from '@hooks/useDocumentTitle'; -import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -46,7 +45,6 @@ function SaveTheWorldPage() { const theme = useTheme(); const {isActingAsDelegate} = useDelegateNoAccessState(); const {showDelegateNoAccessModal} = useDelegateNoAccessActions(); - const illustrations = useMemoizedLazyIllustrations(['TeachersUnite']); const [personalOffsetsEnabled = false] = useOnyx(ONYXKEYS.NVP_PERSONAL_OFFSETS); const [userBillingFundID] = useOnyx(ONYXKEYS.NVP_BILLING_FUND_ID); const [fundList] = useOnyx(ONYXKEYS.FUND_LIST); @@ -150,11 +148,10 @@ function SaveTheWorldPage() { shouldDisplaySearchRouter shouldDisplayHelpButton onBackButtonPress={Navigation.goBack} - icon={illustrations.TeachersUnite} shouldUseHeadlineHeader /> - +
Navigation.goBack(ROUTES.DOMAINS_LIST.route)} shouldDisplayHelpButton={shouldUseNarrowLayout} /> diff --git a/src/pages/domain/DomainSamlPage.tsx b/src/pages/domain/DomainSamlPage.tsx index 2eecf64bd0c1..2b945865447f 100644 --- a/src/pages/domain/DomainSamlPage.tsx +++ b/src/pages/domain/DomainSamlPage.tsx @@ -100,8 +100,8 @@ function DomainSamlPage({route}: DomainSamlPageProps) { > @@ -111,7 +111,7 @@ function DomainSamlPage({route}: DomainSamlPageProps) { addBottomSafeAreaPadding style={[styles.settingsPageBackground, styles.flex1, styles.w100]} > - + {domain?.validated && domainName ? ( <>
diff --git a/src/pages/domain/Members/DomainMembersPage.tsx b/src/pages/domain/Members/DomainMembersPage.tsx index 500bb2ca0668..8300bdcbd035 100644 --- a/src/pages/domain/Members/DomainMembersPage.tsx +++ b/src/pages/domain/Members/DomainMembersPage.tsx @@ -56,7 +56,7 @@ function DomainMembersPage({route}: DomainMembersPageProps) { const {domainAccountID} = route.params; const {translate, formatPhoneNumber} = useLocalize(); const styles = useThemeStyles(); - const illustrations = useMemoizedLazyIllustrations(['Profile', 'LaptopWithMembers', 'LockClosed', 'BuildingCross', 'Encryption']); + const illustrations = useMemoizedLazyIllustrations(['LaptopWithMembers', 'LockClosed', 'BuildingCross', 'Encryption']); const icons = useMemoizedLazyExpensifyIcons(['Plus', 'Gear', 'DotIndicator', 'RemoveMembers', 'Download', 'Transfer']); const {shouldUseNarrowLayout} = useResponsiveLayout(); const [selectedMembers, setSelectedMembers] = useState([]); @@ -302,7 +302,6 @@ function DomainMembersPage({route}: DomainMembersPageProps) { @@ -345,7 +344,6 @@ function DomainMembersPage({route}: DomainMembersPageProps) { domainAccountID={domainAccountID} members={members} headerTitle={translate('domain.members.title')} - headerIcon={illustrations.Profile} headerContent={getHeaderButtons()} selectedMembers={selectedMembers} setSelectedMembers={setSelectedMembers} diff --git a/src/pages/home/AnnouncementSection.tsx b/src/pages/home/AnnouncementSection.tsx index 611d5f291579..69f4a2edb9f5 100644 --- a/src/pages/home/AnnouncementSection.tsx +++ b/src/pages/home/AnnouncementSection.tsx @@ -4,6 +4,7 @@ import WidgetContainer from '@components/WidgetContainer'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; @@ -25,6 +26,7 @@ function AnnouncementSection() { const {shouldUseNarrowLayout} = useResponsiveLayout(); const {translate} = useLocalize(); const styles = useThemeStyles(); + const theme = useTheme(); return ( ( - {!shouldUseNarrowLayout && } + {!shouldUseNarrowLayout && ( + + + + )} {/* Widgets handle their own visibility and may return null to avoid duplicating visibility logic here */} {shouldUseNarrowLayout ? ( diff --git a/src/pages/home/UpcomingTravelSection/UpcomingTravelItem.tsx b/src/pages/home/UpcomingTravelSection/UpcomingTravelItem.tsx index 6c65c8724bb7..27340e4d3793 100644 --- a/src/pages/home/UpcomingTravelSection/UpcomingTravelItem.tsx +++ b/src/pages/home/UpcomingTravelSection/UpcomingTravelItem.tsx @@ -112,6 +112,7 @@ function UpcomingTravelItem({reservation: upcomingReservation}: UpcomingTravelIt return ( (null); @@ -175,11 +174,10 @@ function AboutPage() { shouldDisplaySearchRouter shouldDisplayHelpButton onBackButtonPress={Navigation.goBack} - icon={illustrations.PalmTree} shouldUseHeadlineHeader /> - +
- + ${translate('initialSettingsPage.readTheTermsAndPrivacy')} ${translate('termsOfUse.license')}`} />
diff --git a/src/pages/settings/Agents/AgentsPage.tsx b/src/pages/settings/Agents/AgentsPage.tsx index 0ef384f8fa3a..e77d1d14c91c 100644 --- a/src/pages/settings/Agents/AgentsPage.tsx +++ b/src/pages/settings/Agents/AgentsPage.tsx @@ -13,7 +13,7 @@ import useChatWithAgent from '@hooks/useChatWithAgent'; import useCleanupSelectedOptions from '@hooks/useCleanupSelectedOptions'; import useConfirmModal from '@hooks/useConfirmModal'; import useDocumentTitle from '@hooks/useDocumentTitle'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useNetwork from '@hooks/useNetwork'; @@ -46,7 +46,6 @@ function AgentsPage() { const styles = useThemeStyles(); const {isOffline} = useNetwork(); const {shouldUseNarrowLayout} = useResponsiveLayout(); - const illustrations = useMemoizedLazyIllustrations(['AiBot']); const icons = useMemoizedLazyExpensifyIcons(['Plus', 'Trashcan']); const chatWithAgent = useChatWithAgent(); const switchToDelegator = useSwitchToDelegator(); @@ -213,7 +212,6 @@ function AgentsPage() { offlineIndicatorStyle={styles.mtAuto} > { if (isMobileSelectionModeEnabled) { clearSelectedAgents(); diff --git a/src/pages/settings/Copilot/CopilotPage.tsx b/src/pages/settings/Copilot/CopilotPage.tsx index f30e004fe596..96a213404b48 100644 --- a/src/pages/settings/Copilot/CopilotPage.tsx +++ b/src/pages/settings/Copilot/CopilotPage.tsx @@ -58,7 +58,7 @@ const accountDelegationSelector = (accountValue: Account | undefined) => ({ function CopilotPage() { const icons = useMemoizedLazyExpensifyIcons(['ArrowCircleClockwise', 'CircleSlash', 'Pencil', 'ThreeDots', 'UserPlus']); - const illustrations = useMemoizedLazyIllustrations(['Copilots', 'Members']); + const illustrations = useMemoizedLazyIllustrations(['Copilots']); const styles = useThemeStyles(); const {localeCompare, translate, formatPhoneNumber} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); @@ -413,13 +413,12 @@ function CopilotPage() { title={translate('delegate.copilot')} shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={Navigation.goBack} - icon={illustrations.Members} shouldUseHeadlineHeader shouldDisplaySearchRouter shouldDisplayHelpButton /> - +
( diff --git a/src/pages/settings/HelpPage/HelpPage.tsx b/src/pages/settings/HelpPage/HelpPage.tsx index 0f9b76e3e6a1..9a6bca3412a2 100644 --- a/src/pages/settings/HelpPage/HelpPage.tsx +++ b/src/pages/settings/HelpPage/HelpPage.tsx @@ -33,7 +33,7 @@ import {View} from 'react-native'; function HelpPage() { const icons = useMemoizedLazyExpensifyIcons(['ConciergeAvatar', 'NewWindow', 'Monitor']); - const illustrations = useMemoizedLazyIllustrations(['Chalkboard', 'LifeRing', 'TopiaryDollarSign']); + const illustrations = useMemoizedLazyIllustrations(['Chalkboard', 'TopiaryDollarSign']); const themeIllustrations = useThemeIllustrations(); const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); @@ -174,7 +174,6 @@ function HelpPage() { > - +
- +
loadIllustration('Profile' as IllustrationName)); const icons = useMemoizedLazyExpensifyIcons(['QrCode']); const contactMethodBrickRoadIndicator = getLoginListBrickRoadIndicator(loginList, currentUserPersonalDetails?.email); @@ -210,7 +207,6 @@ function ProfilePage() { shouldShowBackButton={shouldUseNarrowLayout} shouldDisplaySearchRouter shouldDisplayHelpButton - icon={Profile} shouldUseHeadlineHeader /> - +
(), expenseRulesResult] = useOnyx(ONYXKEYS.NVP_EXPENSE_RULES); @@ -174,7 +173,6 @@ function ExpenseRulesPage() { offlineIndicatorStyle={styles.mtAuto} > { if (isMobileSelectionModeEnabled) { setSelectedRules([]); diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index 9f60f9620c4a..063696d27c5e 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -11,7 +11,7 @@ import Section from '@components/Section'; import useConfirmModal from '@hooks/useConfirmModal'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useDocumentTitle from '@hooks/useDocumentTitle'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useOnyx from '@hooks/useOnyx'; @@ -55,7 +55,6 @@ type BaseMenuItemType = WithSentryLabel & { function SecuritySettingsPage() { const icons = useMemoizedLazyExpensifyIcons(['ArrowCollapse', 'ClosedSign', 'Fingerprint', 'Monitor', 'Shield', 'UserLock']); - const illustrations = useMemoizedLazyIllustrations(['LockClosed']); const securitySettingsIllustration = useSecuritySettingsSectionIllustration(); const styles = useThemeStyles(); const {translate} = useLocalize(); @@ -277,13 +276,12 @@ function SecuritySettingsPage() { title={translate('initialSettingsPage.security')} shouldShowBackButton={shouldUseNarrowLayout} onBackButtonPress={Navigation.goBack} - icon={illustrations.LockClosed} shouldUseHeadlineHeader shouldDisplaySearchRouter shouldDisplayHelpButton /> - +
{ openSubscriptionPage(); @@ -76,11 +74,10 @@ function SubscriptionSettingsPage({route}: SubscriptionSettingsPageProps) { shouldShowBackButton={shouldUseNarrowLayout} shouldDisplaySearchRouter shouldDisplayHelpButton - icon={illustrations.CreditCardsNew} shouldUseHeadlineHeader /> - + diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx index c1337fdc043f..35a5c8725ded 100644 --- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx +++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx @@ -16,7 +16,7 @@ import TestToolRow from '@components/TestToolRow'; import useConfirmModal from '@hooks/useConfirmModal'; import useDocumentTitle from '@hooks/useDocumentTitle'; import useEnvironment from '@hooks/useEnvironment'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; @@ -61,7 +61,6 @@ type BaseMenuItem = WithSentryLabel & { function TroubleshootPage() { const icons = useMemoizedLazyExpensifyIcons(['Download', 'ExpensifyLogoNew', 'RotateLeft']); - const illustrations = useMemoizedLazyIllustrations(['Lightbulb']); const troubleshootIllustration = useTroubleshootSectionIllustration(); const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -204,12 +203,11 @@ function TroubleshootPage() { shouldDisplaySearchRouter shouldDisplayHelpButton onBackButtonPress={Navigation.goBack} - icon={illustrations.Lightbulb} shouldUseHeadlineHeader /> {isLoading && } - +
{headerWithBackButton} - + Navigation.goBack(route.params?.backTo ?? ROUTES.WORKSPACES_LIST.route)} policyAvatar={policyAvatar} + policyAvatarSize={CONST.AVATAR_SIZE.SMALL} shouldDisplayHelpButton={shouldUseNarrowLayout} /> diff --git a/src/pages/workspace/WorkspaceMembersPage.tsx b/src/pages/workspace/WorkspaceMembersPage.tsx index 6ee5d9799be5..1ea5f031dd79 100644 --- a/src/pages/workspace/WorkspaceMembersPage.tsx +++ b/src/pages/workspace/WorkspaceMembersPage.tsx @@ -16,7 +16,7 @@ import TextLink from '@components/TextLink'; import useConfirmModal from '@hooks/useConfirmModal'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useHRSyncResultsModal from '@hooks/useHRSyncResultsModal'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useNetwork from '@hooks/useNetwork'; @@ -139,7 +139,6 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers const policyID = route.params.policyID; const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`); const [invitedEmailsToAccountIDsDraft] = useOnyx(`${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT}${policyID}`); - const illustrations = useMemoizedLazyIllustrations(['ReceiptWrangler', 'EmptyShelves']); const accountIDs = useMemo(() => Object.values(policyMemberEmailsToAccountIDs ?? {}).map((accountID) => Number(accountID)), [policyMemberEmailsToAccountIDs]); const prevAccountIDs = usePrevious(accountIDs); @@ -750,7 +749,6 @@ function WorkspaceMembersPage({personalDetails, route, policy}: WorkspaceMembers - + {shouldDisplayButtonsInSeparateLine && {headerButtons}}
- +
{ diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx index 46767b813ea6..8fb4a63d2848 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx @@ -4,7 +4,6 @@ import WorkspaceCompanyCardsTable from '@components/Tables/WorkspaceCompanyCards import useAssignCard from '@hooks/useAssignCard'; import useCompanyCards from '@hooks/useCompanyCards'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; -import {useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePolicy from '@hooks/usePolicy'; @@ -33,7 +32,6 @@ function WorkspaceCompanyCardsPage({route}: WorkspaceCompanyCardsPageProps) { const policyID = route.params.policyID; const {translate} = useLocalize(); const {login: currentUserLogin = ''} = useCurrentUserPersonalDetails(); - const memoizedIllustrations = useMemoizedLazyIllustrations(['CompanyCard']); const {shouldUseNarrowLayout} = useResponsiveLayout(); const policy = usePolicy(policyID); @@ -104,7 +102,6 @@ function WorkspaceCompanyCardsPage({route}: WorkspaceCompanyCardsPageProps) { policyFeature={CONST.POLICY.POLICY_FEATURE.COMPANY_CARDS} > loadIllustration('CarIce' as IllustrationName)); const customUnit = useMemo(() => getDistanceRateCustomUnit(policy), [policy]); const customUnitRates: Record = useMemo(() => customUnit?.rates ?? {}, [customUnit?.rates]); @@ -457,7 +454,6 @@ function PolicyDistanceRatesPage({ shouldShowOfflineIndicatorInWideScreen > - + - + {translate(isUkEuCurrencySupported ? 'workspace.expensifyCard.euUkDisclaimer' : 'workspace.expensifyCard.disclaimer')} diff --git a/src/pages/workspace/hr/WorkspaceHRPage.tsx b/src/pages/workspace/hr/WorkspaceHRPage.tsx index a3ad66f359bf..3d49c4faca92 100644 --- a/src/pages/workspace/hr/WorkspaceHRPage.tsx +++ b/src/pages/workspace/hr/WorkspaceHRPage.tsx @@ -7,7 +7,7 @@ import Section from '@components/Section'; import useConfirmModal from '@hooks/useConfirmModal'; import useHRSyncResultsModal from '@hooks/useHRSyncResultsModal'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useMergeHRInitialSyncingModal from '@hooks/useMergeHRInitialSyncingModal'; import useNetwork from '@hooks/useNetwork'; @@ -56,7 +56,6 @@ function WorkspaceHRPage({ const policy = usePolicy(policyID); const [connectionSyncProgress] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY_CONNECTION_SYNC_PROGRESS}${policyID}`); const icons = useMemoizedLazyExpensifyIcons(['GustoSquare', 'TriNetSquare']); - const illustrations = useMemoizedLazyIllustrations(['NewUser']); const [activeHRFlow, setActiveHRFlow] = useState<{setupLink: string; key: number} | undefined>(); const {showConfirmModal} = useConfirmModal(); @@ -139,14 +138,13 @@ function WorkspaceHRPage({ /> )} Navigation.goBack()} /> - +
{(policyID?: string) => ( - + {!!policyID && } {!!policyID && ( { @@ -387,7 +386,6 @@ function WorkspacePerDiemPage({route}: WorkspacePerDiemPageProps) { { diff --git a/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx b/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx index 3cebb7e4ff9d..ef5a19be5fc8 100644 --- a/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx +++ b/src/pages/workspace/receiptPartners/WorkspaceReceiptPartnersPage.tsx @@ -1,8 +1,6 @@ import Button from '@components/Button'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import {loadIllustration} from '@components/Icon/IllustrationLoader'; -import type {IllustrationName} from '@components/Icon/IllustrationLoader'; import MenuItem from '@components/MenuItem'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import {ModalActions} from '@components/Modal/Global/ModalContext'; @@ -14,7 +12,7 @@ import ThreeDotsMenu from '@components/ThreeDotsMenu'; import useConfirmModal from '@hooks/useConfirmModal'; import useGetReceiptPartnersIntegrationData from '@hooks/useGetReceiptPartnersIntegrationData'; -import {useMemoizedLazyAsset, useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePolicy from '@hooks/usePolicy'; @@ -67,7 +65,6 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps const isAutoRemove = !!integrations?.uber?.autoRemove; const isAutoInvite = !!integrations?.uber?.autoInvite; const centralBillingAccountEmail = !!integrations?.uber?.centralBillingAccountEmail; - const {asset: ReceiptPartners} = useMemoizedLazyAsset(() => loadIllustration('ReceiptPartners' as IllustrationName)); // Track focus and connection change to route to the invite flow once after successful connection const prevIsUberConnected = usePrevious(isUberConnected); const {canWrite: canWriteMoreFeatures, showReadOnlyModal, withReadOnlyFallback} = usePolicyFeatureWriteAccess(policy, CONST.POLICY.POLICY_FEATURE.MORE_FEATURES); @@ -309,7 +306,6 @@ function WorkspaceReceiptPartnersPage({route}: WorkspaceReceiptPartnersPageProps - +
{ @@ -223,7 +222,6 @@ function WorkspaceReportFieldsPage({ offlineIndicatorStyle={styles.mtAuto} > )} {!isLoading && ( - +
{shouldDisplayButtonsInSeparateLine && {headerButtons}} - + {isCustomAgentBetaEnabled && !isAgentsRulesBannerDismissed && ( diff --git a/src/pages/workspace/tags/WorkspaceTagsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsPage.tsx index a5006054638d..6e9250582062 100644 --- a/src/pages/workspace/tags/WorkspaceTagsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsPage.tsx @@ -16,7 +16,7 @@ import Text from '@components/Text'; import useCleanupSelectedOptions from '@hooks/useCleanupSelectedOptions'; import useConfirmModal from '@hooks/useConfirmModal'; import useEnvironment from '@hooks/useEnvironment'; -import {useMemoizedLazyExpensifyIcons, useMemoizedLazyIllustrations} from '@hooks/useLazyAsset'; +import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useMobileSelectionMode from '@hooks/useMobileSelectionMode'; import useNetwork from '@hooks/useNetwork'; @@ -143,7 +143,6 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { openPolicyTagsPage(policyID); }, [policyID]); const isQuickSettingsFlow = route.name === SCREENS.SETTINGS_TAGS.SETTINGS_TAGS_ROOT; - const illustrations = useMemoizedLazyIllustrations(['Tag']); const tagsList = useMemo(() => { if (isMultiLevelTags) { @@ -843,7 +842,6 @@ function WorkspaceTagsPage({route}: WorkspaceTagsPageProps) { offlineIndicatorStyle={styles.mtAuto} > !policy?.taxRates?.taxes[taxID]?.isDisabled).length; const disabledRatesCount = selectedTaxesIDs.length - enabledRatesCount; const icons = useMemoizedLazyExpensifyIcons(['Checkmark', 'Close', 'Gear', 'Plus', 'Trashcan']); - const illustrations = useMemoizedLazyIllustrations(['Coins']); const fetchTaxes = useCallback(() => { openPolicyTaxesPage(policyID); @@ -386,7 +385,6 @@ function WorkspaceTaxesPage({ offlineIndicatorStyle={styles.mtAuto} > - + {}; - const {translate} = useLocalize(); const styles = useThemeStyles(); const illustrations = useMemoizedLazyIllustrations(['PendingTravel']); + const readOnlyButtons: EmptyStateButton[] = [ + { + buttonText: translate('workspace.moreFeatures.travel.getStarted.ctaText'), + buttonAction: showReadOnlyModal, + success: true, + innerStyles: styles.buttonOpacityDisabled, + hoverStyles: styles.buttonOpacityDisabled, + }, + ]; + return ( - + {canWriteTravelFeature && ( + - ) : ( -