pukaad-ui-lib 1.6.0 → 1.8.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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
3
  "configKey": "pukaadUI",
4
- "version": "1.6.0",
4
+ "version": "1.8.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -36,9 +36,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  description: string;
39
+ limit: number;
39
40
  options: AutocompleteOption[] | string[] | number[];
40
41
  placeholder: string;
41
- limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -36,9 +36,9 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
36
36
  id: string;
37
37
  name: string;
38
38
  description: string;
39
+ limit: number;
39
40
  options: AutocompleteOption[] | string[] | number[];
40
41
  placeholder: string;
41
- limit: number;
42
42
  disabledErrorMessage: boolean;
43
43
  disabledBorder: boolean;
44
44
  showCounter: boolean;
@@ -6,7 +6,7 @@
6
6
  <Icon name="lucide:chevron-down" />
7
7
  </div>
8
8
  </ShadPopoverTrigger>
9
- <ShadPopoverContent class="flex p-[24px] w-[425px]">
9
+ <ShadPopoverContent class="flex p-[24px] w-[425px] h-full">
10
10
  <ShadCommand>
11
11
  <div class="space-y-[22px]">
12
12
  <div class="font-title-medium-prominent">เลือกจังหวัด</div>
@@ -16,26 +16,56 @@
16
16
  <Icon name="lucide:search" />
17
17
  </template>
18
18
  </InputTextField>
19
- <ShadCommandList>
19
+ <ShadCommandList class="h-[550px]">
20
20
  <div class="flex flex-col gap-[16px]">
21
21
  <div class="flex flex-col gap-[8px]">
22
22
  <div>ปลายทางยอดนิยม</div>
23
- <ShadCarousel>
24
- <ShadCarouselContent>
25
- <ShadCarouselItem
26
- v-for="province in provinces"
27
- :key="province.value"
28
- @select="selectProvince(province.value)"
29
- >
30
- <img
31
- :src="
32
- province.image_cover_url || 'https://placehold.co/292x164?text=Place+Photo'
23
+ <div class="relative">
24
+ <ShadCarousel>
25
+ <ShadCarouselContent>
26
+ <ShadCarouselItem
27
+ v-for="province in provinces"
28
+ :key="province.value"
29
+ class="flex cursor-pointer basis-1/3.5"
30
+ @click="selectProvince(province.value)"
31
+ >
32
+ <Card
33
+ class="relative overflow-hidden bg-mercury w-[140px] h-[180px]"
34
+ >
35
+ <!-- No image state -->
36
+ <template v-if="province.image_cover_url === null">
37
+ <div class="font-medium">
38
+ {{ province.label }}
39
+ </div>
40
+ <div
41
+ class="flex flex-col items-center justify-center gap-[4px] h-full mt-2"
42
+ >
43
+ <Icon name="lucide:image" size="28" />
44
+ <div class="text-gray">ไม่มีรูป</div>
45
+ </div>
46
+ </template>
47
+
48
+ <!-- Has image state -->
49
+ <template v-else>
50
+ <img
51
+ :src="
52
+ province.image_cover_url || 'https://placehold.co/140x180?text=Place+Photo'
33
53
  "
34
- />
35
- <div>{{ province.label }}</div>
36
- </ShadCarouselItem>
37
- </ShadCarouselContent>
38
- </ShadCarousel>
54
+ class="w-[140px] h-[180px] object-cover"
55
+ />
56
+ <div
57
+ class="absolute top-0 left-0 right-0 p-2 font-medium text-white bg-gradient-to-b from-black/70 to-transparent"
58
+ >
59
+ {{ province.label }}
60
+ </div>
61
+ </template>
62
+ </Card>
63
+ </ShadCarouselItem>
64
+ </ShadCarouselContent>
65
+ <ShadCarouselPrevious class="left-0" />
66
+ <ShadCarouselNext class="right-0" />
67
+ </ShadCarousel>
68
+ </div>
39
69
  </div>
40
70
  <ShadCommandGroup>
41
71
  <ShadCommandItem
@@ -80,10 +110,11 @@ const fetchProvinces = async () => {
80
110
  );
81
111
  const data = response.data ?? response;
82
112
  if (data && Array.isArray(data)) {
83
- provinces.value = data.map((p) => ({
113
+ provinces.value = data.filter((p) => p.is_active === true).map((p) => ({
84
114
  value: String(p.id),
85
115
  label: p.name_th,
86
- image_cover_url: p.image_cover_url ?? ""
116
+ image_cover_url: p.image_cover_url ?? null,
117
+ domain: p.domain ?? null
87
118
  }));
88
119
  }
89
120
  } catch (error) {
@@ -97,6 +128,11 @@ const selectedLabel = computed(() => {
97
128
  const selectProvince = (value) => {
98
129
  modelValue.value = value;
99
130
  open.value = false;
131
+ const selected = provinces.value.find((p) => p.value === value);
132
+ if (selected?.domain) {
133
+ const url = selected.domain.startsWith("http") ? selected.domain : `https://${selected.domain}`;
134
+ window.location.href = url;
135
+ }
100
136
  };
101
137
  onMounted(() => {
102
138
  fetchProvinces();
@@ -1,19 +1,10 @@
1
1
  <template>
2
- <ShadPagination
3
- v-slot="{ page }"
4
- :items-per-page="itemPerPage"
5
- :total="props.totalPage"
6
- v-model:page="pageModel"
7
- >
2
+ <ShadPagination v-slot="{ page }" :items-per-page="itemPerPage" :total="props.totalPage" v-model:page="pageModel">
8
3
  <ShadPaginationContent v-slot="{ items }">
9
4
  <ShadPaginationFirst />
10
5
  <ShadPaginationPrevious />
11
6
  <template v-for="(item, index) in items" :key="index">
12
- <ShadPaginationItem
13
- v-if="item.type === 'page'"
14
- :value="item.value"
15
- :is-active="item.value === page"
16
- >
7
+ <ShadPaginationItem v-if="item.type === 'page'" :value="item.value" :is-active="item.value === page">
17
8
  {{ item.value }}
18
9
  </ShadPaginationItem>
19
10
  </template>
@@ -31,11 +22,7 @@
31
22
  </Button>
32
23
  </ShadDropdownMenuTrigger>
33
24
  <ShadDropdownMenuContent class="max-h-96">
34
- <ShadDropdownMenuItem
35
- v-for="n in [10, 50, 100]"
36
- :key="n"
37
- @click="onSlectItemPerPage(n)"
38
- >
25
+ <ShadDropdownMenuItem v-for="n in [10, 50, 100]" :key="n" @click="onSlectItemPerPage(n)">
39
26
  {{ n }} / หน้า
40
27
  </ShadDropdownMenuItem>
41
28
  </ShadDropdownMenuContent>
@@ -56,5 +43,6 @@ const pageModel = defineModel({ type: Number, ...{
56
43
  const itemPerPage = ref(10);
57
44
  const onSlectItemPerPage = (value) => {
58
45
  itemPerPage.value = value;
46
+ emits("change-item-per-page", value);
59
47
  };
60
48
  </script>
@@ -1,14 +1,11 @@
1
1
  <template>
2
2
  <Form v-slot="{ meta }" @submit="onSubmit">
3
- <div
4
- data-slot="card"
5
- :class="
3
+ <div data-slot="card" :class="
6
4
  cn(
7
- 'bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-4',
5
+ 'bg-card text-card-foreground flex flex-col gap-6 rounded-xl py-4',
8
6
  props.class
9
7
  )
10
- "
11
- >
8
+ ">
12
9
  <slot name="default" :meta="meta" />
13
10
  </div>
14
11
  </Form>
@@ -16,7 +16,7 @@ const { orientation, canScrollNext, scrollNext } = useCarousel();
16
16
  :disabled="!canScrollNext"
17
17
  :class="
18
18
  cn(
19
- 'absolute size-8 rounded-full',
19
+ 'absolute size-8 rounded-full bg-white text-primary shadow-lg',
20
20
  orientation === 'horizontal' ? 'top-1/2 -right-12 -translate-y-1/2' : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
21
21
  props.class
22
22
  )
@@ -16,7 +16,7 @@ const { orientation, canScrollPrev, scrollPrev } = useCarousel();
16
16
  :disabled="!canScrollPrev"
17
17
  :class="
18
18
  cn(
19
- 'absolute size-8 rounded-full',
19
+ 'absolute size-8 rounded-full bg-white text-primary shadow-lg',
20
20
  orientation === 'horizontal' ? 'top-1/2 -left-12 -translate-y-1/2' : '-top-12 left-1/2 -translate-x-1/2 rotate-90',
21
21
  props.class
22
22
  )
@@ -47,8 +47,7 @@ function filterItems() {
47
47
  for (const [id, value] of allItems.value) {
48
48
  const score = contains(value, filterState.search);
49
49
  filterState.filtered.items.set(id, score ? 1 : 0);
50
- if (score)
51
- itemCount++;
50
+ if (score) itemCount++;
52
51
  }
53
52
  for (const [groupId, group] of allGroups.value) {
54
53
  for (const itemId of group) {
@@ -60,9 +59,12 @@ function filterItems() {
60
59
  }
61
60
  filterState.filtered.count = itemCount;
62
61
  }
63
- watch(() => filterState.search, () => {
64
- filterItems();
65
- });
62
+ watch(
63
+ () => filterState.search,
64
+ () => {
65
+ filterItems();
66
+ }
67
+ );
66
68
  provideCommandContext({
67
69
  allItems,
68
70
  allGroups,
@@ -74,7 +76,12 @@ provideCommandContext({
74
76
  <ListboxRoot
75
77
  data-slot="command"
76
78
  v-bind="forwarded"
77
- :class="cn('bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md', props.class)"
79
+ :class="
80
+ cn(
81
+ 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',
82
+ props.class
83
+ )
84
+ "
78
85
  >
79
86
  <slot />
80
87
  </ListboxRoot>
@@ -15,12 +15,7 @@ const forwarded = useForwardProps(delegatedProps);
15
15
  <ListboxContent
16
16
  data-slot="command-list"
17
17
  v-bind="forwarded"
18
- :class="
19
- cn(
20
- 'max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto',
21
- props.class
22
- )
23
- "
18
+ :class="cn('scroll-py-1 overflow-x-hidden overflow-y-auto', props.class)"
24
19
  >
25
20
  <div role="presentation">
26
21
  <slot />
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",