@mixd-id/web-scaffold 0.1.2301231342 → 0.1.2301231344

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mixd-id/web-scaffold",
3
3
  "private": false,
4
- "version": "0.1.2301231342",
4
+ "version": "0.1.2301231344",
5
5
  "scripts": {
6
6
  "dev": "vite serve",
7
7
  "build": "vite build",
@@ -38,7 +38,6 @@
38
38
  "nprogress": "^0.2.0",
39
39
  "pinia": "^2.0.14",
40
40
  "prismjs": "^1.28.0",
41
- "sequelize": "^6.29.0",
42
41
  "serve-static": "^1.15.0",
43
42
  "tailwindcss": "^3.2.4",
44
43
  "vue": "^3.2.25",
@@ -48,6 +47,7 @@
48
47
  "@vitejs/plugin-vue": "^2.2.0",
49
48
  "autoprefixer": "^10.4.4",
50
49
  "postcss": "^8.4.12",
50
+ "sequelize": "^6.29.0",
51
51
  "vite": "^2.8.0"
52
52
  },
53
53
  "description": "This scaffold based on express vitejs vuejs",
@@ -86,7 +86,7 @@ export default{
86
86
  @apply h-[var(--h-cp)];
87
87
  @apply relative flex items-center justify-center;
88
88
  @apply whitespace-nowrap text-ellipsis overflow-hidden;
89
- @apply rounded-md;
89
+ @apply rounded-lg;
90
90
  }
91
91
  .button>*:first-child{
92
92
  @apply flex items-center justify-center
@@ -3,12 +3,12 @@
3
3
  <div :class="$style.inner">
4
4
  <span v-if="images && images.length && images.length > 0" v-for="image in images" :key="image">
5
5
  <a v-if="image.target && image.target.indexOf('://') >= 0" :href="image.target" @click="checkClick">
6
- <Image :src="image.imageUrl" :outerClass="imageClass" />
6
+ <Image :src="image.imageUrl" :class="imageClass" />
7
7
  </a>
8
8
  <router-link v-if="image.target" :to="scrolling ? '' : image.target">
9
- <Image :src="image.imageUrl" :outerClass="imageClass"/>
9
+ <Image :src="image.imageUrl" :class="imageClass"/>
10
10
  </router-link>
11
- <Image v-else :src="image.imageUrl" :outerClass="imageClass" />
11
+ <Image v-else :src="image.imageUrl" :class="imageClass" />
12
12
  </span>
13
13
  <div v-else :class="imageClass" class="bg-gray-200 animate-pulse"></div>
14
14
  </div>
@@ -2,7 +2,7 @@
2
2
  <Teleport to=".Y29u">
3
3
  <div v-if="!!(computedState)" :class="$style.contextMenu" :style="computedStyle" ref="contextMenu">
4
4
  <div :class="bodyClass">
5
- <slot></slot>
5
+ <slot name="default" :context="context"></slot>
6
6
  </div>
7
7
  </div>
8
8
  </Teleport>
@@ -50,7 +50,8 @@ export default {
50
50
  data(){
51
51
  return {
52
52
  computedStyle: null,
53
- isOpen: false
53
+ isOpen: false,
54
+ context: null
54
55
  }
55
56
  },
56
57
 
@@ -105,7 +106,7 @@ export default {
105
106
  this.$refs.contextMenu.classList.remove(this.$style.active)
106
107
  },
107
108
 
108
- open(caller){
109
+ open(caller, context){
109
110
 
110
111
  if(caller){
111
112
  this.isOpen = true
@@ -118,6 +119,8 @@ export default {
118
119
  caller = caller.$el ? caller.$el :
119
120
  caller instanceof HTMLElement ? caller : null
120
121
 
122
+ this.context = context
123
+
121
124
  if(caller){
122
125
 
123
126
  this.$nextTick(() => {
@@ -0,0 +1,154 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <slot v-if="display >= 4 && $slots.day" name="day" :day="day"></slot>
5
+ <div v-else-if="display >= 4" :class="$style.lap"></div>
6
+
7
+ <slot v-if="display >= 3 && $slots.hour" name="hour" :hour="hour"></slot>
8
+ <div v-else-if="display >= 3" :class="$style.lap">{{ hour }}</div>
9
+
10
+ <slot v-if="display >= 2 && $slots.minute" name="minute" :minute="minute"></slot>
11
+ <div v-else-if="display >= 2" :class="$style.lap">{{ minute }}</div>
12
+
13
+ <slot v-if="display >= 1 && $slots.second" name="second" :second="second"></slot>
14
+ <div ref="second" v-else-if="display >= 1" :class="$style.lap">
15
+ <div>23</div>
16
+ <div>21</div>
17
+ </div>
18
+
19
+ <button @click="tick">Tick</button>
20
+
21
+ </div>
22
+ </template>
23
+
24
+ <script>
25
+
26
+ import debounce from "lodash/debounce";
27
+
28
+ export default{
29
+
30
+ props: {
31
+
32
+ display: {
33
+ type: [ String, Number ], // default: 3
34
+ default: 3
35
+ },
36
+
37
+ value: [ String, Number ] // value in second
38
+
39
+ },
40
+
41
+ computed:{
42
+
43
+ day(){
44
+ return Math.floor(this.timer / 86400).toString().padStart(2, '0')
45
+ },
46
+
47
+ hour(){
48
+ return (Math.floor(this.timer / 3600) % 24).toString().padStart(2, '0')
49
+ },
50
+
51
+ minute(){
52
+ return (Math.floor(this.timer / 60) % 60).toString().padStart(2, '0')
53
+ },
54
+
55
+ second(){
56
+ return (this.timer % 60).toString().padStart(2, '0')
57
+ }
58
+
59
+ },
60
+
61
+ data(){
62
+ return {
63
+ timer: null,
64
+ timeoutId: null,
65
+ beforeSecond: null,
66
+ afterSecond: null
67
+ }
68
+ },
69
+
70
+ mounted() {
71
+ this.start()
72
+
73
+ this.$refs.second.addEventListener('transitionend', this.onTransitionEnd)
74
+ },
75
+
76
+ methods: {
77
+
78
+ onTransitionEnd: debounce(function (e){
79
+ /*console.log('onTransitionEnd', e.propertyName)
80
+ console.log(this.$refs.second.childNodes[1])
81
+ console.log(this.$refs.second.childNodes[0])*/
82
+ this.$refs.second.insertBefore(this.$refs.second.childNodes[1], this.$refs.second.childNodes[0])
83
+ this.$refs.second.classList.remove(this.$style.tick)
84
+ this.$refs.second.childNodes[0].innerHTML = ''
85
+ }, 100),
86
+
87
+ start(){
88
+
89
+ this.timer = this.value
90
+ this.timeoutId = window.setInterval(() => {
91
+ this.timer--
92
+
93
+ if(this.timer <= 0){
94
+ window.clearTimeout(this.timeoutId)
95
+ }
96
+ }, 1000)
97
+
98
+ },
99
+
100
+ tick(){
101
+ this.$refs.second.classList.add(this.$style.tick)
102
+ }
103
+
104
+ },
105
+
106
+ watch: {
107
+
108
+ value(to){
109
+ this.start()
110
+ },
111
+
112
+ second(to, from){
113
+ this.$refs.second.firstElementChild.innerHTML = to
114
+ this.$refs.second.lastElementChild.innerHTML = from
115
+ this.tick()
116
+ }
117
+ }
118
+
119
+ }
120
+
121
+ </script>
122
+
123
+ <style module>
124
+
125
+ .comp{
126
+ @apply flex flex-row gap-2;
127
+ }
128
+
129
+ .lap{
130
+ @apply relative overflow-hidden w-[1.5rem];
131
+ }
132
+ .lap>*{
133
+ }
134
+ .lap>*:first-child{
135
+ @apply absolute top-0 left-0;
136
+ transform: translate3d(0, -1rem, 0);
137
+ }
138
+ .lap>*:last-child{
139
+ transform: translate3d(0, 0, 0);
140
+ }
141
+
142
+ .tick{
143
+ }
144
+ .tick>*{
145
+ transition: transform 300ms ease;
146
+ }
147
+ .tick>*:first-child{
148
+ transform: translate3d(0, 0, 0);
149
+ }
150
+ .tick>*:last-child{
151
+ transform: translate3d(0, 1rem, 0);
152
+ }
153
+
154
+ </style>
@@ -1,13 +1,18 @@
1
1
  <template>
2
- <div :class="computedOuterClass">
3
- <slot v-if="editable && $slots['edit-area']" name="edit-area"></slot>
4
- <div v-else-if="editable" :class="$style.editArea" @click="edit"></div>
5
- <img :class="computedClass" :src="actualSrc" ref="img" :style="imageStyle"/>
6
- <input v-if="Boolean(editable)" class="hidden" type="file" accept="image/*" ref="file" @change="onChange"/>
7
- <slot></slot>
8
- <div :class="$style.loading" v-if="loading && spinnerType === 'spinner'">
9
- <svg class="animate-spin aspect-square w-[15%] text-primary" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
2
+ <div :class="outerClass">
3
+
4
+ <slot v-if="$slots['empty'] && status === 0" name="empty" :instance="this"></slot>
5
+ <slot v-else-if="$slots['loading'] && status === 1" name="loading" :instance="this"></slot>
6
+ <div v-else-if="!$slots['loading'] && status === 1 && spinnerType === 'spinner'" :class="$style.loading">
7
+ <svg class="animate-spin aspect-square w-[15%] min-w-[14px] text-primary" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
10
8
  </div>
9
+ <slot v-else-if="$slots['error'] && status === 3" name="error" :instance="this"></slot>
10
+ <img v-else :class="computedClass" :src="actualSrc" ref="img" />
11
+
12
+ <slot :instance="this"></slot>
13
+
14
+ <input v-if="Boolean(editable)" class="hidden" type="file" accept="image/*" ref="file" @change="onChange"/>
15
+
11
16
  </div>
12
17
  </template>
13
18
 
@@ -30,17 +35,11 @@ export default{
30
35
 
31
36
  class: String,
32
37
 
33
- outerClass: String,
34
-
35
38
  editable:{
36
39
  type: [ Boolean, String ],
37
40
  default: false
38
41
  },
39
42
 
40
- aspectRatio: {
41
- type: String
42
- },
43
-
44
43
  src:{
45
44
  type: [ String, Object ]
46
45
  },
@@ -59,36 +58,30 @@ export default{
59
58
 
60
59
  computed:{
61
60
 
62
- computedOuterClass(){
61
+ outerClass(){
63
62
  return [
64
- this.$style.img,
65
- this.outerClass,
66
- this.loading && this.spinnerType === 'shimmer' ? this.$style.shimmer : ''
63
+ this.$style.comp,
64
+ this.class,
65
+ this.status === 1 && this.spinnerType === 'shimmer' && !this.$slots['loading'] ?
66
+ this.$style.shimmer : ''
67
67
  ]
68
68
  .join(' ')
69
69
  },
70
70
 
71
71
  computedClass(){
72
72
  return [
73
+ this.$style.img,
73
74
  this.class
74
75
  ]
75
76
  .join(' ')
76
- },
77
-
78
- imageStyle(){
79
- return {
80
- ...(this.aspectRatio ? { 'aspect-ratio':this.aspectRatio } : {}),
81
- ...(this.actualSrc ? {} : { visibility:'hidden' })
82
- }
83
77
  }
84
78
 
85
79
  },
86
80
 
87
81
  data(){
88
82
  return {
89
- loading: false,
90
- actualSrc: null,
91
- loaded: false
83
+ status: 0, // 0:empty, 1:loading, 2:image, 3:error
84
+ actualSrc: 'data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII='
92
85
  }
93
86
  },
94
87
 
@@ -119,9 +112,9 @@ export default{
119
112
  async loadSrc(){
120
113
 
121
114
  if(typeof this.src === 'string') {
122
- if (!this.loaded && this.src.startsWith('data:image')) {
123
- this.loaded = true
115
+ if (this.src.startsWith('data:image')) {
124
116
  this.actualSrc = this.src
117
+ this.status = 2
125
118
  }
126
119
  else{
127
120
  const src = {}
@@ -140,38 +133,34 @@ export default{
140
133
 
141
134
  var img = new Image()
142
135
  img.addEventListener('load', () => {
143
- this.loaded = true
136
+ this.status = 2
144
137
  this.actualSrc = img.src
145
- this.loading = false
146
138
  })
147
139
  img.addEventListener('error', () => {
148
- this.loaded = true
140
+ this.status = 3
149
141
  this.actualSrc = this.defaultSrc
150
- this.loading = false
151
142
  })
152
143
  img.src = src[screens[b]]
153
- this.loading = true
144
+ this.status = 1
154
145
  }
155
146
  }
156
147
  }
157
148
  }
158
- else if(!this.loaded && this.src instanceof File){
149
+ else if(this.src instanceof File){
159
150
  var reader = new FileReader();
160
151
 
161
152
  reader.addEventListener('load', () => {
162
- this.loaded = true
153
+ this.status = 2
163
154
  this.actualSrc = reader.result
164
- this.loading = false
165
155
  }, false)
166
156
 
167
157
  reader.addEventListener('error', () => {
168
- this.loaded = true
158
+ this.status = 3
169
159
  this.actualSrc = this.defaultSrc
170
- this.loading = false
171
160
  })
172
161
 
173
162
  reader.readAsDataURL(this.src)
174
- this.loading = true
163
+ this.status = 1
175
164
  }
176
165
  }
177
166
 
@@ -180,7 +169,6 @@ export default{
180
169
  watch:{
181
170
 
182
171
  src(to){
183
- this.loaded = false
184
172
  this.loadSrc()
185
173
  },
186
174
 
@@ -195,10 +183,14 @@ export default{
195
183
 
196
184
  <style module>
197
185
 
198
- .img{
186
+ .comp{
199
187
  @apply relative;
200
188
  }
201
189
 
190
+ .img{
191
+ @apply object-contain;
192
+ }
193
+
202
194
  .editArea{
203
195
  @apply absolute top-0 left-0 right-0 bottom-0;
204
196
  }
@@ -209,8 +201,7 @@ export default{
209
201
  }
210
202
 
211
203
  .shimmer{
212
- @apply bg-text-100 animate-pulse;
204
+ @apply bg-text-200 animate-pulse;
213
205
  }
214
206
 
215
-
216
207
  </style>
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <div :class="$style.comp">
3
+
4
+ <div class="absolute top-0 right-0 bg-black/50 rounded-lg flex flex-row gap-2 items-center m-1">
5
+ <button type="button" class="p-1" @click="prev">Prev</button>
6
+ <button type="button" class="p-1" @click="next">Next</button>
7
+ <button type="button" class="p-1" @click="toggleMode" :class="mode === 1 ? 'bg-red-500' : 'bg-green-500'">360</button>
8
+ </div>
9
+
10
+ <img v-if="mode === 1" :src="staticSrc" class="pointer-events-none" style="user-select: none" />
11
+ <div v-else-if="mode === 2 && status === 1">Loading...</div>
12
+ <div v-else-if="mode === 2 && status === 2">
13
+ <img v-for="(path, idx) in src" :src="path" :class="idx === index ? '' : 'hidden'"
14
+ class="pointer-events-none" style="user-select: none"/>
15
+ </div>
16
+ </div>
17
+ </template>
18
+
19
+ <script>
20
+
21
+ export default{
22
+
23
+ props: {
24
+
25
+ src: Array,
26
+
27
+ staticSrc: String
28
+
29
+ },
30
+
31
+ data(){
32
+ return {
33
+ status: 0,
34
+ index: 0,
35
+ mode: 1,
36
+ startX: null
37
+ }
38
+ },
39
+
40
+ mounted(){
41
+ this.load()
42
+
43
+ this.$el.addEventListener('mousedown', this.onMouseDown)
44
+ },
45
+
46
+ methods: {
47
+
48
+ load(){
49
+
50
+ this.status = 1
51
+ let loadedCount = 0
52
+
53
+ const loadComplete = () => {
54
+ loadedCount++
55
+
56
+ if(loadedCount >= this.src.length){
57
+ this.status = 2
58
+ }
59
+ }
60
+
61
+ this.src.forEach((src) => {
62
+ var img = new Image()
63
+ img.addEventListener('load', () => {
64
+ loadComplete()
65
+ })
66
+ img.addEventListener('error', () => {
67
+ loadComplete()
68
+ })
69
+ img.src = src
70
+ })
71
+
72
+ },
73
+
74
+ prev(){
75
+ this.index--
76
+ if(this.index < 0)
77
+ this.index = this.src.length - 1
78
+ },
79
+
80
+ next(){
81
+ this.index++
82
+ if(this.index >= this.src.length)
83
+ this.index = 0
84
+ },
85
+
86
+ toggleMode(){
87
+ this.mode = this.mode === 1 ? 2 : 1
88
+ },
89
+
90
+ onMouseMove(e){
91
+ const curX = e.touches ? e.touches[0].clientX : e.clientX
92
+ const distance = curX - this.startX
93
+ if(distance > 5){
94
+ this.next()
95
+ this.startX = curX
96
+ }
97
+ else if(distance < -5){
98
+ this.prev()
99
+ this.startX = curX
100
+ }
101
+ },
102
+
103
+ onMouseUp(){
104
+ window.removeEventListener('mousemove', this.onMouseMove)
105
+ window.removeEventListener('mouseup', this.onMouseUp)
106
+ this.startX = null
107
+ },
108
+
109
+ onMouseDown(e){
110
+
111
+ if(this.mode !== 2) return
112
+
113
+ this.startX = e.touches ? e.touches[0].clientX : e.clientX
114
+ window.addEventListener('mousemove', this.onMouseMove)
115
+ window.addEventListener('mouseup', this.onMouseUp)
116
+
117
+ }
118
+
119
+ },
120
+
121
+ watch: {
122
+
123
+ src(to){
124
+ console.log('src', to)
125
+ }
126
+
127
+
128
+ }
129
+
130
+ }
131
+
132
+ </script>
133
+
134
+ <style module>
135
+
136
+ .comp{
137
+ @apply relative;
138
+ }
139
+
140
+ </style>
@@ -394,7 +394,7 @@ export default{
394
394
 
395
395
  onHooks(module, event, items){
396
396
 
397
- console.log('onHooks', module, event, items)
397
+ //console.log('onHooks', module, event, items)
398
398
 
399
399
  if(!Array.isArray(items)) return
400
400
  items = items.filter((_) => _).map((_) => {
package/src/index.js CHANGED
@@ -156,6 +156,7 @@ export default{
156
156
  app.component('ChatTyping', defineAsyncComponent(() => import("./components/ChatTyping.vue")))
157
157
  app.component('Checkbox', defineAsyncComponent(() => import("./components/Checkbox.vue")))
158
158
  app.component('CopyToClipboard', defineAsyncComponent(() => import("./components/CopyToClipboard.vue")))
159
+ app.component('Countdown', defineAsyncComponent(() => import("./components/Countdown.vue")))
159
160
  app.component('Dropdown', defineAsyncComponent(() => import("./components/Dropdown.vue")))
160
161
  app.component('Datepicker', defineAsyncComponent(() => import("./components/Datepicker.vue")))
161
162
  app.component('ErrorText', defineAsyncComponent(() => import("./components/ErrorText.vue")))
@@ -164,6 +165,7 @@ export default{
164
165
  app.component('Ahref', defineAsyncComponent(() => import("./components/Ahref.vue")))
165
166
  app.component('Switch', defineAsyncComponent(() => import("./components/Switch.vue")))
166
167
  app.component('Image', defineAsyncComponent(() => import("./components/Image.vue")))
168
+ app.component('Image360', defineAsyncComponent(() => import("./components/Image360.vue")))
167
169
  app.component('ImagePreview', defineAsyncComponent(() => import("./components/ImagePreview.vue")))
168
170
  app.component('ImageFullScreen', defineAsyncComponent(() => import("./components/ImageFullScreen.vue")))
169
171
  app.component('ImportModal', defineAsyncComponent(() => import("./components/ImportModal.vue")))