localized-regions 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +120 -0
- package/data/countries.json +1002 -0
- package/data/provinces.json +31030 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +141 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +2 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Amit Tank
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# localized-regions
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/localized-regions)
|
|
4
|
+
[](https://www.npmjs.com/package/localized-regions)
|
|
5
|
+
[](./LICENSE)
|
|
6
|
+
[](./dist/index.d.ts)
|
|
7
|
+
|
|
8
|
+
**Country, province and city data with bilingual localized labels and ISO 3166 codes.**
|
|
9
|
+
Get country / province / city dropdown options with labels like `Spain (España)`, stable ISO
|
|
10
|
+
3166-1 and ISO 3166-2 codes, and the full set of **50 Spanish provinces** (not the 17
|
|
11
|
+
autonomous communities). Framework-agnostic and TypeScript-first: the data drops straight into
|
|
12
|
+
**react-select**, **MUI Autocomplete**, or any dropdown.
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
import { countryOptions, provinceOptions } from 'localized-regions';
|
|
16
|
+
|
|
17
|
+
countryOptions('es'); // [{ value: 'ES', label: 'Spain (España)' }, { value: 'NL', label: 'Netherlands (Países Bajos)' }, ...]
|
|
18
|
+
provinceOptions('ES'); // [{ value: 'ES-MA', label: 'Málaga' }, { value: 'ES-B', label: 'Barcelona' }, ...]
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Features
|
|
22
|
+
|
|
23
|
+
- **Bilingual / localized country labels** - `Spain (España)`, `Germany (Alemania)`, `France (Francia)`, computed from the browser-native `Intl.DisplayNames` for any locale.
|
|
24
|
+
- **Correct Spanish provinces** - all **50 provinces** with ISO 3166-2 codes and their parent autonomous community. (Popular datasets like `country-state-city` return only ~16 of them for Spain.)
|
|
25
|
+
- **Stable, invoicing-safe values** - country = ISO 3166-1 code (`ES`), province = ISO 3166-2 code (`ES-MA`). Labels are display-only.
|
|
26
|
+
- **Full city database** - cities for every country, sourced from `country-state-city` at runtime.
|
|
27
|
+
- **Framework-agnostic** - no React / MUI / Chakra dependency. Plain data plus ready-to-use `{ value, label }` options.
|
|
28
|
+
- **TypeScript types included.**
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install localized-regions
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
import {
|
|
40
|
+
getCountries, getProvinces, getCities,
|
|
41
|
+
countryOptions, provinceOptions, cityOptions,
|
|
42
|
+
formatCountryLabel,
|
|
43
|
+
} from 'localized-regions';
|
|
44
|
+
|
|
45
|
+
// Bilingual country labels (the locale drives the native part)
|
|
46
|
+
getCountries({ locale: 'es' }); // [{ code:'ES', name:'Spain', localized:'España', label:'Spain (España)' }, ...]
|
|
47
|
+
getCountries(); // English-only labels
|
|
48
|
+
|
|
49
|
+
// Spain -> 50 provinces (ISO 3166-2 codes + community grouping)
|
|
50
|
+
getProvinces('ES'); // [{ code:'ES-MA', countryCode:'ES', name:'Málaga', community:'Andalusia', communityCode:'ES-AN' }, ...]
|
|
51
|
+
|
|
52
|
+
// Cities (full database)
|
|
53
|
+
getCities('ES', 'ES-MA');
|
|
54
|
+
|
|
55
|
+
// Ready-to-use dropdown options
|
|
56
|
+
countryOptions('es'); // [{ value:'ES', label:'Spain (España)' }, ...]
|
|
57
|
+
provinceOptions('ES'); // [{ value:'ES-MA', label:'Málaga' }, ...]
|
|
58
|
+
cityOptions('ES', 'ES-MA'); // [{ value:'Málaga', label:'Málaga' }, ...]
|
|
59
|
+
|
|
60
|
+
formatCountryLabel('ES', 'es'); // "Spain (España)"
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### With react-select (editable / creatable dropdowns)
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import CreatableSelect from 'react-select/creatable';
|
|
67
|
+
import { provinceOptions } from 'localized-regions';
|
|
68
|
+
|
|
69
|
+
<CreatableSelect
|
|
70
|
+
options={provinceOptions('ES')} // 50 Spanish provinces
|
|
71
|
+
onChange={(opt) => save(opt?.value)} // store the ISO 3166-2 code, e.g. "ES-MA"
|
|
72
|
+
onCreateOption={(typed) => saveCustom(typed)} // allow a manual free-text correction
|
|
73
|
+
/>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### With MUI Autocomplete
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import Autocomplete from '@mui/material/Autocomplete';
|
|
80
|
+
import { countryOptions } from 'localized-regions';
|
|
81
|
+
|
|
82
|
+
<Autocomplete options={countryOptions('es')} getOptionLabel={(o) => o.label} />
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## API
|
|
86
|
+
|
|
87
|
+
| Function | Returns |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| `getCountries({ locale? })` | `CountryOption[]` - all countries, bilingual when a locale is given |
|
|
90
|
+
| `getCountry(code)` | `Country` |
|
|
91
|
+
| `formatCountryLabel(code, locale?)` | bilingual / English label string |
|
|
92
|
+
| `getProvinces(countryCode)` | `Province[]` (Spain = curated 50) |
|
|
93
|
+
| `getProvince(provinceCode)` | `Province` |
|
|
94
|
+
| `getCities(countryCode, provinceCode?)` | `City[]` |
|
|
95
|
+
| `countryOptions(locale?)` | `Option[]` (`{ value, label }`) |
|
|
96
|
+
| `provinceOptions(countryCode)` | `Option[]` |
|
|
97
|
+
| `cityOptions(countryCode, provinceCode?)` | `Option[]` |
|
|
98
|
+
|
|
99
|
+
## How the data is built
|
|
100
|
+
|
|
101
|
+
Data is generated at build time (`npm run generate`) and committed under `data/`:
|
|
102
|
+
|
|
103
|
+
- **Countries** - `Intl.DisplayNames` (English) plus a code list, 250 countries.
|
|
104
|
+
- **Provinces** - `iso-3166-2` subdivisions. Spain is curated to 50 provinces, with 4 regional-language names aliased to their common form (Nafarroa -> Navarra, Balears -> Balearic Islands, Alacant -> Alicante, Castelló -> Castellón).
|
|
105
|
+
- **Cities** - `country-state-city` at runtime.
|
|
106
|
+
|
|
107
|
+
Regenerate after a data-source bump:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
npm run generate && npm run build
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Notes and limitations
|
|
114
|
+
|
|
115
|
+
- **Spain city cascade is community-level.** The source city data groups Spanish cities under autonomous communities, not the 50 provinces, so `getCities('ES', 'ES-MA')` returns the parent community's cities (best-effort). City is best treated as a free-text field.
|
|
116
|
+
- **Bilingual labels are country-level only.** `Intl.DisplayNames` does not localize subdivisions; province names are shown as-is.
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT (c) Amit Tank. See [LICENSE](./LICENSE).
|