pukaad-ui-lib 1.39.0 → 1.40.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.
Files changed (26) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/drawer/drawer.d.vue.ts +1 -1
  3. package/dist/runtime/components/drawer/drawer.vue +2 -2
  4. package/dist/runtime/components/drawer/drawer.vue.d.ts +1 -1
  5. package/dist/runtime/components/input/input-address.d.vue.ts +1 -74
  6. package/dist/runtime/components/input/input-address.vue +75 -480
  7. package/dist/runtime/components/input/input-address.vue.d.ts +1 -74
  8. package/dist/runtime/components/input/input-autocomplete.vue +2 -2
  9. package/dist/runtime/components/input/input-combobox.d.vue.ts +4 -5
  10. package/dist/runtime/components/input/input-combobox.vue +131 -122
  11. package/dist/runtime/components/input/input-combobox.vue.d.ts +4 -5
  12. package/dist/runtime/components/input/input-text-field.d.vue.ts +1 -1
  13. package/dist/runtime/components/input/input-text-field.vue.d.ts +1 -1
  14. package/dist/runtime/components/input/input-textarea.d.vue.ts +1 -1
  15. package/dist/runtime/components/input/input-textarea.vue.d.ts +1 -1
  16. package/dist/runtime/components/loading.d.vue.ts +2 -4
  17. package/dist/runtime/components/loading.vue +4 -8
  18. package/dist/runtime/components/loading.vue.d.ts +2 -4
  19. package/dist/runtime/components/modal/modal-share.vue +1 -1
  20. package/dist/runtime/components/modal/modal.d.vue.ts +2 -1
  21. package/dist/runtime/components/modal/modal.vue +2 -2
  22. package/dist/runtime/components/modal/modal.vue.d.ts +2 -1
  23. package/dist/runtime/components/ui/input-group/InputGroupButton.d.vue.ts +1 -1
  24. package/dist/runtime/components/ui/input-group/InputGroupButton.vue.d.ts +1 -1
  25. package/dist/runtime/components/ui/input-group/index.d.ts +1 -1
  26. package/package.json +1 -1
@@ -1,492 +1,87 @@
1
1
  <template>
2
- <div class="space-y-4">
3
- <!-- Address Selector (Province, District, Sub-district, Zip code) -->
4
- <ShadFormField
5
- ref="addressFieldRef"
6
- :name="props.name"
7
- :rules="props.rules || defaultRules"
8
- v-slot="{ componentField }"
9
- v-model="addressValue"
10
- >
11
- <ShadFormItem>
12
- <ShadFormLabel v-if="props.label" class="w-full">
13
- <div class="flex-1">
14
- {{ props.label }}
15
- <span v-if="props.required" class="text-destructive">*</span>
16
- </div>
17
- </ShadFormLabel>
18
- <ShadPopover v-model:open="popoverOpen" v-bind="componentField">
19
- <ShadPopoverTrigger as-child>
20
- <ShadFormControl>
21
- <ShadButton
22
- variant="outline"
23
- role="combobox"
24
- class="w-full justify-between text-start"
2
+ <!-- <div class="space-y-[16px]">
3
+ <Dropdown full-width v-model="isOpen">
4
+ <InputTextField
5
+ name="address"
6
+ label="จังหวัด, อำเภอ/เขต, ตำบล/แขวง, รหัสไปรษณีย์"
7
+ placeholder="จังหวัด, อำเภอ/เขต, ตำบล/แขวง, รหัสไปรษณีย์"
8
+ input-class="cursor-pointer"
9
+ readonly
10
+ :full-width="props.fullWidth"
11
+ append-icon="solar:alt-arrow-down-line-duotone"
12
+ v-model="addressValue"
13
+ />
14
+ <template #content>
15
+ <Tab
16
+ :items="typeAddress"
17
+ type="text"
18
+ tab-content-gab="0"
19
+ v-model="tabValue"
20
+ >
21
+ <template #tab-content-provinces>
22
+ <ul class="h-96 overflow-y-auto">
23
+ <li
24
+ v-for="(pro, i_pro) in getProvince()"
25
+ :key="i_pro"
26
+ class="p-2 border-b-[1px] border-mercury cursor-pointer"
27
+ @click="onSelectProvince(pro)"
25
28
  >
26
- <span :class="{ 'text-cloud': !addressValue }">
27
- {{ addressValue || props.placeholder }}
28
- </span>
29
- <Icon name="lucide:chevron-down" class="h-4 w-4" />
30
- </ShadButton>
31
- </ShadFormControl>
32
- </ShadPopoverTrigger>
33
- <ShadPopoverContent class="w-[400px] p-0">
34
- <ShadCommand>
35
- <ShadCommandInput
36
- v-model="searchQuery"
37
- placeholder="ค้นหาที่อยู่"
38
- />
39
- <ShadTabs v-model="currentTab" class="w-full">
40
- <ShadTabsList class="w-full grid grid-cols-4 rounded-none">
41
- <ShadTabsTrigger value="province" class="rounded-none">
42
- จังหวัด
43
- </ShadTabsTrigger>
44
- <ShadTabsTrigger
45
- value="district"
46
- :disabled="!selectedProvince"
47
- class="rounded-none"
48
- >
49
- อำเภอ/เขต
50
- </ShadTabsTrigger>
51
- <ShadTabsTrigger
52
- value="subDistrict"
53
- :disabled="!selectedDistrict"
54
- class="rounded-none"
55
- >
56
- ตำบล/แขวง
57
- </ShadTabsTrigger>
58
- <ShadTabsTrigger
59
- value="zipCode"
60
- :disabled="!selectedSubDistrict"
61
- class="rounded-none"
62
- >
63
- รหัสไปรษณีย์
64
- </ShadTabsTrigger>
65
- </ShadTabsList>
29
+ {{ pro.name_th }}
30
+ </li>
31
+ </ul>
32
+ </template>
66
33
 
67
- <!-- Province Tab -->
68
- <ShadTabsContent value="province" class="m-0">
69
- <ShadCommandList class="max-h-64">
70
- <ShadCommandGroup>
71
- <ShadCommandItem
72
- v-for="province in filteredProvinces"
73
- :key="province.code"
74
- :value="province.name_th"
75
- @select="onSelectProvince(province)"
76
- >
77
- {{ province.name_th }}
78
- <Icon
79
- v-if="selectedProvince?.code === province.code"
80
- name="lucide:check"
81
- class="ml-auto h-4 w-4"
82
- />
83
- </ShadCommandItem>
84
- </ShadCommandGroup>
85
- <ShadCommandEmpty>ไม่พบจังหวัด</ShadCommandEmpty>
86
- </ShadCommandList>
87
- </ShadTabsContent>
88
-
89
- <!-- District Tab -->
90
- <ShadTabsContent value="district" class="m-0">
91
- <ShadCommandList class="max-h-64">
92
- <ShadCommandGroup>
93
- <ShadCommandItem
94
- v-for="district in filteredDistricts"
95
- :key="district.code"
96
- :value="district.name_th"
97
- @select="onSelectDistrict(district)"
98
- >
99
- {{ district.name_th }}
100
- <Icon
101
- v-if="selectedDistrict?.code === district.code"
102
- name="lucide:check"
103
- class="ml-auto h-4 w-4"
104
- />
105
- </ShadCommandItem>
106
- </ShadCommandGroup>
107
- <ShadCommandEmpty>ไม่พบอำเภอ/เขต</ShadCommandEmpty>
108
- </ShadCommandList>
109
- </ShadTabsContent>
110
-
111
- <!-- Sub-district Tab -->
112
- <ShadTabsContent value="subDistrict" class="m-0">
113
- <ShadCommandList class="max-h-64">
114
- <ShadCommandGroup>
115
- <ShadCommandItem
116
- v-for="subDistrict in filteredSubDistricts"
117
- :key="subDistrict.code"
118
- :value="subDistrict.name_th"
119
- @select="onSelectSubDistrict(subDistrict)"
120
- >
121
- {{ subDistrict.name_th }}
122
- <Icon
123
- v-if="selectedSubDistrict?.code === subDistrict.code"
124
- name="lucide:check"
125
- class="ml-auto h-4 w-4"
126
- />
127
- </ShadCommandItem>
128
- </ShadCommandGroup>
129
- <ShadCommandEmpty>ไม่พบตำบล/แขวง</ShadCommandEmpty>
130
- </ShadCommandList>
131
- </ShadTabsContent>
34
+ <template #tab-content-districts>
35
+ <ul class="h-96 overflow-y-auto">
36
+ <li
37
+ v-for="(dist, i_dist) in getDistrict({ pro_code: provineCode })"
38
+ :key="i_dist"
39
+ class="p-2 border-b-[1px] border-mercury cursor-pointer"
40
+ @click="onSelectDistrict(dist)"
41
+ >
42
+ {{ dist.name_th }}
43
+ </li>
44
+ </ul>
45
+ </template>
132
46
 
133
- <!-- Zip Code Tab -->
134
- <ShadTabsContent value="zipCode" class="m-0">
135
- <ShadCommandList class="max-h-64">
136
- <ShadCommandGroup>
137
- <ShadCommandItem
138
- v-if="selectedSubDistrict"
139
- :value="selectedSubDistrict.zip_code.toString()"
140
- @select="onSelectZipCode"
141
- >
142
- {{ selectedSubDistrict.zip_code }}
143
- <Icon name="lucide:check" class="ml-auto h-4 w-4" />
144
- </ShadCommandItem>
145
- </ShadCommandGroup>
146
- <ShadCommandEmpty>ไม่พบรหัสไปรษณีย์</ShadCommandEmpty>
147
- </ShadCommandList>
148
- </ShadTabsContent>
149
- </ShadTabs>
150
- </ShadCommand>
151
- </ShadPopoverContent>
152
- </ShadPopover>
153
- <ShadFormMessage />
154
- </ShadFormItem>
155
- </ShadFormField>
47
+ <template #tab-content-sub-districts>
48
+ <ul class="h-96 overflow-y-auto">
49
+ <li
50
+ v-for="(sub, i_sub) in getSubDistrict({
51
+ dist_code: districtCode,
52
+ })"
53
+ :key="i_sub"
54
+ class="p-2 border-b-[1px] border-mercury cursor-pointer"
55
+ @click="onSelectSubDistrict(sub)"
56
+ >
57
+ {{ sub.name_th }}
58
+ </li>
59
+ </ul>
60
+ </template>
156
61
 
157
- <!-- Address Detail (House number, Soi, Moo, Road) -->
62
+ <template #tab-content-zip-code>
63
+ <ul class="h-96 overflow-y-auto">
64
+ <li
65
+ class="p-2 border-b-[1px] border-mercury cursor-pointer"
66
+ @click="onSelectZipCode"
67
+ >
68
+ {{ zipCode }}
69
+ </li>
70
+ </ul>
71
+ </template>
72
+ </Tab>
73
+ </template>
74
+ </Dropdown>
158
75
  <InputTextField
159
- ref="detailFieldRef"
160
- :name="`${props.name}-detail`"
161
- :label="props.labelDetail"
162
- :placeholder="props.placeholderDetail"
163
- :disabled="!addressValue"
164
- :required="props.requiredDetail"
76
+ label="บ้านเลขที่, ซอย, หมู่, ถนน"
77
+ placeholder="บ้านเลขที่, ซอย, หมู่, ถนน"
78
+ :full-width="props.fullWidth"
79
+ :disabled="isDisabledAddressDetail"
165
80
  v-model="addressDetailValue"
166
81
  />
167
- </div>
82
+ </div> -->
168
83
  </template>
169
84
 
170
85
  <script setup>
171
- import { ref, computed, watch } from "vue";
172
- import InputTextField from "./input-text-field.vue";
173
- const props = defineProps({
174
- name: { type: String, required: false, default: "address" },
175
- label: { type: String, required: false, default: "\u0E08\u0E31\u0E07\u0E2B\u0E27\u0E31\u0E14, \u0E2D\u0E33\u0E40\u0E20\u0E2D/\u0E40\u0E02\u0E15, \u0E15\u0E33\u0E1A\u0E25/\u0E41\u0E02\u0E27\u0E07, \u0E23\u0E2B\u0E31\u0E2A\u0E44\u0E1B\u0E23\u0E29\u0E13\u0E35\u0E22\u0E4C" },
176
- placeholder: { type: String, required: false, default: "\u0E08\u0E31\u0E07\u0E2B\u0E27\u0E31\u0E14, \u0E2D\u0E33\u0E40\u0E20\u0E2D/\u0E40\u0E02\u0E15, \u0E15\u0E33\u0E1A\u0E25/\u0E41\u0E02\u0E27\u0E07, \u0E23\u0E2B\u0E31\u0E2A\u0E44\u0E1B\u0E23\u0E29\u0E13\u0E35\u0E22\u0E4C" },
177
- labelDetail: { type: String, required: false, default: "\u0E1A\u0E49\u0E32\u0E19\u0E40\u0E25\u0E02\u0E17\u0E35\u0E48, \u0E0B\u0E2D\u0E22, \u0E2B\u0E21\u0E39\u0E48, \u0E16\u0E19\u0E19" },
178
- placeholderDetail: { type: String, required: false, default: "\u0E1A\u0E49\u0E32\u0E19\u0E40\u0E25\u0E02\u0E17\u0E35\u0E48, \u0E0B\u0E2D\u0E22, \u0E2B\u0E21\u0E39\u0E48, \u0E16\u0E19\u0E19" },
179
- required: { type: Boolean, required: false, default: false },
180
- requiredDetail: { type: Boolean, required: false, default: false },
181
- rules: { type: [Object, String, Function], required: false },
182
- provinces: { type: Array, required: false },
183
- districts: { type: Array, required: false },
184
- subDistricts: { type: Array, required: false }
185
- });
186
- const emits = defineEmits(["selectProvince", "selectDistrict", "selectSubDistrict", "selectZipCode", "change"]);
187
- const modelValue = defineModel({ type: Object, ...{
188
- default: () => ({})
189
- } });
190
- const popoverOpen = ref(false);
191
- const currentTab = ref("province");
192
- const searchQuery = ref("");
193
- const addressFieldRef = ref();
194
- const detailFieldRef = ref();
195
- const selectedProvince = ref(null);
196
- const selectedDistrict = ref(null);
197
- const selectedSubDistrict = ref(null);
198
- const addressValue = computed(() => {
199
- const parts = [];
200
- if (selectedProvince.value) parts.push(selectedProvince.value.name_th);
201
- if (selectedDistrict.value) parts.push(selectedDistrict.value.name_th);
202
- if (selectedSubDistrict.value) parts.push(selectedSubDistrict.value.name_th);
203
- if (selectedSubDistrict.value)
204
- parts.push(selectedSubDistrict.value.zip_code.toString());
205
- return parts.join(", ");
206
- });
207
- const addressDetailValue = ref("");
208
- const mockProvinces = props.provinces || [
209
- { code: 10, name_th: "\u0E01\u0E23\u0E38\u0E07\u0E40\u0E17\u0E1E\u0E21\u0E2B\u0E32\u0E19\u0E04\u0E23", name_en: "Bangkok" },
210
- { code: 11, name_th: "\u0E2A\u0E21\u0E38\u0E17\u0E23\u0E1B\u0E23\u0E32\u0E01\u0E32\u0E23", name_en: "Samut Prakan" },
211
- { code: 12, name_th: "\u0E19\u0E19\u0E17\u0E1A\u0E38\u0E23\u0E35", name_en: "Nonthaburi" },
212
- { code: 13, name_th: "\u0E1B\u0E17\u0E38\u0E21\u0E18\u0E32\u0E19\u0E35", name_en: "Pathum Thani" },
213
- { code: 14, name_th: "\u0E1E\u0E23\u0E30\u0E19\u0E04\u0E23\u0E28\u0E23\u0E35\u0E2D\u0E22\u0E38\u0E18\u0E22\u0E32", name_en: "Phra Nakhon Si Ayutthaya" },
214
- { code: 20, name_th: "\u0E0A\u0E25\u0E1A\u0E38\u0E23\u0E35", name_en: "Chon Buri" },
215
- { code: 50, name_th: "\u0E40\u0E0A\u0E35\u0E22\u0E07\u0E43\u0E2B\u0E21\u0E48", name_en: "Chiang Mai" }
216
- ];
217
- const mockDistricts = props.districts || [
218
- // กรุงเทพมหานคร
219
- {
220
- code: 1001,
221
- name_th: "\u0E40\u0E02\u0E15\u0E1E\u0E23\u0E30\u0E19\u0E04\u0E23",
222
- name_en: "Phra Nakhon",
223
- province_code: 10
224
- },
225
- { code: 1002, name_th: "\u0E40\u0E02\u0E15\u0E14\u0E38\u0E2A\u0E34\u0E15", name_en: "Dusit", province_code: 10 },
226
- {
227
- code: 1003,
228
- name_th: "\u0E40\u0E02\u0E15\u0E2B\u0E19\u0E2D\u0E07\u0E08\u0E2D\u0E01",
229
- name_en: "Nong Chok",
230
- province_code: 10
231
- },
232
- { code: 1004, name_th: "\u0E40\u0E02\u0E15\u0E1A\u0E32\u0E07\u0E23\u0E31\u0E01", name_en: "Bang Rak", province_code: 10 },
233
- { code: 1005, name_th: "\u0E40\u0E02\u0E15\u0E1A\u0E32\u0E07\u0E40\u0E02\u0E19", name_en: "Bang Khen", province_code: 10 },
234
- {
235
- code: 1006,
236
- name_th: "\u0E40\u0E02\u0E15\u0E1A\u0E32\u0E07\u0E01\u0E30\u0E1B\u0E34",
237
- name_en: "Bang Kapi",
238
- province_code: 10
239
- },
240
- {
241
- code: 1007,
242
- name_th: "\u0E40\u0E02\u0E15\u0E1B\u0E17\u0E38\u0E21\u0E27\u0E31\u0E19",
243
- name_en: "Pathum Wan",
244
- province_code: 10
245
- },
246
- // สมุทรปราการ
247
- {
248
- code: 1101,
249
- name_th: "\u0E2D\u0E33\u0E40\u0E20\u0E2D\u0E40\u0E21\u0E37\u0E2D\u0E07\u0E2A\u0E21\u0E38\u0E17\u0E23\u0E1B\u0E23\u0E32\u0E01\u0E32\u0E23",
250
- name_en: "Mueang Samut Prakan",
251
- province_code: 11
252
- },
253
- { code: 1102, name_th: "\u0E2D\u0E33\u0E40\u0E20\u0E2D\u0E1A\u0E32\u0E07\u0E1A\u0E48\u0E2D", name_en: "Bang Bo", province_code: 11 },
254
- // นนทบุรี
255
- {
256
- code: 1201,
257
- name_th: "\u0E2D\u0E33\u0E40\u0E20\u0E2D\u0E40\u0E21\u0E37\u0E2D\u0E07\u0E19\u0E19\u0E17\u0E1A\u0E38\u0E23\u0E35",
258
- name_en: "Mueang Nonthaburi",
259
- province_code: 12
260
- },
261
- {
262
- code: 1202,
263
- name_th: "\u0E2D\u0E33\u0E40\u0E20\u0E2D\u0E1A\u0E32\u0E07\u0E01\u0E23\u0E27\u0E22",
264
- name_en: "Bang Kruai",
265
- province_code: 12
266
- }
267
- ];
268
- const mockSubDistricts = props.subDistricts || [
269
- // เขตพระนคร
270
- {
271
- code: 100101,
272
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E1E\u0E23\u0E30\u0E1A\u0E23\u0E21\u0E21\u0E2B\u0E32\u0E23\u0E32\u0E0A\u0E27\u0E31\u0E07",
273
- name_en: "Phra Borom Maha Ratchawang",
274
- district_code: 1001,
275
- zip_code: 10200
276
- },
277
- {
278
- code: 100102,
279
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E27\u0E31\u0E07\u0E1A\u0E39\u0E23\u0E1E\u0E32\u0E20\u0E34\u0E23\u0E21\u0E22\u0E4C",
280
- name_en: "Wang Burapha Phirom",
281
- district_code: 1001,
282
- zip_code: 10200
283
- },
284
- {
285
- code: 100103,
286
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E27\u0E31\u0E14\u0E23\u0E32\u0E0A\u0E1A\u0E1E\u0E34\u0E18",
287
- name_en: "Wat Ratchabophit",
288
- district_code: 1001,
289
- zip_code: 10200
290
- },
291
- // เขตดุสิต
292
- {
293
- code: 100201,
294
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E14\u0E38\u0E2A\u0E34\u0E15",
295
- name_en: "Dusit",
296
- district_code: 1002,
297
- zip_code: 10300
298
- },
299
- {
300
- code: 100202,
301
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E27\u0E0A\u0E34\u0E23\u0E1E\u0E22\u0E32\u0E1A\u0E32\u0E25",
302
- name_en: "Wachiraphayaban",
303
- district_code: 1002,
304
- zip_code: 10300
305
- },
306
- // เขตบางรัก
307
- {
308
- code: 100401,
309
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E21\u0E2B\u0E32\u0E1E\u0E24\u0E12\u0E32\u0E23\u0E32\u0E21",
310
- name_en: "Maha Phruettharam",
311
- district_code: 1004,
312
- zip_code: 10500
313
- },
314
- {
315
- code: 100402,
316
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E2A\u0E35\u0E25\u0E21",
317
- name_en: "Si Lom",
318
- district_code: 1004,
319
- zip_code: 10500
320
- },
321
- // เขตปทุมวัน
322
- {
323
- code: 100701,
324
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E23\u0E2D\u0E07\u0E40\u0E21\u0E37\u0E2D\u0E07",
325
- name_en: "Rong Mueang",
326
- district_code: 1007,
327
- zip_code: 10330
328
- },
329
- {
330
- code: 100702,
331
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E27\u0E31\u0E07\u0E43\u0E2B\u0E21\u0E48",
332
- name_en: "Wang Mai",
333
- district_code: 1007,
334
- zip_code: 10330
335
- },
336
- {
337
- code: 100703,
338
- name_th: "\u0E41\u0E02\u0E27\u0E07\u0E1B\u0E17\u0E38\u0E21\u0E27\u0E31\u0E19",
339
- name_en: "Pathum Wan",
340
- district_code: 1007,
341
- zip_code: 10330
342
- },
343
- // อำเภอเมืองสมุทรปราการ
344
- {
345
- code: 110101,
346
- name_th: "\u0E15\u0E33\u0E1A\u0E25\u0E1B\u0E32\u0E01\u0E19\u0E49\u0E33",
347
- name_en: "Pak Nam",
348
- district_code: 1101,
349
- zip_code: 10270
350
- },
351
- {
352
- code: 110102,
353
- name_th: "\u0E15\u0E33\u0E1A\u0E25\u0E2A\u0E33\u0E42\u0E23\u0E07\u0E40\u0E2B\u0E19\u0E37\u0E2D",
354
- name_en: "Samrong Nuea",
355
- district_code: 1101,
356
- zip_code: 10270
357
- },
358
- // อำเภอเมืองนนทบุรี
359
- {
360
- code: 120101,
361
- name_th: "\u0E15\u0E33\u0E1A\u0E25\u0E2A\u0E27\u0E19\u0E43\u0E2B\u0E0D\u0E48",
362
- name_en: "Suan Yai",
363
- district_code: 1201,
364
- zip_code: 11e3
365
- },
366
- {
367
- code: 120102,
368
- name_th: "\u0E15\u0E33\u0E1A\u0E25\u0E15\u0E25\u0E32\u0E14\u0E02\u0E27\u0E31\u0E0D",
369
- name_en: "Talat Khwan",
370
- district_code: 1201,
371
- zip_code: 11e3
372
- }
373
- ];
374
- const filteredProvinces = computed(() => {
375
- if (!searchQuery.value) return mockProvinces;
376
- const query = searchQuery.value.toLowerCase();
377
- return mockProvinces.filter(
378
- (p) => p.name_th.toLowerCase().includes(query) || p.name_en.toLowerCase().includes(query)
379
- );
380
- });
381
- const filteredDistricts = computed(() => {
382
- if (!selectedProvince.value) return [];
383
- const districts = mockDistricts.filter(
384
- (d) => d.province_code === selectedProvince.value?.code
385
- );
386
- if (!searchQuery.value) return districts;
387
- const query = searchQuery.value.toLowerCase();
388
- return districts.filter(
389
- (d) => d.name_th.toLowerCase().includes(query) || d.name_en.toLowerCase().includes(query)
390
- );
391
- });
392
- const filteredSubDistricts = computed(() => {
393
- if (!selectedDistrict.value) return [];
394
- const subDistricts = mockSubDistricts.filter(
395
- (s) => s.district_code === selectedDistrict.value?.code
396
- );
397
- if (!searchQuery.value) return subDistricts;
398
- const query = searchQuery.value.toLowerCase();
399
- return subDistricts.filter(
400
- (s) => s.name_th.toLowerCase().includes(query) || s.name_en.toLowerCase().includes(query)
401
- );
402
- });
403
- const onSelectProvince = (province) => {
404
- selectedProvince.value = province;
405
- selectedDistrict.value = null;
406
- selectedSubDistrict.value = null;
407
- searchQuery.value = "";
408
- currentTab.value = "district";
409
- emits("selectProvince", province);
410
- updateModelValue();
411
- };
412
- const onSelectDistrict = (district) => {
413
- selectedDistrict.value = district;
414
- selectedSubDistrict.value = null;
415
- searchQuery.value = "";
416
- currentTab.value = "subDistrict";
417
- emits("selectDistrict", district);
418
- updateModelValue();
419
- };
420
- const onSelectSubDistrict = (subDistrict) => {
421
- selectedSubDistrict.value = subDistrict;
422
- searchQuery.value = "";
423
- currentTab.value = "zipCode";
424
- emits("selectSubDistrict", subDistrict);
425
- updateModelValue();
426
- };
427
- const onSelectZipCode = () => {
428
- if (selectedSubDistrict.value) {
429
- emits("selectZipCode", selectedSubDistrict.value.zip_code);
430
- popoverOpen.value = false;
431
- currentTab.value = "province";
432
- updateModelValue();
433
- }
434
- };
435
- const updateModelValue = () => {
436
- const value = {
437
- province: selectedProvince.value || void 0,
438
- district: selectedDistrict.value || void 0,
439
- subDistrict: selectedSubDistrict.value || void 0,
440
- zipCode: selectedSubDistrict.value?.zip_code,
441
- detail: addressDetailValue.value || void 0,
442
- fullAddress: buildFullAddress()
443
- };
444
- modelValue.value = value;
445
- emits("change", value);
446
- };
447
- const buildFullAddress = () => {
448
- const parts = [];
449
- if (addressDetailValue.value) parts.push(addressDetailValue.value);
450
- if (selectedSubDistrict.value) parts.push(selectedSubDistrict.value.name_th);
451
- if (selectedDistrict.value) parts.push(selectedDistrict.value.name_th);
452
- if (selectedProvince.value) parts.push(selectedProvince.value.name_th);
453
- if (selectedSubDistrict.value)
454
- parts.push(selectedSubDistrict.value.zip_code.toString());
455
- return parts.join(" ");
456
- };
457
- watch(addressDetailValue, () => {
458
- updateModelValue();
459
- });
460
- const defaultRules = (v) => {
461
- if (!v && props.required) {
462
- return "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48";
463
- }
464
- if (v && v.split(", ").length < 4 && props.required) {
465
- return "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48\u0E43\u0E2B\u0E49\u0E04\u0E23\u0E1A\u0E16\u0E49\u0E27\u0E19";
466
- }
467
- return true;
468
- };
469
- const validate = async () => {
470
- const addressValid = await addressFieldRef.value?.validate();
471
- const detailValid = await detailFieldRef.value?.validate?.();
472
- return addressValid?.valid !== false && detailValid !== false;
473
- };
474
- const setErrors = (errMsg) => {
475
- addressFieldRef.value?.setErrors(errMsg);
476
- };
477
- const reset = () => {
478
- selectedProvince.value = null;
479
- selectedDistrict.value = null;
480
- selectedSubDistrict.value = null;
481
- addressDetailValue.value = "";
482
- currentTab.value = "province";
483
- updateModelValue();
484
- };
485
- defineExpose({
486
- validate,
487
- setErrors,
488
- reset,
489
- addressFieldRef,
490
- detailFieldRef
491
- });
86
+
492
87
  </script>
@@ -1,76 +1,3 @@
1
- interface Province {
2
- code: number;
3
- name_th: string;
4
- name_en: string;
5
- }
6
- interface District {
7
- code: number;
8
- name_th: string;
9
- name_en: string;
10
- province_code: number;
11
- }
12
- interface SubDistrict {
13
- code: number;
14
- name_th: string;
15
- name_en: string;
16
- district_code: number;
17
- zip_code: number;
18
- }
19
- export interface InputAddressValue {
20
- province?: Province;
21
- district?: District;
22
- subDistrict?: SubDistrict;
23
- zipCode?: number;
24
- detail?: string;
25
- fullAddress?: string;
26
- }
27
- export interface InputAddressProps {
28
- name?: string;
29
- label?: string;
30
- placeholder?: string;
31
- labelDetail?: string;
32
- placeholderDetail?: string;
33
- required?: boolean;
34
- requiredDetail?: boolean;
35
- rules?: object | string | Function;
36
- provinces?: Province[];
37
- districts?: District[];
38
- subDistricts?: SubDistrict[];
39
- }
40
- type __VLS_Props = InputAddressProps;
41
- type __VLS_ModelProps = {
42
- modelValue?: InputAddressValue;
43
- };
44
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
45
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
46
- validate: () => Promise<boolean>;
47
- setErrors: (errMsg: string[]) => void;
48
- reset: () => void;
49
- addressFieldRef: import("vue").Ref<any, any>;
50
- detailFieldRef: import("vue").Ref<any, any>;
51
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
52
- "update:modelValue": (value: InputAddressValue) => any;
53
- } & {
54
- change: (value: InputAddressValue) => any;
55
- selectProvince: (province: Province) => any;
56
- selectDistrict: (district: District) => any;
57
- selectSubDistrict: (subDistrict: SubDistrict) => any;
58
- selectZipCode: (zipCode: number) => any;
59
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
60
- onChange?: ((value: InputAddressValue) => any) | undefined;
61
- "onUpdate:modelValue"?: ((value: InputAddressValue) => any) | undefined;
62
- onSelectProvince?: ((province: Province) => any) | undefined;
63
- onSelectDistrict?: ((district: District) => any) | undefined;
64
- onSelectSubDistrict?: ((subDistrict: SubDistrict) => any) | undefined;
65
- onSelectZipCode?: ((zipCode: number) => any) | undefined;
66
- }>, {
67
- label: string;
68
- required: boolean;
69
- name: string;
70
- placeholder: string;
71
- labelDetail: string;
72
- placeholderDetail: string;
73
- requiredDetail: boolean;
74
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
75
2
  declare const _default: typeof __VLS_export;
76
3
  export default _default;
@@ -14,7 +14,7 @@
14
14
  :disabled-error-message="props.disabledErrorMessage"
15
15
  autocomplete="off"
16
16
  @focus="open = true"
17
- @click="console.log('click')"
17
+ @click="open = true"
18
18
  @blur="handleBlur"
19
19
  :show-counter="props.showCounter"
20
20
  :limit="props.limit"
@@ -24,7 +24,7 @@
24
24
  @mousedown.stop.prevent="handleIconMouseDown"
25
25
  :name="modelValue ? 'lucide:x' : 'lucide:search'"
26
26
  size="16"
27
- class="cursor-pointer"
27
+ class="cursor-pointer text-black"
28
28
  />
29
29
  </template>
30
30
  </InputTextField>