Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

apply custom scrollview throughout the app #37727

Merged
merged 8 commits into from
Mar 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
const restrictedImportPaths = [
{
name: 'react-native',
importNames: ['useWindowDimensions', 'StatusBar', 'TouchableOpacity', 'TouchableWithoutFeedback', 'TouchableNativeFeedback', 'TouchableHighlight', 'Pressable', 'Text'],
importNames: ['useWindowDimensions', 'StatusBar', 'TouchableOpacity', 'TouchableWithoutFeedback', 'TouchableNativeFeedback', 'TouchableHighlight', 'Pressable', 'Text', 'ScrollView'],
message: [
'',
"For 'useWindowDimensions', please use 'src/hooks/useWindowDimensions' instead.",
"For 'TouchableOpacity', 'TouchableWithoutFeedback', 'TouchableNativeFeedback', 'TouchableHighlight', 'Pressable', please use 'PressableWithFeedback' and/or 'PressableWithoutFeedback' from 'src/components/Pressable' instead.",
"For 'StatusBar', please use 'src/libs/StatusBar' instead.",
"For 'Text', please use '@components/Text' instead.",
"For 'ScrollView', please use '@components/ScrollView' instead.",
].join('\n'),
},
{
Expand Down
3 changes: 2 additions & 1 deletion src/components/AddressSearch/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, {forwardRef, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import type {ForwardedRef} from 'react';
import {ActivityIndicator, Keyboard, LogBox, ScrollView, View} from 'react-native';
import {ActivityIndicator, Keyboard, LogBox, View} from 'react-native';
import type {LayoutChangeEvent} from 'react-native';
import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
import type {GooglePlaceData, GooglePlaceDetail} from 'react-native-google-places-autocomplete';
import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
import LocationErrorMessage from '@components/LocationErrorMessage';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import useLocalize from '@hooks/useLocalize';
Expand Down
3 changes: 2 additions & 1 deletion src/components/Attachments/AttachmentView/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import Str from 'expensify-common/lib/str';
import PropTypes from 'prop-types';
import React, {memo, useEffect, useState} from 'react';
import {ActivityIndicator, ScrollView, View} from 'react-native';
import {ActivityIndicator, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import * as AttachmentsPropTypes from '@components/Attachments/propTypes';
import DistanceEReceipt from '@components/DistanceEReceipt';
import EReceipt from '@components/EReceipt';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip';
import {usePlaybackContext} from '@components/VideoPlayerContexts/PlaybackContext';
Expand Down
3 changes: 2 additions & 1 deletion src/components/DistanceEReceipt.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {useMemo} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import EReceiptBackground from '@assets/images/eReceipt_background.svg';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -15,6 +15,7 @@ import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import ImageSVG from './ImageSVG';
import PendingMapView from './MapView/PendingMapView';
import ScrollView from './ScrollView';
import Text from './Text';
import ThumbnailImage from './ThumbnailImage';

Expand Down
1 change: 1 addition & 0 deletions src/components/DistanceRequest/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {RouteProp} from '@react-navigation/native';
import lodashIsEqual from 'lodash/isEqual';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {ScrollView} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
Expand Down
6 changes: 4 additions & 2 deletions src/components/DraggableList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React, {useCallback} from 'react';
import {DragDropContext, Draggable, Droppable} from 'react-beautiful-dnd';
import type {OnDragEndResponder} from 'react-beautiful-dnd';
import {ScrollView} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {ScrollView as RNScrollView} from 'react-native';
import ScrollView from '@components/ScrollView';
import useThemeStyles from '@hooks/useThemeStyles';
import type {DraggableListProps} from './types';
import useDraggableInPortal from './useDraggableInPortal';
Expand Down Expand Up @@ -37,7 +39,7 @@ function DraggableList<T>(
// eslint-disable-next-line @typescript-eslint/naming-convention
ListFooterComponent,
}: DraggableListProps<T>,
ref: React.ForwardedRef<ScrollView>,
ref: React.ForwardedRef<RNScrollView>,
) {
const styles = useThemeStyles();
/**
Expand Down
8 changes: 5 additions & 3 deletions src/components/Form/FormWrapper.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React, {useCallback, useMemo, useRef} from 'react';
import type {RefObject} from 'react';
import type {StyleProp, View, ViewStyle} from 'react-native';
import {Keyboard, ScrollView} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {ScrollView as RNScrollView, StyleProp, View, ViewStyle} from 'react-native';
import {Keyboard} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
import FormElement from '@components/FormElement';
import SafeAreaConsumer from '@components/SafeAreaConsumer';
import type {SafeAreaChildrenProps} from '@components/SafeAreaConsumer/types';
import ScrollView from '@components/ScrollView';
import ScrollViewWithContext from '@components/ScrollViewWithContext';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
Expand Down Expand Up @@ -60,7 +62,7 @@ function FormWrapper({
disablePressOnEnter = true,
}: FormWrapperProps) {
const styles = useThemeStyles();
const formRef = useRef<ScrollView>(null);
const formRef = useRef<RNScrollView>(null);
const formContentRef = useRef<View>(null);
const errorMessage = useMemo(() => (formState ? ErrorUtils.getLatestErrorMessage(formState) : undefined), [formState]);

Expand Down
7 changes: 4 additions & 3 deletions src/components/FormScrollView.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import type {ForwardedRef} from 'react';
import React from 'react';
import type {ScrollViewProps} from 'react-native';
import {ScrollView} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {ScrollView as RNScrollView, ScrollViewProps} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
import ScrollView from './ScrollView';

type FormScrollViewProps = ScrollViewProps & {
/** Form elements */
children: React.ReactNode;
};

function FormScrollView({children, ...rest}: FormScrollViewProps, ref: ForwardedRef<ScrollView>) {
function FormScrollView({children, ...rest}: FormScrollViewProps, ref: ForwardedRef<RNScrollView>) {
const styles = useThemeStyles();
return (
<ScrollView
Expand Down
3 changes: 2 additions & 1 deletion src/components/HeaderPageLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useMemo} from 'react';
import type {ReactNode} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import type {StyleProp, ViewStyle} from 'react-native';
import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
Expand All @@ -13,6 +13,7 @@ import FixedFooter from './FixedFooter';
import HeaderWithBackButton from './HeaderWithBackButton';
import type HeaderWithBackButtonProps from './HeaderWithBackButton/types';
import ScreenWrapper from './ScreenWrapper';
import ScrollView from './ScrollView';

type HeaderPageLayoutProps = ChildrenProps &
HeaderWithBackButtonProps & {
Expand Down
3 changes: 2 additions & 1 deletion src/components/OptionsSelector/BaseOptionsSelector.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {Component} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import _ from 'underscore';
import ArrowKeyFocusManager from '@components/ArrowKeyFocusManager';
import Button from '@components/Button';
import FixedFooter from '@components/FixedFooter';
import FormHelpMessage from '@components/FormHelpMessage';
import OptionsList from '@components/OptionsList';
import ReferralProgramCTA from '@components/ReferralProgramCTA';
import ScrollView from '@components/ScrollView';
import ShowMoreButton from '@components/ShowMoreButton';
import TextInput from '@components/TextInput';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
Expand Down
3 changes: 2 additions & 1 deletion src/components/PDFView/PDFPasswordForm.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import PropTypes from 'prop-types';
import React, {useEffect, useMemo, useRef, useState} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import _ from 'underscore';
import Button from '@components/Button';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import TextInput from '@components/TextInput';
import useLocalize from '@hooks/useLocalize';
Expand Down
1 change: 1 addition & 0 deletions src/components/Picker/BasePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import lodashDefer from 'lodash/defer';
import type {ForwardedRef, ReactElement, ReactNode, RefObject} from 'react';
import React, {forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react';
// eslint-disable-next-line no-restricted-imports
import type {ScrollView} from 'react-native';
import {View} from 'react-native';
import RNPickerSelect from 'react-native-picker-select';
Expand Down
28 changes: 28 additions & 0 deletions src/components/ScrollView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import type {ForwardedRef} from 'react';
// eslint-disable-next-line no-restricted-imports
import {ScrollView as RNScrollView} from 'react-native';
import type {ScrollViewProps} from 'react-native';

function ScrollView({children, scrollIndicatorInsets, ...props}: ScrollViewProps, ref: ForwardedRef<RNScrollView>) {
return (
<RNScrollView
ref={ref}
// on iOS, navigation animation sometimes cause the scrollbar to appear
// on middle/left side of scrollview. scrollIndicatorInsets with right
// to closest value to 0 fixes this issue, 0 (default) doesn't work
// See: https://github.com/Expensify/App/issues/31441
scrollIndicatorInsets={scrollIndicatorInsets ?? {right: Number.MIN_VALUE}}
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
>
{children}
</RNScrollView>
);
}

ScrollView.displayName = 'ScrollView';

export type {ScrollViewProps};

export default React.forwardRef(ScrollView);
11 changes: 6 additions & 5 deletions src/components/ScrollViewWithContext.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type {ForwardedRef, ReactNode} from 'react';
import React, {createContext, forwardRef, useMemo, useRef, useState} from 'react';
import type {NativeScrollEvent, NativeSyntheticEvent, ScrollViewProps} from 'react-native';
import {ScrollView} from 'react-native';
// eslint-disable-next-line no-restricted-imports
import type {NativeScrollEvent, NativeSyntheticEvent, ScrollView as RNScrollView, ScrollViewProps} from 'react-native';
import ScrollView from './ScrollView';

const MIN_SMOOTH_SCROLL_EVENT_THROTTLE = 16;

type ScrollContextValue = {
contentOffsetY: number;
scrollViewRef: ForwardedRef<ScrollView>;
scrollViewRef: ForwardedRef<RNScrollView>;
};

const ScrollContext = createContext<ScrollContextValue>({
Expand All @@ -28,9 +29,9 @@ type ScrollViewWithContextProps = Partial<ScrollViewProps> & {
* Using this wrapper will automatically handle scrolling to the picker's <TextInput />
* when the picker modal is opened
*/
function ScrollViewWithContext({onScroll, scrollEventThrottle, children, ...restProps}: ScrollViewWithContextProps, ref: ForwardedRef<ScrollView>) {
function ScrollViewWithContext({onScroll, scrollEventThrottle, children, ...restProps}: ScrollViewWithContextProps, ref: ForwardedRef<RNScrollView>) {
const [contentOffsetY, setContentOffsetY] = useState(0);
const defaultScrollViewRef = useRef<ScrollView>(null);
const defaultScrollViewRef = useRef<RNScrollView>(null);
const scrollViewRef = ref ?? defaultScrollViewRef;

const setContextScrollPosition = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
Expand Down
3 changes: 2 additions & 1 deletion src/pages/DetailsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {StackScreenProps} from '@react-navigation/stack';
import Str from 'expensify-common/lib/str';
import React from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import AttachmentModal from '@components/AttachmentModal';
Expand All @@ -15,6 +15,7 @@ import MenuItem from '@components/MenuItem';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import UserDetailsTooltip from '@components/UserDetailsTooltip';
import useLocalize from '@hooks/useLocalize';
Expand Down
2 changes: 1 addition & 1 deletion src/pages/EnablePayments/TermsStep.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, {useEffect, useState} from 'react';
import {ScrollView} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import CheckboxWithLabel from '@components/CheckboxWithLabel';
import FormAlertWithSubmitButton from '@components/FormAlertWithSubmitButton';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/FlagCommentPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import type {SvgProps} from 'react-native-svg';
import type {ValueOf} from 'type-fest';
Expand All @@ -9,6 +9,7 @@ import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/GetAssistancePage.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxEntry} from 'react-native-onyx';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import type {MenuItemWithLink} from '@components/MenuItemList';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Section from '@components/Section';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/KeyboardShortcutsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import MenuItem from '@components/MenuItem';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/OnboardEngagement/ManageTeamsExpensesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, {useMemo} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import Button from '@components/Button';
import FixedFooter from '@components/FixedFooter';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import type {MenuItemProps} from '@components/MenuItem';
import MenuItemList from '@components/MenuItemList';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {useCallback, useMemo} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
Expand All @@ -8,6 +8,7 @@ import LottieAnimations from '@components/LottieAnimations';
import type {MenuItemProps} from '@components/MenuItem';
import MenuItemList from '@components/MenuItemList';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
Expand Down
2 changes: 1 addition & 1 deletion src/pages/PrivateNotes/PrivateNotesListPage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, {useMemo} from 'react';
import {ScrollView} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import type {OnyxCollection} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/ProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Str from 'expensify-common/lib/str';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useEffect} from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import AutoUpdateTime from '@components/AutoUpdateTime';
Expand All @@ -17,6 +17,7 @@ import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import PressableWithoutFocus from '@components/Pressable/PressableWithoutFocus';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Text from '@components/Text';
import UserDetailsTooltip from '@components/UserDetailsTooltip';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
Expand Down
3 changes: 2 additions & 1 deletion src/pages/ReimbursementAccount/BankAccountStep.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React from 'react';
import {ScrollView, View} from 'react-native';
import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
Expand All @@ -11,6 +11,7 @@ import * as Illustrations from '@components/Icon/Illustrations';
import MenuItem from '@components/MenuItem';
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
import ScreenWrapper from '@components/ScreenWrapper';
import ScrollView from '@components/ScrollView';
import Section from '@components/Section';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
Expand Down
Loading
Loading