@mixd-id/web-scaffold 0.1.230406400 → 0.1.240411001

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 (58) hide show
  1. package/package.json +11 -22
  2. package/src/components/ChartBar.vue +2 -3
  3. package/src/components/ColorPicker3.vue +94 -0
  4. package/src/components/Confirm.vue +2 -0
  5. package/src/components/ContextMenu.vue +7 -5
  6. package/src/components/Datepicker.vue +51 -24
  7. package/src/components/Dropdown.vue +4 -1
  8. package/src/components/Flex.vue +1 -1
  9. package/src/components/HTMLEditor.vue +3 -2
  10. package/src/components/Image.vue +12 -4
  11. package/src/components/List.vue +89 -62
  12. package/src/components/ListItem.vue +5 -2
  13. package/src/components/Modal.vue +2 -9
  14. package/src/components/MultiDropdown.vue +120 -0
  15. package/src/components/Tabs.vue +1 -1
  16. package/src/components/Textbox.vue +1 -1
  17. package/src/components/Timepicker.vue +24 -14
  18. package/src/components/TreeViewItem.vue +1 -1
  19. package/src/components/Uploader.vue +47 -0
  20. package/src/components/VirtualTable.vue +20 -12
  21. package/src/configs/web-page-builder.js +95 -0
  22. package/src/index.js +11 -73
  23. package/src/mixin/component.js +28 -17
  24. package/src/themes/default/index.js +4 -0
  25. package/src/utils/helpers.cjs +635 -0
  26. package/src/utils/helpers.js +37 -1
  27. package/src/utils/helpers.mjs +138 -9
  28. package/src/utils/list.mjs +1444 -0
  29. package/src/utils/preset-selector.cjs +1430 -0
  30. package/src/utils/preset-selector.js +1 -2
  31. package/src/utils/preset-selector.mjs +4 -1
  32. package/src/utils/web.mjs +120 -0
  33. package/src/widgets/AhrefSetting.vue +16 -13
  34. package/src/widgets/ArticleSetting.vue +15 -27
  35. package/src/widgets/BackgroundColorSetting.vue +147 -0
  36. package/src/widgets/ButtonSetting.vue +12 -13
  37. package/src/widgets/CarouselSetting.vue +27 -45
  38. package/src/widgets/ComponentSetting2.vue +73 -201
  39. package/src/widgets/ContactFormSetting.vue +39 -28
  40. package/src/widgets/FlexSetting.vue +83 -106
  41. package/src/widgets/GridSetting.vue +71 -178
  42. package/src/widgets/Header2Setting.vue +8 -4
  43. package/src/widgets/HeaderSetting.vue +16 -18
  44. package/src/widgets/ImageSetting.vue +42 -59
  45. package/src/widgets/MultiValueSetting2.vue +60 -39
  46. package/src/widgets/ParagraphSetting.vue +16 -13
  47. package/src/widgets/PositionSetting.vue +209 -0
  48. package/src/widgets/PresetSelector.vue +1 -1
  49. package/src/widgets/StyleSetting.vue +130 -147
  50. package/src/widgets/WebComponentSelector.vue +4 -4
  51. package/src/widgets/WebLayoutSelector.vue +44 -92
  52. package/src/widgets/WebPageBuilder.vue +488 -468
  53. package/src/widgets/WebPageSelector.vue +1 -1
  54. package/src/App.vue +0 -25
  55. package/src/entry-client.js +0 -27
  56. package/src/entry-server.js +0 -73
  57. package/src/main.js +0 -29
  58. package/src/router.js +0 -57
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.230406400",
4
+ "version": "0.1.240411001",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -14,7 +14,6 @@
14
14
  "./components/*": "./src/components/*",
15
15
  "./widgets/*": "./src/widgets/*",
16
16
  "./mixin/component": "./src/mixin/component.js",
17
-
18
17
  "./mixin/edit-mode": "./src/mixin/edit-mode.js",
19
18
  "./middleware/http/trim-string": "./src/middleware/http/trim-string.js",
20
19
  "./helpers": {
@@ -24,31 +23,31 @@
24
23
  "./helpers.js": "./src/utils/helpers.js",
25
24
  "./helpers.mjs": "./src/utils/helpers.mjs",
26
25
  "./queue": "./src/utils/queue.js",
27
-
28
26
  "./wss": {
29
27
  "require": "./src/utils/wss.js",
30
28
  "import": "./src/utils/wss.mjs"
31
29
  },
32
30
  "./wss.js": "./src/utils/wss.js",
33
31
  "./wss.mjs": "./src/utils/wss.mjs",
34
-
35
32
  "./importer": "./src/utils/importer.js",
36
33
  "./listpage1": "./src/utils/listpage1.js",
37
34
  "./dashboard": "./src/utils/dashboard.js",
38
35
  "./listview": "./src/utils/listview.js",
39
-
40
36
  "./preset-selector": {
41
- "require": "./src/utils/preset-selector.js",
37
+ "require": "./src/utils/preset-selector.cjs",
42
38
  "import": "./src/utils/preset-selector.mjs"
43
39
  },
40
+ "./preset-selector.cjs": "./src/utils/preset-selector.cjs",
44
41
  "./preset-selector.js": "./src/utils/preset-selector.js",
45
42
  "./preset-selector.mjs": "./src/utils/preset-selector.mjs",
46
-
47
- "./web": "./src/utils/web.js"
43
+ "./list.mjs": "./src/utils/list.mjs",
44
+ "./web": {
45
+ "require": "./src/utils/web.js",
46
+ "import": "./src/utils/web.mjs"
47
+ }
48
48
  },
49
49
  "dependencies": {
50
- "@faker-js/faker": "^7.3.0",
51
- "@googlemaps/js-api-loader": "^1.15.1",
50
+ "@googlemaps/js-api-loader": "^1.16.8",
52
51
  "@tailwindcss/line-clamp": "^0.4.0",
53
52
  "@vueuse/core": "^9.0.2",
54
53
  "adm-zip": "^0.5.10",
@@ -56,36 +55,26 @@
56
55
  "bcrypt": "^5.1.1",
57
56
  "chart.js": "^4.2.1",
58
57
  "compression": "^1.7.4",
59
- "cookie-parser": "^1.4.6",
60
- "cors": "^2.8.5",
61
58
  "crypto-js": "^4.2.0",
62
59
  "dayjs": "^1.11.2",
63
60
  "eventemitter2": "^6.4.7",
64
61
  "exceljs": "^4.3.0",
65
- "express": "^4.18.1",
66
62
  "file-type": "^18.2.1",
67
63
  "glob": "^8.0.3",
68
64
  "lodash": "^4.17.21",
65
+ "lodash-es": "^4.17.21",
69
66
  "md5": "^2.3.0",
70
67
  "mitt": "^3.0.1",
71
- "nprogress": "^0.2.0",
72
68
  "pinia": "^2.0.2",
73
69
  "prismjs": "1.30.0",
74
70
  "redis": "^4.6.13",
75
- "sequelize": "^6.37.5",
76
- "serve-static": "2.1.0",
71
+ "sequelize": "^6.37.6",
77
72
  "tailwindcss": "^3.2.4",
78
73
  "vue": "^3.2.25",
79
74
  "vue-chartjs": "^5.2.0",
80
75
  "vue-router": "^4.0.14",
81
76
  "ws": "^8.16.0"
82
77
  },
83
- "devDependencies": {
84
- "@vitejs/plugin-vue": "^2.2.0",
85
- "autoprefixer": "^10.4.4",
86
- "postcss": "^8.4.12",
87
- "vite": "^2.8.0"
88
- },
89
78
  "description": "This scaffold based on express vitejs vuejs",
90
79
  "repository": {
91
80
  "type": "git",
@@ -7,10 +7,9 @@
7
7
 
8
8
  <script>
9
9
 
10
- import { Bar } from 'vue-chartjs';
11
- import Chart from 'chart.js/auto'
10
+ import {Bar} from 'vue-chartjs';
12
11
  import dayjs from "dayjs";
13
- import groupBy from "lodash/groupBy";
12
+ import {groupBy} from "../utils/helpers.mjs";
14
13
 
15
14
  export default{
16
15
 
@@ -0,0 +1,94 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <Dropdown v-model="mode" @change="calculate">
5
+ <option value="solid">Solid</option>
6
+ <option value="linear">Linear Gradient</option>
7
+ <option value="radial">Radial Gradient</option>
8
+ </Dropdown>
9
+
10
+ <div class="h-[8px]" :style="{ background:computedBackground }"></div>
11
+
12
+ <div v-if="mode === 'solid'">
13
+ <input type="color" v-model="color1" @change="calculate" />
14
+ </div>
15
+
16
+ <div v-else class="flex flex-row gap-3">
17
+ <input type="color" v-model="color1" @change="calculate" />
18
+ <div class="flex-1"></div>
19
+ <input type="color" v-model="color2" @change="calculate" />
20
+ </div>
21
+
22
+ </div>
23
+ </template>
24
+
25
+ <script>
26
+ export default {
27
+
28
+ emits: [ 'update:modelValue' ],
29
+
30
+ props: {
31
+
32
+ modelValue: String
33
+
34
+ },
35
+
36
+ methods: {
37
+
38
+ calculate(){
39
+ this.$emit('update:modelValue', this.computedBackground)
40
+ }
41
+ },
42
+
43
+ mounted() {
44
+ console.log(this.modelValue)
45
+
46
+ if(`${this.modelValue ?? ''}`.substring(0, 1) === '#'){
47
+ this.color1 = this.modelValue
48
+ this.mode = 'solid'
49
+ }
50
+ else if(`${this.modelValue ?? ''}`.indexOf('linear-') >= 0){
51
+ const match = this.modelValue.match(/linear-gradient\(([^,]+),([^,]+),([^)]+)\)/)
52
+
53
+ this.mode = 'linear'
54
+ this.color1 = ((match ?? [])[2] ?? '').trim()
55
+ this.color2 = ((match ?? [])[3] ?? '').trim()
56
+ }
57
+ else if(`${this.modelValue ?? ''}`.indexOf('radial-') >= 0){
58
+ const match = this.modelValue.match(/radial-gradient\(([^,]+),([^,]+),([^)]+)\)/)
59
+
60
+ this.mode = 'radial'
61
+ this.color1 = ((match ?? [])[2] ?? '').trim()
62
+ this.color2 = ((match ?? [])[3] ?? '').trim()
63
+ }
64
+ },
65
+
66
+ data() {
67
+ return {
68
+ mode: "solid", // solid, linear, radial
69
+ color1: "#ff0000",
70
+ color2: "#0000ff",
71
+ };
72
+ },
73
+
74
+ computed: {
75
+ computedBackground() {
76
+ if (this.mode === "solid") {
77
+ return this.color1;
78
+ } else if (this.mode === "linear") {
79
+ return `linear-gradient(to right, ${this.color1}, ${this.color2})`;
80
+ } else {
81
+ return `radial-gradient(circle, ${this.color1}, ${this.color2})`;
82
+ }
83
+ },
84
+ },
85
+ };
86
+ </script>
87
+
88
+ <style module>
89
+
90
+ .comp {
91
+ @apply flex flex-col gap-2;
92
+ }
93
+
94
+ </style>
@@ -28,6 +28,8 @@
28
28
  </Button>
29
29
  </div>
30
30
 
31
+ <slot name="end"></slot>
32
+
31
33
  </div>
32
34
  </Transition>
33
35
  </div>
@@ -209,7 +209,7 @@ export default {
209
209
 
210
210
  default:
211
211
  left = Math.round(rect.x)
212
- top = Math.round(rect.y + rect.height + 8)
212
+ top = Math.round(rect.y + rect.height)
213
213
  //maxHeight = window.innerHeight - Math.round(rect.y + rect.height + 16)
214
214
  transformOrigin = 'top left'
215
215
  break
@@ -226,8 +226,8 @@ export default {
226
226
  }
227
227
 
228
228
  if(top){
229
- if(top + this.$refs.contextMenu.clientHeight >= (window.innerHeight - 16)){
230
- top = window.innerHeight - (this.$refs.contextMenu.clientHeight + 16)
229
+ if(top + this.$refs.contextMenu.clientHeight >= (window.innerHeight)){
230
+ top = window.innerHeight - (this.$refs.contextMenu.clientHeight)
231
231
 
232
232
  if(transformOrigin === 'top left'){
233
233
  transformOrigin = 'bottom left'
@@ -251,6 +251,7 @@ export default {
251
251
  top: top ? top + 'px' : top,
252
252
  bottom: bottom ? bottom + 'px' : bottom,
253
253
  maxHeight: maxHeight ? maxHeight + 'px' : maxHeight,
254
+ minWidth: `${caller.clientWidth}px`,
254
255
  transformOrigin: transformOrigin
255
256
  }
256
257
 
@@ -312,9 +313,10 @@ export default {
312
313
  <style module>
313
314
 
314
315
  .contextMenu{
315
- @apply fixed z-20 bg-base-400 min-w-[150px] overflow-y-auto rounded-xl;
316
+ @apply fixed bg-base-400 min-w-[150px] overflow-y-auto rounded-xl;
316
317
  @apply border-[2px] border-text-200 shadow-2xl whitespace-nowrap;
317
318
  transition: all 150ms cubic-bezier(0.25, 1, 0.5, 1);
319
+ z-index: 100;
318
320
  opacity: 0;
319
321
  }
320
322
 
@@ -326,7 +328,7 @@ export default {
326
328
  @media screen(md){
327
329
 
328
330
  .contextMenu{
329
- @apply fixed z-20 bg-base-400 min-w-[150px] overflow-y-auto rounded-lg;
331
+ @apply fixed bg-base-400 min-w-[150px] overflow-y-auto rounded-lg;
330
332
  @apply border-[1px] border-text-50 shadow-2xl whitespace-nowrap;
331
333
  transition: all 150ms cubic-bezier(0.25, 1, 0.5, 1);
332
334
  opacity: 0;
@@ -1,18 +1,45 @@
1
1
  <template>
2
2
 
3
- <div v-if="mode === ''" :class="compClass">
4
- <select v-model="DD">
5
- <option disabled selected>Tanggal</option>
6
- <option v-for="d in 31" :value="d.toString().padStart(2, '0')">{{ d }}</option>
7
- </select>
8
- <select v-model="MM">
9
- <option disabled selected>Bulan</option>
10
- <option v-for="mmm in months" :value="mmm[0]">{{ mmm[1] }}</option>
11
- </select>
12
- <select v-model="YYYY">
13
- <option disabled selected>Tahun</option>
14
- <option v-for="yyyy in years" :value="yyyy">{{ yyyy }}</option>
15
- </select>
3
+ <div v-if="mode === ''" :class="compClass" class="divide-x divide-text-50">
4
+ <div class="w-[50px] flex flex-row items-center relative">
5
+ <select v-model="DD" class="text-left w-full flex-1 px-3">
6
+ <option disabled selected>Tanggal</option>
7
+ <option v-for="d in 31" :value="d.toString().padStart(2, '0')">{{ d }}</option>
8
+ </select>
9
+
10
+ <div class="absolute top-0 bottom-0 right-0 p-2 flex justify-center items-center pointer-events-none">
11
+ <svg class="fill-text-300" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
12
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M4.96967 8.71967C5.26256 8.42678 5.73744 8.42678 6.03033 8.71967L11.8232 14.5126C11.9209 14.6102 12.0791 14.6102 12.1768 14.5126L17.9697 8.71967C18.2626 8.42677 18.7374 8.42677 19.0303 8.71967C19.3232 9.01256 19.3232 9.48743 19.0303 9.78033L13.2374 15.5732C12.554 16.2566 11.446 16.2566 10.7626 15.5732L4.96967 9.78033C4.67678 9.48744 4.67678 9.01256 4.96967 8.71967Z"/>
13
+ </svg>
14
+ </div>
15
+ </div>
16
+
17
+ <div class="w-[60px] flex flex-row items-center relative">
18
+ <select v-model="MM" class="text-left w-full flex-1 px-3">
19
+ <option disabled selected>Bulan</option>
20
+ <option v-for="mmm in months" :value="mmm[0]">{{ mmm[1] }}</option>
21
+ </select>
22
+
23
+ <div class="absolute top-0 bottom-0 right-0 p-2 flex justify-center items-center pointer-events-none">
24
+ <svg class="fill-text-300" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
25
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M4.96967 8.71967C5.26256 8.42678 5.73744 8.42678 6.03033 8.71967L11.8232 14.5126C11.9209 14.6102 12.0791 14.6102 12.1768 14.5126L17.9697 8.71967C18.2626 8.42677 18.7374 8.42677 19.0303 8.71967C19.3232 9.01256 19.3232 9.48743 19.0303 9.78033L13.2374 15.5732C12.554 16.2566 11.446 16.2566 10.7626 15.5732L4.96967 9.78033C4.67678 9.48744 4.67678 9.01256 4.96967 8.71967Z"/>
26
+ </svg>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="w-[70px] flex flex-row items-center relative">
31
+ <select v-model="YYYY" class="text-left w-full flex-1 px-3">
32
+ <option disabled selected>Tahun</option>
33
+ <option v-for="yyyy in years" :value="yyyy">{{ yyyy }}</option>
34
+ </select>
35
+
36
+ <div class="absolute top-0 bottom-0 right-0 p-2 flex justify-center items-center pointer-events-none">
37
+ <svg class="fill-text-300" width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
38
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M4.96967 8.71967C5.26256 8.42678 5.73744 8.42678 6.03033 8.71967L11.8232 14.5126C11.9209 14.6102 12.0791 14.6102 12.1768 14.5126L17.9697 8.71967C18.2626 8.42677 18.7374 8.42677 19.0303 8.71967C19.3232 9.01256 19.3232 9.48743 19.0303 9.78033L13.2374 15.5732C12.554 16.2566 11.446 16.2566 10.7626 15.5732L4.96967 9.78033C4.67678 9.48744 4.67678 9.01256 4.96967 8.71967Z"/>
39
+ </svg>
40
+ </div>
41
+ </div>
42
+
16
43
  </div>
17
44
 
18
45
  <div v-else :class="compClass">
@@ -70,7 +97,7 @@
70
97
  <div class="grid grid-cols-7 gap-2 mt-2">
71
98
  <div v-for="i in 7">{{ getDayOfWeekLabel(i) }}</div>
72
99
  <button type="button" :class="buttonStyle(d.value)"
73
- :disabled="(allowedDates && !allowedDates.includes(d.value)) || (onlyTodayAndFuture && isValidTodayAndFuture(d.value))"
100
+ :disabled="(allowedDates && !allowedDates.includes(d.value)) || (onlyTodayAndFuture && isValidTodayAndFuture(d.value)) || (pastOnly && isPast(d.value))"
74
101
  v-for="d in contextMenuDates" @click="setValue(d.value)">
75
102
  {{ d.date }}
76
103
  </button>
@@ -146,7 +173,8 @@ export default{
146
173
 
147
174
  allowedDates: Array,
148
175
 
149
- onlyTodayAndFuture: Boolean
176
+ onlyTodayAndFuture: Boolean,
177
+ pastOnly: Boolean,
150
178
 
151
179
  },
152
180
 
@@ -274,6 +302,10 @@ export default{
274
302
  return val.localeCompare(this.today) < 0
275
303
  },
276
304
 
305
+ isPast(val){
306
+ return val.localeCompare(this.today) > 0
307
+ },
308
+
277
309
  setValue(d){
278
310
  this.$emit('update:modelValue', d)
279
311
  this.$emit('change', d)
@@ -291,8 +323,7 @@ export default{
291
323
  <style module>
292
324
 
293
325
  .datepicker {
294
- @apply min-h-[var(--h-cp)];
295
- @apply flex items-center rounded-lg overflow-hidden cursor-pointer relative;
326
+ @apply inline-flex overflow-hidden cursor-pointer relative min-w-[160px];
296
327
  @apply border-[1px] border-text-200 bg-base-300 rounded-lg;
297
328
  @apply cursor-pointer;
298
329
  }
@@ -300,7 +331,7 @@ export default{
300
331
  @apply hover:border-text-300
301
332
  }
302
333
  .datepicker select{
303
- @apply appearance-none p-2 bg-transparent text-center w-full outline-none;
334
+ @apply appearance-none p-2 bg-transparent text-center outline-none;
304
335
  }
305
336
  .datepicker input{
306
337
  @apply appearance-none p-2 bg-transparent w-full outline-none;
@@ -310,7 +341,7 @@ export default{
310
341
  }
311
342
  .datepicker input[type=radio]{
312
343
  @apply hidden;
313
- }K
344
+ }
314
345
  .datepicker input[type=radio]:checked + label{
315
346
  }
316
347
 
@@ -347,11 +378,7 @@ export default{
347
378
  }
348
379
 
349
380
  .mode-{
350
- @apply flex flex-row gap-2;
351
- }
352
- .mode- select{
353
- @apply rounded-lg;
354
- @apply min-h-[var(--h-cp)];
381
+ @apply inline-flex flex-row;
355
382
  }
356
383
  .mode- select:first-child{
357
384
  @apply w-12;
@@ -179,6 +179,9 @@ export default {
179
179
  @apply bg-base-50 text-text;
180
180
  }
181
181
 
182
+ .dropdown select[disabled]{
183
+ @apply cursor-not-allowed;
184
+ }
182
185
  .dropdown option[disabled]{
183
186
  @apply text-text-300;
184
187
  }
@@ -190,7 +193,7 @@ export default {
190
193
  }
191
194
 
192
195
  .arrow svg{
193
- @apply block fill-text-200;
196
+ @apply block fill-text-300;
194
197
  }
195
198
  .dropdown:hover svg{
196
199
  @apply fill-text-300;
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div :class="$style.Flex" :style="computedStyle">
3
3
 
4
- <component v-for="(item, idx) in items"
4
+ <component v-for="item in items"
5
5
  :is="item.type"
6
6
  :key="item.key"
7
7
  :="item" />
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div :class="$style.comp">
3
3
 
4
- <div class="overflow-x-auto bg-text-50" :class="containerClass">
4
+ <div class="overflow-x-auto bg-text-50" :class="containerClass" v-if="!readonly">
5
5
  <div class="flex flex-row">
6
6
  <button class="p-3" type="button" @click="format('bold')">
7
7
  <svg width="14" height="14" class="fill-text-400 hover:fill-primary" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M0 64C0 46.3 14.3 32 32 32H80 96 224c70.7 0 128 57.3 128 128c0 31.3-11.3 60.1-30 82.3c37.1 22.4 62 63.1 62 109.7c0 70.7-57.3 128-128 128H96 80 32c-17.7 0-32-14.3-32-32s14.3-32 32-32H48V256 96H32C14.3 96 0 81.7 0 64zM224 224c35.3 0 64-28.7 64-64s-28.7-64-64-64H112V224H224zM112 288V416H256c35.3 0 64-28.7 64-64s-28.7-64-64-64H224 112z"/></svg>
@@ -34,7 +34,7 @@
34
34
  </div>
35
35
  </div>
36
36
 
37
- <article ref="article" contenteditable="true" v-html="html" @paste="onPaste" spellcheck="false"
37
+ <article ref="article" :contenteditable="!readonly" v-html="html" @paste="onPaste" spellcheck="false"
38
38
  @input="onInput" @click="onClick" :class="itemClass"
39
39
  @blur="onBlur">
40
40
  </article>
@@ -262,6 +262,7 @@ export default{
262
262
  uploadImageFn: String,
263
263
  containerClass: String,
264
264
  itemClass: String,
265
+ readonly: Boolean
265
266
  },
266
267
 
267
268
  computed: {
@@ -5,7 +5,11 @@
5
5
  @mousedown="onMouseDown"
6
6
  :style="computedStyle">
7
7
 
8
- <slot v-if="status === 0" name="empty" :instance="this"></slot>
8
+ <slot v-if="status === 0" name="empty" :instance="this">
9
+ <div :class="$style.loading">
10
+ <svg width="50%" height="50%" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M447.1 32h-384C28.64 32-.0091 60.65-.0091 96v320c0 35.35 28.65 64 63.1 64h384c35.35 0 64-28.65 64-64V96C511.1 60.65 483.3 32 447.1 32zM111.1 96c26.51 0 48 21.49 48 48S138.5 192 111.1 192s-48-21.49-48-48S85.48 96 111.1 96zM446.1 407.6C443.3 412.8 437.9 416 432 416H82.01c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C142.1 290.4 146.9 288 152 288s9.916 2.441 12.93 6.574l32.46 44.51l93.3-139.1C293.7 194.7 298.7 192 304 192s10.35 2.672 13.31 7.125l128 192C448.6 396 448.9 402.3 446.1 407.6z"/></svg>
11
+ </div>
12
+ </slot>
9
13
 
10
14
  <slot v-else-if="status === 1" name="loading">
11
15
  <div :class="$style.loading + (spinnerType === 'shimmer' ? ' ' + $style.shimmer : '')">
@@ -16,7 +20,11 @@
16
20
  <div v-else-if="status === 2 && actualSrc.indexOf('<svg') >= 0" v-html="actualSrc"></div>
17
21
  <img v-else-if="status === 2" :class="computedItemClass" :src="actualSrc" ref="img" :alt="alt" />
18
22
 
19
- <slot v-else-if="status === 3" name="error" :instance="this"></slot>
23
+ <slot v-else-if="status === 3" name="error" :instance="this">
24
+ <div :class="$style.loading">
25
+ <svg width="50%" height="50%" class="fill-text-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.0.0-alpha3 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) --><path d="M630.8 469.1l-55.95-43.85C575.3 422.2 575.1 419.2 575.1 416l.0034-320c0-35.35-28.65-64-64-64H127.1C113.6 32 100.4 36.98 89.78 45.06L38.81 5.113C28.34-3.058 13.31-1.246 5.109 9.192C-3.063 19.63-1.235 34.72 9.187 42.89L601.2 506.9C605.6 510.3 610.8 512 615.1 512c7.125 0 14.17-3.156 18.91-9.188C643.1 492.4 641.2 477.3 630.8 469.1zM223.1 149.6l-64.29-50.39C164.2 97.15 169.9 96 175.1 96c26.51 0 48 21.49 48 48C223.1 145.9 223.4 147.7 223.1 149.6zM331.2 234.3l23.45-35.18C357.7 194.7 362.7 192 368 192s10.35 2.672 13.31 7.125l103.9 155.9L331.2 234.3zM145.1 416c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C206.1 290.4 210.9 288 216 288s9.916 2.441 12.93 6.574l32.46 44.51l16.43-24.65L63.99 146.8L63.99 416c0 35.35 28.65 64 64 64h361.1l-81.66-64H145.1z"/></svg>
26
+ </div>
27
+ </slot>
20
28
 
21
29
  <input v-if="Boolean(editable)" class="hidden" type="file" accept="image/*" ref="file" @change="onChange"/>
22
30
 
@@ -209,9 +217,9 @@ export default{
209
217
  else if(Array.isArray(this.src)){
210
218
 
211
219
  const src = {}
212
- src['all'] = (this.src[0].indexOf('://') < 0 ? import.meta.env.VITE_IMAGE_HOST + '/' : '') + this.src[0]
220
+ src['all'] = ((this.src[0] ?? '').indexOf('://') < 0 ? import.meta.env.VITE_IMAGE_HOST + '/' : '') + this.src[0]
213
221
  if(this.src[1]){
214
- src['md'] = (this.src[1].indexOf('://') < 0 ? import.meta.env.VITE_IMAGE_HOST + '/' : '') + this.src[1]
222
+ src['md'] = ((this.src[1] ?? '').indexOf('://') < 0 ? import.meta.env.VITE_IMAGE_HOST + '/' : '') + this.src[1]
215
223
  }
216
224
 
217
225
  let imgSrc