From 589006625b40e58c0038fdc5454654332cd19590 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Tue, 12 May 2026 12:15:46 +0800 Subject: [PATCH 1/3] fix saved search tooltip doesn't show for the first time --- src/pages/Search/SearchTypeMenuWide.tsx | 41 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/pages/Search/SearchTypeMenuWide.tsx b/src/pages/Search/SearchTypeMenuWide.tsx index 2782b9ad640b..174c33a21bf2 100644 --- a/src/pages/Search/SearchTypeMenuWide.tsx +++ b/src/pages/Search/SearchTypeMenuWide.tsx @@ -1,5 +1,5 @@ import {useRoute} from '@react-navigation/native'; -import React, {useContext, useLayoutEffect, useRef, useState} from 'react'; +import React, {useContext, useEffect, useEffectEvent, useLayoutEffect, useRef, useState} from 'react'; import {View} from 'react-native'; // eslint-disable-next-line no-restricted-imports import type {NativeScrollEvent, NativeSyntheticEvent, ScrollView as RNScrollView} from 'react-native'; @@ -40,10 +40,10 @@ type SectionParams = { reportCounts: NonNullable>; areAllSectionsExpanded: boolean; onItemPress: (query: string) => void; - onExpanded: (isExpanded: boolean) => void; + onCollapsed: (isCollapsed: boolean) => void; }; -function Section({section, hash, activeItemIndex, sectionStartIndex, reportCounts, areAllSectionsExpanded, onItemPress, onExpanded}: SectionParams) { +function Section({section, hash, activeItemIndex, sectionStartIndex, reportCounts, areAllSectionsExpanded, onItemPress, onCollapsed}: SectionParams) { const {translate} = useLocalize(); const expensifyIcons = useMemoizedLazyExpensifyIcons([ 'Basket', @@ -63,15 +63,31 @@ function Section({section, hash, activeItemIndex, sectionStartIndex, reportCount ]); const [isExpanded, setIsExpanded] = useState(true); + const isExpandedRef = useRef(isExpanded); + + const onCollapsedCallback = useEffectEvent(onCollapsed); + + useEffect(() => { + isExpandedRef.current = isExpanded; + }, [isExpanded]); + + // When the section is removed/unmounted while collapsed, + // notify the parent that the section is no longer collapsed. + useEffect(() => { + return () => { + if (!isExpandedRef.current) { + onCollapsedCallback(false); + } + }; + }, []); return ( { setIsExpanded((prevIsExpanded) => { - const newValue = !prevIsExpanded; - onExpanded(newValue); - return newValue; + onCollapsed(prevIsExpanded); + return !prevIsExpanded; }); }} title={translate(section.translationPath)} @@ -150,12 +166,11 @@ function SearchTypeMenuWide({queryJSON}: SearchTypeMenuProps) { const areSuggestedSearchesLoading = !isOffline && !isSearchDataLoaded && !isLoadingOnyxValue(isSearchDataLoadedResult); - const numberOfSections = nonExpenseReportsSections.length + 1; - const [expandedSectionCount, setExpandedSectionCount] = useState(numberOfSections); - const areAllSectionsExpanded = expandedSectionCount === numberOfSections; + const [collapsedSectionCount, setCollapsedSectionCount] = useState(0); + const areAllSectionsExpanded = collapsedSectionCount === 0; - const updateExpandedCount = (isExpanded: boolean) => { - setExpandedSectionCount((prevExpandedCount) => prevExpandedCount + (isExpanded ? 1 : -1)); + const updateCollapsedCount = (isCollapsed: boolean) => { + setCollapsedSectionCount((prevCollapsedCount) => prevCollapsedCount + (isCollapsed ? 1 : -1)); }; return ( @@ -169,7 +184,7 @@ function SearchTypeMenuWide({queryJSON}: SearchTypeMenuProps) {
Date: Tue, 12 May 2026 12:53:44 +0800 Subject: [PATCH 2/3] lint --- src/pages/Search/SearchTypeMenuWide.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/Search/SearchTypeMenuWide.tsx b/src/pages/Search/SearchTypeMenuWide.tsx index 174c33a21bf2..be64298b01da 100644 --- a/src/pages/Search/SearchTypeMenuWide.tsx +++ b/src/pages/Search/SearchTypeMenuWide.tsx @@ -75,9 +75,10 @@ function Section({section, hash, activeItemIndex, sectionStartIndex, reportCount // notify the parent that the section is no longer collapsed. useEffect(() => { return () => { - if (!isExpandedRef.current) { - onCollapsedCallback(false); + if (isExpandedRef.current) { + return; } + onCollapsedCallback(false); }; }, []); From 162fd2b827dfd17b005f97534a805f8d5f6914db Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Wed, 13 May 2026 22:15:24 +0800 Subject: [PATCH 3/3] moves all unmount code inside useEffectEvent --- src/pages/Search/SearchTypeMenuWide.tsx | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/pages/Search/SearchTypeMenuWide.tsx b/src/pages/Search/SearchTypeMenuWide.tsx index be64298b01da..0eefc65cf3a1 100644 --- a/src/pages/Search/SearchTypeMenuWide.tsx +++ b/src/pages/Search/SearchTypeMenuWide.tsx @@ -63,23 +63,18 @@ function Section({section, hash, activeItemIndex, sectionStartIndex, reportCount ]); const [isExpanded, setIsExpanded] = useState(true); - const isExpandedRef = useRef(isExpanded); - const onCollapsedCallback = useEffectEvent(onCollapsed); - - useEffect(() => { - isExpandedRef.current = isExpanded; - }, [isExpanded]); + const onUnmount = useEffectEvent(() => { + if (isExpanded) { + return; + } + // When the section is removed/unmounted while collapsed, + // notify the parent that the section is no longer collapsed. + onCollapsed(false); + }); - // When the section is removed/unmounted while collapsed, - // notify the parent that the section is no longer collapsed. useEffect(() => { - return () => { - if (isExpandedRef.current) { - return; - } - onCollapsedCallback(false); - }; + return () => onUnmount(); }, []); return (