nuxt-glorious 0.7.9-7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. package/README.md +29 -0
  2. package/dist/module.cjs +5 -0
  3. package/dist/module.d.mts +7 -0
  4. package/dist/module.d.ts +7 -0
  5. package/dist/module.json +5 -0
  6. package/dist/module.mjs +93 -0
  7. package/dist/runtime/assets/icons/glorious-arrow.svg +3 -0
  8. package/dist/runtime/assets/icons/glorious-check-fill.svg +10 -0
  9. package/dist/runtime/assets/icons/glorious-x.svg +3 -0
  10. package/dist/runtime/assets/style/components/buttons.css +88 -0
  11. package/dist/runtime/assets/style/components/drawer.css +55 -0
  12. package/dist/runtime/assets/style/components/dropdown.css +18 -0
  13. package/dist/runtime/assets/style/components/editor.css +4 -0
  14. package/dist/runtime/assets/style/components/file.css +65 -0
  15. package/dist/runtime/assets/style/components/input.css +91 -0
  16. package/dist/runtime/assets/style/components/modal.css +46 -0
  17. package/dist/runtime/assets/style/components/paginate.css +17 -0
  18. package/dist/runtime/assets/style/components/select.css +54 -0
  19. package/dist/runtime/assets/style/components/tab.css +9 -0
  20. package/dist/runtime/assets/style/components/textarea.css +64 -0
  21. package/dist/runtime/components/G/Breadcrump.vue +41 -0
  22. package/dist/runtime/components/G/Button.vue +163 -0
  23. package/dist/runtime/components/G/CountDown.vue +65 -0
  24. package/dist/runtime/components/G/Drawer.vue +80 -0
  25. package/dist/runtime/components/G/Dropdown.vue +63 -0
  26. package/dist/runtime/components/G/File.vue +142 -0
  27. package/dist/runtime/components/G/Icon/index.vue +142 -0
  28. package/dist/runtime/components/G/Input.vue +269 -0
  29. package/dist/runtime/components/G/IntersectionObserve.vue +22 -0
  30. package/dist/runtime/components/G/Loading.vue +35 -0
  31. package/dist/runtime/components/G/Modal.vue +92 -0
  32. package/dist/runtime/components/G/Paginate.vue +130 -0
  33. package/dist/runtime/components/G/Radio.vue +38 -0
  34. package/dist/runtime/components/G/Select.vue +145 -0
  35. package/dist/runtime/components/G/Tab.vue +57 -0
  36. package/dist/runtime/components/G/Wizard.vue +123 -0
  37. package/dist/runtime/components/G/textarea.vue +141 -0
  38. package/dist/runtime/composables/useGloriousAppSetting.d.ts +11 -0
  39. package/dist/runtime/composables/useGloriousAppSetting.mjs +37 -0
  40. package/dist/runtime/composables/useGloriousFetch.d.ts +13 -0
  41. package/dist/runtime/composables/useGloriousFetch.mjs +107 -0
  42. package/dist/runtime/composables/useGloriousHead.d.ts +8 -0
  43. package/dist/runtime/composables/useGloriousHead.mjs +33 -0
  44. package/dist/runtime/middlewares/Auth.d.ts +2 -0
  45. package/dist/runtime/middlewares/Auth.mjs +37 -0
  46. package/dist/runtime/middlewares/AuthStrategy.d.ts +2 -0
  47. package/dist/runtime/middlewares/AuthStrategy.mjs +17 -0
  48. package/dist/runtime/plugins/Drawer.d.ts +2 -0
  49. package/dist/runtime/plugins/Drawer.mjs +35 -0
  50. package/dist/runtime/plugins/Modal.d.ts +2 -0
  51. package/dist/runtime/plugins/Modal.mjs +38 -0
  52. package/dist/runtime/plugins/TailwindColor.d.ts +6 -0
  53. package/dist/runtime/plugins/TailwindColor.mjs +10 -0
  54. package/dist/runtime/plugins/glorious-app-setting.d.ts +2 -0
  55. package/dist/runtime/plugins/glorious-app-setting.mjs +11 -0
  56. package/dist/runtime/plugins/shortcut-key.d.ts +2 -0
  57. package/dist/runtime/plugins/shortcut-key.mjs +11 -0
  58. package/dist/runtime/stores/GloriousStore.d.ts +9 -0
  59. package/dist/runtime/stores/GloriousStore.mjs +88 -0
  60. package/dist/types.d.mts +16 -0
  61. package/dist/types.d.ts +16 -0
  62. package/package.json +53 -0
@@ -0,0 +1,142 @@
1
+ <script lang="ts" setup>
2
+ import { ref, watch } from "#imports";
3
+
4
+ const props = defineProps({
5
+ name: {
6
+ required: true,
7
+ type: String,
8
+ default: "",
9
+ },
10
+ color: {
11
+ required: false,
12
+ type: String,
13
+ default: "#000",
14
+ },
15
+ size: {
16
+ required: false,
17
+ type: Number,
18
+ default: 20,
19
+ },
20
+ stroke: {
21
+ required: false,
22
+ type: Number,
23
+ default: 1,
24
+ },
25
+ });
26
+
27
+ const icon = ref("");
28
+
29
+ const methods = {
30
+ computeProps: (icon: any) => {
31
+ //color
32
+ icon = icon.replaceAll("\n", " ");
33
+ //stroke
34
+ icon = icon
35
+ .split(" ")
36
+ .map((item: any) =>
37
+ item.includes('stroke="') && typeof props.color !== "undefined"
38
+ ? 'stroke="' + props.color + '"'
39
+ : item
40
+ )
41
+ .join(" ");
42
+
43
+ //fill
44
+ if (typeof props.color !== "undefined") {
45
+ icon = icon
46
+ .split(" ")
47
+ .map((item: any) => {
48
+ if (!item.includes('fill="none"')) {
49
+ if (item.includes('fill="') && !item.includes('"/>'))
50
+ return `fill="${props.color}"`;
51
+ else if (item.includes('fill="') && item.includes('"/>'))
52
+ return `fill="${props.color}"/>`;
53
+ else return item;
54
+ } else return item;
55
+ })
56
+ .join(" ");
57
+ }
58
+
59
+ //size
60
+ icon = icon.replaceAll("\n", " ");
61
+
62
+ //width
63
+ icon = icon
64
+ .split(" ")
65
+ .map((item: any) =>
66
+ item.includes('width="') &&
67
+ !item.includes("stroke-width") &&
68
+ typeof props.size !== "undefined"
69
+ ? 'width="' + props.size + '"'
70
+ : item
71
+ )
72
+ .join(" ");
73
+
74
+ icon = icon
75
+ .split(" ")
76
+ .map((item: any) =>
77
+ item.includes('height="') && typeof props.size !== "undefined"
78
+ ? 'height="' + props.size + '"'
79
+ : item
80
+ )
81
+ .join(" ");
82
+
83
+ //stroke
84
+ icon = icon.replaceAll("\n", " ");
85
+
86
+ icon = icon
87
+ .split(" ")
88
+ .map((item: any) =>
89
+ item.includes("stroke-width") && typeof props.stroke !== "undefined"
90
+ ? 'stroke-width="' + props.stroke + '"'
91
+ : item
92
+ )
93
+ .join(" ");
94
+
95
+ return icon;
96
+ },
97
+ };
98
+
99
+ async function getIcon() {
100
+ try {
101
+ const iconsImport = import.meta.glob("assets/icons/**/**.svg", {
102
+ query: "?raw",
103
+ eager: false,
104
+ });
105
+ let rawIcon = "";
106
+ if (typeof iconsImport[`/assets/icons/${props.name}.svg`] !== "undefined") {
107
+ const icon: any = await iconsImport[`/assets/icons/${props.name}.svg`]();
108
+ rawIcon = icon.default;
109
+ } else {
110
+ const staticAssets = import.meta.glob("../../../assets/icons/**/**.svg", {
111
+ query: "?raw",
112
+ eager: false,
113
+ });
114
+
115
+ const icon: any = await staticAssets[
116
+ `../../../assets/icons/${props.name}.svg`
117
+ ]();
118
+ rawIcon = icon.default;
119
+ }
120
+
121
+ icon.value = methods.computeProps(rawIcon);
122
+ } catch (e) {
123
+ console.error(
124
+ `glorious error -> Icon '${props.name}' doesn't exist in 'assets/icons'`
125
+ );
126
+ }
127
+ }
128
+
129
+ await getIcon();
130
+
131
+ watch(
132
+ () => props,
133
+ () => getIcon(),
134
+ {
135
+ deep: true,
136
+ }
137
+ );
138
+ </script>
139
+ <template>
140
+ <!-- eslint-disable vue/no-v-html -->
141
+ <div class="w-max h-max" v-html="icon" />
142
+ </template>
@@ -0,0 +1,269 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref, watch, GloriousStore } from "#imports";
3
+ const props = defineProps({
4
+ modelValue: {
5
+ required: false,
6
+ default: "",
7
+ type: [String, Array<String>, Number],
8
+ },
9
+ color: {
10
+ required: false,
11
+ default: "primary",
12
+ type: String,
13
+ },
14
+ placeholder: {
15
+ required: false,
16
+ default: "",
17
+ type: String,
18
+ },
19
+ title: {
20
+ required: false,
21
+ default: "",
22
+ type: String,
23
+ },
24
+ size: {
25
+ required: false,
26
+ default: "md",
27
+ type: String,
28
+ },
29
+ error: {
30
+ required: false,
31
+ default: "|",
32
+ type: String,
33
+ },
34
+ icon: {
35
+ required: false,
36
+ default: "",
37
+ type: String,
38
+ },
39
+ disabled: {
40
+ required: false,
41
+ default: false,
42
+ type: Boolean,
43
+ },
44
+ type: {
45
+ required: false,
46
+ default: "text",
47
+ type: String,
48
+ },
49
+ autocomplete: {
50
+ required: false,
51
+ default: "off",
52
+ type: String,
53
+ },
54
+ mode: {
55
+ required: false,
56
+ default: "normal",
57
+ type: String,
58
+ },
59
+ });
60
+
61
+ const inputValue: any = ref(null);
62
+
63
+ const emits = defineEmits(["update:modelValue"]);
64
+
65
+ watch(
66
+ () => inputValue.value,
67
+ () => {
68
+ if (props.mode === "tag") return;
69
+ emits("update:modelValue", inputValue.value);
70
+ }
71
+ );
72
+
73
+ const gs: any = GloriousStore();
74
+ const error: any = props.error.split("|");
75
+
76
+ const computeIconSize = computed(() => {
77
+ let iconSize = 0;
78
+
79
+ switch (props.size) {
80
+ case "xl":
81
+ iconSize = 30;
82
+ break;
83
+ case "lg":
84
+ iconSize = 27;
85
+ break;
86
+ case "md":
87
+ iconSize = 25;
88
+ break;
89
+ case "sm":
90
+ iconSize = 23;
91
+ break;
92
+ case "xsm":
93
+ iconSize = 20;
94
+ break;
95
+ default:
96
+ iconSize = 30;
97
+ break;
98
+ }
99
+
100
+ return iconSize;
101
+ });
102
+
103
+ // ------------------------------------------------------------------------------------------------ TAG
104
+ const tags: any = ref([]);
105
+
106
+ const addTag = (event: any) => {
107
+ if (tags.value.length === 0) tags.value = [];
108
+
109
+ if (props.mode !== "tag") return;
110
+ const value: any = event.target.value;
111
+ tags.value.push(value);
112
+ emits("update:modelValue", tags.value);
113
+ inputValue.value = "";
114
+ };
115
+ const removeTag = (tag: string) => {
116
+ tags.value = tags.value.filter((item: any) => item !== tag);
117
+ emits("update:modelValue", tags.value);
118
+ };
119
+
120
+ // -------------------------------------- init value
121
+ const initValue = () => {
122
+ if (props.mode === "tag") {
123
+ tags.value = props.modelValue;
124
+ return;
125
+ }
126
+
127
+ inputValue.value = props.modelValue;
128
+ };
129
+ initValue();
130
+ watch(
131
+ () => props.modelValue,
132
+ () => initValue()
133
+ );
134
+ </script>
135
+
136
+ <template>
137
+ <div class="flex flex-col">
138
+ <span class="text-[14px] font-medium text-gray-500">{{ props.title }}</span>
139
+ <div
140
+ class="glorious-input"
141
+ :class="[props.icon !== '' ? `icon-${props.size}` : '']"
142
+ >
143
+ <input
144
+ v-model="inputValue"
145
+ :autocomplete="props.autocomplete"
146
+ :class="[props.size, `glorious-input-${props.color}`]"
147
+ :placeholder="props.placeholder"
148
+ :disabled="props.disabled"
149
+ :type="props.type"
150
+ @keyup.enter="addTag($event)"
151
+ />
152
+ <div v-if="tags.length !== 0" class="glorious-input-tag">
153
+ <div v-for="(item, index) in tags" :key="index">
154
+ {{ item }}
155
+ <GIcon
156
+ name="glorious-x"
157
+ :size="10"
158
+ color="#ff0000"
159
+ @click="removeTag(item)"
160
+ />
161
+ </div>
162
+ </div>
163
+ <GIcon
164
+ v-if="props.icon !== ''"
165
+ class="glorious-input-icon"
166
+ :name="props.icon"
167
+ :size="computeIconSize"
168
+ :color="$tailwindColor('gray', '500')"
169
+ />
170
+ </div>
171
+ <span v-if="gs.forms[error[0]]?.errors[error[1]]" class="text-red-500">
172
+ {{ gs.forms[error[0]].errors[error[1]][0] }}
173
+ </span>
174
+ </div>
175
+ </template>
176
+
177
+ <style>
178
+ .xl.glorious-input-orange, .xl.glorious-input-blue, .xl.glorious-input-gray, .xl.glorious-input-red, .xl.glorious-input-primary {
179
+ @apply py-2.5;
180
+ }
181
+ .lg.glorious-input-orange, .lg.glorious-input-blue, .lg.glorious-input-gray, .lg.glorious-input-red, .lg.glorious-input-primary {
182
+ @apply py-2;
183
+ }
184
+ .md.glorious-input-orange, .md.glorious-input-blue, .md.glorious-input-gray, .md.glorious-input-red, .md.glorious-input-primary {
185
+ @apply py-1.5;
186
+ }
187
+ .sm.glorious-input-orange, .sm.glorious-input-blue, .sm.glorious-input-gray, .sm.glorious-input-red, .sm.glorious-input-primary {
188
+ @apply py-1;
189
+ }
190
+ .xsm.glorious-input-orange, .xsm.glorious-input-blue, .xsm.glorious-input-gray, .xsm.glorious-input-red, .xsm.glorious-input-primary {
191
+ @apply py-0.5;
192
+ }
193
+
194
+ .glorious-input-orange:focus-visible, .glorious-input-blue:focus-visible, .glorious-input-gray:focus-visible, .glorious-input-red:focus-visible, .glorious-input-primary:focus-visible {
195
+ @apply outline-none ring-2;
196
+ }
197
+
198
+ .glorious-input-primary {
199
+ @apply rounded-md ring-1 ring-green-500 px-3;
200
+ }
201
+ .glorious-input-primary:disabled {
202
+ @apply bg-green-300 cursor-not-allowed;
203
+ }
204
+
205
+ .glorious-input-red {
206
+ @apply rounded-md ring-1 ring-red-500 px-3;
207
+ }
208
+ .glorious-input-red:disabled {
209
+ @apply cursor-not-allowed;
210
+ }
211
+
212
+ .glorious-input-gray {
213
+ @apply rounded-md ring-1 ring-gray-500 px-3;
214
+ }
215
+ .glorious-input-gray:disabled {
216
+ @apply cursor-not-allowed;
217
+ }
218
+
219
+ .glorious-input-blue {
220
+ @apply rounded-md ring-1 ring-blue-500 px-3;
221
+ }
222
+ .glorious-input-blue:disabled {
223
+ @apply cursor-not-allowed;
224
+ }
225
+
226
+ .glorious-input-orange {
227
+ @apply rounded-md ring-1 ring-orange-500 px-3;
228
+ }
229
+ .glorious-input-orange:disabled {
230
+ @apply cursor-not-allowed;
231
+ }
232
+
233
+ .glorious-input {
234
+ @apply relative w-full;
235
+ }
236
+ .glorious-input > input {
237
+ @apply w-full;
238
+ }
239
+ .glorious-input > input::placeholder {
240
+ @apply text-[14px];
241
+ }
242
+ .glorious-input.icon-xl > input {
243
+ @apply rtl:pr-9 ltr:pl-9;
244
+ }
245
+ .glorious-input.icon-lg > input {
246
+ @apply rtl:pr-9 ltr:pl-8;
247
+ }
248
+ .glorious-input.icon-md > input {
249
+ @apply rtl:pr-9 ltr:pl-8;
250
+ }
251
+ .glorious-input.icon-sm > input {
252
+ @apply rtl:pr-8 ltr:pl-8;
253
+ }
254
+ .glorious-input.icon-xsm > input {
255
+ @apply rtl:pr-8 ltr:pl-7;
256
+ }
257
+
258
+ .glorious-input-icon {
259
+ @apply absolute h-max top-0 bottom-0 my-auto rtl:right-1 ltr:left-1;
260
+ }
261
+
262
+ /* ----------------------------------------------- TAG */
263
+ .glorious-input-tag {
264
+ @apply mt-3 gap-2 flex flex-wrap;
265
+ }
266
+ .glorious-input-tag > div {
267
+ @apply bg-green-500 px-1 rounded text-white flex items-center gap-2 cursor-pointer;
268
+ }
269
+ </style>
@@ -0,0 +1,22 @@
1
+ <script setup lang="ts">
2
+ import { onMounted, useId } from "#imports";
3
+ const elementId = useId();
4
+ const emits = defineEmits(["intersect"]);
5
+
6
+ onMounted(() => {
7
+ const element: any = document.querySelector(
8
+ `#intersection-observe-${elementId}`
9
+ );
10
+
11
+ const observe: any = new IntersectionObserver((event: any) => {
12
+ if (event[0].isIntersecting) emits("intersect", true);
13
+ });
14
+
15
+ observe.observe(element);
16
+ });
17
+ </script>
18
+ <template>
19
+ <div :id="`intersection-observe-${elementId}`">
20
+ <slot />
21
+ </div>
22
+ </template>
@@ -0,0 +1,35 @@
1
+ <script setup lang="ts">
2
+ const props = defineProps({
3
+ color: {
4
+ required: false,
5
+ default: "#fff",
6
+ type: String,
7
+ },
8
+ size: {
9
+ required: false,
10
+ default: 30,
11
+ type: Number,
12
+ },
13
+ stroke: {
14
+ required: false,
15
+ default: 3,
16
+ type: Number,
17
+ },
18
+ });
19
+ </script>
20
+
21
+ <template>
22
+ <div class="inline">
23
+ <div
24
+ class="loader"
25
+ :style="{
26
+ width: `${props.size}px`,
27
+ border: `${props.stroke}px solid ${props.color}`,
28
+ }"
29
+ />
30
+ </div>
31
+ </template>
32
+
33
+ <style>
34
+ .loader{animation:l20-1 .8s linear infinite alternate,l20-2 1.6s linear infinite;aspect-ratio:1;border-radius:50%}@keyframes l20-1{0%{-webkit-clip-path:polygon(50% 50%,0 0,50% 0,50% 0,50% 0,50% 0,50% 0);clip-path:polygon(50% 50%,0 0,50% 0,50% 0,50% 0,50% 0,50% 0)}12.5%{-webkit-clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 0,100% 0,100% 0);clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 0,100% 0,100% 0)}25%{-webkit-clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 100%,100% 100%,100% 100%);clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 100%,100% 100%,100% 100%)}50%{-webkit-clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 100%,50% 100%,0 100%);clip-path:polygon(50% 50%,0 0,50% 0,100% 0,100% 100%,50% 100%,0 100%)}62.5%{-webkit-clip-path:polygon(50% 50%,100% 0,100% 0,100% 0,100% 100%,50% 100%,0 100%);clip-path:polygon(50% 50%,100% 0,100% 0,100% 0,100% 100%,50% 100%,0 100%)}75%{-webkit-clip-path:polygon(50% 50%,100% 100%,100% 100%,100% 100%,100% 100%,50% 100%,0 100%);clip-path:polygon(50% 50%,100% 100%,100% 100%,100% 100%,100% 100%,50% 100%,0 100%)}to{-webkit-clip-path:polygon(50% 50%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,0 100%);clip-path:polygon(50% 50%,50% 100%,50% 100%,50% 100%,50% 100%,50% 100%,0 100%)}}@keyframes l20-2{0%{transform:scaleY(1) rotate(0deg)}49.99%{transform:scaleY(1) rotate(135deg)}50%{transform:scaleY(-1) rotate(0deg)}to{transform:scaleY(-1) rotate(-135deg)}}
35
+ </style>
@@ -0,0 +1,92 @@
1
+ <script lang="ts" setup>
2
+ const props = defineProps({
3
+ id: {
4
+ required: false,
5
+ default: "modal",
6
+ type: String,
7
+ },
8
+ size: {
9
+ required: false,
10
+ default: "md", //[sm,md,lg,xl,full]
11
+ type: String,
12
+ },
13
+ title: {
14
+ required: false,
15
+ default: "",
16
+ type: String,
17
+ },
18
+ });
19
+ </script>
20
+
21
+ <template>
22
+ <div
23
+ :id="props.id"
24
+ :class="[`size-${props.size}`]"
25
+ class="glorious-modal close"
26
+ >
27
+ <!-- start title -->
28
+ <div v-if="props?.title !== ''" class="flex justify-between items-center">
29
+ <span class="font-medium">{{ props.title }}</span>
30
+ <GButton
31
+ class="flex justify-center items-center w-[10px]"
32
+ size="sm"
33
+ @click="$modal(`${props.id}`)"
34
+ >
35
+ <GIcon name="glorious-x" color="#fff" :size="10" />
36
+ </GButton>
37
+ </div>
38
+ <hr v-if="props.title !== ''" class="my-3" />
39
+ <!-- end title -->
40
+
41
+ <slot />
42
+ </div>
43
+ </template>
44
+
45
+ <style>
46
+ .bg-blur-modal {
47
+ @apply fixed top-0 right-0 backdrop-blur-sm bg-gray-500 bg-opacity-50 h-full w-full z-[40];
48
+ }
49
+
50
+ .glorious-modal {
51
+ @apply fixed bg-white md:top-[15%] z-50 right-0 left-0 mx-auto p-3 md:rounded-md rounded-t-md md:bottom-0 bottom-0 overflow-y-auto;
52
+ }
53
+ .glorious-modal.size-full {
54
+ @apply w-full h-full top-0 rounded-none;
55
+ }
56
+ .glorious-modal.size-xl {
57
+ @apply md:w-[70%] w-full md:h-max max-h-[70%];
58
+ }
59
+ .glorious-modal.size-lg {
60
+ @apply md:w-[60%] w-full md:h-max max-h-[70%];
61
+ }
62
+ .glorious-modal.size-md {
63
+ @apply md:w-[50%] w-full md:h-max max-h-[70%];
64
+ }
65
+ .glorious-modal.size-sm {
66
+ @apply lg:w-[25%] md:w-[35%] w-full md:h-max max-h-[70%];
67
+ }
68
+ .glorious-modal.close {
69
+ @apply hidden;
70
+ }
71
+ .glorious-modal.open {
72
+ animation: animation-mobile 0.3s normal forwards;
73
+ }
74
+ @screen md {
75
+ .glorious-modal.open {
76
+ animation: animation-opacity 0.2s normal forwards;
77
+ }
78
+ }
79
+ @keyframes animation-opacity {
80
+ from {
81
+ opacity: 0;
82
+ }
83
+ to {
84
+ opacity: 1;
85
+ }
86
+ }
87
+ @keyframes animation-mobile {
88
+ to {
89
+ bottom: 0;
90
+ }
91
+ }
92
+ </style>
@@ -0,0 +1,130 @@
1
+ <script lang="ts" setup>
2
+ import { reactive, watch } from "#imports";
3
+ const props = defineProps({
4
+ data: {
5
+ required: true,
6
+ type: Object,
7
+ },
8
+ modelValue: {
9
+ required: true,
10
+ type: Number,
11
+ },
12
+ });
13
+ const el = reactive({
14
+ pageList: [],
15
+ });
16
+
17
+ const emits = defineEmits(["update:modelValue"]);
18
+ const methods = {
19
+ emit: (item: any) => {
20
+ if (props.data?.current_page !== item) emits("update:modelValue", item);
21
+ },
22
+ computePageList: () => {
23
+ let count: number = 0;
24
+
25
+ for (
26
+ let i: number = props.data?.current_page;
27
+ i > 0 && el.pageList.length <= 2;
28
+ i--
29
+ ) {
30
+ if (!el.pageList.includes(i)) el.pageList.push(i);
31
+
32
+ count++;
33
+ }
34
+
35
+ let page: number = props.data?.current_page;
36
+ while (count < 5 && page < props.data?.last_page) {
37
+ page++;
38
+
39
+ if (!el.pageList.includes(page)) el.pageList.push(page);
40
+
41
+ count++;
42
+ }
43
+
44
+ if (!el.pageList.includes(props.data?.current_page))
45
+ el.pageList.push(props.data?.current_page);
46
+
47
+ el.pageList = el.pageList.sort((a: number, b: number) => a - b);
48
+ },
49
+ };
50
+ methods.computePageList();
51
+ watch(
52
+ () => props.data,
53
+ () => methods.computePageList(),
54
+ { deep: true }
55
+ );
56
+ </script>
57
+
58
+ <template>
59
+ <div
60
+ v-if="props.data?.current_page && props.data?.last_page !== 1"
61
+ class="w-max glorious-paginate"
62
+ >
63
+ <div>
64
+ <ClientOnly>
65
+ <GIcon
66
+ v-if="props.data?.current_page !== 1"
67
+ class="ml-2 cursor-pointer"
68
+ name="glorious-arrow"
69
+ :size="15"
70
+ @click="methods.emit(props.data?.current_page - 1)"
71
+ />
72
+ <GIcon
73
+ v-else
74
+ name="glorious-arrow"
75
+ :size="15"
76
+ class="ml-2"
77
+ color="#cbd5e1"
78
+ />
79
+ </ClientOnly>
80
+
81
+ <div
82
+ v-for="(item, index) in el.pageList"
83
+ :key="index"
84
+ class="w-6 h-6 rounded-lg flex items-center justify-center paginate"
85
+ :class="[
86
+ props.data?.current_page === item ? 'active' : 'cursor-pointer',
87
+ ]"
88
+ @click="methods.emit(item)"
89
+ >
90
+ {{ item }}
91
+ </div>
92
+
93
+ <ClientOnly>
94
+ <GIcon
95
+ v-if="props.data?.current_page !== props.data?.last_page"
96
+ name="glorious-arrow"
97
+ class="mr-2 cursor-pointer"
98
+ :size="15"
99
+ @click="methods.emit(props.data?.current_page + 1)"
100
+ />
101
+ <GIcon
102
+ v-else
103
+ name="glorious-arrow"
104
+ color="#cbd5e1"
105
+ class="mr-2 cursor-pointer"
106
+ />
107
+ </ClientOnly>
108
+ </div>
109
+ </div>
110
+ </template>
111
+
112
+ <style>
113
+ .glorious-paginate > div {
114
+ @apply border border-gray-50 rounded-xl h-8 flex items-center px-1 bg-white shadow-md gap-1 w-max;
115
+ direction: rtl;
116
+ }
117
+ .glorious-paginate > div > div {
118
+ @apply px-2;
119
+ }
120
+ .glorious-paginate > div > div:last-child {
121
+ @apply rotate-[180deg];
122
+ }
123
+
124
+ .paginate {
125
+ @apply text-[13px];
126
+ }
127
+ .paginate.active {
128
+ @apply bg-green-500 rounded-lg text-white font-bold text-[13px];
129
+ }
130
+ </style>