Skip to content

Commit

Permalink
Merge pull request #8256 from mananjadhav/fix/nested-scroll-views-goo…
Browse files Browse the repository at this point in the history
…gle-places-api
  • Loading branch information
roryabraham committed Apr 13, 2022
2 parents 7706091 + f6af4f1 commit fc3e13e
Showing 1 changed file with 98 additions and 83 deletions.
181 changes: 98 additions & 83 deletions src/components/AddressSearch.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'underscore';
import React, {useRef, useState} from 'react';
import PropTypes from 'prop-types';
import {LogBox} from 'react-native';
import {LogBox, ScrollView, View} from 'react-native';
import {GooglePlacesAutocomplete} from 'react-native-google-places-autocomplete';
import CONFIG from '../CONFIG';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
Expand Down Expand Up @@ -117,89 +117,104 @@ const AddressSearch = (props) => {
};

return (
<GooglePlacesAutocomplete
fetchDetails
suppressDefaultStyles
enablePoweredByContainer={false}
onPress={(data, details) => {
saveLocationDetails(details);

// After we select an option, we set displayListViewBorder to false to prevent UI flickering
setDisplayListViewBorder(false);
}}
query={{
key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
language: props.preferredLocale,
types: 'address',
components: 'country:us',
}}
requestUrl={{
useOnPlatform: 'web',
url: `${CONFIG.EXPENSIFY.EXPENSIFY_URL}api?command=Proxy_GooglePlaces&proxyUrl=`,
}}
textInputProps={{
InputComp: TextInput,
ref: (node) => {
if (!props.innerRef) {
return;
}

if (_.isFunction(props.innerRef)) {
props.innerRef(node);
return;
}

// eslint-disable-next-line no-param-reassign
props.innerRef.current = node;
},
label: props.label,
containerStyles: props.containerStyles,
errorText: props.errorText,
value: props.value,
isFormInput: props.isFormInput,
inputID: props.inputID,
shouldSaveDraft: props.shouldSaveDraft,
onBlur: props.onBlur,
autoComplete: 'off',
onChangeText: (text) => {
if (skippedFirstOnChangeTextRef.current) {
props.onChange({street: text});
} else {
skippedFirstOnChangeTextRef.current = true;
}

// If the text is empty, we set displayListViewBorder to false to prevent UI flickering
if (_.isEmpty(text)) {

/*
* The GooglePlacesAutocomplete component uses a VirtualizedList internally,
* and VirtualizedLists cannot be directly nested within other VirtualizedLists of the same orientation.
* To work around this, we wrap the GooglePlacesAutocomplete component with a horizontal ScrollView
* that has scrolling disabled and would otherwise not be needed
*/
<ScrollView
horizontal
contentContainerStyle={styles.flex1}
scrollEnabled={false}
>
<View style={styles.w100}>
<GooglePlacesAutocomplete
fetchDetails
suppressDefaultStyles
enablePoweredByContainer={false}
onPress={(data, details) => {
saveLocationDetails(details);

// After we select an option, we set displayListViewBorder to false to prevent UI flickering
setDisplayListViewBorder(false);
}
},
}}
styles={{
textInputContainer: [styles.flexColumn],
listView: [
!displayListViewBorder && styles.googleListView,
displayListViewBorder && styles.borderTopRounded,
displayListViewBorder && styles.borderBottomRounded,
displayListViewBorder && styles.mt1,
styles.overflowAuto,
styles.borderLeft,
styles.borderRight,
],
row: [
styles.pv4,
styles.ph3,
styles.overflowAuto,
],
description: [styles.googleSearchText],
separator: [styles.googleSearchSeparator],
}}
onLayout={(event) => {
// We use the height of the element to determine if we should hide the border of the listView dropdown
// to prevent a lingering border when there are no address suggestions.
// The height of the empty element is 2px (1px height for each top and bottom borders)
setDisplayListViewBorder(event.nativeEvent.layout.height > 2);
}}
/>
}}
query={{
key: 'AIzaSyC4axhhXtpiS-WozJEsmlL3Kg3kXucbZus',
language: props.preferredLocale,
types: 'address',
components: 'country:us',
}}
requestUrl={{
useOnPlatform: 'web',
url: `${CONFIG.EXPENSIFY.EXPENSIFY_URL}api?command=Proxy_GooglePlaces&proxyUrl=`,
}}
textInputProps={{
InputComp: TextInput,
ref: (node) => {
if (!props.innerRef) {
return;
}

if (_.isFunction(props.innerRef)) {
props.innerRef(node);
return;
}

// eslint-disable-next-line no-param-reassign
props.innerRef.current = node;
},
label: props.label,
containerStyles: props.containerStyles,
errorText: props.errorText,
value: props.value,
isFormInput: props.isFormInput,
inputID: props.inputID,
shouldSaveDraft: props.shouldSaveDraft,
onBlur: props.onBlur,
autoComplete: 'off',
onChangeText: (text) => {
if (skippedFirstOnChangeTextRef.current) {
props.onChange({street: text});
} else {
skippedFirstOnChangeTextRef.current = true;
}

// If the text is empty, we set displayListViewBorder to false to prevent UI flickering
if (_.isEmpty(text)) {
setDisplayListViewBorder(false);
}
},
}}
styles={{
textInputContainer: [styles.flexColumn],
listView: [
!displayListViewBorder && styles.googleListView,
displayListViewBorder && styles.borderTopRounded,
displayListViewBorder && styles.borderBottomRounded,
displayListViewBorder && styles.mt1,
styles.overflowAuto,
styles.borderLeft,
styles.borderRight,
],
row: [
styles.pv4,
styles.ph3,
styles.overflowAuto,
],
description: [styles.googleSearchText],
separator: [styles.googleSearchSeparator],
}}
onLayout={(event) => {
// We use the height of the element to determine if we should hide the border of the listView dropdown
// to prevent a lingering border when there are no address suggestions.
// The height of the empty element is 2px (1px height for each top and bottom borders)
setDisplayListViewBorder(event.nativeEvent.layout.height > 2);
}}
/>
</View>
</ScrollView>
);
};

Expand Down

0 comments on commit fc3e13e

Please sign in to comment.