pukaad-ui-lib 1.309.0 → 1.310.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.309.0",
4
+ "version": "1.310.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -4,16 +4,16 @@
4
4
  props.variant === 'text' || props.variant === 'link' ? '!p-0 !h-auto' : '',
5
5
  props.circle && 'rounded-full aspect-square',
6
6
  props.class
7
- ]" :variant="props.variant" :color="props.color" :size="resolvedSize" :type="props.type"
8
- :disabled="props.loading || props.disabled">
9
- <span class="inline-grid place-items-center">
10
- <span class="inline-flex items-center justify-center gap-[8px] [grid-area:1/1]"
11
- :class="{ invisible: props.loading }">
12
- <slot />
13
- </span>
14
- <ShadSpinner v-if="props.loading" class="[grid-area:1/1]" />
15
- </span>
16
- </ShadButton>
7
+ ]" :variant="props.variant" :color="props.color" :size="resolvedSize" :type="props.type"
8
+ :disabled="props.loading || props.disabled">
9
+ <span class="inline-grid place-items-center">
10
+ <span class="inline-flex items-center justify-center gap-[8px] [grid-area:1/1]"
11
+ :class="{ invisible: props.loading }">
12
+ <slot />
13
+ </span>
14
+ <ShadSpinner v-if="props.loading" class="[grid-area:1/1]" />
15
+ </span>
16
+ </ShadButton>
17
17
  </template>
18
18
 
19
19
  <script setup>
@@ -95,6 +95,7 @@
95
95
  v-model="isOpen"
96
96
  :items="props.item.review?.images"
97
97
  :start-index="startIndex"
98
+ :review="props.item"
98
99
  title="รูปภาพรีวิว"
99
100
  />
100
101
 
@@ -1,53 +1,51 @@
1
1
  <template>
2
- <NuxtRating
3
- :border-color="props.borderColor"
4
- :active-color="props.activeColor"
5
- :inactive-color="props.backgroundColor"
6
- :border-width="props.borderSize"
7
- :read-only="props.readonly"
8
- :rating-step="props.ratingStep"
9
- :rounded-corners="true"
10
- :rating-size="`${props.size}px`"
11
- :rating-content="[
12
- 12,
13
- 17.27,
14
- 16.15,
15
- 19.78,
16
- 17.64,
17
- 18.7,
18
- 16.54,
19
- 13.98,
20
- 20.21,
21
- 10.8,
22
- 19.64,
23
- 9.05,
24
- 14.81,
25
- 8.64,
26
- 12.92,
27
- 4.18,
28
- 11.08,
29
- 4.18,
30
- 9.19,
31
- 8.63,
32
- 4.36,
33
- 9.04,
34
- 3.79,
35
- 10.8,
36
- 7.46,
37
- 13.98,
38
- 6.36,
39
- 18.7,
40
- 7.85,
41
- 19.78,
42
- 12,
43
- 17.27
44
- ]"
45
- @rating-selected="onSelect"
46
- :rating-value="ratingValue"
47
- />
2
+ <div class="inline-flex items-center gap-0">
3
+ <svg
4
+ v-for="n in 5"
5
+ :key="n"
6
+ :width="props.size"
7
+ :height="props.size"
8
+ viewBox="4 2 16.42 20.21"
9
+ xmlns="http://www.w3.org/2000/svg"
10
+ :style="{
11
+ cursor: props.readonly ? 'default' : 'pointer',
12
+ marginRight: n < 5 ? '2px' : '0'
13
+ }"
14
+ @click="!props.readonly && onSelect(n)"
15
+ >
16
+ <defs>
17
+ <linearGradient
18
+ :id="`star-grad-${uid}-${n}`"
19
+ x1="0"
20
+ x2="100%"
21
+ y1="0"
22
+ y2="0"
23
+ >
24
+ <stop
25
+ :offset="`${getFill(n)}%`"
26
+ :stop-color="props.activeColor"
27
+ stop-opacity="1"
28
+ />
29
+ <stop
30
+ :offset="`${getFill(n)}%`"
31
+ :stop-color="props.backgroundColor"
32
+ stop-opacity="1"
33
+ />
34
+ </linearGradient>
35
+ </defs>
36
+ <polygon
37
+ points="12,17.27,16.15,19.78,17.64,18.7,16.54,13.98,20.21,10.8,19.64,9.05,14.81,8.64,12.92,4.18,11.08,4.18,9.19,8.63,4.36,9.04,3.79,10.8,7.46,13.98,6.36,18.7,7.85,19.78,12,17.27"
38
+ :fill="`url(#star-grad-${uid}-${n})`"
39
+ :stroke="props.borderSize > 0 ? props.borderColor : 'none'"
40
+ :stroke-width="props.borderSize"
41
+ stroke-linejoin="round"
42
+ />
43
+ </svg>
44
+ </div>
48
45
  </template>
49
46
 
50
47
  <script setup>
48
+ import { computed } from "vue";
51
49
  const emit = defineEmits(["select"]);
52
50
  const props = defineProps({
53
51
  readonly: { type: Boolean, required: false, default: false },
@@ -62,6 +60,13 @@ const ratingValue = defineModel({
62
60
  type: Number,
63
61
  default: 0
64
62
  });
63
+ const uid = Math.random().toString(36).slice(2, 7);
64
+ const getFill = (n) => {
65
+ const val = ratingValue.value;
66
+ if (val >= n) return 100;
67
+ if (val < n - 1) return 0;
68
+ return Math.round((val - (n - 1)) * 100);
69
+ };
65
70
  const onSelect = (value) => {
66
71
  ratingValue.value = value;
67
72
  emit("select", value);
@@ -1,7 +1,10 @@
1
+ import type { CardReviewProps } from "#pukaad-ui/types/components/card/card-review";
1
2
  export interface ModalMediaViewProps {
2
3
  items?: string[];
3
4
  title?: string;
4
5
  startIndex?: number;
6
+ /** ข้อมูล review เต็ม (user, review, replies) สำหรับแสดงที่ overlay ด้านล่าง */
7
+ review?: CardReviewProps;
5
8
  }
6
9
  type __VLS_Props = ModalMediaViewProps;
7
10
  type __VLS_ModelProps = {
@@ -9,15 +9,153 @@
9
9
  :select-index="props.startIndex"
10
10
  class="h-full"
11
11
  />
12
+
13
+ <!-- Review info overlay (แสดงเมื่อมีข้อมูล review) -->
14
+ <div
15
+ v-if="props.review"
16
+ class="absolute bottom-0 w-full z-10"
17
+ style="
18
+ background: linear-gradient(
19
+ to top,
20
+ rgba(0, 0, 0, 0.75) 0%,
21
+ transparent 100%
22
+ );
23
+ "
24
+ >
25
+ <div class="flex flex-colw-full">
26
+ <!-- User row -->
27
+ <div
28
+ v-if="!showMoreDescription"
29
+ class="flex gap-[16px] p-[16px] w-full text-white"
30
+ >
31
+ <Avatar
32
+ :src="props.review.user?.avatar"
33
+ :alt="props.review.user?.name"
34
+ :size="36"
35
+ class="shrink-0"
36
+ />
37
+ <div class="flex flex-col gap-[8px] w-full">
38
+ <div class="flex flex-col gap-[8px]">
39
+ <div class="flex justify-between w-full">
40
+ <span class="font-body-large">
41
+ {{ props.review.user?.name }}
42
+ </span>
43
+ <Icon name="lucide:flag" />
44
+ </div>
45
+ <div class="flex flex-col">
46
+ <span class="font-body-small">
47
+ {{ convertNumber(props.review.user?.review_count ?? 0) }}
48
+ รีวิว •
49
+ {{ convertNumber(props.review.user?.like_count ?? 0) }}
50
+ ชื่นชอบรีวิว
51
+ </span>
52
+
53
+ <!-- Rating + date -->
54
+ <div
55
+ v-if="props.review.review"
56
+ class="flex items-center gap-[8px]"
57
+ >
58
+ <InputRating
59
+ :size="14"
60
+ readonly
61
+ :model-value="props.review.review.rating"
62
+ />
63
+ <span class="font-body-small opacity-75">
64
+ {{
65
+ convertDateTorelativeText(
66
+ props.review.review.created_at ?? ""
67
+ )
68
+ }}
69
+ </span>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <!-- Description -->
74
+ <p
75
+ v-if="props.review.review?.description"
76
+ class="font-body-large line-clamp-1 cursor-pointer"
77
+ @click="showMoreDescription = true"
78
+ >
79
+ {{ props.review.review.description }}
80
+ </p>
81
+ </div>
82
+ </div>
83
+ <div
84
+ v-if="showMoreDescription"
85
+ class="flex gap-[16px] bg-white rounded-t-[16px] w-full p-[16px] max-h-[322px]"
86
+ >
87
+ <Avatar
88
+ :src="props.review.user?.avatar"
89
+ :alt="props.review.user?.name"
90
+ :size="36"
91
+ class="shrink-0"
92
+ />
93
+ <div class="flex flex-col gap-[8px] w-full">
94
+ <div class="flex flex-col gap-[8px]">
95
+ <div class="flex justify-between w-full">
96
+ <span class="font-body-large">
97
+ {{ props.review.user?.name }}
98
+ </span>
99
+ <Icon
100
+ name="lucide:x"
101
+ class="cursor-pointer"
102
+ @click="showMoreDescription = false"
103
+ />
104
+ </div>
105
+ <div class="flex flex-col">
106
+ <span class="font-body-small">
107
+ {{ convertNumber(props.review.user?.review_count ?? 0) }}
108
+ รีวิว •
109
+ {{ convertNumber(props.review.user?.like_count ?? 0) }}
110
+ ชื่นชอบรีวิว
111
+ </span>
112
+
113
+ <!-- Rating + date -->
114
+ <div
115
+ v-if="props.review.review"
116
+ class="flex items-center gap-[8px]"
117
+ >
118
+ <InputRating
119
+ :size="14"
120
+ readonly
121
+ :model-value="props.review.review.rating"
122
+ />
123
+ <span class="font-body-small opacity-75">
124
+ {{
125
+ convertDateTorelativeText(
126
+ props.review.review.created_at ?? ""
127
+ )
128
+ }}
129
+ </span>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ <!-- Description -->
134
+ <p
135
+ v-if="props.review.review?.description"
136
+ class="font-body-large max-h-[280px] overflow-y-auto"
137
+ @click="showMoreDescription = true"
138
+ >
139
+ {{ props.review.review.description }}
140
+ </p>
141
+ </div>
142
+ </div>
143
+ </div>
144
+ </div>
12
145
  </div>
13
146
  </Modal>
14
147
  </template>
15
148
 
16
149
  <script setup>
150
+ import { ref } from "vue";
151
+ import { useConvert } from "../../composables/useConvert";
152
+ const { convertNumber, convertDateTorelativeText } = useConvert();
17
153
  const props = defineProps({
18
154
  items: { type: Array, required: false, default: () => [] },
19
155
  title: { type: String, required: false, default: "" },
20
- startIndex: { type: Number, required: false, default: 0 }
156
+ startIndex: { type: Number, required: false, default: 0 },
157
+ review: { type: Object, required: false }
21
158
  });
22
159
  const isOpen = defineModel({ type: Boolean, ...{ default: false } });
160
+ const showMoreDescription = ref(false);
23
161
  </script>
@@ -1,7 +1,10 @@
1
+ import type { CardReviewProps } from "#pukaad-ui/types/components/card/card-review";
1
2
  export interface ModalMediaViewProps {
2
3
  items?: string[];
3
4
  title?: string;
4
5
  startIndex?: number;
6
+ /** ข้อมูล review เต็ม (user, review, replies) สำหรับแสดงที่ overlay ด้านล่าง */
7
+ review?: CardReviewProps;
5
8
  }
6
9
  type __VLS_Props = ModalMediaViewProps;
7
10
  type __VLS_ModelProps = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pukaad-ui-lib",
3
- "version": "1.309.0",
3
+ "version": "1.310.0",
4
4
  "description": "pukaad-ui for MeMSG",
5
5
  "repository": {
6
6
  "type": "git",