Skip to content

Commit

Permalink
feat(hooks): new hook and base major
Browse files Browse the repository at this point in the history
  • Loading branch information
EQuimper committed Jul 11, 2024
1 parent e8182fc commit 15eddca
Show file tree
Hide file tree
Showing 8 changed files with 15,942 additions and 19 deletions.
4 changes: 2 additions & 2 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
"web": "expo start --web"
},
"dependencies": {
"@expo/metro-runtime": "~3.2.1",
"expo": "~51.0.19",
"expo-status-bar": "~1.12.1",
"react": "18.2.0",
"react-native": "0.74.3",
"@expo/metro-runtime": "~3.2.1",
"react-dom": "18.2.0",
"react-native": "0.74.3",
"react-native-web": "~0.19.10"
},
"devDependencies": {
Expand Down
51 changes: 39 additions & 12 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,37 @@
import { useState, useEffect } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import { multiply } from '@appandflow/react-native-google-autocomplete';
import { StyleSheet, View, Text, TextInput, ScrollView } from 'react-native';
import { useGoogleAutocomplete } from '@appandflow/react-native-google-autocomplete';

export default function App() {
const [result, setResult] = useState<number | undefined>();
const API_KEY = '';

useEffect(() => {
multiply(3, 7).then(setResult);
}, []);
export default function App() {
const { setTerm, locationResults, isSearching } = useGoogleAutocomplete(
API_KEY,
{
language: 'en',
minLength: 3,
}
);

return (
<View style={styles.container}>
<Text>Result: {result}</Text>
<View style={styles.box}>
<TextInput
placeholder="Search"
onChangeText={setTerm}
style={styles.input}
/>
</View>

<ScrollView contentContainerStyle={{ paddingHorizontal: 16 }}>
{isSearching && locationResults.length === 0 && (
<Text>Searching...</Text>
)}
{locationResults.map((location) => (
<View key={location.id}>
<Text>{location.structured_formatting.main_text}</Text>
</View>
))}
</ScrollView>
</View>
);
}
Expand All @@ -22,9 +42,16 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
},
input: {
height: 50,
borderRadius: 10,
borderWidth: 1,
width: '100%',
marginTop: 100,
paddingHorizontal: 16,
},
box: {
width: 60,
height: 60,
marginVertical: 20,
paddingHorizontal: 16,
width: '100%',
},
});
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@appandflow/react-native-google-autocomplete",
"version": "0.1.0",
"version": "1.0.0",
"description": "A library to help you use google places autocomplete",
"source": "./src/index.tsx",
"main": "./lib/commonjs/index.cjs",
Expand Down Expand Up @@ -38,7 +38,8 @@
"lint": "eslint \"**/*.{js,ts,tsx}\"",
"clean": "del-cli lib",
"prepare": "bob build",
"release": "release-it"
"release": "release-it",
"release:beta": "release-it major --preRelease=beta"
},
"keywords": [
"react-native",
Expand Down Expand Up @@ -126,6 +127,8 @@
],
"rules": {
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "off",
"react-native/no-inline-styles": "off",
"prettier/prettier": [
"error",
{
Expand Down Expand Up @@ -176,5 +179,9 @@
"create-react-native-library": {
"type": "library",
"version": "0.38.1"
},
"dependencies": {
"query-string": "^9.0.0",
"use-debounce": "^10.0.1"
}
}
132 changes: 132 additions & 0 deletions src/GoogleAutocomplete.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { useEffect, useState } from 'react';
import {
GoogleService,
type GoogleLocationResult,
} from './services/google.service';
import { useDebounce } from 'use-debounce';
import { useIsMounted } from './useIsMounted';

interface Options {
/**
* Minimun length of the input before start fetching - default: 2
*/
minLength?: number;

/**
* Debounce request time in ms - default: 300
*/
debounce?: number;

/**
* Language for Google query - default: en
*/
language?: string;

/**
* A grouping of places to which you would like to restrict your results
*/
components?: string;

/**
* See https://developers.google.com/places/web-service/autocomplete#place_types = default: address
*/
queryTypes?:
| 'address'
| 'geocode'
| '(cities)'
| 'establishment'
| 'geocode|establishment';

/**
* The distance (in meters) within which to return place results.
* Note that setting a radius biases results to the indicated area,
* but may not fully restrict results to the specified area.
*/
radius?: string;

/**
* The latitude to retrieve place information
*/
lat?: number;

/**
* The longitude to retrieve place information
*/
lng?: number;

/**
* Enable strict mode to return search result only in the area defined by radius, lat and lng
*/
strictBounds?: boolean;
}

export const useGoogleAutocomplete = (apiKey: string, opts: Options = {}) => {
const {
minLength = 2,
debounce = 300,
language = 'en',
queryTypes = 'address',
} = opts;
const isMounted = useIsMounted();
const [isSearching, setIsSearching] = useState(false);
const [term, setTerm] = useState('');
const [debouncedTerm] = useDebounce(term, debounce);
const [locationResults, setLocationResults] = useState<
GoogleLocationResult[]
>([]);
const [searchError, setSearchError] = useState<Error | null>(null);

const search = async (value: string) => {
setIsSearching(true);
try {
const results = await GoogleService.search(value, {
key: apiKey,
language,
types: queryTypes,
strictBounds: opts.strictBounds,
lat: opts.lat,
lng: opts.lng,
radius: opts.radius,
});

setLocationResults(results.predictions);
} catch (error) {
if (error instanceof Error) {
setSearchError(error);
}
} finally {
setIsSearching(false);
}
};

const searchDetails = async (placeId: string) => {
return GoogleService.searchDetails(placeId, {
key: apiKey,
language,
types: queryTypes,
components: opts.components,
});
};

const clearSearch = () => {
if (isMounted()) {
setLocationResults([]);
setIsSearching(false);
}
};

useEffect(() => {
if (debouncedTerm.length >= minLength) {
search(debouncedTerm);
}
}, [debouncedTerm]);

return {
locationResults,
isSearching,
searchError,
clearSearch,
setTerm,
searchDetails,
};
};
14 changes: 11 additions & 3 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export function multiply(a: number, b: number): Promise<number> {
return Promise.resolve(a * b);
}
import { useGoogleAutocomplete } from './GoogleAutocomplete';
import {
type GoogleLocationDetailResult,
type GoogleLocationResult,
} from './services/google.service';

export {
useGoogleAutocomplete,
type GoogleLocationDetailResult,
type GoogleLocationResult,
};
Loading

0 comments on commit 15eddca

Please sign in to comment.