pukaad-ui-lib 1.309.0 → 1.311.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 +1 -1
- package/dist/runtime/components/button.vue +10 -10
- package/dist/runtime/components/card/card-review.vue +1 -0
- package/dist/runtime/components/image/image-cropper.d.vue.ts +2 -2
- package/dist/runtime/components/image/image-cropper.vue.d.ts +2 -2
- package/dist/runtime/components/input/input-rating.d.vue.ts +6 -9
- package/dist/runtime/components/input/input-rating.vue +56 -53
- package/dist/runtime/components/input/input-rating.vue.d.ts +6 -9
- package/dist/runtime/components/modal/modal-media-view.d.vue.ts +3 -0
- package/dist/runtime/components/modal/modal-media-view.vue +139 -1
- package/dist/runtime/components/modal/modal-media-view.vue.d.ts +3 -0
- package/package.json +1 -1
- /package/dist/runtime/assets/svg/socials/{WhatsApp.svg → Whatsapp.svg} +0 -0
package/dist/module.json
CHANGED
|
@@ -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>
|
|
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
|
|
|
64
64
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
|
|
65
65
|
src: string;
|
|
66
66
|
center: boolean;
|
|
67
|
+
background: boolean;
|
|
68
|
+
modal: boolean;
|
|
67
69
|
responsive: boolean;
|
|
68
70
|
restore: boolean;
|
|
69
71
|
checkCrossOrigin: boolean;
|
|
70
72
|
checkOrientation: boolean;
|
|
71
73
|
crossorigin: "" | "anonymous" | "use-credentials";
|
|
72
|
-
modal: boolean;
|
|
73
74
|
guides: boolean;
|
|
74
75
|
highlight: boolean;
|
|
75
|
-
background: boolean;
|
|
76
76
|
autoCrop: boolean;
|
|
77
77
|
movable: boolean;
|
|
78
78
|
rotatable: boolean;
|
|
@@ -64,15 +64,15 @@ declare const __VLS_export: import("vue").DefineComponent<ImageCropperProps, {
|
|
|
64
64
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ImageCropperProps> & Readonly<{}>, {
|
|
65
65
|
src: string;
|
|
66
66
|
center: boolean;
|
|
67
|
+
background: boolean;
|
|
68
|
+
modal: boolean;
|
|
67
69
|
responsive: boolean;
|
|
68
70
|
restore: boolean;
|
|
69
71
|
checkCrossOrigin: boolean;
|
|
70
72
|
checkOrientation: boolean;
|
|
71
73
|
crossorigin: "" | "anonymous" | "use-credentials";
|
|
72
|
-
modal: boolean;
|
|
73
74
|
guides: boolean;
|
|
74
75
|
highlight: boolean;
|
|
75
|
-
background: boolean;
|
|
76
76
|
autoCrop: boolean;
|
|
77
77
|
movable: boolean;
|
|
78
78
|
rotatable: boolean;
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import type { InputRatingProps } from "#pukaad-ui/types/components/input/input-rating";
|
|
2
|
-
type __VLS_Props = InputRatingProps
|
|
3
|
-
|
|
4
|
-
type __VLS_ModelProps = {
|
|
5
|
-
modelValue?: typeof ratingValue['value'];
|
|
2
|
+
type __VLS_Props = InputRatingProps & {
|
|
3
|
+
modelValue?: number;
|
|
6
4
|
};
|
|
7
|
-
|
|
8
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
-
"update:modelValue": (value: number) => any;
|
|
10
|
-
} & {
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
11
6
|
select: (value: number) => any;
|
|
12
|
-
|
|
7
|
+
"update:modelValue": (value: number) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
13
9
|
onSelect?: ((value: number) => any) | undefined;
|
|
14
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
15
11
|
}>, {
|
|
16
12
|
size: number;
|
|
17
13
|
borderColor: string;
|
|
14
|
+
modelValue: number;
|
|
18
15
|
backgroundColor: string;
|
|
19
16
|
readonly: boolean;
|
|
20
17
|
ratingStep: number;
|
|
@@ -1,54 +1,52 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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>
|
|
51
|
-
|
|
48
|
+
import { computed } from "vue";
|
|
49
|
+
const emit = defineEmits(["select", "update:modelValue"]);
|
|
52
50
|
const props = defineProps({
|
|
53
51
|
readonly: { type: Boolean, required: false, default: false },
|
|
54
52
|
ratingStep: { type: Number, required: false, default: 1 },
|
|
@@ -56,14 +54,19 @@ const props = defineProps({
|
|
|
56
54
|
borderSize: { type: Number, required: false, default: 0 },
|
|
57
55
|
borderColor: { type: String, required: false, default: "#fbc02d" },
|
|
58
56
|
backgroundColor: { type: String, required: false, default: "#c4c4c4" },
|
|
59
|
-
activeColor: { type: String, required: false, default: "#fbc02d" }
|
|
60
|
-
}
|
|
61
|
-
const ratingValue = defineModel({
|
|
62
|
-
type: Number,
|
|
63
|
-
default: 0
|
|
57
|
+
activeColor: { type: String, required: false, default: "#fbc02d" },
|
|
58
|
+
modelValue: { type: Number, required: false, default: 0 }
|
|
64
59
|
});
|
|
60
|
+
const uid = Math.random().toString(36).slice(2, 7);
|
|
61
|
+
const ratingVal = computed(() => props.modelValue ?? 0);
|
|
62
|
+
const getFill = (n) => {
|
|
63
|
+
const val = ratingVal.value;
|
|
64
|
+
if (val >= n) return 100;
|
|
65
|
+
if (val < n - 1) return 0;
|
|
66
|
+
return Math.round((val - (n - 1)) * 100);
|
|
67
|
+
};
|
|
65
68
|
const onSelect = (value) => {
|
|
66
|
-
|
|
69
|
+
emit("update:modelValue", value);
|
|
67
70
|
emit("select", value);
|
|
68
71
|
};
|
|
69
72
|
</script>
|
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
import type { InputRatingProps } from "#pukaad-ui/types/components/input/input-rating";
|
|
2
|
-
type __VLS_Props = InputRatingProps
|
|
3
|
-
|
|
4
|
-
type __VLS_ModelProps = {
|
|
5
|
-
modelValue?: typeof ratingValue['value'];
|
|
2
|
+
type __VLS_Props = InputRatingProps & {
|
|
3
|
+
modelValue?: number;
|
|
6
4
|
};
|
|
7
|
-
|
|
8
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
-
"update:modelValue": (value: number) => any;
|
|
10
|
-
} & {
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
11
6
|
select: (value: number) => any;
|
|
12
|
-
|
|
7
|
+
"update:modelValue": (value: number) => any;
|
|
8
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
13
9
|
onSelect?: ((value: number) => any) | undefined;
|
|
14
10
|
"onUpdate:modelValue"?: ((value: number) => any) | undefined;
|
|
15
11
|
}>, {
|
|
16
12
|
size: number;
|
|
17
13
|
borderColor: string;
|
|
14
|
+
modelValue: number;
|
|
18
15
|
backgroundColor: string;
|
|
19
16
|
readonly: boolean;
|
|
20
17
|
ratingStep: number;
|
|
@@ -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
|
File without changes
|