npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pragadanaveen/react-native-location-autocomplete

v2.2.0

Published

A comprehensive React Native component for location autocomplete with Google Places API, featuring animated placeholders, current location, recent searches, and extensive customization options

Readme

React Native Location Autocomplete

A comprehensive React Native component for location autocomplete with Google Places API integration. Features animated placeholder text, current location detection, recent searches, extensive customization options, and much more.

🚀 Features

  • Advanced API Optimization - Intelligent caching, request coalescing, and reduced API calls
  • Animated Rotating Placeholder - Unique animated placeholder that cycles through location suggestions
  • Advanced Loading States - Custom loading components, skeleton loaders, and shimmer effects
  • Smooth Fade-in Animations - Results appear with elegant fade-in transitions
  • Google Places API Integration - Full autocomplete and place details support
  • Current Location Detection - GPS-based location detection with permissions handling
  • Recent Searches - Automatically saves and displays recent location searches
  • Predefined Places - Support for custom predefined locations
  • Advanced Filtering - City-only filtering, country restrictions, search types
  • Location Bias & Radius - Bias results based on current location with radius control
  • Multiple Themes - Built-in dark, light, and default themes
  • Custom Rendering - Full control over row rendering and styling
  • Accessibility Support - Complete accessibility and testing support
  • TypeScript Ready - Full TypeScript support (coming soon)
  • Debounced Search - Optimized performance with configurable debouncing
  • Error Handling - Comprehensive error handling and callbacks
  • Timeout Management - Request timeout handling

📦 Installation

npm install @pragadanaveen/react-native-location-autocomplete expo-location

Optional Dependencies

# For recent searches persistence
npm install @react-native-async-storage/async-storage

🎯 Basic Usage

import React from 'react';
import { LocationAutocomplete } from '@pragadanaveen/react-native-location-autocomplete';

const MyComponent = () => {
  const handleLocationSelected = (location) => {
    console.log('Selected location:', location);
    // location object contains: { address, latitude, longitude, placeId, details }
  };

  return (
    <LocationAutocomplete
      apiKey="YOUR_GOOGLE_PLACES_API_KEY"
      onLocationSelected={handleLocationSelected}
      enableCurrentLocation={true}
      enableRecentSearches={true}
      filterCitiesOnly={true}
      style={{ margin: 16 }}
    />
  );
};

💰 API Cost Optimization

Your package includes advanced optimizations that significantly reduce Google Places API costs:

Smart Caching System

<LocationAutocomplete
  enableCaching={true}        // Cache responses for 5 minutes
  cacheTimeout={300000}       // Customizable cache duration
  maxCacheSize={100}          // Limit memory usage
/>

Request Coalescing

<LocationAutocomplete
  enableRequestCoalescing={true}  // Prevent duplicate requests
  // If user types "Mumbai" quickly, only 1 API call is made
/>

Skip Unnecessary Details Calls

<LocationAutocomplete
  skipDetailsForPredefined={true}  // Don't call details API for predefined places
  predefinedPlaces={[
    { description: 'Home', latitude: 19.0760, longitude: 72.8777 },
    { description: 'Office', latitude: 19.0896, longitude: 72.8656 }
  ]}
/>

Cost Comparison

Typical Usage Scenario: User types "Mumbai" (6 characters)

| Package | API Calls | Cost Impact | |---------|-----------|-------------| | react-native-google-places-autocomplete | 6 autocomplete + 1 details = 7 calls | Higher cost | | Your Package (optimized) | 1 autocomplete + 1 details = 2 calls | 71% cost reduction |

With Caching: Subsequent searches for "Mumbai" = 0 additional calls for 5 minutes!

🎨 Advanced Loading States

Skeleton Loader with Shimmer

<LocationAutocomplete
  apiKey="YOUR_API_KEY"
  onLocationSelected={handleLocationSelected}
  loadingRows={4}
  useShimmer={true}
  enableFadeIn={true}
  fadeInDuration={500}
/>

Custom Loading Component

const CustomLoader = () => (
  <View style={{ padding: 20, alignItems: 'center' }}>
    <ActivityIndicator size="large" color="#007AFF" />
    <Text style={{ marginTop: 10, color: '#666' }}>
      Finding amazing places...
    </Text>
  </View>
);

<LocationAutocomplete
  apiKey="YOUR_API_KEY"
  onLocationSelected={handleLocationSelected}
  loadingComponent={<CustomLoader />}
/>

Animated Skeleton Cards

<LocationAutocomplete
  apiKey="YOUR_API_KEY"
  onLocationSelected={handleLocationSelected}
  loadingRows={5}
  useShimmer={true}
  enableFadeIn={true}
  fadeInDuration={300}
  theme="dark"
/>

🎨 Advanced Usage

<LocationAutocomplete
  // Basic Configuration
  apiKey="YOUR_API_KEY"
  onLocationSelected={handleLocationSelected}
  initialAddress="Mumbai, India"
  
  // Animated Placeholder (Unique Feature!)
  enableAnimatedPlaceholder={true}
  placeholderOptions={['New York', 'London', 'Tokyo', 'Mumbai']}
  placeholderAnimationDuration={2500}
  
  // Current Location
  enableCurrentLocation={true}
  currentLocationLabel="📍 Use My Location"
  requestLocationPermission={true}
  
  // Recent Searches
  enableRecentSearches={true}
  maxRecentSearches={8}
  recentSearchesLabel="Recent Locations"
  
  // Search Configuration
  filterCitiesOnly={false}
  searchTypes={['establishment', 'geocode']}
  countryCode="IN"
  minLength={3}
  debounceMs={400}
  
  // Location Bias
  radius={50000} // 50km
  strictBounds={false}
  
  // Predefined Places
  predefinedPlaces={[
    { description: 'Home', latitude: 19.0760, longitude: 72.8777 },
    { description: 'Office', latitude: 19.0896, longitude: 72.8656 }
  ]}
  predefinedPlacesAlwaysVisible={true}
  
  // API Optimization (Reduces costs!)
  enableCaching={true}
  cacheTimeout={300000} // 5 minutes
  maxCacheSize={100}
  enableRequestCoalescing={true}
  skipDetailsForPredefined={true}
  
  // Advanced Loading & Animations
  loadingComponent={<CustomLoader />}
  loadingRows={4}
  useShimmer={true}
  enableFadeIn={true}
  fadeInDuration={400}
  
  // Styling & Theming
  theme="dark" // 'default', 'light', 'dark'
  containerStyle={{ backgroundColor: '#f5f5f5' }}
  inputStyle={{ borderRadius: 12, fontSize: 18 }}
  
  // Custom Rendering
  renderRow={(data, index) => (
    <CustomLocationRow data={data} index={index} />
  )}
  renderLeftButton={() => <SearchIcon />}
  renderRightButton={() => <FilterIcon />}
  
  // Callbacks
  onFail={(error) => console.error('Location error:', error)}
  onNotFound={() => console.log('No results found')}
  onTimeout={() => console.log('Request timed out')}
  onFocus={() => console.log('Input focused')}
  onBlur={() => console.log('Input blurred')}
  
  // Accessibility
  accessibilityLabel="Location search input"
  testID="location-autocomplete"
/>

📋 Complete Props Reference

Basic Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | apiKey | string | required | Your Google Places API key | | onLocationSelected | function | required | Callback when location is selected | | initialAddress | string | "" | Initial address value |

Search & Filtering

| Prop | Type | Default | Description | |------|------|---------|-------------| | filterCitiesOnly | boolean | false | Filter results to cities only | | searchTypes | array | [] | Google Places search types | | countryCode | string | "" | Restrict to specific country (e.g., 'IN', 'US') | | minLength | number | 2 | Minimum characters before search | | debounceMs | number | 300 | Debounce delay in milliseconds |

Animated Placeholder (Unique Feature!)

| Prop | Type | Default | Description | |------|------|---------|-------------| | enableAnimatedPlaceholder | boolean | true | Enable rotating placeholder animation | | placeholderOptions | array | Indian cities | Array of placeholder suggestions | | placeholderAnimationDuration | number | 3000 | Animation cycle duration (ms) |

Current Location

| Prop | Type | Default | Description | |------|------|---------|-------------| | enableCurrentLocation | boolean | false | Show current location option | | currentLocationLabel | string | "Use Current Location" | Current location button text | | requestLocationPermission | boolean | true | Auto-request location permissions |

Recent Searches

| Prop | Type | Default | Description | |------|------|---------|-------------| | enableRecentSearches | boolean | false | Enable recent searches | | maxRecentSearches | number | 5 | Maximum recent searches to store | | recentSearchesLabel | string | "Recent Searches" | Recent searches header text |

Location Bias & Radius

| Prop | Type | Default | Description | |------|------|---------|-------------| | radius | number | 0 | Search radius in meters | | strictBounds | boolean | false | Strict boundary enforcement |

Predefined Places

| Prop | Type | Default | Description | |------|------|---------|-------------| | predefinedPlaces | array | [] | Array of predefined locations | | predefinedPlacesAlwaysVisible | boolean | false | Always show predefined places |

API Optimization (Reduces Costs!)

| Prop | Type | Default | Description | |------|------|---------|-------------| | enableCaching | boolean | true | Cache API responses to reduce duplicate calls | | cacheTimeout | number | 300000 | Cache expiry time in milliseconds (5 min) | | maxCacheSize | number | 100 | Maximum number of cached responses | | enableRequestCoalescing | boolean | true | Prevent duplicate simultaneous requests | | skipDetailsForPredefined | boolean | true | Skip details API for predefined places |

Loading & Animation

| Prop | Type | Default | Description | |------|------|---------|-------------| | loadingComponent | component | null | Custom loading component | | loadingRows | number | 3 | Number of skeleton rows to show | | useShimmer | boolean | false | Enable shimmer effect on skeleton | | enableFadeIn | boolean | true | Enable fade-in animation for results | | fadeInDuration | number | 300 | Fade-in animation duration (ms) |

Styling & Theming

| Prop | Type | Default | Description | |------|------|---------|-------------| | theme | string | 'default' | Theme: 'default', 'light', 'dark' | | style | object | {} | Input style | | containerStyle | object | {} | Container style | | inputStyle | object | {} | Input field style | | listStyle | object | {} | Results list style | | suggestionStyle | object | {} | Individual suggestion style | | suggestionTextStyle | object | {} | Suggestion text style | | loadingStyle | object | {} | Loading indicator style | | currentLocationStyle | object | {} | Current location item style | | recentSearchStyle | object | {} | Recent search item style |

Behavior

| Prop | Type | Default | Description | |------|------|---------|-------------| | autoFocus | boolean | false | Auto-focus input on mount | | clearButtonMode | string | 'while-editing' | Clear button visibility | | returnKeyType | string | 'search' | Keyboard return key type | | timeout | number | 20000 | Request timeout (ms) |

Custom Rendering

| Prop | Type | Default | Description | |------|------|---------|-------------| | renderRow | function | null | Custom row renderer | | renderLeftButton | function | null | Custom left button renderer | | renderRightButton | function | null | Custom right button renderer | | renderDescription | function | null | Custom description renderer |

Callbacks

| Prop | Type | Default | Description | |------|------|---------|-------------| | onFail | function | null | Error callback | | onNotFound | function | null | No results callback | | onTimeout | function | null | Timeout callback | | onPress | function | null | Item press callback | | onFocus | function | null | Input focus callback | | onBlur | function | null | Input blur callback |

Accessibility

| Prop | Type | Default | Description | |------|------|---------|-------------| | accessibilityLabel | string | null | Accessibility label | | testID | string | null | Test identifier |

🎨 Theming Examples

Dark Theme

<LocationAutocomplete
  theme="dark"
  apiKey="YOUR_API_KEY"
  onLocationSelected={handleLocationSelected}
/>

Custom Styling

<LocationAutocomplete
  containerStyle={{
    backgroundColor: '#f8f9fa',
    borderRadius: 12,
    padding: 16,
  }}
  inputStyle={{
    backgroundColor: 'white',
    borderColor: '#007AFF',
    borderWidth: 2,
    borderRadius: 8,
    fontSize: 16,
  }}
  suggestionStyle={{
    backgroundColor: 'white',
    paddingVertical: 16,
  }}
  suggestionTextStyle={{
    fontSize: 16,
    color: '#333',
  }}
/>

🔧 Custom Rendering

Custom Row Renderer

const renderCustomRow = (data, index) => (
  <TouchableOpacity style={customStyles.row}>
    <Icon name="location" size={20} />
    <Text style={customStyles.text}>{data.description}</Text>
    <Text style={customStyles.distance}>{data.distance}</Text>
  </TouchableOpacity>
);

<LocationAutocomplete
  renderRow={renderCustomRow}
  // ... other props
/>

Custom Buttons

<LocationAutocomplete
  renderLeftButton={() => (
    <TouchableOpacity style={styles.iconButton}>
      <Icon name="search" size={20} color="#666" />
    </TouchableOpacity>
  )}
  renderRightButton={() => (
    <TouchableOpacity style={styles.iconButton}>
      <Icon name="filter" size={20} color="#666" />
    </TouchableOpacity>
  )}
/>

🌍 Location Data Structure

The onLocationSelected callback receives a comprehensive location object:

{
  address: "Mumbai, Maharashtra, India",
  latitude: 19.0760,
  longitude: 72.8777,
  placeId: "ChIJwe1EZjDG5zsRaYxkjY_tpF0",
  details: {
    // Full Google Places API response
    geometry: { location: { lat: 19.0760, lng: 72.8777 } },
    address_components: [...],
    formatted_address: "Mumbai, Maharashtra, India",
    // ... other place details
  }
}

🚀 Performance Tips

  1. Use debouncing: Adjust debounceMs based on your needs (300-500ms recommended)
  2. Set minimum length: Use minLength to avoid unnecessary API calls
  3. Implement caching: Cache recent results to reduce API usage
  4. Use country restrictions: Limit search scope with countryCode
  5. Optimize rendering: Use renderRow for complex custom layouts

🔐 API Key Setup

  1. Go to Google Cloud Console
  2. Create a new project or select existing
  3. Enable these APIs:
    • Places API
    • Geocoding API (for reverse geocoding)
  4. Create credentials (API Key)
  5. Restrict the key to your app's bundle ID/package name

🆚 Comparison with react-native-google-places-autocomplete

| Feature | This Package | react-native-google-places-autocomplete | |---------|-------------|----------------------------------------| | API Cost Optimization | ✅ 70%+ cost reduction | ❌ No optimization | | Intelligent Caching | ✅ 5-minute smart cache | ❌ No caching | | Request Coalescing | ✅ Prevents duplicate calls | ❌ Multiple duplicate calls | | Animated Placeholder | ✅ Unique rotating animation | ❌ Static placeholder | | Bundle Size | 🟢 Lightweight | 🟡 Larger | | Current Location | ✅ Built-in GPS support | ✅ Supported | | Recent Searches | ✅ Built-in | ✅ Supported | | Theming | ✅ 3 built-in themes | ✅ Extensive theming | | Custom Rendering | ✅ Full control | ✅ Full control | | TypeScript | 🟡 Coming soon | ✅ Full support | | Modern React | ✅ Hooks-based | 🟡 Mixed patterns | | City Focus | ✅ Built for location apps | 🟡 General purpose |

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License

MIT © pragadanaveen

🙏 Acknowledgments

  • Google Places API for location data
  • React Native community for inspiration
  • All contributors and users

Made with ❤️ for the React Native community