nuxt-glorious 0.7.9-7

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 (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>