Skip to content

Commit ecb629d

Browse files
authored
Merge pull request #48898 from bernhardoj/fix/47640-keep-status-scroll-position
Scroll into view the search status button
2 parents 70e88a6 + b6878e3 commit ecb629d

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

src/components/Button/index.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {useIsFocused} from '@react-navigation/native';
22
import type {ForwardedRef} from 'react';
33
import React, {useCallback, useMemo, useState} from 'react';
4-
import type {GestureResponderEvent, StyleProp, TextStyle, ViewStyle} from 'react-native';
4+
import type {GestureResponderEvent, LayoutChangeEvent, StyleProp, TextStyle, ViewStyle} from 'react-native';
55
import {ActivityIndicator, View} from 'react-native';
66
import Icon from '@components/Icon';
77
import * as Expensicons from '@components/Icon/Expensicons';
@@ -53,6 +53,9 @@ type ButtonProps = Partial<ChildrenProps> & {
5353
/** Indicates whether the button should be disabled */
5454
isDisabled?: boolean;
5555

56+
/** Invoked on mount and layout changes */
57+
onLayout?: (event: LayoutChangeEvent) => void;
58+
5659
/** A function that is called when the button is clicked on */
5760
onPress?: (event?: GestureResponderEvent | KeyboardEvent) => void;
5861

@@ -192,6 +195,7 @@ function Button(
192195
isLoading = false,
193196
isDisabled = false,
194197

198+
onLayout = () => {},
195199
onPress = () => {},
196200
onLongPress = () => {},
197201
onPressIn = () => {},
@@ -325,6 +329,7 @@ function Button(
325329
)}
326330
<PressableWithFeedback
327331
ref={ref}
332+
onLayout={onLayout}
328333
onPress={(event) => {
329334
if (event?.type === 'click') {
330335
const currentTarget = event?.currentTarget as HTMLElement;

src/components/Search/SearchStatusBar.tsx

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
import React from 'react';
1+
import React, {useRef} from 'react';
2+
// eslint-disable-next-line no-restricted-imports
3+
import type {ScrollView as RNScrollView} from 'react-native';
24
import Button from '@components/Button';
35
import * as Expensicons from '@components/Icon/Expensicons';
46
import ScrollView from '@components/ScrollView';
@@ -150,9 +152,12 @@ function SearchStatusBar({type, status, resetOffset}: SearchStatusBarProps) {
150152
const theme = useTheme();
151153
const {translate} = useLocalize();
152154
const options = getOptions(type);
155+
const scrollRef = useRef<RNScrollView>(null);
156+
const isScrolledRef = useRef(false);
153157

154158
return (
155159
<ScrollView
160+
ref={scrollRef}
156161
style={[styles.flexRow, styles.mb5, styles.overflowScroll, styles.flexGrow0]}
157162
horizontal
158163
showsHorizontalScrollIndicator={false}
@@ -169,6 +174,13 @@ function SearchStatusBar({type, status, resetOffset}: SearchStatusBarProps) {
169174
return (
170175
<Button
171176
key={item.key}
177+
onLayout={(e) => {
178+
if (!isActive || isScrolledRef.current || !('left' in e.nativeEvent.layout)) {
179+
return;
180+
}
181+
isScrolledRef.current = true;
182+
scrollRef.current?.scrollTo({x: (e.nativeEvent.layout.left as number) - styles.pl5.paddingLeft});
183+
}}
172184
text={translate(item.text)}
173185
onPress={onPress}
174186
icon={item.icon}

src/pages/Search/SearchTypeMenuNarrow.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
77
import type {SearchQueryJSON} from '@components/Search/types';
88
import Text from '@components/Text';
99
import useSingleExecution from '@hooks/useSingleExecution';
10+
import useStyleUtils from '@hooks/useStyleUtils';
1011
import useTheme from '@hooks/useTheme';
1112
import useThemeStyles from '@hooks/useThemeStyles';
1213
import useWindowDimensions from '@hooks/useWindowDimensions';
1314
import * as SearchActions from '@libs/actions/Search';
1415
import Navigation from '@libs/Navigation/Navigation';
16+
import variables from '@styles/variables';
1517
import * as Expensicons from '@src/components/Icon/Expensicons';
1618
import * as SearchUtils from '@src/libs/SearchUtils';
1719
import ROUTES from '@src/ROUTES';
@@ -27,6 +29,7 @@ type SearchTypeMenuNarrowProps = {
2729
function SearchTypeMenuNarrow({typeMenuItems, activeItemIndex, queryJSON, title}: SearchTypeMenuNarrowProps) {
2830
const theme = useTheme();
2931
const styles = useThemeStyles();
32+
const StyleUtils = useStyleUtils();
3033
const {singleExecution} = useSingleExecution();
3134
const {windowHeight} = useWindowDimensions();
3235

@@ -86,21 +89,23 @@ function SearchTypeMenuNarrow({typeMenuItems, activeItemIndex, queryJSON, title}
8689
onPress={openMenu}
8790
>
8891
{({hovered}) => (
89-
<Animated.View style={[styles.tabSelectorButton, styles.tabBackground(hovered, true, theme.border), styles.w100]}>
92+
<Animated.View style={[styles.tabSelectorButton, styles.tabBackground(hovered, true, theme.border), styles.w100, StyleUtils.getHeight(variables.componentSizeNormal)]}>
9093
<View style={[styles.flexRow, styles.gap2, styles.alignItemsCenter, titleViewStyles]}>
9194
<Icon
9295
src={menuIcon}
9396
fill={theme.icon}
97+
small
9498
/>
9599
<Text
96100
numberOfLines={1}
97-
style={[styles.textStrong, styles.flexShrink1]}
101+
style={[styles.textStrong, styles.flexShrink1, styles.fontSizeLabel]}
98102
>
99103
{menuTitle}
100104
</Text>
101105
<Icon
102106
src={Expensicons.DownArrow}
103107
fill={theme.icon}
108+
small
104109
/>
105110
</View>
106111
</Animated.View>

0 commit comments

Comments
 (0)