thaizip 0.1.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/README.md +229 -0
- package/data/thai_amphures.json +8282 -0
- package/data/thai_geographies.json +26 -0
- package/data/thai_provinces.json +695 -0
- package/data/thai_tambons.json +74532 -0
- package/dist/data.cjs +103402 -0
- package/dist/data.d.cts +22 -0
- package/dist/data.d.ts +22 -0
- package/dist/data.js +103400 -0
- package/dist/index.cjs +210 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +99 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +203 -0
- package/dist/index.js.map +1 -0
- package/package.json +73 -0
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# thaizip
|
|
2
|
+
|
|
3
|
+
ไลบรารี autocomplete ที่อยู่ไทยแบบ fuzzy search รวดเร็ว รองรับทั้ง Vanilla JS และ React
|
|
4
|
+
|
|
5
|
+
- ค้นหาได้ทั้งภาษาไทย ภาษาอังกฤษ และรหัสไปรษณีย์
|
|
6
|
+
- Fuzzy search — ไม่ต้องใส่วรรณยุกต์ก็ค้นหาได้ เช่น "ลาดพราว" เจอ "ลาดพร้าว"
|
|
7
|
+
- ไม่มี dependency นอกจาก React (optional)
|
|
8
|
+
- Index สร้างไว้ล่วงหน้า ไม่มีต้นทุนตอน runtime
|
|
9
|
+
- รองรับ ESM และ CJS
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ติดตั้ง
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install thaizip
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
ถ้าใช้กับ React ต้องมี React >= 18 เป็น peer dependency อยู่แล้ว ไม่ต้องติดตั้งเพิ่ม
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## การใช้งานพื้นฐาน (Vanilla JS / TypeScript)
|
|
24
|
+
|
|
25
|
+
### ค้นหาที่อยู่
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { defaultIndex } from 'thaizip/data'
|
|
29
|
+
import { searchThaiAddress } from 'thaizip'
|
|
30
|
+
|
|
31
|
+
// ค้นหาด้วยชื่อตำบล/อำเภอ/จังหวัด
|
|
32
|
+
const results = searchThaiAddress(defaultIndex, 'ลาดพร้าว')
|
|
33
|
+
|
|
34
|
+
// ค้นหาด้วยรหัสไปรษณีย์
|
|
35
|
+
const results = searchThaiAddress(defaultIndex, '10900')
|
|
36
|
+
|
|
37
|
+
// ค้นหาด้วยภาษาอังกฤษ
|
|
38
|
+
const results = searchThaiAddress(defaultIndex, 'chiang mai')
|
|
39
|
+
|
|
40
|
+
console.log(results)
|
|
41
|
+
// [{ tambonId, tambonNameTh, tambonNameEn, amphureId, amphureNameTh, ... zipCode }, ...]
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### ตัวเลือก (options)
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const results = searchThaiAddress(defaultIndex, 'ลาดพร้าว', {
|
|
48
|
+
limit: 5, // จำนวนผลลัพธ์สูงสุด (default: 10)
|
|
49
|
+
threshold: 0.4, // ความแม่นยำขั้นต่ำ 0–1 (default: 0.4)
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### แปลงผลลัพธ์เป็นรูปแบบต่าง ๆ
|
|
54
|
+
|
|
55
|
+
**`formatThaiAddressSuggestion`** — ใช้แสดงใน dropdown
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
import { formatThaiAddressSuggestion } from 'thaizip'
|
|
59
|
+
|
|
60
|
+
const suggestion = formatThaiAddressSuggestion(results[0])
|
|
61
|
+
// {
|
|
62
|
+
// id: '100101',
|
|
63
|
+
// label: 'ลาดพร้าว > ลาดพร้าว > กรุงเทพมหานคร 10230',
|
|
64
|
+
// tambon: 'ลาดพร้าว',
|
|
65
|
+
// amphure: 'ลาดพร้าว',
|
|
66
|
+
// province: 'กรุงเทพมหานคร',
|
|
67
|
+
// zipCode: '10230',
|
|
68
|
+
// }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**`resolveThaiAddress`** — ใช้บันทึกข้อมูลหลังผู้ใช้เลือก
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { resolveThaiAddress } from 'thaizip'
|
|
75
|
+
|
|
76
|
+
const resolved = resolveThaiAddress(results[0])
|
|
77
|
+
// {
|
|
78
|
+
// tambon: 'ลาดพร้าว', subdistrict: 'ลาดพร้าว',
|
|
79
|
+
// amphure: 'ลาดพร้าว', district: 'ลาดพร้าว',
|
|
80
|
+
// province: 'กรุงเทพมหานคร',
|
|
81
|
+
// zipCode: '10230', postalCode: '10230',
|
|
82
|
+
// }
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## การใช้งานกับ React
|
|
88
|
+
|
|
89
|
+
### `useThaiAddressAutocomplete`
|
|
90
|
+
|
|
91
|
+
Hook นี้จัดการ state ของ query, suggestions, debounce ให้ทั้งหมด
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { defaultIndex } from 'thaizip/data'
|
|
95
|
+
import { useThaiAddressAutocomplete } from 'thaizip'
|
|
96
|
+
|
|
97
|
+
function AddressForm() {
|
|
98
|
+
const { query, setQuery, suggestions, isOpen, selectSuggestion, clear } =
|
|
99
|
+
useThaiAddressAutocomplete({
|
|
100
|
+
index: defaultIndex,
|
|
101
|
+
limit: 10, // default: 10
|
|
102
|
+
debounce: 200, // default: 200ms
|
|
103
|
+
threshold: 0.4, // default: 0.4
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
const [address, setAddress] = useState(null)
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<div>
|
|
110
|
+
<input
|
|
111
|
+
value={query}
|
|
112
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
113
|
+
placeholder="พิมพ์ตำบล อำเภอ จังหวัด หรือรหัสไปรษณีย์"
|
|
114
|
+
/>
|
|
115
|
+
|
|
116
|
+
{isOpen && (
|
|
117
|
+
<ul>
|
|
118
|
+
{suggestions.map((s) => (
|
|
119
|
+
<li key={s.id} onClick={() => {
|
|
120
|
+
const resolved = selectSuggestion(s)
|
|
121
|
+
setAddress(resolved)
|
|
122
|
+
}}>
|
|
123
|
+
{s.label}
|
|
124
|
+
</li>
|
|
125
|
+
))}
|
|
126
|
+
</ul>
|
|
127
|
+
)}
|
|
128
|
+
|
|
129
|
+
{address && (
|
|
130
|
+
<div>
|
|
131
|
+
<p>ตำบล: {address.tambon}</p>
|
|
132
|
+
<p>อำเภอ: {address.amphure}</p>
|
|
133
|
+
<p>จังหวัด: {address.province}</p>
|
|
134
|
+
<p>รหัสไปรษณีย์: {address.zipCode}</p>
|
|
135
|
+
</div>
|
|
136
|
+
)}
|
|
137
|
+
</div>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Return ของ hook
|
|
143
|
+
|
|
144
|
+
| ค่า | ประเภท | คำอธิบาย |
|
|
145
|
+
|---|---|---|
|
|
146
|
+
| `query` | `string` | ข้อความที่ผู้ใช้พิมพ์อยู่ |
|
|
147
|
+
| `setQuery` | `(value: string) => void` | อัปเดต query |
|
|
148
|
+
| `suggestions` | `ThaiAddressSuggestion[]` | รายการผลลัพธ์ที่แสดงใน dropdown |
|
|
149
|
+
| `isOpen` | `boolean` | `true` เมื่อมี query และมี suggestions |
|
|
150
|
+
| `selectSuggestion` | `(item) => ResolvedThaiAddress` | เลือก suggestion แล้วได้ข้อมูลที่อยู่ครบ |
|
|
151
|
+
| `clear` | `() => void` | ล้าง query และ suggestions ทั้งหมด |
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## การใช้งานกับ Node.js / Express
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import express from 'express'
|
|
159
|
+
import { defaultIndex } from 'thaizip/data'
|
|
160
|
+
import { searchThaiAddress, formatThaiAddressSuggestion } from 'thaizip'
|
|
161
|
+
|
|
162
|
+
const app = express()
|
|
163
|
+
|
|
164
|
+
app.get('/address/search', (req, res) => {
|
|
165
|
+
const query = String(req.query.q ?? '')
|
|
166
|
+
if (!query) return res.json([])
|
|
167
|
+
|
|
168
|
+
const results = searchThaiAddress(defaultIndex, query, { limit: 10 })
|
|
169
|
+
res.json(results.map(formatThaiAddressSuggestion))
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
app.listen(3000)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
เรียกใช้งาน:
|
|
176
|
+
```
|
|
177
|
+
GET /address/search?q=ลาดพร้าว
|
|
178
|
+
GET /address/search?q=10900
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## ใช้ข้อมูล Index ของตัวเอง
|
|
184
|
+
|
|
185
|
+
หากต้องการสร้าง index จากข้อมูลที่กำหนดเอง
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { buildThaiAddressIndex } from 'thaizip'
|
|
189
|
+
|
|
190
|
+
const index = buildThaiAddressIndex({
|
|
191
|
+
geographies: [...],
|
|
192
|
+
provinces: [...],
|
|
193
|
+
amphures: [...],
|
|
194
|
+
tambons: [...],
|
|
195
|
+
})
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
รูปแบบข้อมูล raw ดูได้จาก type `RawData`, `RawProvince`, `RawAmphure`, `RawTambon` ที่ export มาจาก library
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Types หลัก
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
type ThaiAddressSuggestion = {
|
|
206
|
+
id: string
|
|
207
|
+
label: string // "ตำบล > อำเภอ > จังหวัด XXXXX"
|
|
208
|
+
tambon: string
|
|
209
|
+
amphure: string
|
|
210
|
+
province: string
|
|
211
|
+
zipCode: string
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
type ResolvedThaiAddress = {
|
|
215
|
+
tambon: string // alias: subdistrict
|
|
216
|
+
amphure: string // alias: district
|
|
217
|
+
province: string
|
|
218
|
+
zipCode: string // alias: postalCode
|
|
219
|
+
subdistrict: string
|
|
220
|
+
district: string
|
|
221
|
+
postalCode: string
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|