@code-plate/iran-cities 1.0.0 → 1.0.1
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/README.fa.md +259 -0
- package/README.md +67 -65
- package/package.json +12 -1
package/README.fa.md
ADDED
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
[English](./README.md) | فارسی
|
|
2
|
+
|
|
3
|
+
# @code-plate/iran-cities
|
|
4
|
+
|
|
5
|
+
لیست کامل و آمادهی **استانها و شهرهای ایران** (فارسی + انگلیسی)، بستهبندیشده به شکل یک کتابخانهی سبک، بدون هیچ وابستگی اجباری، که در **هر پروژهی جاوااسکریپتی/تایپاسکریپتی** قابل استفاده است:
|
|
6
|
+
|
|
7
|
+
- ✅ React / Next.js (App Router و Pages Router)
|
|
8
|
+
- ✅ Vue 2 / Vue 3
|
|
9
|
+
- ✅ Angular
|
|
10
|
+
- ✅ Svelte
|
|
11
|
+
- ✅ Node.js / Express (بکاند خالص)
|
|
12
|
+
- ✅ Vanilla JS (مرورگر یا هر باندلر دیگر)
|
|
13
|
+
|
|
14
|
+
هستهی اصلی پکیج **هیچ وابستگیای** ندارد (zero-dependency) و هم بهصورت **CJS** و هم **ESM** ارائه میشود. یک سابپس اختیاری (`@code-plate/iran-cities/react`) هم برای کسانی که در React کار میکنند وجود دارد که چند هوک آماده میدهد؛ اگر پروژهتان React نیست، هرگز این فایل import نمیشود و React اصلاً لازم نیست نصب شود.
|
|
15
|
+
|
|
16
|
+
## نصب
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @code-plate/iran-cities
|
|
20
|
+
# یا
|
|
21
|
+
yarn add @code-plate/iran-cities
|
|
22
|
+
# یا
|
|
23
|
+
pnpm add @code-plate/iran-cities
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## دادهها
|
|
27
|
+
|
|
28
|
+
- `۳۱` استان
|
|
29
|
+
- `۱۲۵۳` شهر
|
|
30
|
+
- هر رکورد شامل `en` (شناسه لاتین kebab-case، مثل `tehran`) و `fa` (نام فارسی، مثل `تهران`) است.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## استفاده در جاوااسکریپت / تایپاسکریپت خالص (و Node.js/Express)
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import {
|
|
38
|
+
getProvinces,
|
|
39
|
+
getProvincesList,
|
|
40
|
+
getProvince,
|
|
41
|
+
getCities,
|
|
42
|
+
getCity,
|
|
43
|
+
getAllCities,
|
|
44
|
+
getProvinceOfCity,
|
|
45
|
+
searchProvinces,
|
|
46
|
+
searchCities,
|
|
47
|
+
getStats,
|
|
48
|
+
} from '@code-plate/iran-cities';
|
|
49
|
+
|
|
50
|
+
// همهی استانها به همراه شهرهایشان
|
|
51
|
+
getProvinces();
|
|
52
|
+
// [{ en: 'alborz', fa: 'البرز', cities: [{ en: 'karaj', fa: 'کرج' }, ...] }, ...]
|
|
53
|
+
|
|
54
|
+
// فقط لیست استانها (بدون شهر) - برای Select/Dropdown
|
|
55
|
+
getProvincesList();
|
|
56
|
+
// [{ en: 'alborz', fa: 'البرز' }, { en: 'ardabil', fa: 'اردبیل' }, ...]
|
|
57
|
+
|
|
58
|
+
// گرفتن یک استان با نام انگلیسی یا فارسی
|
|
59
|
+
getProvince('tehran');
|
|
60
|
+
getProvince('تهران'); // همین نتیجه را میدهد
|
|
61
|
+
|
|
62
|
+
// شهرهای یک استان خاص
|
|
63
|
+
getCities('fars'); // بر اساس شناسه انگلیسی
|
|
64
|
+
getCities('فارس'); // یا بر اساس نام فارسی، هر دو یکسان کار میکنند
|
|
65
|
+
|
|
66
|
+
// پیدا کردن یک شهر مشخص (در کل کشور یا محدود به یک استان)
|
|
67
|
+
getCity('shiraz');
|
|
68
|
+
getCity('شیراز', 'fars'); // محدود به استان فارس
|
|
69
|
+
|
|
70
|
+
// لیست مسطح (flat) همهی شهرهای کشور همراه با استان مربوطه
|
|
71
|
+
getAllCities();
|
|
72
|
+
// [{ en: 'karaj', fa: 'کرج', provinceEn: 'alborz', provinceFa: 'البرز' }, ...]
|
|
73
|
+
|
|
74
|
+
// پیدا کردن استانِ یک شهر
|
|
75
|
+
getProvinceOfCity('اصفهان'); // => { en: 'isfahan', fa: 'اصفهان', cities: [...] }
|
|
76
|
+
|
|
77
|
+
// جستجوی زنده (autocomplete) در استانها یا شهرها
|
|
78
|
+
searchProvinces('خراسان'); // هر سه استان خراسان را برمیگرداند
|
|
79
|
+
searchCities('شهر', { limit: 10 }); // ۱۰ نتیجهی اول شامل «شهر»
|
|
80
|
+
searchCities('mashhad', { locale: 'en' }); // جستجو فقط در نام انگلیسی
|
|
81
|
+
|
|
82
|
+
// آمار کلی
|
|
83
|
+
getStats(); // { provinceCount: 31, cityCount: 1253 }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### نکتهی مهم دربارهی جستجو
|
|
87
|
+
تابعهای `getProvince`, `getCities`, `getCity` و `getProvinceOfCity` بهصورت **نرمالشده** مقایسه میکنند؛ یعنی تفاوت «ی» فارسی/«ي» عربی، «ک»/«ك»، نیمفاصله، فاصله و خطتیره را نادیده میگیرند. پس `getCity('كرج')` و `getCity('کرج')` هر دو کار میکنند.
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## استفاده در Node.js / Express (بکاند)
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
const express = require('express');
|
|
95
|
+
const { getProvincesList, getCities, searchCities } = require('@code-plate/iran-cities');
|
|
96
|
+
|
|
97
|
+
const app = express();
|
|
98
|
+
|
|
99
|
+
app.get('/api/provinces', (req, res) => {
|
|
100
|
+
res.json(getProvincesList());
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
app.get('/api/cities/:province', (req, res) => {
|
|
104
|
+
res.json(getCities(req.params.province));
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
app.get('/api/cities/search', (req, res) => {
|
|
108
|
+
res.json(searchCities(req.query.q ?? '', { limit: 20 }));
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## استفاده در React / Next.js
|
|
115
|
+
|
|
116
|
+
برای React یک سابپس اختیاری وجود دارد که چند هوک آماده ارائه میدهد:
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
import { useProvinces, useCities, useProvinceCitySelect, useCitySearch } from '@code-plate/iran-cities/react';
|
|
120
|
+
|
|
121
|
+
function AddressForm() {
|
|
122
|
+
const { provinces, cities, province, setProvince, city, setCity } = useProvinceCitySelect();
|
|
123
|
+
|
|
124
|
+
return (
|
|
125
|
+
<>
|
|
126
|
+
<select value={province} onChange={(e) => setProvince(e.target.value)}>
|
|
127
|
+
<option value="">انتخاب استان</option>
|
|
128
|
+
{provinces.map((p) => (
|
|
129
|
+
<option key={p.en} value={p.en}>{p.fa}</option>
|
|
130
|
+
))}
|
|
131
|
+
</select>
|
|
132
|
+
|
|
133
|
+
<select value={city} onChange={(e) => setCity(e.target.value)} disabled={!province}>
|
|
134
|
+
<option value="">انتخاب شهر</option>
|
|
135
|
+
{cities.map((c) => (
|
|
136
|
+
<option key={c.en} value={c.en}>{c.fa}</option>
|
|
137
|
+
))}
|
|
138
|
+
</select>
|
|
139
|
+
</>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
جستجوی زندهی شهر (autocomplete):
|
|
145
|
+
|
|
146
|
+
```tsx
|
|
147
|
+
import { useCitySearch } from '@code-plate/iran-cities/react';
|
|
148
|
+
|
|
149
|
+
function CityAutocomplete() {
|
|
150
|
+
const { query, setQuery, results } = useCitySearch('', { limit: 8 });
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div>
|
|
154
|
+
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="نام شهر..." />
|
|
155
|
+
<ul>
|
|
156
|
+
{results.map((c) => (
|
|
157
|
+
<li key={`${c.provinceEn}-${c.en}`}>{c.fa} ({c.provinceFa})</li>
|
|
158
|
+
))}
|
|
159
|
+
</ul>
|
|
160
|
+
</div>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
هوکهای در دسترس در سابپس `react`:
|
|
166
|
+
|
|
167
|
+
| هوک | کاربرد |
|
|
168
|
+
|---|---|
|
|
169
|
+
| `useProvinces()` | لیست استانها |
|
|
170
|
+
| `useCities(provinceQuery)` | شهرهای یک استان، وابسته به تغییر پارامتر |
|
|
171
|
+
| `useProvinceCitySelect()` | state کامل یک فرم استان→شهر (با ریست خودکار شهر هنگام تغییر استان) |
|
|
172
|
+
| `useCitySearch(initialQuery?, options?)` | state جستجوی زندهی شهر |
|
|
173
|
+
| `useProvinceSearch(initialQuery?, options?)` | state جستجوی زندهی استان |
|
|
174
|
+
|
|
175
|
+
> اگر پروژهتان Vue، Angular یا هر چیز دیگری است، فقط از مسیر اصلی (`@code-plate/iran-cities`) استفاده کنید و توابع خام (`getProvinces`, `getCities`, ...) را داخل computed/signal/observable خودتان قرار دهید — نیازی به هیچ ابزار اضافهای نیست.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## استفاده در Vue 3 (نمونه)
|
|
180
|
+
|
|
181
|
+
```vue
|
|
182
|
+
<script setup>
|
|
183
|
+
import { ref, computed } from 'vue';
|
|
184
|
+
import { getProvincesList, getCities } from '@code-plate/iran-cities';
|
|
185
|
+
|
|
186
|
+
const provinces = getProvincesList();
|
|
187
|
+
const selectedProvince = ref('');
|
|
188
|
+
const cities = computed(() => getCities(selectedProvince.value));
|
|
189
|
+
</script>
|
|
190
|
+
|
|
191
|
+
<template>
|
|
192
|
+
<select v-model="selectedProvince">
|
|
193
|
+
<option v-for="p in provinces" :key="p.en" :value="p.en">{{ p.fa }}</option>
|
|
194
|
+
</select>
|
|
195
|
+
<select :disabled="!selectedProvince">
|
|
196
|
+
<option v-for="c in cities" :key="c.en" :value="c.en">{{ c.fa }}</option>
|
|
197
|
+
</select>
|
|
198
|
+
</template>
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## استفاده در Angular (نمونه سرویس)
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import { Injectable } from '@angular/core';
|
|
205
|
+
import { getProvincesList, getCities, type City } from '@code-plate/iran-cities';
|
|
206
|
+
|
|
207
|
+
@Injectable({ providedIn: 'root' })
|
|
208
|
+
export class IranLocationsService {
|
|
209
|
+
getProvinces() {
|
|
210
|
+
return getProvincesList();
|
|
211
|
+
}
|
|
212
|
+
getCitiesOf(provinceEn: string): City[] {
|
|
213
|
+
return getCities(provinceEn);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## API کامل
|
|
221
|
+
|
|
222
|
+
### توابع اصلی (import از `'@code-plate/iran-cities'`)
|
|
223
|
+
|
|
224
|
+
| تابع | ورودی | خروجی | توضیح |
|
|
225
|
+
|---|---|---|---|
|
|
226
|
+
| `getProvinces()` | - | `Province[]` | همهی استانها به همراه شهرها |
|
|
227
|
+
| `getProvincesList()` | - | `{en, fa}[]` | فقط لیست استانها |
|
|
228
|
+
| `getProvince(query)` | `string` | `Province \| undefined` | یک استان با en یا fa |
|
|
229
|
+
| `getCities(provinceQuery)` | `string` | `City[]` | شهرهای یک استان |
|
|
230
|
+
| `getCity(cityQuery, provinceQuery?)` | `string, string?` | `FlatCity \| undefined` | یک شهر مشخص |
|
|
231
|
+
| `getAllCities()` | - | `FlatCity[]` | همهی شهرها بهصورت مسطح |
|
|
232
|
+
| `getProvinceOfCity(cityQuery)` | `string` | `Province \| undefined` | استانِ یک شهر |
|
|
233
|
+
| `searchProvinces(query, options?)` | `string, SearchOptions?` | `Province[]` | جستجوی fuzzy استان |
|
|
234
|
+
| `searchCities(query, options?)` | `string, SearchOptions?` | `FlatCity[]` | جستجوی fuzzy شهر |
|
|
235
|
+
| `getStats()` | - | `{provinceCount, cityCount}` | آمار کلی |
|
|
236
|
+
|
|
237
|
+
`SearchOptions`: `{ limit?: number; locale?: 'en' | 'fa' | 'both' }`
|
|
238
|
+
|
|
239
|
+
### تایپها
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
interface City { en: string; fa: string; }
|
|
243
|
+
interface Province { en: string; fa: string; cities: City[]; }
|
|
244
|
+
interface FlatCity extends City { provinceEn: string; provinceFa: string; }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
## توسعه
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npm install
|
|
253
|
+
npm run build # خروجی dist/ (cjs + esm + d.ts)
|
|
254
|
+
npm run typecheck
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## لایسنس
|
|
258
|
+
|
|
259
|
+
MIT
|
package/README.md
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
|
+
English | [فارسی](./README.fa.md)
|
|
2
|
+
|
|
1
3
|
# @code-plate/iran-cities
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
A complete, ready-to-use list of **Iran's provinces and cities** (Persian + English), packaged as a lightweight library with no forced dependencies, usable in **any JavaScript/TypeScript project**:
|
|
4
6
|
|
|
5
|
-
- ✅ React / Next.js (App Router
|
|
7
|
+
- ✅ React / Next.js (App Router and Pages Router)
|
|
6
8
|
- ✅ Vue 2 / Vue 3
|
|
7
9
|
- ✅ Angular
|
|
8
10
|
- ✅ Svelte
|
|
9
|
-
- ✅ Node.js / Express (
|
|
10
|
-
- ✅ Vanilla JS (
|
|
11
|
+
- ✅ Node.js / Express (pure backend)
|
|
12
|
+
- ✅ Vanilla JS (browser or any other bundler)
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
The core of the package has **zero dependencies** and ships as both **CJS** and **ESM**. There's also an optional subpath (`@code-plate/iran-cities/react`) for React users with a few ready-made hooks; if your project isn't React, that file is never imported and React doesn't need to be installed at all.
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Installation
|
|
15
17
|
|
|
16
18
|
```bash
|
|
17
19
|
npm install @code-plate/iran-cities
|
|
18
|
-
#
|
|
20
|
+
# or
|
|
19
21
|
yarn add @code-plate/iran-cities
|
|
20
|
-
#
|
|
22
|
+
# or
|
|
21
23
|
pnpm add @code-plate/iran-cities
|
|
22
24
|
```
|
|
23
25
|
|
|
24
|
-
##
|
|
26
|
+
## Data
|
|
25
27
|
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
28
|
+
- `31` provinces
|
|
29
|
+
- `1253` cities
|
|
30
|
+
- Every record has an `en` field (latin, kebab-case identifier, e.g. `tehran`) and an `fa` field (Persian name, e.g. `تهران`).
|
|
29
31
|
|
|
30
32
|
---
|
|
31
33
|
|
|
32
|
-
##
|
|
34
|
+
## Usage in plain JavaScript / TypeScript (and Node.js/Express)
|
|
33
35
|
|
|
34
36
|
```ts
|
|
35
37
|
import {
|
|
@@ -45,48 +47,48 @@ import {
|
|
|
45
47
|
getStats,
|
|
46
48
|
} from '@code-plate/iran-cities';
|
|
47
49
|
|
|
48
|
-
//
|
|
50
|
+
// All provinces along with their cities
|
|
49
51
|
getProvinces();
|
|
50
52
|
// [{ en: 'alborz', fa: 'البرز', cities: [{ en: 'karaj', fa: 'کرج' }, ...] }, ...]
|
|
51
53
|
|
|
52
|
-
//
|
|
54
|
+
// Just the list of provinces (no cities) - for a Select/Dropdown
|
|
53
55
|
getProvincesList();
|
|
54
56
|
// [{ en: 'alborz', fa: 'البرز' }, { en: 'ardabil', fa: 'اردبیل' }, ...]
|
|
55
57
|
|
|
56
|
-
//
|
|
58
|
+
// Get a single province by English id or Persian name
|
|
57
59
|
getProvince('tehran');
|
|
58
|
-
getProvince('تهران'); //
|
|
60
|
+
getProvince('تهران'); // same result
|
|
59
61
|
|
|
60
|
-
//
|
|
61
|
-
getCities('fars'); //
|
|
62
|
-
getCities('فارس'); //
|
|
62
|
+
// Cities of a specific province
|
|
63
|
+
getCities('fars'); // by English id
|
|
64
|
+
getCities('فارس'); // or by Persian name, both work the same way
|
|
63
65
|
|
|
64
|
-
//
|
|
66
|
+
// Find a specific city (across the whole country, or scoped to a province)
|
|
65
67
|
getCity('shiraz');
|
|
66
|
-
getCity('شیراز', 'fars'); //
|
|
68
|
+
getCity('شیراز', 'fars'); // scoped to Fars province
|
|
67
69
|
|
|
68
|
-
//
|
|
70
|
+
// Flat list of every city in the country, along with its province
|
|
69
71
|
getAllCities();
|
|
70
72
|
// [{ en: 'karaj', fa: 'کرج', provinceEn: 'alborz', provinceFa: 'البرز' }, ...]
|
|
71
73
|
|
|
72
|
-
//
|
|
74
|
+
// Find which province a city belongs to
|
|
73
75
|
getProvinceOfCity('اصفهان'); // => { en: 'isfahan', fa: 'اصفهان', cities: [...] }
|
|
74
76
|
|
|
75
|
-
//
|
|
76
|
-
searchProvinces('خراسان');
|
|
77
|
-
searchCities('شهر', { limit: 10 });
|
|
78
|
-
searchCities('mashhad', { locale: 'en' }); //
|
|
77
|
+
// Live search (autocomplete) over provinces or cities
|
|
78
|
+
searchProvinces('خراسان'); // returns all three "Khorasan" provinces
|
|
79
|
+
searchCities('شهر', { limit: 10 }); // first 10 results containing "شهر"
|
|
80
|
+
searchCities('mashhad', { locale: 'en' }); // search English names only
|
|
79
81
|
|
|
80
|
-
//
|
|
82
|
+
// Overall stats
|
|
81
83
|
getStats(); // { provinceCount: 31, cityCount: 1253 }
|
|
82
84
|
```
|
|
83
85
|
|
|
84
|
-
###
|
|
85
|
-
|
|
86
|
+
### A note on search
|
|
87
|
+
`getProvince`, `getCities`, `getCity` and `getProvinceOfCity` compare strings in a **normalized** way — differences between Persian «ی» and Arabic «ي», «ک» vs. «ك», zero-width non-joiners, spaces and hyphens are all ignored. So `getCity('كرج')` and `getCity('کرج')` both work.
|
|
86
88
|
|
|
87
89
|
---
|
|
88
90
|
|
|
89
|
-
##
|
|
91
|
+
## Usage in Node.js / Express (backend)
|
|
90
92
|
|
|
91
93
|
```js
|
|
92
94
|
const express = require('express');
|
|
@@ -109,9 +111,9 @@ app.get('/api/cities/search', (req, res) => {
|
|
|
109
111
|
|
|
110
112
|
---
|
|
111
113
|
|
|
112
|
-
##
|
|
114
|
+
## Usage in React / Next.js
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
An optional subpath is available for React with a few ready-made hooks:
|
|
115
117
|
|
|
116
118
|
```tsx
|
|
117
119
|
import { useProvinces, useCities, useProvinceCitySelect, useCitySearch } from '@code-plate/iran-cities/react';
|
|
@@ -122,14 +124,14 @@ function AddressForm() {
|
|
|
122
124
|
return (
|
|
123
125
|
<>
|
|
124
126
|
<select value={province} onChange={(e) => setProvince(e.target.value)}>
|
|
125
|
-
<option value=""
|
|
127
|
+
<option value="">Select a province</option>
|
|
126
128
|
{provinces.map((p) => (
|
|
127
129
|
<option key={p.en} value={p.en}>{p.fa}</option>
|
|
128
130
|
))}
|
|
129
131
|
</select>
|
|
130
132
|
|
|
131
133
|
<select value={city} onChange={(e) => setCity(e.target.value)} disabled={!province}>
|
|
132
|
-
<option value=""
|
|
134
|
+
<option value="">Select a city</option>
|
|
133
135
|
{cities.map((c) => (
|
|
134
136
|
<option key={c.en} value={c.en}>{c.fa}</option>
|
|
135
137
|
))}
|
|
@@ -139,7 +141,7 @@ function AddressForm() {
|
|
|
139
141
|
}
|
|
140
142
|
```
|
|
141
143
|
|
|
142
|
-
|
|
144
|
+
Live city search (autocomplete):
|
|
143
145
|
|
|
144
146
|
```tsx
|
|
145
147
|
import { useCitySearch } from '@code-plate/iran-cities/react';
|
|
@@ -149,7 +151,7 @@ function CityAutocomplete() {
|
|
|
149
151
|
|
|
150
152
|
return (
|
|
151
153
|
<div>
|
|
152
|
-
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="
|
|
154
|
+
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="City name..." />
|
|
153
155
|
<ul>
|
|
154
156
|
{results.map((c) => (
|
|
155
157
|
<li key={`${c.provinceEn}-${c.en}`}>{c.fa} ({c.provinceFa})</li>
|
|
@@ -160,21 +162,21 @@ function CityAutocomplete() {
|
|
|
160
162
|
}
|
|
161
163
|
```
|
|
162
164
|
|
|
163
|
-
|
|
165
|
+
Hooks available in the `react` subpath:
|
|
164
166
|
|
|
165
|
-
|
|
|
167
|
+
| Hook | Purpose |
|
|
166
168
|
|---|---|
|
|
167
|
-
| `useProvinces()` |
|
|
168
|
-
| `useCities(provinceQuery)` |
|
|
169
|
-
| `useProvinceCitySelect()` | state
|
|
170
|
-
| `useCitySearch(initialQuery?, options?)` |
|
|
171
|
-
| `useProvinceSearch(initialQuery?, options?)` |
|
|
169
|
+
| `useProvinces()` | List of provinces |
|
|
170
|
+
| `useCities(provinceQuery)` | Cities of a province, reacts to changes in the parameter |
|
|
171
|
+
| `useProvinceCitySelect()` | Full state + logic for a province→city form field (auto-resets the city when the province changes) |
|
|
172
|
+
| `useCitySearch(initialQuery?, options?)` | Live city search state |
|
|
173
|
+
| `useProvinceSearch(initialQuery?, options?)` | Live province search state |
|
|
172
174
|
|
|
173
|
-
>
|
|
175
|
+
> If your project is Vue, Angular, or anything else, just use the main entry point (`@code-plate/iran-cities`) and plug the raw functions (`getProvinces`, `getCities`, ...) into your own computed/signal/observable — no extra tooling required.
|
|
174
176
|
|
|
175
177
|
---
|
|
176
178
|
|
|
177
|
-
##
|
|
179
|
+
## Usage in Vue 3 (example)
|
|
178
180
|
|
|
179
181
|
```vue
|
|
180
182
|
<script setup>
|
|
@@ -196,7 +198,7 @@ const cities = computed(() => getCities(selectedProvince.value));
|
|
|
196
198
|
</template>
|
|
197
199
|
```
|
|
198
200
|
|
|
199
|
-
##
|
|
201
|
+
## Usage in Angular (example service)
|
|
200
202
|
|
|
201
203
|
```ts
|
|
202
204
|
import { Injectable } from '@angular/core';
|
|
@@ -215,26 +217,26 @@ export class IranLocationsService {
|
|
|
215
217
|
|
|
216
218
|
---
|
|
217
219
|
|
|
218
|
-
## API
|
|
220
|
+
## Full API
|
|
219
221
|
|
|
220
|
-
###
|
|
222
|
+
### Core functions (import from `'@code-plate/iran-cities'`)
|
|
221
223
|
|
|
222
|
-
|
|
|
224
|
+
| Function | Input | Output | Description |
|
|
223
225
|
|---|---|---|---|
|
|
224
|
-
| `getProvinces()` | - | `Province[]` |
|
|
225
|
-
| `getProvincesList()` | - | `{en, fa}[]` |
|
|
226
|
-
| `getProvince(query)` | `string` | `Province \| undefined` |
|
|
227
|
-
| `getCities(provinceQuery)` | `string` | `City[]` |
|
|
228
|
-
| `getCity(cityQuery, provinceQuery?)` | `string, string?` | `FlatCity \| undefined` |
|
|
229
|
-
| `getAllCities()` | - | `FlatCity[]` |
|
|
230
|
-
| `getProvinceOfCity(cityQuery)` | `string` | `Province \| undefined` |
|
|
231
|
-
| `searchProvinces(query, options?)` | `string, SearchOptions?` | `Province[]` |
|
|
232
|
-
| `searchCities(query, options?)` | `string, SearchOptions?` | `FlatCity[]` |
|
|
233
|
-
| `getStats()` | - | `{provinceCount, cityCount}` |
|
|
226
|
+
| `getProvinces()` | - | `Province[]` | All provinces with their cities |
|
|
227
|
+
| `getProvincesList()` | - | `{en, fa}[]` | Provinces only |
|
|
228
|
+
| `getProvince(query)` | `string` | `Province \| undefined` | A province by en or fa |
|
|
229
|
+
| `getCities(provinceQuery)` | `string` | `City[]` | Cities of a province |
|
|
230
|
+
| `getCity(cityQuery, provinceQuery?)` | `string, string?` | `FlatCity \| undefined` | A specific city |
|
|
231
|
+
| `getAllCities()` | - | `FlatCity[]` | All cities, flattened |
|
|
232
|
+
| `getProvinceOfCity(cityQuery)` | `string` | `Province \| undefined` | The province a city belongs to |
|
|
233
|
+
| `searchProvinces(query, options?)` | `string, SearchOptions?` | `Province[]` | Fuzzy province search |
|
|
234
|
+
| `searchCities(query, options?)` | `string, SearchOptions?` | `FlatCity[]` | Fuzzy city search |
|
|
235
|
+
| `getStats()` | - | `{provinceCount, cityCount}` | Overall stats |
|
|
234
236
|
|
|
235
237
|
`SearchOptions`: `{ limit?: number; locale?: 'en' | 'fa' | 'both' }`
|
|
236
238
|
|
|
237
|
-
###
|
|
239
|
+
### Types
|
|
238
240
|
|
|
239
241
|
```ts
|
|
240
242
|
interface City { en: string; fa: string; }
|
|
@@ -244,14 +246,14 @@ interface FlatCity extends City { provinceEn: string; provinceFa: string; }
|
|
|
244
246
|
|
|
245
247
|
---
|
|
246
248
|
|
|
247
|
-
##
|
|
249
|
+
## Development
|
|
248
250
|
|
|
249
251
|
```bash
|
|
250
252
|
npm install
|
|
251
|
-
npm run build #
|
|
253
|
+
npm run build # outputs dist/ (cjs + esm + d.ts)
|
|
252
254
|
npm run typecheck
|
|
253
255
|
```
|
|
254
256
|
|
|
255
|
-
##
|
|
257
|
+
## License
|
|
256
258
|
|
|
257
259
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-plate/iran-cities",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "لیست کامل استانها و شهرهای ایران (فارسی/انگلیسی) بههمراه ابزارهای جستجو - بدون وابستگی، سازگار با هر فریمورک جاوااسکریپتی (React, Next.js, Vue, Angular, Node.js/Express و ...)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iran",
|
|
@@ -16,6 +16,14 @@
|
|
|
16
16
|
],
|
|
17
17
|
"author": "code-plate",
|
|
18
18
|
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/MJavadSF/Iran-Cities.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/MJavadSF/Iran-Cities#readme",
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/MJavadSF/Iran-Cities/issues"
|
|
26
|
+
},
|
|
19
27
|
"sideEffects": false,
|
|
20
28
|
"main": "./dist/index.cjs",
|
|
21
29
|
"module": "./dist/index.mjs",
|
|
@@ -60,5 +68,8 @@
|
|
|
60
68
|
},
|
|
61
69
|
"publishConfig": {
|
|
62
70
|
"access": "public"
|
|
71
|
+
},
|
|
72
|
+
"allowScripts": {
|
|
73
|
+
"esbuild@0.27.7": true
|
|
63
74
|
}
|
|
64
75
|
}
|