npm package: @maphorbs/location-picker
Description: Universal location data package for React, Next.js, and Node.js with TypeScript support
Author: Maphorbs
Latest version: 1.0.2

# 📍 @maphorbs/location-picker

A comprehensive, type-safe location data package for React, Next.js, and Node.js applications. Access detailed information about countries, states, and cities with full TypeScript support.

[![npm version](https://img.shields.io/npm/v/@maphorbs/location-picker.svg)](https://www.npmjs.com/package/@maphorbs/location-picker)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)

## ✨ Features

- 🌍 **Complete Location Data** - Countries, states/regions, and cities
- 📍 **Geographic Coordinates** - Latitude and longitude for all locations
- 💱 **Rich Country Information** - Currency, phone codes, capitals, timezones
- 🎌 **Multi-language Support** - Country names in 12+ languages
- ⚛️ **React Hooks** - Ready-to-use hooks for React applications
- 🔍 **Search & Filter** - Built-in search and filtering capabilities
- 📦 **Tree-shakeable** - Import only what you need
- 🎯 **TypeScript First** - Full type safety out of the box
- 🚀 **Zero Dependencies** - Lightweight and fast
- 🔄 **Dual Package** - Works in both browser and Node.js

## 📦 Installation

```bash
npm install @maphorbs/location-picker
# or
yarn add @maphorbs/location-picker
# or
pnpm add @maphorbs/location-picker
```

## 🚀 Quick Start

### React Usage (with Hooks)

```tsx
import { useCountries, useStates, useCities } from '@maphorbs/location-picker/react';

function LocationPicker() {
  const { countries, loading } = useCountries();
  const { states } = useStates('US'); // ISO2 country code
  const { cities } = useCities('US', 'CA'); // Country code + State code

  if (loading) return <div>Loading...</div>;

  return (
    <div>
      <select>
        {countries.map(country => (
          <option key={country.iso2} value={country.iso2}>
            {country.emoji} {country.name}
          </option>
        ))}
      </select>
      {/* States and cities dropdowns */}
    </div>
  );
}
```

### Node.js / Vanilla JavaScript Usage

```javascript
import {
  getCountries,
  getStatesByCountry,
  getCitiesByState,
  searchCountries,
  getCountryByCode
} from '@maphorbs/location-picker';

// Get all countries
const countries = getCountries();
console.log(countries.length); // 250+ countries

// Get a specific country
const usa = getCountryByCode('US'); // or 'USA'
console.log(usa.capital); // "Washington"
console.log(usa.currency); // "USD"
console.log(usa.emoji); // "🇺🇸"

// Get states for a country
const states = getStatesByCountry('US');
console.log(states.length); // 50+ states

// Get cities in a state
const cities = getCitiesByState('US', 'CA');
console.log(cities[0]); // { id: 1, name: "Los Angeles", latitude: "34.05", longitude: "-118.24" }

// Search countries
const searchResults = searchCountries('united', { limit: 5 });
```

## 📚 API Reference

### Core Functions (No React Required)

#### Countries

```typescript
// Get all countries with basic info
getCountries(): CountryInfo[]

// Get full country details including states
getCountryByCode(code: string): Country | null

// Get country by name
getCountryByName(name: string): Country | null

// Get country by ID
getCountryById(id: number): Country | null

// Search countries by name or native name
searchCountries(query: string, options?: SearchOptions): CountryInfo[]

// Filter by region (e.g., "Asia", "Europe")
getCountriesByRegion(region: string): CountryInfo[]

// Filter by subregion (e.g., "Southern Asia", "Western Europe")
getCountriesBySubregion(subregion: string): CountryInfo[]

// Get total count
getCountriesCount(): number
```

#### States

```typescript
// Get all states in a country
getStatesByCountry(countryCode: string): StateInfo[]

// Get specific state by code
getStateByCode(countryCode: string, stateCode: string): State | null

// Get specific state by name
getStateByName(countryCode: string, stateName: string): State | null

// Get state by ID
getStateById(countryCode: string, stateId: number): State | null

// Search states within a country
searchStates(countryCode: string, query: string, options?: SearchOptions): StateInfo[]

// Get total states count
getStatesCount(countryCode: string): number
```

#### Cities

```typescript
// Get all cities in a state
getCitiesByState(countryCode: string, stateCode: string): CityInfo[]

// Get all cities in a country (all states)
getCitiesByCountry(countryCode: string): CityInfo[]

// Get specific city by ID
getCityById(countryCode: string, stateCode: string, cityId: number): CityInfo | null

// Search cities within a state
searchCities(countryCode: string, stateCode: string, query: string, options?: SearchOptions): CityInfo[]

// Search cities across entire country
searchCitiesInCountry(countryCode: string, query: string, options?: SearchOptions): CityInfo[]

// Get cities count in a state
getCitiesCount(countryCode: string, stateCode: string): number

// Get total cities in a country
getCitiesCountByCountry(countryCode: string): number
```

### React Hooks

Import from `@maphorbs/location-package/react`:

```typescript
import { useCountries, useStates, useCities } from '@maphorbs/location-package/react';

// Get all countries
const { countries, loading, error, searchCountries } = useCountries();

// Get states for a country
const { states, loading, error, searchStates } = useStates(countryCode);

// Get cities for a state
const { cities, loading, error, searchCities } = useCities(countryCode, stateCode);
```

## 📊 Data Structure

### CountryInfo

```typescript
interface CountryInfo {
  id: number;
  name: string;
  iso2: string;              // "US"
  iso3: string;              // "USA"
  phone_code: string;        // "1"
  capital: string;           // "Washington"
  currency: string;          // "USD"
  currency_symbol: string;   // "$"
  region: string;            // "Americas"
  subregion: string;         // "Northern America"
  emoji: string;             // "🇺🇸"
}
```

### Full Country Object

```typescript
interface Country extends CountryInfo {
  tld: string;                    // ".us"
  native: string;                 // Native name
  latitude: string;
  longitude: string;
  emojiU: string;                 // Unicode representation
  timezones: Timezone[];
  translations: Translations;      // Names in 12+ languages
  states: State[];
}
```

### StateInfo

```typescript
interface StateInfo {
  id: number;
  name: string;
  state_code: string;        // "CA", "TX", etc.
  latitude: string;
  longitude: string;
}
```

### CityInfo

```typescript
interface CityInfo {
  id: number;
  name: string;
  latitude: string;
  longitude: string;
}
```

### SearchOptions

```typescript
interface SearchOptions {
  caseSensitive?: boolean;   // Default: false
  limit?: number;            // Limit results
}
```

## 💡 Usage Examples

### Basic Location Picker Component

```tsx
import { useState } from 'react';
import { useCountries, useStates, useCities } from '@maphorbs/location-picker/react';

function LocationForm() {
  const [country, setCountry] = useState<string>('');
  const [state, setState] = useState<string>('');
  const [city, setCity] = useState<number | null>(null);

  const { countries } = useCountries();
  const { states } = useStates(country);
  const { cities } = useCities(country, state);

  return (
    <form>
      <select onChange={(e) => setCountry(e.target.value)} value={country}>
        <option value="">Select Country</option>
        {countries.map(c => (
          <option key={c.iso2} value={c.iso2}>
            {c.emoji} {c.name}
          </option>
        ))}
      </select>

      <select onChange={(e) => setState(e.target.value)} value={state}>
        <option value="">Select State</option>
        {states.map(s => (
          <option key={s.state_code} value={s.state_code}>
            {s.name}
          </option>
        ))}
      </select>

      <select onChange={(e) => setCity(Number(e.target.value))} value={city || ''}>
        <option value="">Select City</option>
        {cities.map(c => (
          <option key={c.id} value={c.id}>
            {c.name}
          </option>
        ))}
      </select>
    </form>
  );
}
```

### Search with Autocomplete

```tsx
import { useState } from 'react';
import { searchCountries } from '@maphorbs/location-picker';

function CountrySearch() {
  const [query, setQuery] = useState('');
  const results = query ? searchCountries(query, { limit: 10 }) : [];

  return (
    <div>
      <input
        type="text"
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search countries..."
      />
      <ul>
        {results.map(country => (
          <li key={country.iso2}>
            {country.emoji} {country.name} - {country.capital}
          </li>
        ))}
      </ul>
    </div>
  );
}
```

### Filter by Region

```typescript
import { getCountriesByRegion, getCountriesBySubregion } from '@maphorbs/location-picker';

// Get all Asian countries
const asianCountries = getCountriesByRegion('Asia');
console.log(asianCountries.length); // 50+ countries

// Get Southeast Asian countries specifically
const seAsiaCountries = getCountriesBySubregion('South-Eastern Asia');
console.log(seAsiaCountries.map(c => c.name));
// ["Thailand", "Vietnam", "Singapore", ...]
```

### Distance Calculation Between Cities

```typescript
import { getCityById } from '@maphorbs/location-picker';

function calculateDistance(lat1: number, lon1: number, lat2: number, lon2: number) {
  const R = 6371; // Earth's radius in km
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
            Math.sin(dLon/2) * Math.sin(dLon/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  return R * c;
}

const city1 = getCityById('US', 'CA', 123);
const city2 = getCityById('US', 'NY', 456);

if (city1 && city2) {
  const distance = calculateDistance(
    parseFloat(city1.latitude),
    parseFloat(city1.longitude),
    parseFloat(city2.latitude),
    parseFloat(city2.longitude)
  );
  console.log(`Distance: ${distance.toFixed(2)} km`);
}
```

### Server-Side Usage (Next.js API Route)

```typescript
// pages/api/countries.ts
import { getCountries } from '@maphorbs/location-picker';
import type { NextApiRequest, NextApiResponse } from 'next';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const countries = getCountries();
  res.status(200).json(countries);
}
```

### Node.js CLI Tool

```javascript
#!/usr/bin/env node
import { getCountryByCode, getStatesByCountry } from '@maphorbs/location-picker';

const countryCode = process.argv[2];

if (!countryCode) {
  console.log('Usage: node cli.js <country-code>');
  process.exit(1);
}

const country = getCountryByCode(countryCode);

if (!country) {
  console.log(`Country not found: ${countryCode}`);
  process.exit(1);
}

console.log(`\n${country.emoji} ${country.name}`);
console.log(`Capital: ${country.capital}`);
console.log(`Currency: ${country.currency} (${country.currency_symbol})`);
console.log(`Phone Code: +${country.phone_code}`);
console.log(`States: ${country.states.length}`);
```

## 🌍 Supported Regions

- **Africa** - 60+ countries
- **Americas** - 57+ countries
- **Asia** - 51+ countries
- **Europe** - 53+ countries
- **Oceania** - 27+ countries

Total: **250+ countries**, **5000+ states/regions**, **150,000+ cities**

## 🎯 TypeScript Support

The package is written in TypeScript and includes full type definitions. All functions and data structures are fully typed:

```typescript
import type {
  Country,
  State,
  City,
  CountryInfo,
  StateInfo,
  CityInfo,
  Timezone,
  Translations,
  SearchOptions
} from '@maphorbs/location-picker';
```

## 📦 Bundle Size

- **Core Package**: ~2MB (includes all location data)
- **React Package**: +5KB (hooks only)
- **Tree-shakeable**: Import only what you need

## 🔧 Advanced Configuration

### Custom Search

```typescript
import { searchCountries } from '@maphorbs/location-picker';

// Case-sensitive search
const results = searchCountries('United', { caseSensitive: true });

// Limit results
const top5 = searchCountries('United', { limit: 5 });

// Search in native language
const results = searchCountries('日本'); // Finds Japan
```

### Accessing Timezone Information

```typescript
import { getCountryByCode } from '@maphorbs/location-picker';

const country = getCountryByCode('US');
if (country) {
  country.timezones.forEach(tz => {
    console.log(tz.zoneName);       // "America/New_York"
    console.log(tz.gmtOffsetName);  // "UTC-05:00"
    console.log(tz.tzName);         // "Eastern Standard Time"
  });
}
```

### Multi-language Country Names

```typescript
import { getCountryByCode } from '@oa/location-package';

const country = getCountryByCode('JP');
if (country) {
  console.log(country.translations.cn); // "日本"
  console.log(country.translations.es); // "Japón"
  console.log(country.translations.fr); // "Japon"
  console.log(country.translations.de); // "Japan"
}
```

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 📄 License

MIT © [Your Name]

## 🔗 Links

- [GitHub Repository](https://github.com/maphorbs/location-picker)
- [NPM Package](https://www.npmjs.com/package/@maphorbs/location-picker)
- [Report Issues](https://github.com/maphorbs/location-picker/issues)
- [Changelog](https://github.com/maphorbs/location-picker/blob/main/CHANGELOG.md)

## ⭐ Support

If this package helped you, please consider giving it a star on GitHub!

---

Made with ❤️ by [Maphorbs](https://github.com/maphorbs)